Skip to content

Commit 65f7298

Browse files
authored
Merge branch 'master' into Lenstra-elliptic-curve
2 parents 0f17131 + 9067ce1 commit 65f7298

File tree

5 files changed

+58
-24
lines changed

5 files changed

+58
-24
lines changed

.github/workflows/TagBot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: TagBot
2+
on:
3+
schedule:
4+
- cron: 0 * * * *
5+
jobs:
6+
TagBot:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: JuliaRegistries/TagBot@v1
10+
with:
11+
token: ${{ secrets.GITHUB_TOKEN }}

Project.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
name = "Primes"
22
uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
3-
version = "0.5.1"
3+
version = "0.5.2"
4+
5+
[deps]
6+
IntegerMathUtils = "18e54dd8-cb9d-406c-a71d-865a43cbb235"
47

58
[extras]
6-
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
79
IntegerMathUtils = "18e54dd8-cb9d-406c-a71d-865a43cbb235"
10+
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
811
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
912

1013
[targets]
1114
test = ["DataStructures", "IntegerMathUtils", "Test"]
1215

1316
[compat]
14-
DataStructures = "0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17"
1517
IntegerMathUtils = "0.1"
1618
julia = "1"

src/Primes.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,19 +252,19 @@ function factor!(n::T, h::AbstractDict{K,Int}) where {T<:Integer,K<:Integer}
252252
end
253253

254254
local p::T
255-
nsqrt = isqrt(n)
256255
for p in PRIMES
257-
p > nsqrt && break
258-
if n % p == 0
259-
while true
260-
h[p] = get(h, p, 0) + 1
261-
n, r = divrem(n, p)
262-
r != 0 && break
263-
end
264-
n == 1 && return h
265-
nsqrt = isqrt(n)
256+
num_p = 0
257+
while true
258+
q, r = divrem(n, T(p)) # T(p) so julia <1.9 uses fast divrem for `BigInt`
259+
r == 0 || break
260+
num_p += 1
261+
n = q
266262
end
263+
# h[p] += num_p (about 2x faster, but the speed only matters for small numbers)
264+
num_p > 0 && increment!(h, num_p, p)
265+
p*p > n && break
267266
end
267+
n == 1 && return h
268268
isprime(n) && (h[n]=1; return h)
269269
lenstrafactors!(widen(n), h)
270270
end
@@ -417,7 +417,7 @@ function lenstrafactors!(n::T, h::AbstractDict{K,Int}) where{T<:Integer,K<:Integ
417417
end
418418
end
419419
end
420-
throw(ArgumentError("This number is too big to be factored with this algorith effectively"))
420+
throw(ArgumentError("This number is too big to be factored with this algorithm effectively"))
421421
end
422422

423423
function lenstra_get_factor(N::T, a, small_primes, plimit) where T <: Integer

src/factorization.jl

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
struct Factorization{T<:Integer} <: AbstractDict{T, Int}
55
pe::Vector{Pair{T, Int}} # Prime-Exponent
66

7-
Factorization{T}() where {T<:Integer} = new{T}(Vector{Pair{T, Int}}())
7+
function Factorization{T}() where {T<:Integer}
8+
# preallocates enough space that numbers smaller than 2310 won't need to resize
9+
v = Vector{Pair{T, Int}}(undef, 4)
10+
empty!(v)
11+
new{T}(v)
12+
end
813
end
914

1015
function Factorization{T}(d::AbstractDict) where T<:Integer
@@ -19,23 +24,39 @@ Base.convert(::Type{Factorization}, d::AbstractDict) = Factorization(d)
1924
Base.iterate(f::Factorization, state...) = iterate(f.pe, state...)
2025

2126
function Base.get(f::Factorization, p, default)
22-
found = searchsorted(f.pe, p, by=first)
23-
isempty(found) ?
24-
default :
25-
last(f.pe[first(found)])
27+
found = searchsortedfirst(f.pe, p, by=first)
28+
(found > length(f.pe) || first(f.pe[found])) != p ? default : last(f.pe[found])
2629
end
2730

2831
Base.getindex(f::Factorization, p::Integer) = get(f, p, 0)
2932

3033
function Base.setindex!(f::Factorization{T}, e::Int, p::Integer) where T
31-
found = searchsorted(f.pe, p, by=first)
32-
if isempty(found)
33-
insert!(f.pe, first(found), T(p)=>e)
34+
found = searchsortedfirst(f.pe, p, by=first)
35+
if found > length(f.pe)
36+
push!(f.pe, T(p)=>e)
37+
elseif first(f.pe[found]) != p
38+
insert!(f.pe, found, T(p)=>e)
39+
else
40+
f.pe[found] = T(p)=>e
41+
end
42+
f
43+
end
44+
45+
"""
46+
impliments f[p] += e faster
47+
"""
48+
function increment!(f::Factorization{T}, e::Int, p::Integer) where T
49+
found = searchsortedfirst(f.pe, p, by=first)
50+
if found > length(f.pe)
51+
push!(f.pe, T(p)=>e)
52+
elseif first(f.pe[found]) != p
53+
insert!(f.pe, found, T(p)=>e)
3454
else
35-
f.pe[first(found)] = T(p)=>e
55+
f.pe[found] = T(p)=>(last(f.pe[found])+e)
3656
end
3757
f
3858
end
59+
increment!(f::AbstractDict, e::Int, p::Integer) = (f[p] = get(f, p, 0) + e)
3960

4061
Base.length(f::Factorization) = length(f.pe)
4162

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ for T = (Int, UInt, BigInt)
261261
@test f == d == Dict(f) == Factorization(d) == convert(Factorization, d)
262262
@test collect(f) == sort!(collect(d)) # test start/next/done
263263
@test length(f) == length(d)
264-
@test get(f, T(101), nothing) == nothing
264+
@test get(f, T(101), nothing) === nothing
265265
@test f[101] == 0
266266
@test f[0] == 0
267267
f[0] = 1

0 commit comments

Comments
 (0)