Skip to content

Commit ad4c66d

Browse files
committed
use IntegerMathUtils
1 parent c5f8c04 commit ad4c66d

File tree

1 file changed

+6
-101
lines changed

1 file changed

+6
-101
lines changed

src/Primes.jl

Lines changed: 6 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,10 @@ Base.isempty(f::FactorIterator) = f.n == 1
320320
# Uses a variety of algorithms depending on the size of n to find a factor.
321321
# https://en.algorithmica.org/hpc/algorithms/factorization
322322
# Cache of small factors for small numbers (n < 2^16)
323-
# Trial division of small (< 2^16) precomputed primes
324-
# Pollard rho's algorithm with Richard P. Brent optimizations
323+
# Trial division of small (< 2^16) precomputed primes and
324+
# Lenstra elliptic curve algorithm
325325
# https://en.wikipedia.org/wiki/Trial_division
326-
# https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
327-
# http://maths-people.anu.edu.au/~brent/pub/pub051.html
326+
# https://en.wikipedia.org/wiki/Lenstra_elliptic-curve_factorization
328327
#
329328

330329
"""
@@ -668,7 +667,7 @@ given by `f`. This method may be preferable to [`totient(::Integer)`](@ref)
668667
when the factorization can be reused for other purposes.
669668
"""
670669
function totient(f::Factorization{T}) where T <: Integer
671-
if iszero(sign(f))
670+
if !isempty(f) && first(first(f)) == 0
672671
throw(ArgumentError("ϕ(0) is not defined"))
673672
end
674673
result = one(T)
@@ -687,16 +686,8 @@ positive integers less than or equal to ``n`` that are relatively prime to
687686
The totient function of `n` when `n` is negative is defined to be
688687
`totient(abs(n))`.
689688
"""
690-
function totient(n::T) where T<:Integer
691-
n = abs(n)
692-
if n == 0
693-
throw(ArgumentError("ϕ(0) is not defined"))
694-
end
695-
result = one(T)
696-
for (p, k) in eachfactor(n)
697-
result *= p^(k-1) * (p - 1)
698-
end
699-
result
689+
function totient(n::Integer)
690+
totient(factor(abs(n)))
700691
end
701692

702693
# add: checked add (when makes sense), result of same type as first argument
@@ -984,90 +975,4 @@ julia> prevprimes(10, 10)
984975
prevprimes(start::T, n::Integer) where {T<:Integer} =
985976
collect(T, Iterators.take(prevprimes(start), n))
986977

987-
"""
988-
divisors(n::Integer) -> Vector
989-
990-
Return a vector with the positive divisors of `n`.
991-
992-
For a nonzero integer `n` with prime factorization `n = p₁^k₁ ⋯ pₘ^kₘ`, `divisors(n)`
993-
returns a vector of length (k₁ + 1)⋯(kₘ + 1) containing the divisors of `n` in
994-
lexicographic (rather than numerical) order.
995-
996-
`divisors(-n)` is equivalent to `divisors(n)`.
997-
998-
For convenience, `divisors(0)` returns `[]`.
999-
1000-
# Example
1001-
1002-
```jldoctest; filter = r"(\\s+#.*)?"
1003-
julia> divisors(60)
1004-
12-element Vector{Int64}:
1005-
1 # 1
1006-
2 # 2
1007-
4 # 2 * 2
1008-
3 # 3
1009-
6 # 3 * 2
1010-
12 # 3 * 2 * 2
1011-
5 # 5
1012-
10 # 5 * 2
1013-
20 # 5 * 2 * 2
1014-
15 # 5 * 3
1015-
30 # 5 * 3 * 2
1016-
60 # 5 * 3 * 2 * 2
1017-
1018-
julia> divisors(-10)
1019-
4-element Vector{Int64}:
1020-
1
1021-
2
1022-
5
1023-
10
1024-
1025-
julia> divisors(0)
1026-
Int64[]
1027-
```
1028-
"""
1029-
function divisors(n::T) where {T<:Integer}
1030-
n = abs(n)
1031-
if iszero(n)
1032-
return T[]
1033-
elseif isone(n)
1034-
return [n]
1035-
else
1036-
return divisors(factor(n))
1037-
end
1038-
end
1039-
1040-
"""
1041-
divisors(f::Factorization) -> Vector
1042-
1043-
Return a vector with the positive divisors of the number whose factorization is `f`.
1044-
Divisors are sorted lexicographically, rather than numerically.
1045-
"""
1046-
function divisors(f::Factorization{T}) where T
1047-
sgn = sign(f)
1048-
if iszero(sgn) # n == 0
1049-
return T[]
1050-
elseif isempty(f) || length(f) == 1 && sgn < 0 # n == 1 or n == -1
1051-
return [one(T)]
1052-
end
1053-
1054-
i = m = 1
1055-
fs = rest(f, 1 + (sgn < 0))
1056-
divs = Vector{T}(undef, prod(x -> x.second + 1, fs))
1057-
divs[i] = one(T)
1058-
1059-
for (p, k) in fs
1060-
i = 1
1061-
for _ in 1:k
1062-
for j in i:(i+m-1)
1063-
divs[j+m] = divs[j] * p
1064-
end
1065-
i += m
1066-
end
1067-
m += i - 1
1068-
end
1069-
1070-
return divs
1071-
end
1072-
1073978
end # module

0 commit comments

Comments
 (0)