use warnings; use strict; use Data::Dumper; # nCk - combinatoric n Choose k (binomial coefficients) sub nck (&&\$@) { my \$end_cond = shift(); my \$nextk_cond = shift(); my \$k = shift(); return () unless defined(\$k); # start recursive grouping when end condition is fulfilled return [] if \$end_cond->(\$k); # keep looking for a partner my @groups; while (@_) { # nextk condition can force early exit by returning undef my \$pick = shift(); push @groups, map { unshift(@{ \$_ }, \$pick); \$_ } &nck(\$end_cond, \$nextk_cond, \$nextk_cond->(\$k, \$pick), @_); } return @groups; } # standard 5 choose 3 my @grouping = nck sub { \$_[0] <= 0 }, sub { \$_[0] - 1 }, 3, qw(a b c d e); # conditions set to figure out \$1.51 exactly my @stamps = (.02, .03, .04, .05, .1, .26, .27, .42, .8, .84, .87, 5); my @packing = nck sub { \$_[0] >= 1.51 }, sub { my \$nextk = \$_[0] + \$_[1]; \$nextk <= 1.51 ? \$nextk : undef }, 0, @stamps; print Dumper(\@grouping, \@packing); __DATA__ \$VAR1 = [ [ 'a', 'b', 'c' ], [ 'a', 'b', 'd' ], [ 'a', 'b', 'e' ], [ 'a', 'c', 'd' ], [ 'a', 'c', 'e' ], [ 'a', 'd', 'e' ], [ 'b', 'c', 'd' ], [ 'b', 'c', 'e' ], [ 'b', 'd', 'e' ], [ 'c', 'd', 'e' ] ]; \$VAR2 = [ [ '0.02', '0.03', '0.04', '0.05', '0.26', '0.27', '0.84' ], [ '0.02', '0.04', '0.05', '0.26', '0.27', '0.87' ], [ '0.02', '0.27', '0.42', '0.8' ], [ '0.03', '0.04', '0.05', '0.1', '0.42', '0.87' ], [ '0.03', '0.05', '0.1', '0.26', '0.27', '0.8' ], [ '0.03', '0.26', '0.42', '0.8' ], [ '0.04', '0.1', '0.26', '0.27', '0.84' ] ];