sum_of_cubes_function_nonnegative_recursive.sf 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/ruby
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 12 August 2021
  4. # https://github.com/trizen
  5. # Count the number of ways or representing n as a sum of k cubes.
  6. # See also:
  7. # https://en.wikipedia.org/wiki/Sum_of_squares_function
  8. # OEIS sequences:
  9. # https://oeis.org/A173677 -- Number of ways of writing n as a sum of 2 nonnegative cubes
  10. # https://oeis.org/A051343 -- Number of ways of writing n as a sum of 3 nonnegative cubes
  11. # https://oeis.org/A173678 -- Number of ways of writing n as a sum of 4 nonnegative cubes
  12. # https://oeis.org/A173679 -- Number of ways of writing n as a sum of 5 nonnegative cubes
  13. # https://oeis.org/A173680 -- Number of ways of writing n as a sum of 6 nonnegative cubes
  14. # https://oeis.org/A173676 -- Number of ways of writing n as a sum of 7 nonnegative cubes
  15. # https://oeis.org/A173681 -- Number of ways of writing n as a sum of 8 nonnegative cubes
  16. # https://oeis.org/A173682 -- Number of ways of writing n as a sum of 9 nonnegative cubes
  17. func is_sum_of_two_cubes(n) { # OEIS: A004999
  18. var L = iroot(n-1, 3)+1
  19. var U = iroot(4*n, 3)
  20. n.divisors.each {|m|
  21. if ((L <= m) && (m <= U)) {
  22. var l = (m*m - n/m)
  23. l.is_div(3) || next
  24. l = idiv(l, 3)
  25. is_square(m*m - 4*l) && return true
  26. }
  27. }
  28. return false
  29. }
  30. func cubes_r(n, k=2) is cached {
  31. return 1 if (n == 0)
  32. return 0 if (k <= 0)
  33. return (n.is_cube ? 1 : 0) if (k == 1)
  34. if (k == 2) {
  35. is_sum_of_two_cubes(n) || return 0
  36. }
  37. var count = 0
  38. for a in (0 .. n.iroot(3)) {
  39. if (k > 2) {
  40. count += __FUNC__(n - a**3, k-1)
  41. }
  42. elsif (n - a**3 -> is_cube) {
  43. ++count
  44. }
  45. }
  46. return count
  47. }
  48. for k in (0..9) {
  49. say ("k = #{k}: ", 20.of { cubes_r(_, k) })
  50. }
  51. __END__
  52. k = 0: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  53. k = 1: [1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  54. k = 2: [1, 2, 1, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
  55. k = 3: [1, 3, 3, 1, 0, 0, 0, 0, 3, 6, 3, 0, 0, 0, 0, 0, 3, 3, 0, 0]
  56. k = 4: [1, 4, 6, 4, 1, 0, 0, 0, 4, 12, 12, 4, 0, 0, 0, 0, 6, 12, 6, 0]
  57. k = 5: [1, 5, 10, 10, 5, 1, 0, 0, 5, 20, 30, 20, 5, 0, 0, 0, 10, 30, 30, 10]
  58. k = 6: [1, 6, 15, 20, 15, 6, 1, 0, 6, 30, 60, 60, 30, 6, 0, 0, 15, 60, 90, 60]
  59. k = 7: [1, 7, 21, 35, 35, 21, 7, 1, 7, 42, 105, 140, 105, 42, 7, 0, 21, 105, 210, 210]
  60. k = 8: [1, 8, 28, 56, 70, 56, 28, 8, 9, 56, 168, 280, 280, 168, 56, 8, 28, 168, 420, 560]
  61. k = 9: [1, 9, 36, 84, 126, 126, 84, 36, 18, 73, 252, 504, 630, 504, 252, 72, 45, 252, 756, 1260]