#! /usr/bin/env raku subset BOARDPOS where * ~~ /^<[a..h]><[1..8]>$/; subset MOVE of Int where -7 <= * <= 7; unit sub MAIN (BOARDPOS $start, BOARDPOS $end, :v(:$verbose)); my %seen = ( $start => True ); my @queue = \{ steps => 0, pos => $start, path => ($start,) }; while @queue { my %curr = @queue.shift; say ": Steps %curr: at pos %curr (path: %curr)" if $verbose; if (%curr eq $end) { say ": Arrived at target after %curr steps (path: %curr)" if $verbose; say %curr; last; } for ( (-2,-1), (-2,1), (2,-1), (2,1), (-1,-2), (-1,2), (1,-2), (1,2)) -> ($row-offset, $col-offset) { my $new-pos = new-pos-knight(%curr, c => $col-offset, r => $row-offset) // next; next if %seen{$new-pos}++; @queue.push: { pos => $new-pos, steps => %curr +1, path => ( %curr, $new-pos).flat }; } } sub new-pos-knight (BOARDPOS $pos, MOVE :r(:$row-offset), MOVE :c(:$col-offset)) { my ($col, $row) = $pos.comb; my $new-row = $row + $row-offset; return unless 1 <= $new-row <= 8; my $new-col = (ord($col) + $col-offset).chr; return unless $new-col eq any(); return $new-col ~ $new-row; }