Program: permute
Problem
Have you ever wanted to generate all possible permutations of an array or to execute some code for every possible permutation? For example:
% echo man bites dog | permute
dog bites man
bites dog man
dog man bites
man dog bites
bites man dog
man bites dogThe number of permutations of a set is the factorial of the size of the set. This grows big extremely fast, so you don’t want to run it on many permutations:
Set Size Permutations 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 10 3628800 11 39916800 12 479001600 13 6227020800 14 87178291200 15 1307674368000
Doing something for each alternative takes a correspondingly large amount of time. In fact, factorial algorithms exceed the number of particles in the universe with very small inputs. The factorial of 500 is greater than ten raised to the thousandth power!
use Math::BigInt;
sub factorial {
my $n = shift;
my $s = 1;
$s *= $n-- while $n > 0;
return $s;
}
print factorial(Math::BigInt->new("500"));
+1220136... (1035 digits total)The two solutions that follow differ in the order of the permutations they return.
The solution in Example 4.3 uses a classic list permutation algorithm used by Lisp hackers. It’s relatively straightforward but makes unnecessary copies. It’s also hardwired to do nothing but print out its permutations.
Example 4-3. tsc-permute
#!/usr/bin/perl -n
# tsc_permute: permute each word of input permute([split], []); sub permute { my @items = @{ $_[0] }; my @perms = @{ $_[1] }; unless (@items) ...Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access