solve_reciprocal_pythagorean_equation.sf 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/ruby
  2. # Find all the primitive solutions to the inverse Pythagorean equation:
  3. # 1/x^2 + 1/y^2 = 1/z^2
  4. # such that x <= y and 1 <= x,y,z <= N.
  5. # It can be shown that all the primitive solutions are generated from the following parametric form:
  6. #
  7. # x = 2*a*b*(a^2 + b^2)
  8. # y = a^4 - b^4
  9. # z = 2*a*b*(a^2 - b^2)
  10. #
  11. # where gcd(a, b) = 1 and a+b is odd.
  12. # See also:
  13. # https://oeis.org/A341990
  14. # https://math.stackexchange.com/questions/2688808/diophantine-equation-of-three-variables
  15. func S(N) {
  16. var solutions = []
  17. var limit = N.iroot(4)
  18. for a in (1..limit), b in (1 ..^ a) {
  19. is_odd(a+b) || next
  20. is_coprime(a,b) || next
  21. var x = (2*a*b * (a**2 + b**2))
  22. var y = (a**4 - b**4)
  23. var z = (2*a*b * (a**2 - b**2))
  24. x <= N || next
  25. y <= N || next
  26. z <= N || next
  27. solutions << [x,y,z]
  28. assert_eq(1/x**2 + 1/y**2, 1/z**2)
  29. }
  30. solutions.sort
  31. }
  32. var N = 1e4
  33. say <<"EOT"
  34. :: Primitve solutions (x,y,z) with 1 <= x,y,z <= #{N} and x <= y, to equation:
  35. 1/x^2 + 1/y^2 = 1/z^2
  36. EOT
  37. for x,y,z in (S(N)) {
  38. say "(#{x}, #{y}, #{z})"
  39. }
  40. __END__
  41. :: Primitve solutions (x,y,z) with 1 <= x,y,z <= 10000 and x <= y, to equation:
  42. 1/x^2 + 1/y^2 = 1/z^2
  43. (20, 15, 12)
  44. (136, 255, 120)
  45. (156, 65, 60)
  46. (444, 1295, 420)
  47. (580, 609, 420)
  48. (600, 175, 168)
  49. (1040, 4095, 1008)
  50. (1484, 2385, 1260)
  51. (1640, 369, 360)
  52. (2020, 9999, 1980)
  53. (3060, 6545, 2772)
  54. (3504, 4015, 2640)
  55. (3640, 2145, 1848)
  56. (3660, 671, 660)
  57. (6540, 9919, 5460)
  58. (6984, 6305, 4680)
  59. (7120, 3471, 3120)
  60. (7140, 1105, 1092)