# Start with leftmost $by symbols (except last, # which is preincremented before use) @position = (0 .. $by - 2, $by - 2); # Our stop condition is when we've returned the # rightmost $by symbols @stop = @list - $by .. $#list; $next = undef; } # Start by trying to advance the rightmost digit my $cur = $#position; { # **** redo comes back here! **** # Advance current digit to next symbol if ( ++$position[ $cur ] > $stop[ $cur ] ) { # Keep trying next-most rightmost digit # until we find one that's not 'stopped' $position[ --$cur ]++; redo if $position[ $cur ] > $stop[ $cur ]; # Reset digits to right of current digit to # the leftmost possible positions my $new_pos = $position[ $cur ]; @position[$cur .. $#position] = $new_pos .. $new_pos+$by; } } # Advance to next result size when we return last # possible result of this size $next = $position[0]==$stop[0]; return @list[ @position ]; } }