Skip to content

Commit 62c8597

Browse files
committed
Implement divisors
1 parent 560a9f4 commit 62c8597

File tree

1 file changed

+83
-2
lines changed

1 file changed

+83
-2
lines changed

src/Primes.jl

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# This file includes code that was formerly a part of Julia. License is MIT: http://julialang.org/license
2-
32
module Primes
43

54
using Base.Iterators: repeated
@@ -9,7 +8,7 @@ using Base: BitSigned
98
using Base.Checked: checked_neg
109
using IntegerMathUtils
1110

12-
export isprime, primes, primesmask, factor, eachfactor, ismersenneprime, isrieselprime,
11+
export isprime, primes, primesmask, factor, eachfactor, divisors, ismersenneprime, isrieselprime,
1312
nextprime, nextprimes, prevprime, prevprimes, prime, prodfactors, radical, totient
1413

1514
include("factorization.jl")
@@ -908,4 +907,86 @@ julia> prevprimes(10, 10)
908907
prevprimes(start::T, n::Integer) where {T<:Integer} =
909908
collect(T, Iterators.take(prevprimes(start), n))
910909

910+
"""
911+
divisors(n::T) -> Vector{T}
912+
913+
Return a vector of all positive divisors of an integer `n`.
914+
915+
For an integer `n` with prime factorization `n = p₁^k₁ ⋯ pₘ^kₘ`, `divisors(n)`
916+
returns a vector of length (k₁ + 1)⋯(kₘ + 1) containing the divisors of `n` in
917+
lexicographic (rather than numerical) order.
918+
919+
```julia
920+
julia> divisors(60)
921+
12-element Vector{Int64}:
922+
1 # 1
923+
2 # 2
924+
4 # 2 * 2
925+
3 # 3
926+
6 # 3 * 2
927+
12 # 3 * 2 * 2
928+
5 # 5
929+
10 # 5 * 2
930+
20 # 5 * 2 * 2
931+
15 # 5 * 3
932+
30 # 5 * 3 * 2
933+
60 # 5 * 3 * 2 * 2
934+
```
935+
936+
`divisors(-n)` is equivalent to `divisors(n)`.
937+
938+
`divisors(0)` returns `[]`.
939+
"""
940+
function divisors(n::T)::Vector{T} where {T<:Integer}
941+
if iszero(n)
942+
return T[]
943+
elseif isone(n)
944+
return T[n]
945+
elseif n < 0
946+
return divisors(abs(n))
947+
else
948+
return divisors(factor(n))
949+
end
950+
end
951+
952+
"""
953+
divisors(factors::Factorization{T}) -> Vector{T}
954+
955+
Return a vector containing the divisors of the number described by `factors`.
956+
Divisors are sorted lexicographically, rather than numerically.
957+
"""
958+
function divisors(factors::Primes.Factorization{T})::Vector{T} where {T<:Integer}
959+
pe = factors.pe
960+
961+
if isempty(pe)
962+
return T[one(T)] # n == 1
963+
elseif pe[1][1] == 0 # n == 0
964+
return T[]
965+
elseif pe[1][1] == -1 # n < 0
966+
if length(pe) == 1 # n == -1
967+
return T[one(T)]
968+
else
969+
pe = pe[2:end]
970+
end
971+
end
972+
973+
i::Int = 1
974+
m::Int = 1
975+
divs = Vector{T}(undef, prod(x -> x.second + 1, pe))
976+
divs[i] = one(T)
977+
978+
for (p, k) in pe
979+
i = 1
980+
for _ in 1:k
981+
for j in i:(i+m-1)
982+
divs[j+m] = divs[j] * p
983+
end
984+
i += m
985+
end
986+
m += i - 1
987+
end
988+
989+
return divs
990+
end
991+
911992
end # module

0 commit comments

Comments
 (0)