Learning/AoC/2024/day_1/day_1.pl
2025-02-25 21:46:22 +01:00

153 lines
3.4 KiB
Perl

#!/usr/bin/perl
use v5.40;
sub day1_1( $filename ) {
open my $fh, '<', $filename;
my @list1;
my @list2;
my $counter = 0;
while(my $line = readline $fh) {
my @data = split " ", $line;
if (@data == 2) {
push @list1, $data[0];
push @list2, $data[1];
} else {
print "More than two data points found at: $counter\n";
return -1;
}
$counter++;
}
@list1 = sort @list1;
@list2 = sort @list2;
if (@list1 != @list2) {
print("indices don't match\n");
return -1;
}
my $total = 0;
foreach my $i ( 0 .. $#list1) {
$total += abs($list1[$i] - $list2[$i]);
}
close $fh;
return $total;
}
sub find_count($item, $is_sorted, @list) {
if($is_sorted != 1) {
@list = sort @list;
}
my $lower_bound = 0;
my $upper_bound = $#list;
my $index = 0;
my $found_location = 0;
until($found_location == 1) {
if ($upper_bound - $lower_bound <= 1) {
if ($list[$upper_bound] == $item) {
$index = $upper_bound;
last;
} elsif ($list[$lower_bound] == $item) {
$index = $lower_bound;
last;
} else {
return 0;
}
}
$index = round(($upper_bound + $lower_bound) / 2);
if ($list[$index] > $item) {
$upper_bound = $index;
} elsif ($list[$index] < $item) {
$lower_bound = $index;
} else {
last;
}
}
my $count = 1;
my $index_above = $index + 1;
my $index_lower = $index - 1;
my $index_above_found = 1;
my $index_lower_found = 1;
while( $index_above_found == 1 || $index_lower_found == 1 ) {
if($index_above_found == 1) {
if($list[$index_above] == $item) {
$count++;
$index_above++;
} else {
$index_above_found = 0;
}
}
if($index_lower_found == 1) {
if($list[$index_lower] == $item) {
$count++;
$index_lower--;
} else {
$index_lower_found = 0;
}
}
}
return $count;
}
sub day1_2( $filename ) {
open( my $FH, '<', $filename) or die $!;
my @list1;
my @list2;
my $counter = 0;
while(<$FH>) {
my @data = split(" ", $_);
if (@data == 2) {
push(@list1, $data[0]);
push(@list2, $data[1]);
} else {
print("More than two data points found at: $counter\n");
return -1;
}
$counter++;
}
if($#list1 != $#list2) {
print("indices don't match\n");
return -1;
}
@list1 = sort @list1;
@list2 = sort @list2;
my $total = 0;
my $prev_num = 0;
my $prev_count = 0;
foreach my $item (@list1) {
my $loc_count = 0;
if ($item == $prev_num ) {
$loc_count = $prev_count;
} else {
$loc_count = find_count($item, 1, @list2);
}
$total += $item * $loc_count;
$prev_num = $item;
$prev_count = $loc_count;
}
return $total;
}
my $data = "./input_day_1_1.txt";
my $sum = day1_1($data);
my $simi = day1_2($data);
print("Sum of differences: $sum\n");
print("Similarity score: $simi\n");