primes-utils 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -12
- data/lib/primes/utils.rb +68 -75
- data/lib/primes/utils/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af94be1cfe58cb1704376223da97cdb48d6cc8a0
|
4
|
+
data.tar.gz: 924587a02967cd156d2115d5d1ac22d547ca9089
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b30b2ac81ef9e21321a667d3e5f009218300048367a6be81c083f3293c32b131bd1461020ec349674d7449f0bef453431aaa96b334a526c0cb065dc9c2c5ba0
|
7
|
+
data.tar.gz: 78bdfd7fcc6d0b9904a42b13b4cf5be82c45da2a21317e47c05efefc44928b411a6612a6b044b4ff9536a29500d49a099714c4155f1e8a4c98ab01c17c2b341e
|
data/README.md
CHANGED
@@ -2,21 +2,22 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
`primes-utils` is a Rubygem which provides a suite of extremely fast
|
5
|
+
`primes-utils` is a Rubygem which provides a suite of extremely fast utility methods for testing and generating primes.
|
6
6
|
|
7
|
-
For details on
|
7
|
+
For details on the Math and Code used to implement them see:
|
8
8
|
|
9
9
|
`PRIMES-UTILS HANDBOOK`
|
10
10
|
|
11
|
+
Now available and `FREE` to view and download at:
|
12
|
+
|
11
13
|
https://www.scribd.com/doc/266461408/Primes-Utils-Handbook
|
12
14
|
|
13
|
-
Periodically check for updates.
|
14
15
|
|
15
16
|
## Installation
|
16
17
|
|
17
18
|
Add this line to your application's Gemfile:
|
18
19
|
|
19
|
-
```
|
20
|
+
```
|
20
21
|
gem 'primes-utils'
|
21
22
|
```
|
22
23
|
|
@@ -59,8 +60,9 @@ The reliability can be increased by increasing the default input parameter of k=
|
|
59
60
|
1111111111111111111.primemr?(50) => true
|
60
61
|
11111111111111111111.primemr? => false
|
61
62
|
-3333333333333333333.primemr? => false
|
62
|
-
|
63
|
-
|
63
|
+
n=10**1700; (n+469).primemr? => true
|
64
|
+
0.primemr? => false
|
65
|
+
1.primemr? => false
|
64
66
|
```
|
65
67
|
|
66
68
|
**factors(p=13) or prime_division(p=13)**
|
@@ -86,7 +88,7 @@ Can change SP PG used on input. Acceptable primes range: [3 - 19].
|
|
86
88
|
|
87
89
|
Return an array of primes within the absolute value range `(|start| - |end|)`.
|
88
90
|
The order of the range doesn't matter if both given: `start.primes end <=> end.prime start`.
|
89
|
-
If only one parameter used, then all the primes
|
91
|
+
If only one parameter used, then all the primes up to that number will be returned.
|
90
92
|
See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
91
93
|
Also see `Error Handling`.
|
92
94
|
|
@@ -112,7 +114,7 @@ n=10**8; (25*n).primes -> ERROR3: not enough memory to store all primes in outp
|
|
112
114
|
|
113
115
|
Provide count of primes within the absolute value range `(|start| - |end|)`.
|
114
116
|
The order of the range doesn't matter if both given: `start.primes end <=> end.prime start`.
|
115
|
-
If only one parameter used, the count of all the primes
|
117
|
+
If only one parameter used, the count of all the primes up to that number will be returned.
|
116
118
|
See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
117
119
|
Also see `Error Handling`.
|
118
120
|
|
@@ -152,7 +154,7 @@ n = 10**11; n.primenth -> ERROR1: range size too big for available memory. => ni
|
|
152
154
|
**primes_utils**
|
153
155
|
|
154
156
|
Displays a list of all the `primes-utils` methods available for your system.
|
155
|
-
Use as `
|
157
|
+
Use as `n.primes_utils` where n is any `class Integer` value.
|
156
158
|
|
157
159
|
```
|
158
160
|
0.primes_utils => "prime? primemr? primes primesf primesmr primescnt primescntf primescntmr primenth|nthprime factors|prime_division"
|
@@ -162,9 +164,9 @@ Use as `x.primes_utils` where x is any `class Integer` value.
|
|
162
164
|
Starting with 2.2.0, error handling has been implemented to gracefully fail when array creation requires more memory than available.
|
163
165
|
This occurs when the range size, or end_num, need arrays greater than the amount of avalable memory. The first case shows the message
|
164
166
|
`ERROR1: range size too big for available memory.` and the second case `ERROR2: end_num too big for available memory.`
|
165
|
-
The affected methods are `primes`,
|
167
|
+
The affected methods are `primes`, `primescnt`, and `nthprime|primenth`.
|
166
168
|
`nthprime|primenth` also displays the error message `<pcnt> not enough primes, approx nth too small.`
|
167
|
-
(`<pcnt>` is computed count of primes) when the computed approx_nth value < nth value (though this should never happen by design).
|
169
|
+
(`<pcnt>` is computed count of primes) when the computed approx_nth value is < nth value (though this should never happen by design).
|
168
170
|
With 2.4.0 error handling was added to `primes` that catches the error and displays message `ERROR3: not enough memory to store all primes in output array.`.
|
169
171
|
For all errors, the return value for each method is `nil`.
|
170
172
|
|
@@ -191,12 +193,17 @@ All the `primes-utils` methods are `instance_methods` for `class Integer`.
|
|
191
193
|
|
192
194
|
## History
|
193
195
|
```
|
196
|
+
2.5.0 – 9 more index primes under the 110-millionth in nths; fixed Ruby 1.8 incompatibility in primes;
|
197
|
+
better|simpler technique for select_pg, significant speed increases for large ranges; used now
|
198
|
+
in all sozcore2 client methods primes, primescnt and primenth|nthprime; more code cleanups
|
194
199
|
2.4.0 – fixed error in algorithm when ks resgroup ≤ sqrt(end_num) resgroup; algorithm now split
|
195
200
|
arrays when start_num > sqrt(end_num) in sozcore2, whose code also signficantly optimized,
|
196
201
|
with API change adding pcs2start value to output parameters to use in primenth, which changed
|
197
202
|
to use it; ruby idiom code opt for set_start_value; consolidated pcs_to_num | pcs_to_start_num
|
198
203
|
functions into one new pcs_to_num, with associated changes in sozcore1|2; primes|cnt also
|
199
|
-
significantly faster resulting from sozcore2 changes; massive code cleanups all-arround
|
204
|
+
significantly faster resulting from sozcore2 changes; massive code cleanups all-arround; added
|
205
|
+
private methods select_pg (to adaptively select the pg used in primes), and array_check (used in
|
206
|
+
sozcore2 to catch array creation out-of-memory errors)
|
200
207
|
2.3.0 – primescnt now finds primes upto some integer much faster, and for much larger integers
|
201
208
|
increased index nth primes to over 2 billionth; used in nthprime|primenth and primescnt
|
202
209
|
2.2.0 – for sozcore2: refactored to include more common code; changed output api; added memory
|
data/lib/primes/utils.rb
CHANGED
@@ -7,39 +7,34 @@ module Primes
|
|
7
7
|
module Utils
|
8
8
|
# Upon loading, determine if platform has cli command 'factor'
|
9
9
|
private
|
10
|
-
os_has_factor = false
|
10
|
+
@@os_has_factor = false
|
11
11
|
begin
|
12
12
|
if `factor 10`.split(' ') == ["10:", "2", "5"]
|
13
|
-
os_has_factor = true
|
13
|
+
@@os_has_factor = true
|
14
14
|
end
|
15
15
|
rescue
|
16
|
-
os_has_factor = false
|
16
|
+
@@os_has_factor = false
|
17
17
|
end
|
18
18
|
|
19
|
-
# Methods primes* and primescnt* use a number range: end_num - start_num
|
20
|
-
# Use as: end_num.primes*(start_num) (or vice versa) or end_num.primes
|
21
|
-
# If start_num omitted, the method will find all primes <= end_num
|
22
|
-
# If start_num > self, values are switched to make end_num > start_num
|
23
|
-
|
24
19
|
public
|
25
|
-
if os_has_factor # for platforms with cli 'factor' command
|
20
|
+
if @@os_has_factor # for platforms with cli 'factor' command
|
26
21
|
|
27
22
|
def prime?
|
28
23
|
`factor #{self.abs}`.split(' ').size == 2
|
29
24
|
end
|
30
25
|
|
31
|
-
def factors(p=0)
|
26
|
+
def factors(p=0) # p is unused dummy variable for method consistency
|
32
27
|
factors = `factor #{self.abs}`.split(' ')[1..-1].map(&:to_i)
|
33
28
|
h = Hash.new(0); factors.each {|f| h[f] +=1}; h.to_a.sort
|
34
29
|
end
|
35
30
|
|
36
31
|
def primesf(start_num=0)
|
37
|
-
#
|
32
|
+
# List primes within a number range: end_num - start_num
|
38
33
|
# Uses 'prime?' to check primality of prime candidates in range
|
39
|
-
sozdata = sozcore1(self, start_num, true)
|
34
|
+
sozdata = sozcore1(self, start_num, true) # true for primes list
|
40
35
|
pcs_in_range, r, mod, modk, rescnt, residues, primes = sozdata
|
41
36
|
|
42
|
-
pcs_in_range.times do #
|
37
|
+
pcs_in_range.times do # list primes from this num pcs in range
|
43
38
|
prime = modk + residues[r]
|
44
39
|
primes << prime if prime.prime?
|
45
40
|
r +=1; if r > rescnt; r=1; modk +=mod end
|
@@ -50,7 +45,7 @@ module Primes
|
|
50
45
|
def primescntf(start_num=0)
|
51
46
|
# Count primes within a number range: end_num - start_num
|
52
47
|
# Uses 'prime?' to check primality of prime candidates in range
|
53
|
-
sozdata = sozcore1(self, start_num, false) # false for
|
48
|
+
sozdata = sozcore1(self, start_num, false) # false for primes count
|
54
49
|
pcs_in_range, r, mod, modk, rescnt, residues, primescnt = sozdata
|
55
50
|
|
56
51
|
pcs_in_range.times do # count primes from this num pcs in range
|
@@ -71,11 +66,9 @@ module Primes
|
|
71
66
|
mod=210; # rescnt=48
|
72
67
|
|
73
68
|
n = self.abs
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
167, 173, 179, 181, 191, 193, 197, 199, 211].include? n
|
78
|
-
return false unless residues.include?(n%mod) and n > 1
|
69
|
+
is_a_pc = residues.include?(n%mod) # true if n is a prime candidate
|
70
|
+
return false unless (n > 1 and is_a_pc) or [2,3,5,7].include? n
|
71
|
+
return true if n <= 211 and not [121,143,169,187,209].include? n
|
79
72
|
|
80
73
|
sqrtN = Math.sqrt(n).to_i
|
81
74
|
p=11 # first test prime pj
|
@@ -95,7 +88,7 @@ module Primes
|
|
95
88
|
n%(p+186)== 0 or n%(p+188)==0 or n%(p+198)== 0 or n%(p+200)==0
|
96
89
|
p += mod # first prime candidate for next kth residues group
|
97
90
|
end
|
98
|
-
true
|
91
|
+
true # n is prime (100%|deterministically)
|
99
92
|
end
|
100
93
|
|
101
94
|
def factors(p=13)
|
@@ -116,13 +109,12 @@ module Primes
|
|
116
109
|
primes.each {|p| while n%p == 0; factors << p; n /= p end }
|
117
110
|
|
118
111
|
sqrtN = Math.sqrt(n).to_i
|
119
|
-
modk,r=0,1
|
120
|
-
while p <= sqrtN
|
112
|
+
modk,r=0,1
|
113
|
+
while (p = modk+residues[r]) <= sqrtN
|
121
114
|
if n%p == 0
|
122
115
|
factors << p; r -=1; n /= p; sqrtN = Math.sqrt(n).to_i
|
123
116
|
end
|
124
117
|
r +=1; if r > rescnt; r=1; modk +=mod end
|
125
|
-
p = modk+residues[r] # next (or current) prime candidate
|
126
118
|
end
|
127
119
|
factors << n if n > 1
|
128
120
|
h=Hash.new(0); factors.each {|f| h[f] +=1}; h.to_a.sort
|
@@ -130,26 +122,26 @@ module Primes
|
|
130
122
|
|
131
123
|
puts "Using pure ruby versions for all methods"
|
132
124
|
end
|
133
|
-
|
125
|
+
|
134
126
|
# Replace slow ruby library method prime_division with faster version
|
135
127
|
alias prime_division factors
|
136
128
|
|
137
|
-
def primenth(p=
|
138
|
-
# Return value of nth prime
|
129
|
+
def primenth(p=0)
|
130
|
+
# Return value of nth prime
|
131
|
+
# Adaptively selects best SP PG, unless valid input PG given at runtime
|
139
132
|
seeds = [2, 3, 5, 7, 11, 13]
|
140
|
-
p =
|
133
|
+
(primes=seeds[0..seeds.index(p)]; mod=primes.reduce(:*)) if seeds.include? p
|
141
134
|
|
142
135
|
n = self.abs # the desired nth prime
|
143
|
-
return n
|
136
|
+
return n > 0 ? seeds[n-1] : 0 if n <= seeds.size
|
144
137
|
|
145
138
|
start_num, nth, nthflag = set_start_value(n,true)
|
146
|
-
return start_num if nthflag # output nthprime if
|
139
|
+
return start_num if nthflag # output nthprime value if n a ref prime key
|
147
140
|
|
148
141
|
num = approximate_nth(n) # close approx to nth >= real nth
|
149
|
-
primes =
|
150
|
-
mod = primes.reduce(:*) # create modulus of SP PG
|
142
|
+
primes, mod = select_pg(num, start_num) unless primes
|
151
143
|
prms, m, modk, residues, rescnt, pcs2start, * = sozcore2(num, start_num, mod)
|
152
|
-
return
|
144
|
+
return unless prms # exit gracefully if sozcore2 mem error
|
153
145
|
|
154
146
|
# starting at start_num's location, find nth prime within given range
|
155
147
|
prmcnt = n > nth ? nth-1 : primes.size
|
@@ -163,23 +155,22 @@ module Primes
|
|
163
155
|
alias nthprime primenth # to make life easier
|
164
156
|
|
165
157
|
def primes(start_num=0)
|
166
|
-
#
|
158
|
+
# List primes between a number range: end_num - start_num
|
167
159
|
# Adaptively selects Strictly Prime (SP) Prime Generator
|
168
160
|
num = self.abs; start_num = start_num.abs
|
169
161
|
num, start_num = start_num, num if start_num > num
|
170
162
|
|
171
163
|
primes, mod = select_pg(num, start_num) # adaptively select PG
|
172
|
-
|
173
|
-
|
174
|
-
return if prms == nil # exit gracefully if sozcore2 mem error
|
164
|
+
prms, m, modk, residues, rescnt, x, maxprms, r = sozcore2(num, start_num, mod)
|
165
|
+
return unless prms # exit gracefully if sozcore2 mem error
|
175
166
|
|
176
167
|
# init 'primes' w/any excluded primes in range then extract primes from prms
|
177
|
-
primes
|
178
|
-
while m < maxprms #
|
168
|
+
primes.select! {|p| p >= start_num && p <= num}
|
169
|
+
while m < maxprms # list primes from sieved pcs in prms for range
|
179
170
|
begin
|
180
171
|
primes << modk + residues[r] if prms[m] == 1
|
181
|
-
|
182
|
-
|
172
|
+
rescue Exception
|
173
|
+
return puts "ERROR3: not enough memory to store all primes in output array."
|
183
174
|
end
|
184
175
|
r +=1; if r > rescnt; r=1; modk +=mod end
|
185
176
|
m +=1
|
@@ -189,23 +180,22 @@ module Primes
|
|
189
180
|
|
190
181
|
def primescnt(start_num=0)
|
191
182
|
# Count primes between a number range: end_num - start_num
|
192
|
-
#
|
183
|
+
# Adaptively selects Strictly Prime (SP) Prime Generator
|
193
184
|
num = self.abs; start_num = start_num.abs
|
194
185
|
num, start_num = start_num, num if start_num > num
|
195
186
|
|
196
187
|
if start_num < 3 # for all primes upto num
|
197
188
|
start_num, nth, nthflag = set_start_value(num,false)
|
198
|
-
return nth unless nthflag # output
|
189
|
+
return nth unless nthflag # output num's key|count if a ref nth value
|
199
190
|
end
|
200
191
|
|
201
|
-
primes =
|
202
|
-
mod = primes.reduce(:*)
|
192
|
+
primes,mod = select_pg(num, start_num) # adaptively select PG
|
203
193
|
prms, m, * = sozcore2(num, start_num, mod)
|
204
|
-
return
|
194
|
+
return unless prms # exit gracefully if sozcore2 mem error
|
205
195
|
|
206
196
|
# init prmcnt for any excluded primes in range then count primes in prms
|
207
|
-
prmcnt = primes.
|
208
|
-
prmcnt = nth-1 if nthflag && nth > 0 #
|
197
|
+
prmcnt = primes.count {|p| p >= start_num && p <= num}
|
198
|
+
prmcnt = nth-1 if nthflag && nth > 0 # start count for small range
|
209
199
|
prmcnt + prms[m..-1].count(1)
|
210
200
|
end
|
211
201
|
|
@@ -234,16 +224,16 @@ module Primes
|
|
234
224
|
end
|
235
225
|
return false if x != n-1
|
236
226
|
end
|
237
|
-
true # with high probability
|
227
|
+
true # n is prime (with high probability)
|
238
228
|
end
|
239
229
|
|
240
230
|
def primesmr(start_num=0)
|
241
|
-
#
|
231
|
+
# List primes within a number range: end_num - start_num
|
242
232
|
# Uses 'primemr' to check primality of prime candidates in range
|
243
233
|
sozdata = sozcore1(self, start_num, true) # true for primes
|
244
234
|
pcs_in_range, r, mod, modk, rescnt, residues, primes = sozdata
|
245
235
|
|
246
|
-
pcs_in_range.times do #
|
236
|
+
pcs_in_range.times do # list primes from this num pcs in range
|
247
237
|
prime = modk + residues[r]
|
248
238
|
primes << prime if prime.primemr?
|
249
239
|
r +=1; if r > rescnt; r=1; modk +=mod end
|
@@ -264,14 +254,10 @@ module Primes
|
|
264
254
|
primescnt
|
265
255
|
end
|
266
256
|
|
267
|
-
def primes_utils
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
if os_has_factor
|
272
|
-
def primes_utils
|
273
|
-
"prime? primemr? primes primesf primesmr primescnt primescntf primescntmr primenth|nthprime factors|prime_division"
|
274
|
-
end
|
257
|
+
def primes_utils # display list of available methods
|
258
|
+
methods = %w/prime? primemr? primes primesf primesmr primescnt
|
259
|
+
primescntf primescntmr primenth|nthprime factors|prime_division/
|
260
|
+
(methods - (@@os_has_factor ? [] : %w/primesf primescntf/)).join(" ")
|
275
261
|
end
|
276
262
|
|
277
263
|
private
|
@@ -281,7 +267,7 @@ module Primes
|
|
281
267
|
[residues, residues.size-1] # return residues array and rescnt
|
282
268
|
end
|
283
269
|
|
284
|
-
# lte= true: first output element is number pcs <= num
|
270
|
+
# lte= true: first output element is number of pcs <= num
|
285
271
|
# lte=false: num pcs <, residue index, and resgroup value, for (start_)num pc
|
286
272
|
def pcs_to_num(num,mod,rescnt,residues,lte)
|
287
273
|
num -=1; lte ? (num |=1; k=num.abs/mod) : k = (num-1).abs/mod
|
@@ -309,7 +295,7 @@ module Primes
|
|
309
295
|
maxpcs,* = pcs_to_num(num,mod,rescnt,residues,true) # num pcs <= end_num
|
310
296
|
|
311
297
|
# init 'primes' w/any excluded primes in the range, or [] if none
|
312
|
-
primes
|
298
|
+
primes.select! {|p| p >= start_num && p <= num}
|
313
299
|
|
314
300
|
# compute parameters for start_num pc, then create output parameters array
|
315
301
|
m, r, modk = pcs_to_num(start_num, mod, rescnt, residues, false)
|
@@ -330,17 +316,17 @@ module Primes
|
|
330
316
|
residues, rescnt = make_residues_rescnt(mod) # parameters for the PG
|
331
317
|
maxprms,* = pcs_to_num(num,mod,rescnt,residues,true) # num pcs <= end_num
|
332
318
|
|
333
|
-
# for start_num pc, find num pcs <, residue index, and resgroup mod value
|
334
|
-
pcs2start, rs, modks = pcs_to_num(start_num, mod, rescnt, residues, false)
|
335
|
-
|
319
|
+
# for start_num pc, find num pcs <, residue index, and resgroup mod value
|
320
|
+
pcs2start, rs, modks = pcs_to_num(start_num, mod, rescnt, residues, false)
|
321
|
+
|
336
322
|
sqrtN = Math.sqrt(num).to_i # sqrt of end_num (end of range)
|
337
323
|
pcs2sqrtN,* = pcs_to_num(sqrtN,mod,rescnt,residues,true) # num pcs <= sqrtN
|
338
324
|
|
339
325
|
split_arrays = start_num > sqrtN # flag, true if two arrays used for sieve
|
340
|
-
maxpcs = maxprms # init array size for all pcs to end_num
|
326
|
+
maxpcs = maxprms # init array size for all pcs to end_num
|
341
327
|
if split_arrays # if start_num > sqrtN create two arrays
|
342
328
|
maxpcs = pcs2sqrtN # number of pcs|array size, for pcs <= sqrtN
|
343
|
-
max_range = maxprms-pcs2start # number of pcs in range start_num to end_num
|
329
|
+
max_range = maxprms-pcs2start # number of pcs in range start_num to end_num
|
344
330
|
prms_range = array_check(max_range,1) # array to represent pcs in range
|
345
331
|
return puts "ERROR1: range size too big for available memory." unless prms_range
|
346
332
|
end
|
@@ -361,9 +347,9 @@ module Primes
|
|
361
347
|
kcon = k * prmstep # its inner loop constant computed
|
362
348
|
residues[1..-1].each do |ri|# now perform sieve with it
|
363
349
|
# convert (prime * (modk + ri)) pc value to its address in prms
|
364
|
-
|
350
|
+
# computed as nonprm = (k*(prime + ri) + kn)*rescnt + pos[rr]
|
365
351
|
kn,rr = (prm_r * ri).divmod mod # residues product res[group|track]
|
366
|
-
|
352
|
+
nonprm = kcon + (k*ri + kn)*rescnt + pos[rr]# 1st prime multiple address with ri
|
367
353
|
while nonprm < maxpcs; prms[nonprm]=0; nonprm +=prmstep end
|
368
354
|
if split_arrays # when start_num > sqrtN
|
369
355
|
nonprm = (pcs2start - nonprm)%prmstep # (start_num - last multiple) pcs
|
@@ -386,20 +372,23 @@ module Primes
|
|
386
372
|
def set_start_value(n, hshflag) # find largest index nthprime|val <= n
|
387
373
|
if hshflag
|
388
374
|
return [nths[n], 0, true] if nths.has_key? n # if n is key in nths table
|
389
|
-
|
375
|
+
nth = nths.keys.sort.reverse.detect {|k| k < n} # find largest indexed key < n
|
390
376
|
[nth ? nths[nth] : 0, nth ||= n+1, false] # [start_num, nth, false]
|
391
377
|
else
|
392
378
|
return [0,nths.key(n),false] if nths.has_value? n # if n is value in nths table
|
393
|
-
|
379
|
+
v=val= nths.values.sort.reverse.detect {|v| v < n} # find largest indexed val < n
|
394
380
|
[v ||= 0, val ? nths.key(val) : 0, true] # [start_num, nth, true]
|
395
381
|
end
|
396
382
|
end
|
397
383
|
|
398
384
|
def nths # hash table index of reference nth primes
|
399
385
|
nths={1000000 => 15485863, 5000000 => 86028121, 7500000 => 132276691,
|
400
|
-
10000000 => 179424673, 12500000 => 227254201,
|
401
|
-
|
402
|
-
|
386
|
+
10000000 => 179424673, 12500000 => 227254201, 15000000 => 275604541,
|
387
|
+
18500000 => 344032387, 25000000 => 472882027, 31000000 => 593441843,
|
388
|
+
37500000 => 725420401, 43500000 => 848321917, 50000000 => 982451653,
|
389
|
+
56000000 => 1107029837, 62500000 => 1242809749, 68500000 => 1368724829,
|
390
|
+
75000000 => 1505776939, 81500000 => 1643429659, 87500000 => 1770989609,
|
391
|
+
93500000 => 1898979367, 100000000 => 2038074743, 106500000 => 2177624377,
|
403
392
|
112500000 => 2306797469, 125000000 => 2576983867, 137500000 => 2848518523,
|
404
393
|
150000000 => 3121238909, 162500000 => 3395057291, 175000000 => 3669829403,
|
405
394
|
187500000 => 3945592087, 200000000 => 4222234741, 212500000 => 4499683009,
|
@@ -455,14 +444,18 @@ module Primes
|
|
455
444
|
end
|
456
445
|
|
457
446
|
def select_pg(num, start_num) # adaptively select PG
|
458
|
-
|
459
|
-
primes =
|
447
|
+
range_size = num - start_num
|
448
|
+
primes = [2, 3, 5] # use P5 for small ranges
|
449
|
+
primes << 7 if range_size > 35*10**5 # use P7 for midsize ranges
|
450
|
+
primes << 11 if range_size > 850*10**5 # use P11 for large ranges
|
451
|
+
primes << 13 if range_size > 550*10**7 # use P13 for larger ranges
|
460
452
|
[primes, primes.reduce(:*)] # [excluded primes, mod] for PG
|
461
453
|
end
|
462
454
|
|
463
455
|
def array_check(n,v) # catch out-of-memory errors on array creation
|
464
|
-
|
456
|
+
Array.new(n,v) rescue return # return an array or nil
|
465
457
|
end
|
458
|
+
|
466
459
|
end
|
467
460
|
end
|
468
461
|
|
data/lib/primes/utils/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: primes-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jabari Zakiya
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|