powers_of_primes_modulus_in_factorial.pl 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 15 September 2016
  5. # Website: https://github.com/trizen
  6. # Count the number of factors of p modulo p^k in (p^n)! with k <= n.
  7. # Example:
  8. # p n k
  9. # fpower(43, 10, 7) = 6471871693
  10. #
  11. # because (43^10)! contains 514559102697244 factors of 43
  12. # and 514559102697244 mod 43^7 = 6471871693
  13. # See also:
  14. # https://projecteuler.net/problem=288
  15. use 5.010;
  16. use strict;
  17. use warnings;
  18. use Math::AnyNum qw(:overload powmod);
  19. #
  20. ## Iterative version
  21. #
  22. sub fpower {
  23. my ($p, $n, $k) = @_;
  24. return 0 if $n <= 0;
  25. $k = $n if $k > $n;
  26. my $sum = 0;
  27. my $mod = $p**$k;
  28. while ($n > 0) {
  29. $sum += powmod($p, --$n, $mod);
  30. }
  31. $sum;
  32. }
  33. #
  34. ## Recursive version
  35. #
  36. sub _fpower_rec {
  37. my ($p, $n, $mod) = @_;
  38. $n == 0 ? 0 : powmod($p, $n - 1, $mod) + _fpower_rec($p, $n - 1, $mod);
  39. }
  40. sub fpower_rec {
  41. my ($p, $n, $k) = @_;
  42. return 0 if $n <= 0;
  43. $k = $n if $k > $n;
  44. _fpower_rec($p, $n, $p**$k);
  45. }
  46. say fpower(43, 10, 7);
  47. say fpower_rec(43, 10, 7);