in reply to CPAN module to return successive combinations of n things taken k at a time

Here is an explicit solution w/o using a module that uses a recursive procedure to calculate the next combination:

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 ) }

While I think it works, give the time it took me to get it right and the somewhat tricky logic, I have come to the conclusion, that using a module is the better alternative.

  • Comment on Re: CPAN module to return successive combinations of n things taken k at a time
  • Download Code