adventofcode/2023/03/Part2.pm

55 lines
1.1 KiB
Perl

use 5.38.0;
package Part2;
use Part1;
use List::AllUtils qw/ product sum /;
sub find_gears($input) {
my @lines = split "\n", $input;
unshift @lines, '';
my @entries;
for my $i ( 1..$#lines ) {
my $line = $lines[$i];
while ( $line =~ /\*/g ) {
push @entries => {
prefix => length $`,
length => length $&,
line => $i,
};
}
}
return @entries;
}
sub number_near_gear($gear,$number) {
return if abs( $number->{line} - $gear->{line} ) > 1;
return ($number->{prefix} <= $gear->{prefix} + 1 and $number->{prefix}+$number->{length} >= $gear->{prefix} );
}
sub numbers_near_gear($gear,@numbers) {
return grep { number_near_gear($gear,$_)} @numbers;
}
sub solution_2 ($input) {
my @numbers = Part1::numbers_near_symbols($input);
my @gears = find_gears($input);
my $sum = 0;
for my $gear ( @gears ) {
my @near = numbers_near_gear($gear,@numbers);
next unless @near == 2;
$sum += product map { $_->{n} } @near;
}
return $sum;
}
1;