user2335015
user2335015

Reputation: 121

make all possible combinations in perl

I want to make all possible combination from my elements in an array, and I have no clue how to do this, just a little smart.

my array looks like this:

@array = ('a', 'b', 'c', 'd', 'e', 'f');

and I wish to get an output like this:

a
ab
abc
abcd
abcde
abcdef
abcdf
abce
abcef
...

etc

with all combinations, no overlapping (e.g. ab and ba). and having any number of elements from 1-6. The order doesn't matter

Upvotes: 0

Views: 1173

Answers (3)

ikegami
ikegami

Reputation: 385655

So you want

for my $s0 ($array[0], '') {
   for my $s1 ($array[1], '') {
      for my $s2 ($array[2], '') {
         ...
            print(join('', $s1, $s2, $s3, ...), "\n");
         ...
      }
   }
}

Use Algorithm::Loops's NestedLoops when you want arbitrarily nested loops.

use Algorithm::Loops qw( NestedLoops );

NestedLoops(
   [ map { $_, "" } @array ],
   sub { print(join('', @_), "\n"); },
);

But you might notice each of those loops have two states. Binary! It can be done with little overheard.

my $num_bits = @array;
my $last = ~( -1 << $num_bits );
my $high_bit_mask = 1 << ( $num_bits - 1 );

for (my $i = $last; $i--; ) {
   my $s = '';
   my $mask = $high_bit_mask;
   for my $bit_num (0..$num_bits) {
      $s .= $array[$bit_num] if $i & $mask;
      $mask >>= 1;
   }

   print("$s\n");
}

Upvotes: 0

choroba
choroba

Reputation: 241808

See Math::Subsets::List:

use Math::Subsets::List;
subsets {say "@_"} qw(a b c);
#
#  a
#  b
#  c
#  a b
#  a c
#  b c
#  a b c 

Upvotes: 3

Michal Gasek
Michal Gasek

Reputation: 6413

Algorithm::Combinatorics module does exactly what you want:

Math::Combinatorics module does it too.

Upvotes: 1

Related Questions