primes-utils 2.2.0 → 2.3.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 +27 -3
- data/lib/primes/utils.rb +61 -42
- data/lib/primes/utils/version.rb +1 -1
- data/primes-utils.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff3c9d871e492288cbbfac6beb023fd765f9bf8e
|
4
|
+
data.tar.gz: 976926b10063c0fc58ea29b33765b800c937727f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e1b3235a3252ce746a1ba5210060fc9b73998a4b4b789ce37a1bf85a8591ac4bc7f70d76250ac34a71538705c8e2d06f906b15db440ae27e6b555c33fea491b
|
7
|
+
data.tar.gz: cd933f765848c9d5777aa34f677a85c01b3f591205eceb545cd523cd159db5c42381ca27d8044d1ef1f38ce8bd9a472fa93036a37f225cfcd8581fd469e2b28a
|
data/README.md
CHANGED
@@ -114,7 +114,9 @@ See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
|
114
114
|
Also see `Error Handling`.
|
115
115
|
|
116
116
|
```
|
117
|
-
|
117
|
+
100001.primescnt => 9592
|
118
|
+
100002.primescnt => 9592
|
119
|
+
100003.primescnt => 9593
|
118
120
|
100000.primescntf 100500 => 40
|
119
121
|
n=10**400; (n-500).primescntmr(n+500) => 1
|
120
122
|
-10.primescnt -50 => 11
|
@@ -151,7 +153,7 @@ Use as `x.primes_utils` where x is any `class Integer` value.
|
|
151
153
|
|
152
154
|
## Error Handling
|
153
155
|
Starting with 2.2.0, error handling has been implemented to gracefully handle when array creation requires more memory than available.
|
154
|
-
This occurs
|
156
|
+
This occurs when the range size, or end_num, need arrays greater than the amount of avalable memory. The first case shows the message
|
155
157
|
`ERROR1: range size too big for available memory.` and the second case `ERROR2: end_num too big for available memory.`
|
156
158
|
The affected methods are `nthprime|primenth`, `primes`, and `primescnt`.
|
157
159
|
`nthprime|primenth` also displays the error message `<yyyy> not enough primes, approx nth too small.`
|
@@ -160,7 +162,6 @@ For all errors, the return value for each method is `nil`.
|
|
160
162
|
|
161
163
|
This behavior is referenced to MRI Ruby.
|
162
164
|
|
163
|
-
|
164
165
|
## Coding Implementations
|
165
166
|
The methods `primemr?`, `nthprime|primenth`, `primes`, `primescnt`, `primesmr`, and `primescnt` are coded in pure ruby.
|
166
167
|
The methods `prime?` and `prime_division|factors` have two implementations.
|
@@ -175,6 +176,29 @@ New in 2.2.0, upon loading with Ruby 1.8 `require 'rubygems'` is invoked to enab
|
|
175
176
|
|
176
177
|
All the `primes-utils` methods are `instance_methods` for `class Integer`.
|
177
178
|
|
179
|
+
## History
|
180
|
+
```
|
181
|
+
2.3.0 – primescnt now finds primes upto some integer much faster, and for much larger integers
|
182
|
+
increased index nth primes to over 2 billionth; used in nthprime|primenth and primescnt
|
183
|
+
2.2.0 – for sozcore2: refactored to include more common code; changed output api; added memory
|
184
|
+
error messages when prms and prms_range arrays creation fails; for primenth: used new
|
185
|
+
function to compute parameter b and removed ceiling for it; increased number of index primes
|
186
|
+
in nths; primes, primescnt, and primenth|nthprime also refactored, will use all available mem
|
187
|
+
2.1.0 – changed default PG in primes and primescnt from P13 to P5, significantly faster
|
188
|
+
2.0.0 – new methods primesf, primesmr, primescnt, primescntf, primescntmr, primes_utils
|
189
|
+
also improved mem efficiency/speed and extended range for primes and primenth
|
190
|
+
changed default PG in nthprime|primenth from P11 to P7, major refactoring of all methods
|
191
|
+
1.1.1 – more efficient/faster code to count up to nth prime in primenth
|
192
|
+
1.1.0 – new nth prime approximation method in primenth
|
193
|
+
1.0.6 – fixed n=1 check error for prime?
|
194
|
+
1.0.5 – minor bug fix
|
195
|
+
1.0.4 – fixed n=0 case for primenth; fixed subtle bug in primes, refactored to generalize code
|
196
|
+
1.0.3 – minor bug fix
|
197
|
+
1.0.2 – directly test for cli command factor on installed platform at start
|
198
|
+
1.0.1 – check if using Ruby 1.8 at start, if so, require 'rational' library for gcd method
|
199
|
+
1.0.0 – initial release April 1, 2015 with methods prime?, primemr?, primes, prime_division|factors, primenth|nthprime
|
200
|
+
```
|
201
|
+
|
178
202
|
## Author
|
179
203
|
Jabari Zakiya
|
180
204
|
|
data/lib/primes/utils.rb
CHANGED
@@ -37,8 +37,8 @@ module Primes
|
|
37
37
|
# Find primes within a number range: end_num - start_num
|
38
38
|
# Uses 'prime?' to check primality of prime candidates in range
|
39
39
|
sozdata = sozcore1(self, start_num, true) # true for primes
|
40
|
-
return sozdata[1] if sozdata[0]
|
41
|
-
pcs_in_range, r, mod, modk, rescnt, residues, primes = sozdata
|
40
|
+
return sozdata[1] if !sozdata[0] # if sozdata[0] false
|
41
|
+
pcs_in_range, r, mod, modk, rescnt, residues, primes = sozdata
|
42
42
|
pcs_in_range.times do # find primes from this num pcs in range
|
43
43
|
prime = modk + residues[r]
|
44
44
|
primes << prime if prime.prime?
|
@@ -51,9 +51,9 @@ module Primes
|
|
51
51
|
# Count primes within a number range: end_num - start_num
|
52
52
|
# Uses 'prime?' to check primality of prime candidates in range
|
53
53
|
sozdata = sozcore1(self, start_num, false) # false for primescnt
|
54
|
-
return sozdata[1] if sozdata[0]
|
55
|
-
pcs_in_range, r, mod, modk, rescnt, residues,
|
56
|
-
|
54
|
+
return sozdata[1] if !sozdata[0] # if sozdata[0] false
|
55
|
+
pcs_in_range, r, mod, modk, rescnt, residues, primescnt = sozdata
|
56
|
+
|
57
57
|
pcs_in_range.times do # count primes from this num pcs in range
|
58
58
|
primescnt +=1 if (modk + residues[r]).prime?
|
59
59
|
r +=1; if r > rescnt; r=1; modk +=mod end
|
@@ -143,25 +143,22 @@ module Primes
|
|
143
143
|
|
144
144
|
n = self.abs # the desired nth prime
|
145
145
|
return n != 0 ? seeds[n-1] : 0 if n <= seeds.size
|
146
|
-
|
147
|
-
start_num, nth, nthflag = set_start_value(n)
|
146
|
+
|
147
|
+
start_num, nth, nthflag = set_start_value(n,true)
|
148
148
|
return start_num if nthflag # output nthprime if nth ref value
|
149
149
|
|
150
150
|
num = approximate_nth(n) # close approx to nth >= real nth
|
151
151
|
primes = seeds[0..seeds.index(p)]
|
152
152
|
|
153
|
-
prms, m, mod, modk, residues, * = sozcore2(num, start_num, primes)
|
153
|
+
prms, m, mod, modk, residues, rescnt, * = sozcore2(num, start_num, primes)
|
154
154
|
return if prms == nil # exit gracefully if sozcore2 mem error
|
155
|
-
|
156
|
-
rescnt = residues[1..-1].size
|
157
|
-
pcs2ks = rescnt*(modk/mod) # rescnt*ks - number of pcs upto ks resgroup
|
158
|
-
|
155
|
+
|
159
156
|
# starting at start_num's location, find nth prime within given range
|
160
157
|
prmcnt = n > nth ? nth-1 : primes.size
|
161
158
|
pcnt = prmcnt + prms[m..-1].count(1) # number of primes upto nth approx
|
162
159
|
return puts "#{pcnt} not enough primes, approx nth too small." if pcnt < n
|
163
160
|
while prmcnt < n; prmcnt +=1 if prms[m] == 1; m +=1 end
|
164
|
-
k, r = (m+pcs2ks).divmod rescnt
|
161
|
+
k, r = (m + rescnt*(modk/mod)).divmod rescnt # (m+pcs2ks).divmod rescnt
|
165
162
|
mod*k + residues[r]
|
166
163
|
end
|
167
164
|
|
@@ -177,13 +174,11 @@ module Primes
|
|
177
174
|
plast = primes.last # last prime in primes
|
178
175
|
return primes.select {|p| p >= start_num && p <= num} if num <= plast
|
179
176
|
|
180
|
-
prms, m, mod, modk, residues, maxprms, r = sozcore2(num, start_num, primes)
|
177
|
+
prms, m, mod, modk, residues, rescnt, maxprms, r = sozcore2(num, start_num, primes)
|
181
178
|
return if prms == nil # exit gracefully if sozcore2 mem error
|
182
179
|
|
183
|
-
rescnt = residues[1..-1].size
|
184
|
-
|
185
180
|
# starting at start_num's location, extract primes within given range
|
186
|
-
primes = start_num <= plast ? primes.
|
181
|
+
primes = start_num <= plast ? primes.select {|p| p >= start_num} : []
|
187
182
|
while m < maxprms # find primes from pcs within given range
|
188
183
|
primes << modk + residues[r] if prms[m] == 1
|
189
184
|
r +=1; if r > rescnt; r=1; modk +=mod end
|
@@ -194,20 +189,27 @@ module Primes
|
|
194
189
|
|
195
190
|
def primescnt(start_num=0)
|
196
191
|
# Count primes between a number range: end_num - start_num
|
197
|
-
# Uses
|
192
|
+
# Uses P5 or P7 Strictly Prime (SP) Prime Generators
|
198
193
|
num = self.abs; start_num = start_num.abs
|
199
194
|
num, start_num = start_num, num if start_num > num
|
200
195
|
|
201
|
-
|
202
|
-
plast
|
203
|
-
return
|
196
|
+
seeds = [2, 3, 5, 7, 11, 13]
|
197
|
+
plast = seeds.last # last prime in seeds
|
198
|
+
return seeds.select {|p| p >= start_num && p <= num}.size if num <= plast
|
199
|
+
|
200
|
+
if start_num == 0
|
201
|
+
start_num, nth, nthflag = set_start_value(num,false)
|
202
|
+
return nth if !nthflag # output nth's number if n a ref nth prime
|
203
|
+
end
|
204
204
|
|
205
|
+
primes = nthflag ? [2,3,5,7] : [2,3,5] # choose P7 or P5
|
205
206
|
prms, m, * = sozcore2(num, start_num, primes)
|
206
207
|
return if prms == nil # exit gracefully if sozcore2 mem error
|
207
208
|
|
208
209
|
# starting at start_num's location, count primes within given range
|
209
|
-
|
210
|
-
|
210
|
+
prmcnt = start_num <= plast ? primes.select {|p| p >= start_num}.size : 0
|
211
|
+
prmcnt = nth > 0 ? nth-1 : primes.size if nthflag # nflag is nil or true
|
212
|
+
prmcnt + prms[m..-1].count(1)
|
211
213
|
end
|
212
214
|
|
213
215
|
# Miller-Rabin prime test in Ruby
|
@@ -242,8 +244,8 @@ module Primes
|
|
242
244
|
# Find primes within a number range: end_num - start_num
|
243
245
|
# Uses 'primemr' to check primality of prime candidates in range
|
244
246
|
sozdata = sozcore1(self, start_num, true) # true for primes
|
245
|
-
return sozdata[1] if sozdata[0]
|
246
|
-
pcs_in_range, r, mod, modk, rescnt, residues, primes = sozdata
|
247
|
+
return sozdata[1] if !sozdata[0] # if sozdata[0] false
|
248
|
+
pcs_in_range, r, mod, modk, rescnt, residues, primes = sozdata
|
247
249
|
pcs_in_range.times do # find primes from this num pcs in range
|
248
250
|
prime = modk + residues[r]
|
249
251
|
primes << prime if prime.primemr?
|
@@ -256,9 +258,9 @@ module Primes
|
|
256
258
|
# Count primes within a number range: end_num - start_num
|
257
259
|
# Uses 'primemr' to check primality of prime candidates in range
|
258
260
|
sozdata = sozcore1(self, start_num, false) # false for primescnt
|
259
|
-
return sozdata[1] if sozdata[0]
|
260
|
-
pcs_in_range, r, mod, modk, rescnt, residues,
|
261
|
-
|
261
|
+
return sozdata[1] if !sozdata[0] # if sozdata[0] false
|
262
|
+
pcs_in_range, r, mod, modk, rescnt, residues, primescnt = sozdata
|
263
|
+
|
262
264
|
pcs_in_range.times do # count primes from this num pcs in range
|
263
265
|
primescnt +=1 if (modk + residues[r]).primemr?
|
264
266
|
r +=1; if r > rescnt; r=1; modk +=mod end
|
@@ -301,23 +303,24 @@ module Primes
|
|
301
303
|
|
302
304
|
def sozcore1(num, start_num, method_flag)
|
303
305
|
# Uses the P13 Strictly Prime (SP) Prime Generator
|
304
|
-
num = num.abs;
|
306
|
+
num = num.abs; start_num = start_num.abs
|
305
307
|
num, start_num = start_num, num if start_num > num
|
306
308
|
|
307
309
|
primes = [2,3,5,7,11,13] # P13 excluded primes lists
|
308
310
|
plast = primes.last # last prime in primes
|
309
311
|
if num <= plast
|
310
312
|
primes = primes.select {|p| p >= start_num && p <= num}
|
311
|
-
return [
|
313
|
+
return [false, method_flag ? primes : primes.size]
|
312
314
|
end
|
313
315
|
mod = primes.reduce(:*) # P13 modulus: 2*3*5*7*11*13 = 30030
|
314
316
|
residues, rescnt = make_residues_rescnt(mod)
|
315
|
-
maxpcs = pcs_to_num(num,mod,rescnt,residues) # num of pcs <= end_num
|
317
|
+
maxpcs = pcs_to_num(num, mod, rescnt, residues) # num of pcs <= end_num
|
316
318
|
|
317
319
|
# compute parameters for start location and number of pcs within range
|
318
|
-
primes = start_num <= plast ? primes.
|
320
|
+
primes = start_num <= plast ? primes.select {|p| p >= start_num} : []
|
319
321
|
m, r, modk = pcs_to_start_num(start_num, mod, rescnt, residues)
|
320
|
-
|
322
|
+
|
323
|
+
[maxpcs-m, r, mod, modk, rescnt, residues, method_flag ? primes : primes.size]
|
321
324
|
end
|
322
325
|
|
323
326
|
# Perform SoZ for given Prime Generator and return array of parameters
|
@@ -327,8 +330,9 @@ module Primes
|
|
327
330
|
# mod - modulus value for PG
|
328
331
|
# modk - mod*ks; mod value for ks, start_num's resgroup
|
329
332
|
# residues - array of residues plus mod+1 for PG
|
333
|
+
# rescnt - number of residues < mod
|
330
334
|
# maxprms - the number of pcs in range to find primes from
|
331
|
-
# r - first residue location in ks >= start_num
|
335
|
+
# r - first residue index location in ks >= start_num
|
332
336
|
|
333
337
|
def sozcore2(num, start_num, primes)
|
334
338
|
mod = primes.reduce(:*) # modulus: modPn = 2*3*5*7*..*Pn
|
@@ -384,7 +388,7 @@ module Primes
|
|
384
388
|
r=1; modk = mod*ks # find 1st residue val|location
|
385
389
|
while modk + residues[r] < start_num; r +=1 end # r in ks >= start_num
|
386
390
|
|
387
|
-
[prms, m=r-1, mod, modk, residues, maxprms, r] # parameter output
|
391
|
+
[prms, m=r-1, mod, modk, residues, rescnt, maxprms, r] # parameter output
|
388
392
|
end
|
389
393
|
|
390
394
|
def approximate_nth(n) # approximate nthprime value >= real value
|
@@ -393,12 +397,16 @@ module Primes
|
|
393
397
|
(n*(Math.log(n)+a)+3).to_i # use nth approximation as end_num of range
|
394
398
|
end
|
395
399
|
|
396
|
-
def set_start_value(n)
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
400
|
+
def set_start_value(n, hshflag) # find largest index nthprime|val <= requested
|
401
|
+
if hshflag
|
402
|
+
return [nths[n], 0, true] if nths.has_key? n # if n is key in nths table
|
403
|
+
nth = nths.keys.sort.select {|k| k < n}.last # find largest indexed key < n
|
404
|
+
[nth ? nths[nth] : 0, nth ||= n+1, false] # [start_num, nth, false]
|
405
|
+
else
|
406
|
+
return [0,nths.key(n),false] if nths.has_value? n # if n is value in nths table
|
407
|
+
v=val = nths.values.sort.select {|v| v < n}.last # find largest indexed val < n
|
408
|
+
[v ||= 0, val ? nths.key(val) : 0, true] # [start_num, nth, true]
|
409
|
+
end
|
402
410
|
end
|
403
411
|
|
404
412
|
def nths # hash table index of reference nth primes
|
@@ -445,7 +453,18 @@ module Primes
|
|
445
453
|
1462500000=>33930284893, 1475000000=>34233442279, 1487500000=>34536683891,
|
446
454
|
1500000000=>34840062373, 1512500000=>35143545889, 1525000000=>35447088559,
|
447
455
|
1537500000=>35750747297, 1550000000=>36054501641, 1562500000=>36358440731,
|
448
|
-
1575000000=>36662430631, 1587500000=>36966563321, 1600000000=>37270791697
|
456
|
+
1575000000=>36662430631, 1587500000=>36966563321, 1600000000=>37270791697,
|
457
|
+
1612500000=>37575137933, 1625000000=>37879532671, 1637500000=>38184009763,
|
458
|
+
1650000000=>38488677419, 1662500000=>38793413899, 1675000000=>39098225629,
|
459
|
+
1687500000=>39403174463, 1700000000=>39708229123, 1712500000=>40013309359,
|
460
|
+
1725000000=>40318523009, 1737500000=>40623800311, 1750000000=>40929166261,
|
461
|
+
1762500000=>41234743751, 1775000000=>41540289619, 1787500000=>41845958971,
|
462
|
+
1800000000=>42151671491, 1812500000=>42457500313, 1825000000=>42763499629,
|
463
|
+
1837500000=>43069571603, 1850000000=>43375710643, 1862500000=>43681898699,
|
464
|
+
1875000000=>43988172667, 1887500000=>44294549347, 1900000000=>44601021791,
|
465
|
+
1912500000=>44907564593, 1925000000=>45214177441, 1937500000=>45520935011,
|
466
|
+
1950000000=>45827700419, 1962500000=>46134655219, 1975000000=>46441643177,
|
467
|
+
1987500000=>46748693981, 2000000000=>47055833459, 2012500000=>47363059687
|
449
468
|
}
|
450
469
|
end
|
451
470
|
end
|
data/lib/primes/utils/version.rb
CHANGED
data/primes-utils.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["jzakiya@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{suite of extremely fast utility methods for testing and generating primes}
|
13
|
-
spec.description = %q{Methods: prime?, primemr?, primes, primesf, primesmr, primescnt, primescntf, primescntmr, nthprime
|
13
|
+
spec.description = %q{Methods: prime?, primemr?, primes, primesf, primesmr, primescnt, primescntf, primescntmr, primenth|nthprime, factors|prime_division}
|
14
14
|
spec.homepage = "https://github.com/jzakiya/primes-utils"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
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.3.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-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
description: 'Methods: prime?, primemr?, primes, primesf, primesmr, primescnt, primescntf,
|
42
|
-
primescntmr, nthprime
|
42
|
+
primescntmr, primenth|nthprime, factors|prime_division'
|
43
43
|
email:
|
44
44
|
- jzakiya@gmail.com
|
45
45
|
executables: []
|
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
78
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.
|
79
|
+
rubygems_version: 2.4.6
|
80
80
|
signing_key:
|
81
81
|
specification_version: 4
|
82
82
|
summary: suite of extremely fast utility methods for testing and generating primes
|