use strict; use warnings; use 5.010; # defined-or use Data::Dump 'dd'; sub get_iterator { my ( $x_to, $y_to, $x_from, $y_from ) = @_; $x_from //= 0; $y_from //= 0; # store partial solutions to explore, to follow left or right # branches, respectively my @left_agenda = [[ $x_from, $y_from ]]; my @right_agenda = [[ $x_from, $y_from ]]; return sub { LOOP: { return undef unless @left_agenda || @right_agenda; my ( $ref, $right ); unless ( $ref = pop @left_agenda ) { $ref = pop @right_agenda; $right = 1 } my @path = @$ref; my ( $x, $y ) = @{ $path[ -1 ] }; $x ++; $y ++ if $right; if ( $x <= $x_to and $y <= $y_to ) { push @path, [ $x, $y ]; return \@path if $x == $x_to and $y == $y_to; push @left_agenda, \@path; push @right_agenda, \@path; } redo LOOP; } } } my $iter = get_iterator( 5, 2 ); my $solution; dd $solution while $solution = $iter-> ();