use 5.20.0; use List::UtilsBy qw/ nsort_by /; use List::AllUtils qw/ min max /; use Math::Vector::Real; use experimental qw/ signatures postderef /; my @grid; my $number = 1364; my @pos = ( [V(1,1), dist(V(1,1)),0] ); my $best = 50; while (@pos) { @pos = nsort_by { $_->[1] } @pos; my $c = shift @pos; use DDP; # p $c; my $i = $c->[2]; next if $i >= $best; unless( $c->[1] ) { say "ONE! ", $i; $best = min $best, $i; next; } push @pos, map { [ $_, dist($_), $i+1 ] } grep { movable($_,$i) } surround($c->[0]); say map { length($_) ? $_ : ' ' } @$_ for @grid; say "\n\n"; # my $x = ; } say scalar grep { $_ and $_ ne '#' } map { @$_} @grid; sub movable( $v, $steps ) { my($x,$y) = @$v; return if $grid[$x][$y] eq '#' or ( $grid[$x][$y] and $grid[$x][$y] <= $steps ); my $is_wall = ( grep { $_ == 1 } split '', sprintf "%b", $x**2 + 3*$x + 2*$x*$y + $y + $y**2 + $number ) % 2; $grid[$x][$y] = $is_wall ? '#' : $steps; return !$is_wall; } sub surround($v) { grep { 0 <= min @$_ } map { $v + $_ } [1,0], [-1,0], [0,1], [0,-1]; } sub dist($v) { return $v->dist2([ 31, 39 ]); }