142 Perfect Square Collection.sf 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #!/usr/bin/ruby
  2. # Perfect Square Collection
  3. # https://projecteuler.net/problem=142
  4. # Find the smallest x + y + z with integers x > y > z > 0 such that x + y, x − y, x + z, x − z, y + z, y − z are all perfect squares.
  5. # Solution based on the following idea:
  6. # (x+y)*(x-y) = x^2 - y^2
  7. # Since x+y and x-y must be squares, their product is also a square: (x+y)*(x-y) = n^2
  8. # Iterate over n=1..Inf and find the (x,y) solutions to the equation n^2 = x^2 - y^2.
  9. # Then, for each solution (x,y), try to find z, iterating from k=1 to sqrt(y), setting z = y - k^2 and checking if it satisfies the conditions.
  10. # See the Perl version for shorter runtime.
  11. func difference_of_two_squares_solutions(n) {
  12. n.divisors.map {|d|
  13. break if (d*d >= n)
  14. var a = d
  15. var b = n/d
  16. (a+b).is_even || next
  17. var x = (a + b)/2
  18. var y = (b - a)/2
  19. [x, y]
  20. }.flip
  21. }
  22. for k in (1 .. 1e9) {
  23. say "Checking: #{k}"
  24. difference_of_two_squares_solutions(k**2).each_2d {|x,y|
  25. x-y -> is_square || next
  26. x+y -> is_square || next
  27. for n in (1 .. y.isqrt) {
  28. var z = (y - n*n)
  29. if (is_square(x + z) && is_square(x - z) && is_square(y + z) && is_square(y - z)) {
  30. die "Found: sum(#{[x,y,z]}) = #{x+y+z}\n"
  31. }
  32. }
  33. }
  34. }