inverse_of_p_adic_valuation.pl 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 18 September 2017
  4. # https://github.com/trizen
  5. # Find the smallest number `n` such that `n!` has at least `k` factors of prime `p`.
  6. # See also:
  7. # https://projecteuler.net/problem=320
  8. # https://en.wikipedia.org/wiki/Legendre%27s_formula
  9. use 5.020;
  10. use strict;
  11. use warnings;
  12. use experimental qw(signatures);
  13. use ntheory qw(vecsum todigits);
  14. sub factorial_power ($n, $p) {
  15. ($n - vecsum(todigits($n, $p))) / ($p - 1);
  16. }
  17. sub p_adic_inverse ($p, $k) {
  18. my $n = $k * ($p - 1);
  19. while (factorial_power($n, $p) < $k) {
  20. $n -= $n % $p;
  21. $n += $p;
  22. }
  23. return $n;
  24. }
  25. say p_adic_inverse(2, 100); #=> 104
  26. say p_adic_inverse(3, 51); #=> 108
  27. say p_adic_inverse(2, 992); #=> 1000
  28. say p_adic_inverse(13, 83333329); #=> 999999988
  29. say p_adic_inverse(97, 1234567890); #=> 118518517733
  30. say factorial_power(p_adic_inverse(7, 1234567890), 7); #=> 1234567890
  31. say factorial_power(p_adic_inverse(23, 1234567890), 23); #=> 1234567890
  32. say factorial_power(p_adic_inverse(97, 1234567890), 97); #=> 1234567890