adventofcode/2024/06/Part2.pm
2024-12-10 18:34:16 -05:00

75 lines
1.5 KiB
Perl

use 5.36.0;
use lib '.';
use DDP;
use Part1;
package Part2;
use Math::Vector::Real;
use List::AllUtils qw/ uniq /;
my @directions = map { V(@$_) } [ -1, 0 ], [ 0, 1 ], [ 1, 0 ], [ 0, -1 ];
sub copy_grid ($grid) {
return [ map { [@$_] } @$grid ];
}
sub add_vectors($x,$y) {
return [ $x->[0]+$y->[0],$x->[1]+$y->[1]];
}
sub do_the_round ($grid) {
my $guard = Part1::find_guard($grid);
my $current_direction = 0;
my %seen;
my $loop = 0;
while () {
my $ahead = $guard + $directions[$current_direction];
last unless Part1::inside_grid( $grid, $ahead );
if ( $grid->[ $ahead->[0] ][ $ahead->[1] ] eq '#' ) {
$current_direction++;
$current_direction %= @directions;
redo;
}
$guard = $ahead;
if ( $seen{"$guard"}{$current_direction} ) {
$loop = 1;
last;
}
$seen{"$guard"}{$current_direction}++;
}
return {
loop => $loop,
seen => [
keys %seen
]
};
}
sub solve ($grid) {
my $guard = Part1::find_guard($grid);
my $current_direction = 0;
my $r = do_the_round($grid);
my $loops = 0;
for my $loc ( grep { $grid->[ $_->[0] ][ $_->[1] ] ne '^' }
map { [/(\d+)/g] } $r->{seen}->@* ) {
my $copy = copy_grid($grid);
$copy->[ $loc->[0] ][ $loc->[1] ] = '#';
$loops++ if do_the_round($copy)->{loop};
}
return $loops;
}
1;