55 lines
1.1 KiB
Perl
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;
|