solve_reciprocal_pythagorean_equation.pl 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/perl
  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. use 5.020;
  16. use strict;
  17. use warnings;
  18. use ntheory qw(:all);
  19. use experimental qw(signatures);
  20. sub S ($N) {
  21. my @solutions;
  22. my $limit = rootint($N, 4);
  23. foreach my $a (1 .. $limit) {
  24. foreach my $b (1 .. $a - 1) {
  25. ($a + $b) % 2 == 1 or next;
  26. gcd($a, $b) == 1 or next;
  27. my $aa = mulint($a, $a);
  28. my $ab = mulint($a, $b);
  29. my $bb = mulint($b, $b);
  30. my $x = vecprod(2, $ab, addint($aa, $bb));
  31. my $y = subint(powint($a, 4), powint($b, 4));
  32. my $z = vecprod(2, $ab, subint($aa, $bb));
  33. $x <= $N or next;
  34. $y <= $N or next;
  35. $z <= $N or next;
  36. push @solutions, [$x, $y, $z];
  37. }
  38. }
  39. sort { $a->[0] <=> $b->[0] } @solutions;
  40. }
  41. my $N = 10000;
  42. say <<"EOT";
  43. :: Primitve solutions (x,y,z) with 1 <= x,y,z <= $N and x <= y, to equation:
  44. 1/x^2 + 1/y^2 = 1/z^2
  45. EOT
  46. foreach my $triple (S($N)) {
  47. my ($x, $y, $z) = @$triple;
  48. say "($x, $y, $z)";
  49. }
  50. __END__
  51. :: Primitve solutions (x,y,z) with 1 <= x,y,z <= 10000 and x <= y, to equation:
  52. 1/x^2 + 1/y^2 = 1/z^2
  53. (20, 15, 12)
  54. (136, 255, 120)
  55. (156, 65, 60)
  56. (444, 1295, 420)
  57. (580, 609, 420)
  58. (600, 175, 168)
  59. (1040, 4095, 1008)
  60. (1484, 2385, 1260)
  61. (1640, 369, 360)
  62. (2020, 9999, 1980)
  63. (3060, 6545, 2772)
  64. (3504, 4015, 2640)
  65. (3640, 2145, 1848)
  66. (3660, 671, 660)
  67. (6540, 9919, 5460)
  68. (6984, 6305, 4680)
  69. (7120, 3471, 3120)
  70. (7140, 1105, 1092)