count_of_square-full_numbers.sf 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/ruby
  2. # Fast algorithm for counting the number of square-full numbers <= n.
  3. # A positive integer n is square-full, if for every prime p that divides n, so does p^2.
  4. # See also:
  5. # The distribution of square-full integers, by H.-Q. Liu.
  6. # OEIS:
  7. # https://oeis.org/A001694 -- Powerful (square-full) numbers.
  8. # https://oeis.org/A118896 -- Number of powerful numbers <= 10^n.
  9. # 1) PARI/GP:
  10. # Q(n) = sum(m=1, sqrtnint(n, 6), sum(b=1, sqrtnint(n\m^6, 3), sqrtint(n\(m^6*b^3)) * moebius(m)));
  11. # 2) PARI/GP:
  12. # Q(n) = my(s=0); forsquarefree(k=1, sqrtnint(n, 3), s += sqrtint(n\k[1]^3)); s
  13. func squarefull_count(n) {
  14. var total = 0
  15. iroot(n, 6).each_squarefree {|m|
  16. for b in (1..iroot(idiv(n, m**6), 3)) {
  17. total += moebius(m)*isqrt(idiv(n, (m*m*b)**3))
  18. }
  19. }
  20. return total
  21. }
  22. func squarefull_count_faster(n) {
  23. var total = 0
  24. n.iroot(3).each_squarefree {|k|
  25. total += isqrt(idiv(n, k**3))
  26. }
  27. return total
  28. }
  29. for n in (1..10) {
  30. var a = squarefull_count(10**n)
  31. var b = squarefull_count_faster(10**n)
  32. assert_eq(a, b)
  33. say ("Q(10^#{n}) = ", a)
  34. }
  35. __END__
  36. Q(10^1) = 4
  37. Q(10^2) = 14
  38. Q(10^3) = 54
  39. Q(10^4) = 185
  40. Q(10^5) = 619
  41. Q(10^6) = 2027
  42. Q(10^7) = 6553
  43. Q(10^8) = 21044
  44. Q(10^9) = 67231
  45. Q(10^10) = 214122
  46. Q(10^11) = 680330
  47. Q(10^12) = 2158391
  48. Q(10^13) = 6840384
  49. Q(10^14) = 21663503
  50. Q(10^15) = 68575557
  51. Q(10^16) = 217004842
  52. Q(10^17) = 686552743
  53. Q(10^18) = 2171766332
  54. Q(10^19) = 6869227848
  55. Q(10^20) = 21725636644