square_form_factorization_method.sf 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/ruby
  2. # Daniel Shanks's Square Form Factorization (SquFoF).
  3. # See also:
  4. # https://rosettacode.org/wiki/Square_form_factorization
  5. const multipliers = divisors(3*5*7*11).grep { _ > 1 }
  6. func sff(N) {
  7. N.is_prime && return 1 # n is prime
  8. N.is_square && return N.isqrt # n is square
  9. multipliers.each {|k|
  10. var P0 = isqrt(k*N) # P[0]=floor(sqrt(N)
  11. var Q0 = 1 # Q[0]=1
  12. var Q = (k*N - P0*P0) # Q[1]=N-P[0]^2 & Q[i]
  13. var P1 = P0 # P[i-1] = P[0]
  14. var Q1 = Q0 # Q[i-1] = Q[0]
  15. var P = 0 # P[i]
  16. var Qn = 0 # P[i+1]
  17. var b = 0 # b[i]
  18. while (!Q.is_square) { # until Q[i] is a perfect square
  19. b = idiv(isqrt(k*N) + P1, Q) # floor(floor(sqrt(N+P[i-1])/Q[i])
  20. P = (b*Q - P1) # P[i]=b*Q[i]-P[i-1]
  21. Qn = (Q1 + b*(P1 - P)) # Q[i+1]=Q[i-1]+b(P[i-1]-P[i])
  22. (Q1, Q, P1) = (Q, Qn, P)
  23. }
  24. b = idiv(isqrt(k*N) + P, Q) # b=floor((floor(sqrt(N)+P[i])/Q[0])
  25. P1 = (b*Q0 - P) # P[i-1]=b*Q[0]-P[i]
  26. Q = (k*N - P1*P1)/Q0 # Q[1]=(N-P[0]^2)/Q[0] & Q[i]
  27. Q1 = Q0 # Q[i-1] = Q[0]
  28. loop {
  29. b = idiv(isqrt(k*N) + P1, Q) # b=floor(floor(sqrt(N)+P[i-1])/Q[i])
  30. P = (b*Q - P1) # P[i]=b*Q[i]-P[i-1]
  31. Qn = (Q1 + b*(P1 - P)) # Q[i+1]=Q[i-1]+b(P[i-1]-P[i])
  32. break if (P == P1) # until P[i+1]=P[i]
  33. (Q1, Q, P1) = (Q, Qn, P)
  34. }
  35. with (gcd(N,P)) {|g|
  36. return g if g.is_ntf(N)
  37. }
  38. }
  39. return 0
  40. }
  41. [ 11111, 2501, 12851, 13289, 75301, 120787, 967009, 997417, 4558849,
  42. 7091569, 13290059, 42854447, 223553581, 2027651281,
  43. ].each {|n|
  44. var v = sff(n)
  45. if (v == 0) { say "The number #{n} is not factored." }
  46. elsif (v == 1) { say "The number #{n} is a prime." }
  47. else { say "#{n} = #{[n/v, v].sort.join(' * ')}" }
  48. }
  49. __END__
  50. 11111 = 41 * 271
  51. 2501 = 41 * 61
  52. 12851 = 71 * 181
  53. 13289 = 97 * 137
  54. 75301 = 257 * 293
  55. 120787 = 43 * 2809
  56. 967009 = 601 * 1609
  57. 997417 = 257 * 3881
  58. 4558849 = 383 * 11903
  59. 7091569 = 2663 * 2663
  60. 13290059 = 3119 * 4261
  61. 42854447 = 4423 * 9689
  62. 223553581 = 11213 * 19937
  63. 2027651281 = 44021 * 46061