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;