I know implemented some general loop for your problem. A index array is used to remember which index of which array is currently taken. In every iteration the index of the first array is incremented and wrapped around to zero if got to big. In this case the second index is incremented, and so forth...
The resulting order is combinations is here in different, but this could be fixed by changing the order of index incrementation.
my @lists = (
[1,2,6],
[4,5],
[7,3],
);
# Init indexes to zero
my @idx = map { 0 } (0..$#lists);
my $n = 0;
COMP:
while (1) {
$n++;
print "comp[$n] = [";
# Join all list elements given by index array
print join ',', map { $lists[$_][$idx[$_]] } (0..$#lists);
print "]\n";
# Increment lowest index, handle overrun
INDEX:
foreach my $i (0..$#lists) {
$idx[$i]++;
# If new index greater then highest index
if ($idx[$i] > $#{$lists[$i]}) {
# Wrap around
$idx[$i] = 0;
if ($i == $#lists) {
# Stop outher loop if last index overruns
last COMP;
}
}
else {
# stop if no overrun occured
last INDEX;
}
}
}
__END__
comp[1] = [1,4,7]
comp[2] = [2,4,7]
comp[3] = [6,4,7]
comp[4] = [1,5,7]
comp[5] = [2,5,7]
comp[6] = [6,5,7]
comp[7] = [1,4,3]
comp[8] = [2,4,3]
comp[9] = [6,4,3]
comp[10] = [1,5,3]
comp[11] = [2,5,3]
comp[12] = [6,5,3]
Update:
To get the same order like in your example add/change the following:
22a23
> $i = $#lists - $i;
28c29
< if ($i == $#lists) {
---
> if ($i == 0) {
e.g. add the first line after the INDEX foreach loop line and change the if statement like shown. |