162 lines
3.5 KiB
Perl
162 lines
3.5 KiB
Perl
#!/usr/bin/perl
|
|
use v5.40;
|
|
|
|
sub day1_1( $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++;
|
|
}
|
|
|
|
@list1 = sort @list1;
|
|
@list2 = sort @list2;
|
|
|
|
if ($#list1 != $#list2) {
|
|
print("indices don't match\n");
|
|
return -1;
|
|
}
|
|
|
|
my $total = 0;
|
|
for( my $i = 0; $i<=$#list1; $i++) {
|
|
$total += abs($list1[$i] - $list2[$i]);
|
|
}
|
|
|
|
close($FH);
|
|
|
|
return $total;
|
|
}
|
|
|
|
sub round( $num ) {
|
|
my $base = int($num);
|
|
if($num - $base >= 0.5) {
|
|
$base++;
|
|
}
|
|
|
|
return $base
|
|
}
|
|
|
|
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");
|