-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy path365 A huge binomial coefficient -- v3.pl
68 lines (49 loc) · 1.37 KB
/
365 A huge binomial coefficient -- v3.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/perl
# Daniel "Trizen" Șuteu
# Date: 19 September 2020
# https://github.com/trizen
# https://projecteuler.net/problem=365
# See also:
# https://en.wikipedia.org/wiki/Lucas%27s_theorem
# Runtime: ~7 minutes.
use 5.020;
use strict;
use warnings;
use experimental qw(signatures);
use ntheory qw(:all);
sub modular_binomial {
my ($n, $k, $m) = @_;
divmod(divmod(factorialmod($n, $m), factorialmod($k, $m), $m), factorialmod($n - $k, $m), $m);
}
sub lucas_theorem ($n, $k, $p) {
if ($n < $k) {
return 0;
}
my $prod = 1;
while ($k > 0) {
my ($Nr, $Kr) = ($n % $p, $k % $p);
if ($Nr < $Kr) {
return 0;
}
($n, $k) = (divint($n, $p), divint($k, $p));
$prod = mulmod($prod, modular_binomial($Nr, $Kr, $p), $p);
}
return $prod;
}
my @primes = @{primes(1000, 5000)};
my $end = $#primes;
my $N = 1000000000000000000;
my $K = 1000000000;
my $sum = 0;
foreach my $i (0 .. $end - 2) {
my $first = [lucas_theorem($N, $K, $primes[$i]), $primes[$i]];
foreach my $j ($i + 1 .. $end - 1) {
my $second = [lucas_theorem($N, $K, $primes[$j]), $primes[$j]];
foreach my $k ($j + 1 .. $end) {
my $third = [lucas_theorem($N, $K, $primes[$k]), $primes[$k]];
$sum += chinese($first, $second, $third);
}
}
say "$i -> $sum";
}
say "Total: $sum";