primorial_deflation.pl 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 15 April 2019
  4. # https://github.com/trizen
  5. # Represent a given number as a product of primorials (if possible).
  6. # The sequence of numbers that can be represented as a product of primorials, is given by:
  7. # https://oeis.org/A025487
  8. # Among other terms, the sequence includes the factorials and the highly composite numbers.
  9. # See also:
  10. # https://oeis.org/A181815 -- "primorial deflation" of A025487(n)
  11. # https://oeis.org/A108951 -- "primorial inflation" of n
  12. use 5.020;
  13. use strict;
  14. use warnings;
  15. use experimental qw(signatures declared_refs);
  16. use ntheory qw(factor factor_exp prev_prime);
  17. use Math::AnyNum qw(factorial primorial prod ipow);
  18. sub primorial_deflation ($n) {
  19. my @terms;
  20. while ($n > 1) {
  21. my $g = (factor($n))[-1];
  22. my $p = primorial($g);
  23. $n /= $p;
  24. $n->is_int || return undef;
  25. push @terms, $g;
  26. }
  27. return prod(@terms);
  28. }
  29. sub primorial_deflation_fast ($n) {
  30. my @p;
  31. foreach my \@pp (factor_exp($n)) {
  32. my ($p, $e) = @pp;
  33. push @p, ($p == 2) ? 1 : ipow(prev_prime($p), $e);
  34. }
  35. $n / prod(@p);
  36. }
  37. my @arr = map { primorial_deflation(factorial($_)) } 0 .. 15; # https://oeis.org/A307035
  38. say join ', ', @arr; #=> 1, 1, 2, 3, 12, 20, 60, 84, 672, 1512, 5040, 7920, 47520, 56160, 157248
  39. say join ', ', map { prod(map { primorial($_) } factor($_)) } @arr; #=> 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200
  40. my @test = map { primorial_deflation_fast(factorial($_)) } 0 .. 15;
  41. if ("@arr" ne "@test") {
  42. die "error: (@arr) != (@test)";
  43. }
  44. say join ', ', map { primorial_deflation_fast($_) } 1..20; # A319626 / A319627
  45. my $n = Math::AnyNum->new("14742217487368791965347653720647452690286549052234444179664342042930370966727413549068727214664401976854238590421417268673037399536054005777393104248210539172848500736334237168727231561710827753972114334247396552090671649834020135652920430241738510495400044737265204738821393451152066370913670083496651044937158497896720493198891148968218874744806522767468280764179516341996273430700779982929787918221844760577694188288275419541410142336911631623319041967633591283303769044016192030492715535641753600000");
  46. say primorial_deflation($n); #=> 52900585920
  47. say primorial_deflation_fast($n); #=> 52900585920