use strict; use warnings; sub first { ( (1)x$_[1], (0)x($_[0]-$_[1]) ); } sub nextstep { my @p = @_; my $i = $#p; $i-- while $i>=0 and !$p[$i]; # find leading 1 return () if $i<0; # only 0s => nothing to do my @sub; if( $i==0 or not( @sub = nextstep( @p[0..($i-1)] ) ) ) { return () if $i==$#p; $p[$i] = 0; $p[$i+1] = 1; @sub = first( $i, scalar grep { $_ == 1 } @p[0..($i-1)] ); } return ( @sub, @p[$i..$#p] ); } my @data = 'a'..'e'; my @logical = first( scalar(@data), 3 ); while( @logical ) { print "@logical: ", @data[ grep { $logical[$_] } 0..$#logical ], "\n"; @logical = nextstep( @logical ) }