518 Prime Triples and Geometric Sequences.sf 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/ruby
  2. # Author: Trizen
  3. # Date: 11 September 2023
  4. # https://github.com/trizen
  5. # Prime Triples and Geometric Sequences
  6. # https://projecteuler.net/problem=518
  7. # Solution:
  8. # `(p+1, q+1, r+1)` must form a geometric progression and `p < q < r`.
  9. #
  10. # This means that there is a positive rational value `r` such that:
  11. # (p+1)*r = q+1
  12. # (p+1)*r^2 = r+1
  13. #
  14. # Since `r` can be rational, the denominator of the reduced fraction `r` must be a divisor of `p+1`.
  15. #
  16. # Furthermore, the denominator `j` must divide `p+1` twice, since we have, with `gcd(k,j) = 1`:
  17. # (p+1)*k/j = q+1
  18. # (p+1)*k^2/j^2 = r+1
  19. #
  20. # Therefore, we iterate over the primes p <= N, then we iterate over the square-divisors j^2 of p+1,
  21. # and for each k in the range `2 .. sqrt(n/((p+1)/j^2))` we compute:
  22. # q = (p+1)*k/j - 1
  23. # r = (p+1)*k^2/j^2 - 1
  24. # Runtime: ~36 minutes (untested)
  25. func problem_518(n) {
  26. var sum = 0
  27. n.each_prime {|p|
  28. for jj in (p+1 -> square_divisors) {
  29. var j = jj.isqrt
  30. var d1 = idiv(p+1, j)
  31. var d2 = idiv(d1, j)
  32. for k in (2 .. idiv(n,d2).isqrt) {
  33. k.is_coprime(j) || next
  34. var q = d1*k
  35. var r = d2*k*k
  36. p < q || next
  37. q < r || next
  38. q.dec.is_prime || next
  39. r.dec.is_prime || next
  40. #say [p,q.dec,r.dec]
  41. sum += (p + q + r - 2)
  42. }
  43. }
  44. }
  45. return sum
  46. }
  47. var sum = problem_518(1e8)
  48. say "Sum = #{sum}"
  49. __END__
  50. S(10^2) = 1035
  51. S(10^3) = 75019
  52. S(10^4) = 4225228
  53. S(10^5) = 249551109 (takes 3 seconds)
  54. S(10^6) = 17822459735 (takes 23 seconds)
  55. S(10^7) = 1316768308545 (takes 221 seconds)