sub gen2 { my @set = map chr,@_; my @is = 0; return sub { my $di = $#is; { if( ( $is[ $di ] ||= 0 ) == $#set ) { $is[ $di ] = 0; unshift @is, $di = 0 if --$di < 0; redo; } ++$is[ $di ]; return [ @set[ @is ] ]; } }; } my $gen2 = gen2( 33 .. 126 ); print @$_ while $_ = $gen2->();