use strict; use warnings; use Data::Dump qw/pp dd/; my @paths = find_paths ( [0,0,'start'], [3,1,'goal'] ); pp @paths; sub find_paths { my ($start,$goal)=@_; # --- transform to easier coordinates ($start,$goal) = map old2new($_), ($start,$goal); # --- define closure my @results; my ($gl,$gr) = @$goal; my $pathfinder; $pathfinder = sub { my ( $last ) = @_; # pp \@_ ;# track recursion path my ( $l, $r ) = @$last ; if ( $gl == $l and $gr == $r) { push @results, [ map new2old($_), reverse @_ ]; return; } $pathfinder->( [$l+1,$r ,"left" ], @_ ) if $l < $gl; $pathfinder->( [$l ,$r+1 ,"right"], @_ ) if $r < $gr; }; # --- init recursion $pathfinder->($start); return \@results; } # -------------------------------------------------- # coordinate transformations sub old2new { # left = level - right my ($a_old)=@_; my @new = @$a_old; $new[0] = $new[0] - $new[1]; return \@new; } sub new2old { # level = left + right my ($a_new)=@_; my @old = @$a_new; $old[0] = $old[0] + $old[1]; return \@old; }