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;