-
Notifications
You must be signed in to change notification settings - Fork 33
/
multinomial_coefficient.pl
executable file
·53 lines (38 loc) · 1.03 KB
/
multinomial_coefficient.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/perl
# Daniel "Trizen" Șuteu
# License: GPLv3
# Date: 01 February 2018
# https://github.com/trizen
# Simple algorithm for computing the multinomial coefficient, using prime powers.
# See also:
# https://mathworld.wolfram.com/MultinomialCoefficient.html
use 5.020;
use strict;
use warnings;
use experimental qw(signatures);
use ntheory qw(forprimes vecsum);
use Math::AnyNum qw(:overload sumdigits);
sub factorial_power ($n, $p) {
($n - sumdigits($n, $p)) / ($p - 1);
}
sub multinomial (@mset) {
my $sum = vecsum(@mset);
my $prod = 1;
my $end = $#mset;
forprimes {
my $p = $_;
my $e = factorial_power($sum, $p);
for (my $i = $end ; $i >= 0 ; --$i) {
my $n = $mset[$i];
if ($p <= $n) {
$e -= factorial_power($n, $p);
}
else {
splice(@mset, $i, 1), --$end;
}
}
$prod *= $p**$e;
} $sum;
return $prod;
}
say multinomial(7, 2, 5, 2, 12, 11); # 440981754363423854380800