@@ -270,7 +270,7 @@ function factor!(n::T, h::AbstractDict{K,Int}) where {T<:Integer,K<:Integer}
270270 end
271271 end
272272 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)
274274end
275275
276276
@@ -394,36 +394,46 @@ function inthroot(n::Integer, r::Int)
394394 return ans
395395end
396396
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 }
399398 r = ceil (Int, inv (log (n, Primes. PRIMES[end ])))+ 1
400399 root = inthroot (n, r)
401400 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
405404 end
406405 r -= 1
407406 root = inthroot (n, r)
408407 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)
413424 if res != 1
414425 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)
418429 end
419430 end
420431 end
432+ throw (ArgumentError (" This number is too big to be factored with this algorith effectively" ))
421433end
422434
423435function 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 )
427437 for B in small_primes
428438 t = B^ trunc (Int64, log (B, plimit))
429439 xn, yn = T (0 ), T (0 )
@@ -463,7 +473,6 @@ function lenstra_get_factor(N::T, a, small_primes, plimit) where T <: Integer
463473 end
464474 return T (1 )
465475end
466-
467476"""
468477 ismersenneprime(M::Integer; [check::Bool = true]) -> Bool
469478
0 commit comments