365 A huge binomial coefficient -- v3.pl 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 19 September 2020
  4. # https://github.com/trizen
  5. # https://projecteuler.net/problem=365
  6. # See also:
  7. # https://en.wikipedia.org/wiki/Lucas%27s_theorem
  8. # Runtime: ~7 minutes.
  9. use 5.020;
  10. use strict;
  11. use warnings;
  12. use experimental qw(signatures);
  13. use ntheory qw(:all);
  14. sub modular_binomial {
  15. my ($n, $k, $m) = @_;
  16. divmod(divmod(factorialmod($n, $m), factorialmod($k, $m), $m), factorialmod($n - $k, $m), $m);
  17. }
  18. sub lucas_theorem ($n, $k, $p) {
  19. if ($n < $k) {
  20. return 0;
  21. }
  22. my $prod = 1;
  23. while ($k > 0) {
  24. my ($Nr, $Kr) = ($n % $p, $k % $p);
  25. if ($Nr < $Kr) {
  26. return 0;
  27. }
  28. ($n, $k) = (divint($n, $p), divint($k, $p));
  29. $prod = mulmod($prod, modular_binomial($Nr, $Kr, $p), $p);
  30. }
  31. return $prod;
  32. }
  33. my @primes = @{primes(1000, 5000)};
  34. my $end = $#primes;
  35. my $N = 1000000000000000000;
  36. my $K = 1000000000;
  37. my $sum = 0;
  38. foreach my $i (0 .. $end - 2) {
  39. my $first = [lucas_theorem($N, $K, $primes[$i]), $primes[$i]];
  40. foreach my $j ($i + 1 .. $end - 1) {
  41. my $second = [lucas_theorem($N, $K, $primes[$j]), $primes[$j]];
  42. foreach my $k ($j + 1 .. $end) {
  43. my $third = [lucas_theorem($N, $K, $primes[$k]), $primes[$k]];
  44. $sum += chinese($first, $second, $third);
  45. }
  46. }
  47. say "$i -> $sum";
  48. }
  49. say "Total: $sum";