sum_of_k-powerful_numbers_in_range.pl 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #!/usr/bin/perl
  2. # Author: Trizen
  3. # Date: 28 February 2021
  4. # Edit: 11 April 2024
  5. # https://github.com/trizen
  6. # Fast recursive algorithm for computing the sum of k-powerful numbers in a given range [A,B].
  7. # A positive integer n is considered k-powerful, if for every prime p that divides n, so does p^k.
  8. # Example:
  9. # 2-powerful = a^2 * b^3, for a,b >= 1
  10. # 3-powerful = a^3 * b^4 * c^5, for a,b,c >= 1
  11. # 4-powerful = a^4 * b^5 * c^6 * d^7, for a,b,c,d >= 1
  12. # OEIS:
  13. # https://oeis.org/A001694 -- 2-powerful numbers
  14. # https://oeis.org/A036966 -- 3-powerful numbers
  15. # https://oeis.org/A036967 -- 4-powerful numbers
  16. # https://oeis.org/A069492 -- 5-powerful numbers
  17. # https://oeis.org/A069493 -- 6-powerful numbers
  18. # See also:
  19. # https://oeis.org/A118896 -- Number of powerful numbers <= 10^n.
  20. use 5.036;
  21. use ntheory qw(:all);
  22. use Math::AnyNum qw(faulhaber_sum);
  23. sub divceil ($x, $y) { # ceil(x/y)
  24. (($x % $y == 0) ? 0 : 1) + divint($x, $y);
  25. }
  26. sub powerful_sum_in_range ($A, $B, $k = 2) {
  27. return 0 if ($A > $B);
  28. my $sum = 0;
  29. sub ($m, $r) {
  30. my $from = 1;
  31. my $upto = rootint(divint($B, $m), $r);
  32. if ($r <= $k) {
  33. if ($A > $m) {
  34. # Optimization by Dana Jacobsen (from Math::Prime::Util::PP)
  35. my $l = divceil($A, $m);
  36. if (($l >> $r) == 0) {
  37. $from = 2;
  38. }
  39. else {
  40. $from = rootint($l, $r);
  41. $from++ if (powint($from, $r) != $l);
  42. }
  43. }
  44. return if ($from > $upto);
  45. $sum += $m * (faulhaber_sum($upto, $r) - faulhaber_sum($from - 1, $r));
  46. return;
  47. }
  48. foreach my $v ($from .. $upto) {
  49. gcd($m, $v) == 1 or next;
  50. is_square_free($v) or next;
  51. __SUB__->(mulint($m, powint($v, $r)), $r - 1);
  52. }
  53. }
  54. ->(1, 2 * $k - 1);
  55. return $sum;
  56. }
  57. require Math::Sidef;
  58. foreach my $k (2 .. 10) {
  59. my $lo = int rand powint(10, $k - 1);
  60. my $hi = int rand powint(10, $k);
  61. my $c1 = powerful_sum_in_range($lo, $hi, $k);
  62. my $c2 = Math::Sidef::powerful_sum($k, $lo, $hi);
  63. $c1 eq $c2 or die "Error for [$lo, $hi] -- ($c1 != $c2)\n";
  64. printf("Sum of %2d-powerful in range 10^j .. 10^(j+1): {%s}\n",
  65. $k, join(", ", map { powerful_sum_in_range(powint(10, $_), powint(10, $_ + 1), $k) } 0 .. $k + 7));
  66. }
  67. __END__
  68. Sum of 2-powerful in range 10^j .. 10^(j+1): {22, 502, 19545, 628164, 20656197, 668961441, 21437300251, 685328369991, 21824118507902, 693905863243612}
  69. Sum of 3-powerful in range 10^j .. 10^(j+1): {9, 220, 6121, 136410, 3529846, 80934268, 1811337810, 41811161255, 929876351992, 20679545550210, 457363233598112}
  70. Sum of 4-powerful in range 10^j .. 10^(j+1): {1, 193, 2493, 60370, 1440893, 26780053, 516891583, 9990376094, 193432085418, 3626702483663, 68456092587576, 1272728145913757}
  71. Sum of 5-powerful in range 10^j .. 10^(j+1): {1, 96, 1868, 35009, 746121, 14039356, 230448956, 4041417437, 70765409052, 1214243920880, 21187881376824, 365947199216587, 6015063920839580}
  72. Sum of 6-powerful in range 10^j .. 10^(j+1): {1, 64, 1625, 24108, 427138, 7503765, 142877197, 2128546916, 37085174023, 547117264876, 9207435088386, 149796088225544, 2342746880282546, 36741577488049351}
  73. Sum of 7-powerful in range 10^j .. 10^(j+1): {1, 0, 896, 24108, 271545, 4519876, 93259499, 1349452792, 22365106723, 310086289407, 4736025082478, 73612282993023, 1102078225069540, 16970183647609915, 262120890688576034}
  74. Sum of 8-powerful in range 10^j .. 10^(j+1): {1, 0, 768, 21921, 193420, 2016717, 56385643, 851106512, 14014480848, 205584890161, 3186168004038, 43689401756765, 641512327279056, 9291932808199869, 136568208040185109, 2007778182656517551}
  75. Sum of 9-powerful in range 10^j .. 10^(j+1): {1, 0, 512, 15360, 193420, 1626092, 33824682, 596581840, 8827764302, 147389799084, 2165109680321, 29580803725639, 409447338905006, 5697214477371426, 78740331560394730, 1144313243099576141, 15965319118886658764}
  76. Sum of 10-powerful in range 10^j .. 10^(j+1): {1, 0, 0, 15360, 173737, 1626092, 31871557, 284130441, 5610671182, 106206715265, 1591481398917, 21833753103320, 298489744207556, 3892787043427942, 50393901956156445, 725082729912431153, 9766175708618550818, 140084863743264508627}