tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
|
|
@ -0,0 +1,66 @@
|
|||
sub d {
|
||||
# compare this with the deranged() sub to see how to turn procedural
|
||||
# code into functional one ('functional' as not in 'understandable')
|
||||
$#_ ? map d([ @{$_[0]}, $_[$_] ], @_[1 .. $_-1, $_+1 .. $#_ ]),
|
||||
grep { $_[$_] != @{$_[0]} } 1 .. $#_
|
||||
: $_[0]
|
||||
}
|
||||
|
||||
sub deranged { # same as sub d above, just a readable version to explain method
|
||||
my ($result, @avail) = @_;
|
||||
return $result if !@avail; # no more elements to pick from, done
|
||||
|
||||
my @list; # list of permutations to return
|
||||
for my $i (0 .. $#avail) { # try to add each element to result in turn
|
||||
next if $avail[$i] == @$result; # element n at n-th position, no-no
|
||||
my $e = splice @avail, $i, 1; # move the n-th element from available to result
|
||||
push @list, deranged([ @$result, $e ], @avail);
|
||||
# and recurse down, keep what's returned
|
||||
splice @avail, $i, 0, $e; # put that element back, try next
|
||||
}
|
||||
return @list;
|
||||
}
|
||||
|
||||
sub choose { # choose k among n, i.e. n! / k! (n-k)!
|
||||
my ($n, $k) = @_;
|
||||
factorial($n) / factorial($k) / factorial($n - $k)
|
||||
}
|
||||
|
||||
my @fact = (1);
|
||||
sub factorial {
|
||||
# //= : standard caching technique. If cached value available,
|
||||
# return it; else compute, cache and return.
|
||||
# For this specific task not really necessary.
|
||||
$fact[ $_[0] ] //= $_[0] * factorial($_[0] - 1)
|
||||
}
|
||||
|
||||
my @subfact;
|
||||
sub sub_factorial {
|
||||
my $n = shift;
|
||||
$subfact[$n] //= do # same caching stuff, try comment out this line
|
||||
{
|
||||
# computes deranged without formula, using recursion
|
||||
my $total = factorial($n); # total permutations
|
||||
for my $k (1 .. $n) {
|
||||
# minus the permutations where k items are fixed
|
||||
# to original location, and the rest deranged
|
||||
$total -= choose($n, $k) * sub_factorial($n - $k)
|
||||
}
|
||||
$total
|
||||
}
|
||||
}
|
||||
|
||||
print "Derangements for 4 elements:\n";
|
||||
my @deranged = d([], 0 .. 3);
|
||||
for (1 .. @deranged) {
|
||||
print "$_: @{$deranged[$_-1]}\n"
|
||||
}
|
||||
|
||||
print "\nCompare list length and calculated table\n";
|
||||
for (0 .. 9) {
|
||||
my @x = d([], 0 .. $_-1);
|
||||
print $_, "\t", scalar(@x), "\t", sub_factorial($_), "\n"
|
||||
}
|
||||
|
||||
print "\nNumber of derangements:\n";
|
||||
print "$_:\t", sub_factorial($_), "\n" for 1 .. 20;
|
||||
Loading…
Add table
Add a link
Reference in a new issue