Initial commit
This commit is contained in:
parent
23170c57bb
commit
3d45e8bf1b
161
AoC/2024/perl/day_1.pl
Normal file
161
AoC/2024/perl/day_1.pl
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
#!/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");
|
||||
Loading…
Reference in New Issue
Block a user