@@ -270,7 +270,7 @@ function factor!(n::T, h::AbstractDict{K,Int}) where {T<:Integer,K<:Integer}
270
270
end
271
271
end
272
272
isprime (n) && (h[n]= 1 ; return h)
273
- T <: BigInt || widemul (n - 1 , n - 1 ) ≤ typemax (n) ? lenstrafactors! (n, h) : lenstrafactors! (widen (n), h)
273
+ lenstrafactors! (widen (n), h)
274
274
end
275
275
276
276
@@ -394,36 +394,46 @@ function inthroot(n::Integer, r::Int)
394
394
return ans
395
395
end
396
396
397
- function lenstrafactors! (n:: T , h:: AbstractDict{K,Int} , plimit= 10000 ) where {T<: Integer ,K<: Integer }
398
- isprime (n) && (h[n] = get (h, n, 0 )+ 1 ; return h)
397
+ function primepowerfactor! (n:: T , h:: AbstractDict{K,Int} ) where {T<: Integer ,K<: Integer }
399
398
r = ceil (Int, inv (log (n, Primes. PRIMES[end ])))+ 1
400
399
root = inthroot (n, r)
401
400
while r >= 2
402
- if root^ r == n
403
- isprime (root) ? h[root] = get (h, root, 0 ) + 1 : lenstrafactors! (root, h)
404
- return lenstrafactors! ( div (n, root), h)
401
+ if root^ r == n && isprime (root)
402
+ h[root] = get (h, root, 0 ) + r
403
+ return true
405
404
end
406
405
r -= 1
407
406
root = inthroot (n, r)
408
407
end
409
- small_primes = primes (plimit)
410
- for a in zero (T): (n>> 1 )
411
- for p in (- 1 , 1 )
412
- res = lenstra_get_factor (n, p* a, small_primes, plimit)
408
+ return false
409
+ end
410
+
411
+ function lenstrafactors! (n:: T , h:: AbstractDict{K,Int} ) where {T<: Integer ,K<: Integer }
412
+ isprime (n) && (h[n] = get (h, n, 0 )+ 1 ; return h)
413
+ primepowerfactor! (n:: T , h) && return h
414
+ # bounds and runs per bound taken from
415
+ # https://www.rieselprime.de/ziki/Elliptic_curve_method
416
+ B1s = Int[2e3 , 11e3 , 5e4 , 25e4 , 1e6 , 3e6 , 11e6 ,
417
+ 43e6 , 11e7 , 26e7 , 85e7 , 29e8 , 76e8 , 25e9 ]
418
+ runs = (74 , 221 , 453 , 984 , 2541 , 4949 , 8266 , 20158 ,
419
+ 47173 , 77666 , 42057 , 69471 , 102212 , 188056 , 265557 )
420
+ for (B1, run) in zip (B1s, runs)
421
+ small_primes = primes (B1)
422
+ for a in - run: run
423
+ res = lenstra_get_factor (n, a, small_primes, B1)
413
424
if res != 1
414
425
isprime (res) ? h[res] = get (h, res, 0 ) + 1 : lenstrafactors! (res, h)
415
- res2 = div (n,res)
416
- isprime (res2) ? h[res2] = get (h, res2, 0 ) + 1 : lenstrafactors! (res2, h)
417
- return h
426
+ n = div (n,res)
427
+ primepowerfactor! (n :: T , h) && return h
428
+ isprime (n) && (h[n] = get (h, n, 0 ) + 1 ; return h)
418
429
end
419
430
end
420
431
end
432
+ throw (ArgumentError (" This number is too big to be factored with this algorith effectively" ))
421
433
end
422
434
423
435
function lenstra_get_factor (N:: T , a, small_primes, plimit) where T <: Integer
424
- x = T (0 )
425
- y = T (1 )
426
-
436
+ x, y = T (0 ), T (1 )
427
437
for B in small_primes
428
438
t = B^ trunc (Int64, log (B, plimit))
429
439
xn, yn = T (0 ), T (0 )
@@ -463,7 +473,6 @@ function lenstra_get_factor(N::T, a, small_primes, plimit) where T <: Integer
463
473
end
464
474
return T (1 )
465
475
end
466
-
467
476
"""
468
477
ismersenneprime(M::Integer; [check::Bool = true]) -> Bool
469
478
0 commit comments