#!/usr/bin/perl -l use strict; use Algorithm::Loops 'NestedLoops'; sub pick { my( $k, @chars ) = @_; my $idx = NestedLoops( [ ( sub { [ ( @_ ? 1+$_ : 0 ) .. @chars-$k+@_ ] } ) x $k ] ); return sub { @chars[ $idx->() ] }; } @ARGV = ( 3, 'a'..'e' ) if ! @ARGV; my $iter = pick( @ARGV ); while( my @subset = $iter->() ) { print "@subset"; } #### ( sub { [ ( @_ ? $_ : 0 ) .. $#chars ] } ) x $k #### $ comb 10 10 | wc -l # with replacement 92378 $ comb -10 19 | wc -l # without replacement 92378 #### #!/usr/bin/perl -l use strict; use Algorithm::Loops 'NestedLoops'; sub pick { my( $k, @chars ) = @_; my $idx = NestedLoops( [ $k < 0 ? ( sub { [ ( @_ ? 1+$_ : 0 ) .. @chars+$k+@_ ] } ) x -$k : ( sub { [ ( @_ ? $_ : 0 ) .. $#chars ] } ) x $k ] ); return sub { @chars[ $idx->() ] }; } @ARGV = ( 3, 'a'..'e' ) if ! @ARGV; my( $k, @chars ) = @ARGV; if( 1 < @chars ) { } elsif( $chars[0] =~ /^[1-9][0-9]*$/ ) { @chars = 1..$chars[0]; } else { @chars = $chars[0] =~ /./g; } my $iter = pick( $k, @chars ); while( my @subset = $iter->() ) { print "@subset"; }