B
Bertilo Wennergren
As part of an application I had to solve a permutations problem
that gave me much more trouble than I had anticipated. I did
solve the problem, but I have a very strong feeling that my
solution is very far from the best one. It seems very cumbersome
and inefficient. If anyone has any ideas on how to do this in a
better way, I'd be glad for some input.
Here's what I want to do:
#!/usr/bin/perl -w
use strict;
my @numbers = (
[ 1, 2, 3, ],
[ 4, 5, ],
[ 6, 7, ],
);
my $permutations = CreatePermutations(\@numbers);
for (@$permutations) {
print $_ . "\n";
}
sub CreatePermutations {
my $numbers = shift;
my @permutations;
# Magic stuff goes here!
return \@permutations;
}
The print result should be this exciting bunch of numbers:
1 4 6
1 4 7
1 5 6
1 5 7
2 4 6
2 4 7
2 5 6
2 5 7
3 4 6
3 4 7
3 5 6
3 5 7
As you can see the program lists all possible permutations of
picking one number from each group of numbers in the array
"@numbers". The problem for me was that the subroutine
"CreatePermutations" must work for any number of groups, and for
any number of numbers in each group (at least one group though,
and at least one number in each group).
Here's my working but probably very inefficient version of the
subroutine:
sub CreatePermutations {
my $numbers = shift;
my @permutations;
my $h = 1;
for (@$numbers) {
$h = $h * @$_;
}
$#permutations = $h-1;
for (my $i = 0; $i < @$numbers; $i++) {
my $k = 1;
my $l = 0;
my $m = 0;
for (my $j = $i+1; $j < @$numbers; $j++) {
$k = $k * @{$$numbers[$j]};
}
for (@permutations) {
$_ .= ${$$numbers[$i]}[$l] . ' ';
$m++;
if ($m == $k) {
$l++;
if ($l > @{$$numbers[$i]}-1) {
$l = 0;
}
$m = 0;
}
}
}
return \@permutations;
}
Any ideas on how to do that in a better way? The major issue is
speed since the number of permutations rise quickly when there
are lots of groups with lots of numbers.
that gave me much more trouble than I had anticipated. I did
solve the problem, but I have a very strong feeling that my
solution is very far from the best one. It seems very cumbersome
and inefficient. If anyone has any ideas on how to do this in a
better way, I'd be glad for some input.
Here's what I want to do:
#!/usr/bin/perl -w
use strict;
my @numbers = (
[ 1, 2, 3, ],
[ 4, 5, ],
[ 6, 7, ],
);
my $permutations = CreatePermutations(\@numbers);
for (@$permutations) {
print $_ . "\n";
}
sub CreatePermutations {
my $numbers = shift;
my @permutations;
# Magic stuff goes here!
return \@permutations;
}
The print result should be this exciting bunch of numbers:
1 4 6
1 4 7
1 5 6
1 5 7
2 4 6
2 4 7
2 5 6
2 5 7
3 4 6
3 4 7
3 5 6
3 5 7
As you can see the program lists all possible permutations of
picking one number from each group of numbers in the array
"@numbers". The problem for me was that the subroutine
"CreatePermutations" must work for any number of groups, and for
any number of numbers in each group (at least one group though,
and at least one number in each group).
Here's my working but probably very inefficient version of the
subroutine:
sub CreatePermutations {
my $numbers = shift;
my @permutations;
my $h = 1;
for (@$numbers) {
$h = $h * @$_;
}
$#permutations = $h-1;
for (my $i = 0; $i < @$numbers; $i++) {
my $k = 1;
my $l = 0;
my $m = 0;
for (my $j = $i+1; $j < @$numbers; $j++) {
$k = $k * @{$$numbers[$j]};
}
for (@permutations) {
$_ .= ${$$numbers[$i]}[$l] . ' ';
$m++;
if ($m == $k) {
$l++;
if ($l > @{$$numbers[$i]}-1) {
$l = 0;
}
$m = 0;
}
}
}
return \@permutations;
}
Any ideas on how to do that in a better way? The major issue is
speed since the number of permutations rise quickly when there
are lots of groups with lots of numbers.