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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72ccd5984ebd121f01d0846f5e6cd178fd7b007e
4
- data.tar.gz: 6a484343ab2c7b047f382d4b104119c9888a5779
3
+ metadata.gz: af94be1cfe58cb1704376223da97cdb48d6cc8a0
4
+ data.tar.gz: 924587a02967cd156d2115d5d1ac22d547ca9089
5
5
  SHA512:
6
- metadata.gz: ee5446beb5818aaee204b7ea525ab97e5c52e47be2f9e739594a54cc9863a8a4dacbaf074219ea8e634c098bac32d33d4f879c8c81f60770a79df27c5b11f63c
7
- data.tar.gz: 655f6c271d60b538597c861733f48e36683cb61b72cf577d0c9f53a0e0f7498767dc49b964c64599bf3d775d4ae6ca4c814e12035601724fee6261ed3036829a
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 (relative to Ruby's standard library) utility methods for testing and generating primes.
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 best use practices and implementation details see:
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
- ```ruby
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
- 0.prime? => false
63
- 1.prime? => false
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 upto that number will be returned.
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 upto that number will be returned.
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 `x.primes_utils` where x is any `class Integer` value.
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`, and `primescnt`, and possibly `nthprime|primenth`.
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) # p is unused dummy variable for method consistency
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
- # Find primes within a number range: end_num - start_num
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) # true for primes
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 # find primes from this num pcs in range
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 primescnt
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
- return true if [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
75
- 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
76
- 107, 109, 113, 127, 131, 137, 139, 149, 151, 157,163,
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; p=residues[1] # first test prime pj
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=7)
138
- # Return value of nth prime; P7 is default SP Prime Generator
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 = 7 unless seeds.include? 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 != 0 ? seeds[n-1] : 0 if n <= seeds.size
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 nth ref value
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 = seeds[0..seeds.index(p)]
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 if prms == nil # exit gracefully if sozcore2 mem error
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
- # Find primes between a number range: end_num - start_num
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
- prms, m, modk, residues, rescnt, *, maxprms, r = sozcore2(num, start_num, mod)
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 = primes.select {|p| p >= start_num && p <= num}
178
- while m < maxprms # find primes from sieved pcs in prms for range
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
- rescue Exception
182
- return puts "ERROR3: not enough memory to store all primes in output array."
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
- # Uses P5 or P7 Strictly Prime (SP) Prime Generators
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 nth's number if n a ref nth prime
189
+ return nth unless nthflag # output num's key|count if a ref nth value
199
190
  end
200
191
 
201
- primes = nthflag ? [2,3,5,7] : [2,3,5] # use P7 upto an N; P5 for a range
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 if prms == nil # exit gracefully if sozcore2 mem error
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.select {|p| p >= start_num && p <= num}.size
208
- prmcnt = nth-1 if nthflag && nth > 0 # nflag is nil or true
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
- # Find primes within a number range: end_num - start_num
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 # find primes from this num pcs in range
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
- "prime? primemr? primes primesmr primescnt primescntmr primenth|nthprime factors|prime_division"
269
- end
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 = primes.select {|p| p >= start_num && p <= num}
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
- # computed as nonprm = (k*(prime + ri) + kn)*rescnt + pos[rr]
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
- nonprm =kcon + (k*ri + kn)*rescnt + pos[rr] # 1st prime multiple address with ri
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
- nth = nths.keys.sort.reverse.detect {|k| k < n} # find largest indexed key < n
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
- v=val= nths.values.sort.reverse.detect {|v| v < n} # find largest indexed val < n
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, 25000000 => 472882027,
401
- 37500000 => 725420401, 50000000 => 982451653, 62500000 => 1242809749,
402
- 75000000 => 1505776939, 87500000 => 1770989609, 100000000 => 2038074743,
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
- primes = [2, 3, 5]
459
- primes = num > 10**8 ? [2,3,5,7,11] : [2,3,5,7] if start_num < 3
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
- begin Array.new(n,v) rescue return end # return an array or nil
456
+ Array.new(n,v) rescue return # return an array or nil
465
457
  end
458
+
466
459
  end
467
460
  end
468
461
 
@@ -1,5 +1,5 @@
1
1
  module Primes
2
2
  module Utils
3
- VERSION = "2.4.0"
3
+ VERSION = "2.5.0"
4
4
  end
5
5
  end
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.0
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-10-23 00:00:00.000000000 Z
11
+ date: 2015-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler