primes-utils 3.0.5 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4389a00aebe98cc43fc901200e8eebdf0ad704f17ce590aafa47b2fe6eadb4e1
4
- data.tar.gz: af97630fb433b113734d2d04d68c7f24490373a0aec2e57f411383dccfab53e9
3
+ metadata.gz: 6e4efbd1adfba3980cb7d23ff8d6a604c835a1d8159993d52676941534ac9454
4
+ data.tar.gz: 1e730c6ec9e6e505cc7dbcaa706c7a788f25fd3b746b8d3738002f2c95d2d8bd
5
5
  SHA512:
6
- metadata.gz: 92a9e70b078633b8570ad87057ec006ed3b45c9d9884f01cac28718a24dbf4479fd1429ea9b6d0074f4e8c543fdcf4b1ea912b244bccfe707e78ad1101cc35b7
7
- data.tar.gz: 2f1d16062ce8618e22a9c1c1f3b790a3817199400e775d7ad0b0071ace4cfdb96bbd1d4047847316f34398b117f01187f54f48614a5edcaef55cc88cf891fcac
6
+ metadata.gz: 6af6def197418a3c5cf68c0a75d0ce182a96b60f1f414d6da2762ddf7156476a0d863f79bc65d08dc6824d62421f932e082ffb0b718f632a19ac416af618292a
7
+ data.tar.gz: 954aa75ea469ef4ccaaaf3b14b20c78d4d2c1b7e2ee7803126d40e2d35fbcd68e9682bf30710ca7127af31b2f86688951970bef2f7e51ac8ff3102973d0ca984
data/README.md CHANGED
@@ -50,11 +50,15 @@ Uses PGT residues tests, then Miller-Rabin test using `primemr?`.
50
50
 
51
51
  **primemr?(k=5)**
52
52
 
53
- Optimized deterministic (over 64-bits) implementation of Miller-Rabin algorithm.
54
- Default non-deterministic reliability set at k = 5, set higher if desired for very large numbers > 64-bts.
53
+ Optimized deterministic (to 128-bits) implementation of Miller-Rabin algorithm.
54
+ It's the underlying primality test for `prime`, and used in other methods.
55
+ Default probabilistic reliability constant set at k = 5, set higher if desired for numbers > 128-bts.
56
+ Not really necessary to do though.
55
57
 
56
58
  ```
57
- n.prime?(6)
59
+ 5_000_000_000_000_000_003.primemr? => true
60
+ 987_654_321_012_345_678_901_382_737.primemr? 6 => true
61
+ 987_654_321_012_345_678_901_382_739.primemr? 6 => false
58
62
  ```
59
63
 
60
64
  **factors or prime_division**
@@ -80,6 +84,12 @@ Pure Ruby version equivalent of `factors`.
80
84
  Not as fast as `factors` for some values with multiple large prime factors.
81
85
  Always available if OS doesn't have coreutils `factor`.
82
86
 
87
+ ```
88
+ 123_456_789.factors1 => [[3, 1], [7, 2], [839087, 1]]
89
+ 5_000_000_000_000_000_003.factors1 => [[5000000000000000003, 1]]
90
+ 987_654_321_012_345_678_901_382_739.factors1 => [[3, 1], [23, 1], [139, 1], [421, 1], [3469, 1], [7393, 1], [135899, 1], [70180703, 1]]
91
+ ```
92
+
83
93
  **primes(start=0), primesmr(start=0)**
84
94
 
85
95
  Return an array of prime values within the inclusive integers range `[start_num - end_num]`.
@@ -108,8 +118,9 @@ prms => [1000003, 1000033, 1000037, 1000039, 1000081, 1000099]
108
118
  Provide count of primes within the inclusive integers range `[start_num - end_num]`.
109
119
  Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
110
120
  A single input is taken as `end_num`, and the primes count <= to it are returned.
111
- `primescnt` is faster; uses SoZ to identify|count primes from closest hashed value starting point.
112
- `primescntmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
121
+ `primescnt` is generally faster; uses SoZ to identify|count primes from closest hashed value starting point.
122
+ `primescntmr` is situationally slower, but isn't memory limited, especially for very large numbers|ranges.
123
+ Can also perform effective primality test on an integer n as: `n.primescntmr n`
113
124
  See `PRIMES-UTILS HANDBOOK` for details on best use practices.
114
125
  Also see `Error Handling`.
115
126
 
@@ -120,8 +131,11 @@ Also see `Error Handling`.
120
131
  100000.primescntmr 100500 => 40
121
132
  n=10**400; (n-500).primescntmr(n+500) => 1
122
133
  n=10**8; (25*n).primescnt => 121443371
134
+ 541.primescntmr 7919 => 901
123
135
  0.primescnt => 0
124
136
  1.primescntmr => 0
137
+ 100.primescntmr 100 => 0
138
+ 101.primescntmr 101 => 1
125
139
  ```
126
140
 
127
141
  **primenth(p=0) or nthprime(p=0)**
@@ -174,7 +188,7 @@ Return value of previous prime < n > 2. Returns `nil` for n < 2 (and negatives)
174
188
  Displays a list of all the `primes-utils` methods available for a system.
175
189
  Use as eg: `0.primes_utils` where input n is any `class Integer` value.
176
190
 
177
- Available methods for 3.0.0.
191
+ Available methods for 3.1.1.
178
192
 
179
193
  ```
180
194
  0.primes_utils => "prime? primes primesmr primescnt primescntmr primenth|nthprime factors|prime_division factors1 next_prime prev_prime primes_utils"
@@ -194,9 +208,9 @@ If they occur you will know why now.
194
208
  This behavior is referenced to MRI Ruby.
195
209
 
196
210
  ## Coding Implementations
197
- The method `prime_division|factors` has 2 implementations. A pure ruby implementation, and a hybrid implementation
211
+ The method `prime_division|factors` has 2 implementations. A pure ruby implementation `factors1`, and a hybrid implementation
198
212
  using the Unix cli command `factor` [5], if available on the host OS. It's an extremely fast C coded factoring algorithm,
199
- part of the GNU Core Utilities package [4].
213
+ part of the GNU Core Utilities package [4]. However, `factors1` is always exists separately.
200
214
 
201
215
  Upon loading, the gem tests if the command `factor` exists on the host OS.
202
216
  If so, it performs a system call to it within `prime_division|factors`, and Ruby reformats its output.
@@ -208,6 +222,10 @@ All the `primes-utils` methods are `instance_methods` for `Class Integer`.
208
222
 
209
223
  ## History
210
224
  ```
225
+ 3.1.1 – some methods refactoring|DRYing, documentation updates
226
+ 3.1.0 – major performance enhancements for methods primescnt, primescntmr, and nthprimes,
227
+ primarily by extending nth primes hash values up to 10.1 billion. Can now find nth primes
228
+ over ranges up to 10.1 billion, and thus prime counts up to 253+ billion, in < 30 secs at ~5Ghz.
211
229
  3.0.5 – YJIT enabled for Ruby >= 3.3, added new methods: next_prime, prev_prime.
212
230
  Uses 'bitarray' to extend memory use for methods 'nthprime', 'primes', and 'primescnt'.
213
231
  2.7.0 – more tweaking adaptive pg selection ranges in select_pg; coded using between? instead of cover?
@@ -1,5 +1,5 @@
1
1
  module Primes
2
2
  module Utils
3
- VERSION = "3.0.5"
3
+ VERSION = "3.1.1"
4
4
  end
5
5
  end
data/lib/primes/utils.rb CHANGED
@@ -17,9 +17,8 @@ module Primes
17
17
  end
18
18
 
19
19
  begin RUBY = RUBY_ENGINE rescue RUBY = 'ruby'.freeze end
20
- #RUBY = `ruby -v`.split[0] # alternative old way
21
20
 
22
- if @@os_has_factor # for platforms with cli 'factor' command
21
+ if @@os_has_factor # for platforms with cli 'factor' command
23
22
 
24
23
  # Return prime factors of n in form [[-1,1],[p1,e1],...[pn,en]]
25
24
  # Use Linux|Unix coreutils cli command 'factor' for speed and large numbers
@@ -36,7 +35,7 @@ module Primes
36
35
  end # use pure ruby versions for platforms without cli command 'factor'
37
36
 
38
37
  # Return prime factors of n in form [[-1,1],[p1,e1],..[pn,en]]
39
- # Adaptively selects optimum PG of reduced factored number, if possible
38
+ # Uses P7 as default PG to generate factoring primes
40
39
  def factors1
41
40
  modpg, rescnt = 210, (48 + 4) # P7's modulus and residues count
42
41
  residues = [2,3,5,7, 11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,
@@ -60,7 +59,7 @@ module Primes
60
59
  # Use pure Ruby version of `factor` if not in OS.
61
60
  alias prime_division factors1 unless @@os_has_factor
62
61
 
63
- # Return value of nth prime for self > 0, or nil if self < 1
62
+ # Return value of nth prime for self >= 1, or nil if self < 1
64
63
  # Adaptively selects best SP PG, unless valid input PG given at runtime
65
64
  def primenth(p = 0)
66
65
  return nil if (n = self) < 1
@@ -69,56 +68,51 @@ module Primes
69
68
 
70
69
  start_num, nth, nthflag = set_start_value(n, true)
71
70
  return start_num if nthflag # output nthprime value if n a ref prime key
72
- end_num = approximate_nth(n) # close approx to nth >= real nth
71
+ end_num = approx_nthprime(n) # close approx to nth >= real nth
73
72
 
74
73
  (primes = seeds[0..seeds.index(p)]; modpg = primes.reduce(:*)) if seeds.include? p
75
74
  primes, modpg = select_pg(end_num, start_num) unless primes
76
75
 
77
- prms, m, _, residues, pcs2start, * = sozcore2(end_num, start_num, modpg)
76
+ prms, m, _, residues, pcs_to_start, * = sozcore2(end_num, start_num, modpg)
78
77
  return unless prms # exit gracefully if sozcore2 mem error
79
78
 
80
79
  # starting at start_num's location, find nth prime within given range
81
80
  pcnt = n > nth ? nth - 1 : primes.size
82
- max = prms.size
83
- while pcnt < n && m < max; pcnt = pcnt.succ if prms[m].zero?; m = m.succ end
84
- return puts "#{pcnt} not enough primes, ~nth val too small." if pcnt < n
85
- k, r = (m + pcs2start - 1).divmod residues.size
81
+
82
+ while pcnt < n; pcnt = pcnt.succ if prms[m].zero?; m = m.succ end
83
+ k, r = (m + pcs_to_start - 1).divmod residues.size
86
84
  modpg * k + residues[r]
87
85
  end
88
86
 
89
87
  alias nthprime primenth # to make life easier
90
88
 
91
- # List primes between a number range: end_num - start_num
89
+ # List of primes within inputs range: start_num - end_num
92
90
  # Adaptively selects Strictly Prime (SP) Prime Generator
93
91
  def primes(start_num = 0)
94
92
  end_num, start_num = check_inputs(self, start_num)
95
93
 
96
- primes, modpg = select_pg(end_num, start_num) # adaptively select PG
94
+ primes, modpg = select_pg(end_num, start_num) # adaptively select PG
97
95
  prms, m, modk, residues, _, r = sozcore2(end_num, start_num, modpg)
98
96
  return unless prms # exit gracefully if sozcore2 mem error
99
97
  rescnt, modpg, maxprms = residues.size, residues[-1] - 1, prms.size
100
98
 
101
- # init 'primes' w/any excluded primes in range, extract primes from prms
102
- primes.select! { |p| p >= start_num && p <= end_num }
99
+ # init 'primes' w/any modulus primes in range, extract primes from prms
100
+ primes.select! { |p| p.between?(start_num, end_num) }
103
101
 
104
- # Find, numerate, and store primes from sieved pcs in prms for range
102
+ # Find, numerate, and store primes from sieved pcs in prms for range
105
103
  while m < maxprms
106
- begin
107
- primes << modk + residues[r] if prms[m].zero?; m = m.succ
108
- rescue Exception
109
- return puts 'ERROR3: not enough sys memory for primes output array.'
110
- end
104
+ primes << modk + residues[r] if prms[m].zero?; m = m.succ
111
105
  (r = 0; modk += modpg) if (r = r.succ) == rescnt
112
106
  end
113
107
  primes
114
108
  end
115
109
 
116
- # Count primes between a number range: end_num - start_num
110
+ # Count of primes within inputs range: start_num - end_num
117
111
  # Adaptively selects Strictly Prime (SP) Prime Generator
118
112
  def primescnt(start_num = 0)
119
113
  end_num, start_num = check_inputs(self, start_num)
120
114
 
121
- nthflag, nth = 0, 0
115
+ nthflag, nth = nil, 0
122
116
  if start_num < 3 # for all primes upto num
123
117
  start_num, nth, nthflag = set_start_value(end_num, false) # closest nth value
124
118
  return nth unless nthflag # output num's key|count if ref nth value
@@ -129,15 +123,15 @@ module Primes
129
123
  return unless prms # exit gracefully if sozcore2 mem error
130
124
 
131
125
  # init prmcnt for any modulus primes in range; count primes in prms
132
- prmcnt = primes.count { |p| p >= start_num && p <= end_num }
126
+ prmcnt = primes.count { |p| p.between?(start_num, end_num) }
133
127
  prmcnt = nth - 1 if nthflag && (nth > 0) # start count for small range
134
128
  max = prms.size
135
129
  while m < max; prmcnt = prmcnt.succ if prms[m].zero?; m = m.succ end
136
130
  prmcnt
137
131
  end
138
132
 
139
- # List primes within a number range: end_num - start_num
140
- # Uses 'primemr' to check primality of prime candidates in range
133
+ # List of primes within inputs range: start_num - end_num
134
+ # Uses 'primemr?' to check primality of prime candidates in range
141
135
  def primesmr(start_num = 0)
142
136
  end_num, start_num = check_inputs(self, start_num)
143
137
  r, modk, residues, primes = sozcore1(end_num, start_num)
@@ -150,12 +144,12 @@ module Primes
150
144
  primes
151
145
  end
152
146
 
153
- # Count primes within a number range: end_num - start_num
154
- # Uses 'primemr' to check primality of prime candidates in range
147
+ # Count of primes within inputs range: start_num - end_num
148
+ # Uses 'primemr?' to check primality of prime candidates in range
155
149
  def primescntmr(start_num = 0)
156
150
  end_num, start_num = check_inputs(self, start_num)
157
151
 
158
- nthflag, nth = 0, 0
152
+ nthflag, nth = nil, 0
159
153
  if start_num < 3 # for all primes upto num
160
154
  start_num, nth, nthflag = set_start_value(end_num, false) # closest nth value
161
155
  return nth unless nthflag # output num's key|count if ref nth value
@@ -173,18 +167,18 @@ module Primes
173
167
  end
174
168
 
175
169
  # PGT and Miller-Rabin combined primality tests for random n
176
- def prime? (k = 5) # Can change k higher for mr_prime?
177
- #Use PGT residue checks for small values < PRIMES.last**2
170
+ def prime? (k = 5) # Can change k up|down for primemr?
171
+ # Use PGT residue checks for small values < PRIMES.last**2
178
172
  return PRIMES.include? self if self <= PRIMES.last
179
173
  return false if MODPN.gcd(self) != 1
180
174
  return true if self < PRIMES_LAST_SQRD
181
175
  primemr?(k)
182
176
  end
183
177
 
184
- # Returns the next prime number for +self+ >= 0, or nil if n < 0
178
+ # Returns the next prime number for self >= 0, or nil if n < 0
185
179
  def next_prime
186
- return nil if (n = self) < 0
187
- return (n >> 1) + 2 if n <= 2 # return 2 if n is 0|1
180
+ return nil if (n = self) < 0 # return nil if n negative
181
+ return (n >> 1) + 2 if n <= 2 # return 2 or 3 if n is 0|1|2
188
182
  n = n + 1 | 1 # 1st odd number > n
189
183
  until (res = n % 6) & 0b11 == 1; n += 2 end # n first P3 pc >= n, w/residue 1 or 5
190
184
  inc = (res == 1) ? 4 : 2 # set its P3 PGS value, inc by 2 and 4
@@ -192,10 +186,10 @@ module Primes
192
186
  n
193
187
  end
194
188
 
195
- # Returns the previous prime number < +self+, or nil if self <= 2
189
+ # Returns the previous prime number < self, or nil if self <= 2
196
190
  def prev_prime
197
- return nil if (n = self) < 3
198
- return (n >> 1) + 1 if n <= 5
191
+ return nil if (n = self) <= 2 # no primes for n <= 2
192
+ return (n >> 1) + 1 if n <= 5 # 5|4 -> 3, 3 -> 2
199
193
  n = n - 2 | 1 # 1st odd number < n
200
194
  until (res = n % 6) & 0b11 == 1; n -= 2 end # n first P3 pc <= n, w/residue 1 or 5
201
195
  dec = (res == 1) ? 2 : 4 # set its P3 PGS value, dec by 2 and 4
@@ -210,7 +204,8 @@ module Primes
210
204
  factors1 next_prime prev_prime primes_utils].join(" ")
211
205
  end
212
206
 
213
- # Returns true if +self+ is a prime number, else returns false.
207
+ # Miller-Rabin primality test; uses deterministic witnesses for values upto 128-bits
208
+ # Returns true if self is a prime number, else returns false.
214
209
  def primemr? (k = 5) # k is default number of random bases
215
210
  return false if self < 2 # return false for 0|1 and negatives
216
211
  neg_one_mod = n = d = self - 1 # these are even as self is always odd
@@ -221,10 +216,10 @@ module Primes
221
216
  witnesses.each do |b|
222
217
  next if (b % self).zero? # **skip base if a multiple of input**
223
218
  y = b.pow(d, self) # y = (b**d) mod self
224
- s = d
219
+ s = d # set s to odd d value
225
220
  until y == 1 || y == neg_one_mod || s == n
226
221
  y = y.pow(2, self) # y = (y**2) mod self
227
- s <<= 1
222
+ s <<= 1 # multiply s by 2 until its n
228
223
  end
229
224
  return false unless y == neg_one_mod || s.odd?
230
225
  end
@@ -252,13 +247,15 @@ module Primes
252
247
  PRIMES = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103]
253
248
  PRIMES_LAST_SQRD = PRIMES.last ** 2
254
249
 
250
+ # Return correct order for inputs range values start_num|end_num
251
+ # If either are negative then raise an error
255
252
  def check_inputs(end_num, start_num)
256
253
  raise "invalid negative input(s)" if end_num < 0 || start_num < 0
257
254
  end_num, start_num = start_num, end_num if start_num > end_num
258
255
  [end_num, start_num]
259
256
  end
260
257
 
261
- # Returns for SP PG mod value array of residues [r1, r2,..mod-1, mod+1]
258
+ # Returns for SP PG mod value array of residues [r0, r1,..mod-1, mod+1]
262
259
  def make_residues(modpg)
263
260
  return [ 7, 11, 13, 17, 19, 23, 29, 31] if modpg == 30
264
261
  return [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
@@ -266,57 +263,51 @@ module Primes
266
263
  139, 143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191,
267
264
  193, 197, 199, 209, 211] if modpg == 210
268
265
  residues = []
269
- pc, inc, midmod = 13, 4, modpg >> 1
270
- while pc < midmod
271
- residues << pc << (modpg - pc) if modpg.gcd(pc) == 1
272
- pc += inc; inc ^= 0b110
266
+ rc, inc, midmod = 13, 4, modpg / 2
267
+ while rc < midmod
268
+ residues << rc << (modpg - rc) if modpg.gcd(rc) == 1
269
+ rc += inc; inc ^= 0b110
273
270
  end
274
271
  residues.sort << (modpg - 1) << (modpg + 1)
275
272
  end
276
273
 
277
- # lte = true: first output element is number of pcs <= num
278
- # lte = false: num pcs <, residue index, resgroup val, for (start_)num pc
279
- def pcs_to_num(num, residues, lte)
280
- modpg, rescnt = residues[-1] - 1, residues.size
281
- num -= 1; lte ? (num |= 1; k = num.abs/modpg) : k = (num - 1).abs/modpg
282
- modk = modpg * k; r = 0
283
- r = r.succ while num >= modk + residues[r]
284
- [rescnt * k + r, r, modk] # [num pcs, r index, num modulus]
285
- end
286
-
287
- def pcs_to_nums(end_num, start_num, residues)
274
+ # Determine number of pcs upto the effective start|end vals; w/flag
275
+ # The effective start_num is first pc >= start_num, first pc <= end_num,
276
+ # and effective range is number of pcs between them (inclusive).
277
+ # inputs: end_num|start_num of range, PGs residues array, start:t|end:f flag
278
+ # outputs: pcs_to_num - number of pcs < start_num or <= end_num
279
+ # r - residue index for effective start_num pc
280
+ # modk - mod resgroup value for effective num value
281
+ def pcs_to_num(num, residues, flag)
282
+ return [0, 0, 0] if num < residues[0]
288
283
  modpg, rescnt = residues[-1] - 1, residues.size
289
- end_num = 2 if end_num < residues[0]
290
- start_num = 2 if start_num < residues[0]
291
- start_num -= 1; k1 = (start_num - 1)/modpg; modk1 = modpg * k1
292
- end_num -= 1; k2 = (end_num |= 1 )/modpg; modk2 = modpg * k2
293
- r1 = 0; r1 = r1.succ while start_num >= modk1 + residues[r1]
294
- r2 = 0; r2 = r2.succ while end_num >= modk2 + residues[r2]
295
- pcs2end = k2 * rescnt + r2; pcs2start = k1 * rescnt + r1
296
- pcs_in_range = pcs2end - pcs2start
297
- [pcs2end, pcs2start, r1, modk1, pcs_in_range]
284
+ val1, val2 = flag ? [num-2, num-1] : [(num-1)|1, (num-1)|1]
285
+ k = val1 / modpg; modk = k * modpg; r = 0; resk = val2 - modk
286
+ r = r.succ while resk >= residues[r]; pcs_to_num = k * rescnt + r
287
+ [pcs_to_num, r, modk]
298
288
  end
299
289
 
300
- # Use default SP Prime Generator to parametize the pcs within range
301
- # inputs: end_num|start_num of range
302
- # outputs: maxpcs-m - number of pcs in the range
303
- # r - residue index value for start_num pc of range
304
- # modk - base value for start_num's resgroup
305
- # residues - array of residues for PG: [r1..modpg-1, modpg+1]
306
- # primes array|primes.size - based on method_flag
290
+ # Select SP Prime Generator to parametize the pcs within inputs range
291
+ # inputs: end_num and start_num of range
292
+ # outputs: r - residue index value for start_num of pc inputs range
293
+ # modk - resgroup base value for start_num
294
+ # residues - array of residues [r0...mod+1] for PG
295
+ # primes - array of modulus primes in range, if any
307
296
  def sozcore1(end_num, start_num)
308
297
  range = end_num - start_num
309
- modpg = range < 10_000 ? 210 : 30030
310
- residues = make_residues(modpg) # chosen PG residues
311
- primes = PRIMES.select { |p| p < residues[0] && (p >= start_num && p <= end_num) }
312
- start_num = 2 if start_num < residues[0]
313
- k = (start_num - 2) / modpg; modk = k * modpg; r = 0
314
- while (start_num - 1) >= modk + residues[r]; r = r.succ end
298
+ modpg = if range < 100_001; 210 # P7; Math.isqrt(10_000_200_001)
299
+ elsif range < 7_071_267; 30_030 # P13; Math.isqrt(50_002_816_985_289)
300
+ elsif range < 24_494_897; 510_510 # P17; Math.isqrt(600_000_000_000_000)
301
+ else 9_699_690 # P19
302
+ end
303
+ residues = make_residues(modpg) # chosen PG residues
304
+ primes = PRIMES.select { |p| p < residues[0] && p.between?(start_num, end_num) }
305
+ _, r, modk = pcs_to_num(start_num, residues, true)
315
306
  [r, modk, residues, primes]
316
307
  end
317
308
 
318
309
  # Perform SoZ with given Prime Generator and return array of parameters
319
- # inputs: end_num and start_num of range and modulus value for PG
310
+ # inputs: end_num and start_num of inputs range and modulus value for PG
320
311
  # outputs: prms - binary (0,1) array of pcs within a range or to end_num
321
312
  # m - num of pcs in prms < start_num; so prms[m] = start_num
322
313
  # modks - modulus value for start_num's resgroup
@@ -324,50 +315,71 @@ module Primes
324
315
  # pcs2start- number of pcs < start_num pc
325
316
  # rs - residue index location for first pc >= start_num
326
317
  def sozcore2(end_num, start_num, modpg)
327
- residues = make_residues(modpg); rescnt = residues.size
328
- maxpcs, pcs2start, rs, modks, pcs_range = pcs_to_nums(end_num, start_num, residues)
329
- sqrtN, inputs_range = Integer.sqrt(end_num), end_num - start_num
330
- pcs2sqrtN, _ = pcs_to_nums(sqrtN, 0, residues) # num pcs <= sqrtN
331
-
332
- m = pcs2start # index to start retrieving primes in prms array
318
+ residues = make_residues(modpg)
319
+ rescnt, sqrtN = residues.size, Integer.sqrt(end_num)
320
+ pcs_to_start, rs, modks = pcs_to_num(start_num, residues, true) # num pcs < start_num
321
+ maxpcs, _ = pcs_to_num(end_num, residues, false) # num pcs <= end_num
322
+ pcs_to_sqrtN, _ = pcs_to_num(sqrtN, residues, false) # num pcs <= sqrtN
323
+ inputs_range, pcs_range = end_num - start_num, maxpcs - pcs_to_start
324
+
325
+ m = pcs_to_start # index to start retrieving primes in prms array
333
326
  split_arrays = (start_num > sqrtN) # flag, true for split arrays
334
- if split_arrays # if start_num > sqrtN create two arrays
335
- maxpcs = pcs2sqrtN # array size now for primary sieve array prms
327
+ if split_arrays # if start_num > sqrtN create two arrays
328
+ maxpcs = pcs_to_sqrtN # array size now for primary sieve array prms
336
329
  prms_range = array_check(pcs_range) # array for pcs in range
337
330
  raise 'ERROR1: range too big for free sys mem.' unless prms_range
338
- m = 0 # index to start retrieving primes in split array
331
+ m = 0 # address to start of split array
339
332
  end
340
333
  prms = array_check(maxpcs) # array for pcs upto sqrtN, or end_num
341
334
  raise 'ERROR2: end_num too big for available sys mem.' unless prms
342
335
 
343
336
  # Sieve of Zakiya (SoZ) to eliminate nonprimes from prms, prms_range
344
- pcs2sqrtN.times do |i| # sieve primes from pcs upto sqrt(end_num)
337
+ pcs_to_sqrtN.times do |i| # sieve primes from pcs upto sqrt(end_num)
345
338
  next unless prms[i].zero? # if pc not prime, get next one
346
339
  prm_r = residues[i % rescnt] # save its residue value
347
- prime = modpg*(k=i/rescnt)+prm_r # numerate its value; set k resgroup value
348
- rem = start_num % prime # prime's distance to start_num
349
- next unless (prime - rem <= inputs_range) || rem == 0 # skip prime mults not in range
340
+ prime = modpg*(k=i/rescnt) + prm_r # numerate its value; set k resgroup value
341
+ rem = start_num % prime # prime's modular distance to start_num
342
+ next unless (prime - rem <= inputs_range) || rem == 0 # skip prime if no multiple in range
350
343
  prmstep = prime * rescnt # compute its primestep
351
344
  residues.each do |ri| # find|mark its multiples
352
345
  # convert (prime * (modk + ri)) pc value to its address in prms
353
346
  kn, rr = (prm_r * ri - 2).divmod modpg
354
- mult = mult1 = (k*(prime + ri) + kn)*rescnt + residues.index(rr+2) # 1st prime mult
355
- while mult < maxpcs; prms[mult] = 1; mult += prmstep end
356
- if split_arrays # when start_num > sqrtN(pcs2sqrtN+1)
357
- mult = (pcs2start - mult1) % prmstep # (start_num - last mult) pcs
358
- mult = prmstep - mult if mult != 0 # location in range, or beyond
359
- while mult < pcs_range; prms_range[mult] = 1; mult += prmstep end
347
+ prm_mult = (k*(prime + ri) + kn)*rescnt + residues.index(rr+2) # 1st prime mult
348
+ while prm_mult < maxpcs; prms[prm_mult] = 1; prm_mult += prmstep end
349
+ if split_arrays # when start_num > sqrtN(pcs2sqrtN+1)
350
+ prm_mult = (pcs_to_start - prm_mult) % prmstep # (start_num - last mult) pcs
351
+ prm_mult = prmstep - prm_mult if prm_mult != 0 # location in range, or beyond
352
+ while prm_mult < pcs_range; prms_range[prm_mult] = 1; prm_mult += prmstep end
360
353
  end end end
361
354
  # select prms array and start location val m for start_num in it
362
- [(split_arrays ? prms_range : prms), m, modks, residues, pcs2start, rs]
355
+ [(split_arrays ? prms_range : prms), m, modks, residues, pcs_to_start, rs]
363
356
  end
364
357
 
365
- def approximate_nth(n)
366
- b = 0.5722 * n**0.0088
358
+ # Compute close approximate nthprime value >= real value
359
+ def approx_nthprime(n)
360
+ e = if n <= 26_800_000; 0.008702
361
+ elsif n.between?( 26_800_001, 144_000_000 - 0); 0.0088
362
+ elsif n.between?( 144_000_001, 250_000_000 - 1); 0.00881
363
+ elsif n.between?( 250_000_000, 800_000_000 - 1); 0.008798
364
+ elsif n.between?( 800_000_000, 1_000_000_000 - 1); 0.00875
365
+ elsif n.between?(1_000_000_000, 2_000_000_000 - 1); 0.008732
366
+ elsif n.between?(2_000_000_000, 3_000_000_000 - 1); 0.0086806
367
+ elsif n.between?(3_000_000_000, 4_000_000_000 - 1); 0.0086448
368
+ elsif n.between?(4_000_000_000, 5_000_000_000 - 1); 0.00862
369
+ elsif n.between?(5_000_000_000, 5_500_000_000 - 0); 0.008596
370
+ elsif n.between?(5_500_000_001, 6_500_000_000 - 0); 0.0085859
371
+ elsif n.between?(6_500_000_001, 7_500_000_000 - 0); 0.0085687
372
+ elsif n.between?(7_500_000_001, 8_500_000_000 - 0); 0.008554
373
+ elsif n.between?(8_500_000_001, 9_500_000_000 - 0); 0.008541
374
+ elsif n.between?(9_500_000_001, 100_000_000_000 - 0); 0.0085283
375
+ else 0.00825
376
+ end
377
+ b = 0.5722 * (n**e)
367
378
  a = b * Math.log(log_n = Math.log(n))
368
379
  (n * (log_n + a) + 3).to_i
369
380
  end
370
381
 
382
+ # Adaptively select Strictly Prime (SP) Prime Generator
371
383
  def select_pg(end_num, start_num) # adaptively select PG
372
384
  range = end_num - start_num
373
385
  pg = 5
@@ -382,7 +394,7 @@ module Primes
382
394
  pg = 11 if (range.between?(10**8, 10**9 - 1) && start_num < 55 * 10**7) ||
383
395
  (range >= 10**9 && start_num < 45 * 10**9)
384
396
  end
385
- primes = [2, 3, 5, 7, 11, 13].select! { |p| p <= pg }
397
+ primes = PRIMES.select { |p| p <= pg }
386
398
  [primes, primes.reduce(:*)] # [base primes, mod] for PG
387
399
  end
388
400
 
@@ -406,113 +418,195 @@ module Primes
406
418
  end
407
419
 
408
420
  def nths # hash table index of reference nth primes
409
- { 1_000_000 => 15_485_863, 5_000_000 => 86_028_121,
410
- 7_500_000 => 132_276_691, 10_000_000 => 179_424_673,
411
- 12_500_000 => 227_254_201, 15_000_000 => 275_604_541,
412
- 18_500_000 => 344_032_387, 25_000_000 => 472_882_027,
413
- 31_000_000 => 593_441_843, 37_500_000 => 725_420_401,
414
- 43_500_000 => 848_321_917, 50_000_000 => 982_451_653,
415
- 56_000_000 => 1_107_029_837, 62_500_000 => 1_242_809_749,
416
- 68_500_000 => 1_368_724_829, 75_000_000 => 1_505_776_939,
417
- 81_500_000 => 1_643_429_659, 87_500_000 => 1_770_989_609,
418
- 93_500_000 => 1_898_979_367, 100_000_000 => 2_038_074_743,
419
- 106_500_000 => 2_177_624_377, 112_500_000 => 2_306_797_469,
420
- 125_000_000 => 2_576_983_867, 137_500_000 => 2_848_518_523,
421
- 150_000_000 => 3_121_238_909, 162_500_000 => 3_395_057_291,
422
- 175_000_000 => 3_669_829_403, 187_500_000 => 3_945_592_087,
423
- 200_000_000 => 4_222_234_741, 212_500_000 => 4_499_683_009,
424
- 225_000_000 => 4_777_890_881, 237_500_000 => 5_056_862_311,
425
- 250_000_000 => 5_336_500_537, 262_500_000 => 5_616_787_769,
426
- 275_000_000 => 5_897_707_297, 287_500_000 => 6_179_208_157,
427
- 300_000_000 => 6_461_335_109, 312_500_000 => 6_743_943_629,
428
- 325_000_000 => 7_027_107_881, 337_500_000 => 7_310_793_337,
429
- 350_000_000 => 7_594_955_549, 362_500_000 => 7_879_581_839,
430
- 375_000_000 => 8_164_628_191, 387_500_000 => 8_450_100_349,
431
- 400_000_000 => 8_736_028_057, 412_500_000 => 9_022_375_487,
432
- 425_000_000 => 9_309_109_471, 437_500_000 => 9_596_238_593,
433
- 450_000_000 => 9_883_692_017, 462_500_000 => 10_171_564_687,
434
- 475_000_000 => 10_459_805_417, 487_500_000 => 10_748_372_137,
435
- 500_000_000 => 11_037_271_757, 512_500_000 => 11_326_513_039,
436
- 525_000_000 => 11_616_020_609, 537_500_000 => 11_905_863_799,
437
- 550_000_000 => 12_196_034_771, 562_500_000 => 12_486_465_863,
438
- 575_000_000 => 12_777_222_833, 587_500_000 => 13_068_237_251,
439
- 600_000_000 => 13_359_555_403, 612_500_000 => 13_651_119_389,
440
- 625_000_000 => 13_942_985_677, 637_500_000 => 14_235_122_851,
441
- 650_000_000 => 14_527_476_781, 662_500_000 => 14_820_071_503,
442
- 675_000_000 => 15_112_928_683, 687_500_000 => 15_406_031_899,
443
- 700_000_000 => 15_699_342_107, 712_500_000 => 15_992_957_251,
444
- 725_000_000 => 16_286_768_243, 737_500_000 => 16_580_801_137,
445
- 750_000_000 => 16_875_026_921, 762_500_000 => 17_169_527_171,
446
- 775_000_000 => 17_464_243_799, 787_500_000 => 17_759_139_259,
447
- 800_000_000 => 18_054_236_957, 812_500_000 => 18_349_591_409,
448
- 825_000_000 => 18_645_104_897, 837_500_000 => 18_940_846_207,
449
- 850_000_000 => 19_236_701_629, 862_500_000 => 19_532_780_327,
450
- 875_000_000 => 19_829_092_147, 887_500_000 => 20_125_592_731,
451
- 900_000_000 => 20_422_213_579, 912_500_000 => 20_719_050_323,
452
- 925_000_000 => 21_016_060_633, 937_500_000 => 21_313_231_963,
453
- 950_000_000 => 21_610_588_367, 962_500_000 => 21_908_128_993,
454
- 975_000_000 => 22_205_818_561, 987_500_000 => 22_503_733_657,
455
- 1_000_000_000 => 22_801_763_489, 1_012_500_000 => 23_099_993_743,
456
- 1_025_000_000 => 23_398_391_231, 1_037_500_000 => 23_696_858_797,
457
- 1_050_000_000 => 23_995_554_823, 1_062_500_000 => 24_294_392_179,
458
- 1_075_000_000 => 24_593_421_187, 1_087_500_000 => 24_892_587_403,
459
- 1_100_000_000 => 25_191_867_719, 1_112_500_000 => 25_491_361_037,
460
- 1_125_000_000 => 25_790_970_053, 1_137_500_000 => 26_090_709_563,
461
- 1_150_000_000 => 26_390_560_513, 1_162_500_000 => 26_690_560_601,
462
- 1_175_000_000 => 26_990_744_987, 1_187_500_000 => 27_291_009_337,
463
- 1_200_000_000 => 27_591_444_869, 1_212_500_000 => 27_892_051_267,
464
- 1_225_000_000 => 28_192_760_279, 1_237_500_000 => 28_493_648_629,
465
- 1_250_000_000 => 28_794_583_627, 1_262_500_000 => 29_095_694_269,
466
- 1_275_000_000 => 29_396_966_971, 1_287_500_000 => 29_698_366_099,
467
- 1_300_000_000 => 29_999_858_327, 1_312_500_000 => 30_301_430_881,
468
- 1_325_000_000 => 30_603_183_581, 1_337_500_000 => 30_905_024_497,
469
- 1_350_000_000 => 31_207_047_449, 1_362_500_000 => 31_509_131_153,
470
- 1_375_000_000 => 31_811_397_571, 1_387_500_000 => 32_113_702_069,
471
- 1_400_000_000 => 32_416_190_071, 1_412_500_000 => 32_718_790_873,
472
- 1_425_000_000 => 33_021_414_143, 1_437_500_000 => 33_324_275_711,
473
- 1_450_000_000 => 33_627_220_709, 1_462_500_000 => 33_930_284_893,
474
- 1_475_000_000 => 34_233_442_279, 1_487_500_000 => 34_536_683_891,
475
- 1_500_000_000 => 34_840_062_373, 1_512_500_000 => 35_143_545_889,
476
- 1_525_000_000 => 35_447_088_559, 1_537_500_000 => 35_750_747_297,
477
- 1_550_000_000 => 36_054_501_641, 1_562_500_000 => 36_358_440_731,
478
- 1_575_000_000 => 36_662_430_631, 1_587_500_000 => 36_966_563_321,
479
- 1_600_000_000 => 37_270_791_697, 1_612_500_000 => 37_575_137_933,
480
- 1_625_000_000 => 37_879_532_671, 1_637_500_000 => 38_184_009_763,
481
- 1_650_000_000 => 38_488_677_419, 1_662_500_000 => 38_793_413_899,
482
- 1_675_000_000 => 39_098_225_629, 1_687_500_000 => 39_403_174_463,
483
- 1_700_000_000 => 39_708_229_123, 1_712_500_000 => 40_013_309_359,
484
- 1_725_000_000 => 40_318_523_009, 1_737_500_000 => 40_623_800_311,
485
- 1_750_000_000 => 40_929_166_261, 1_762_500_000 => 41_234_743_751,
486
- 1_775_000_000 => 41_540_289_619, 1_787_500_000 => 41_845_958_971,
487
- 1_800_000_000 => 42_151_671_491, 1_812_500_000 => 42_457_500_313,
488
- 1_825_000_000 => 42_763_499_629, 1_837_500_000 => 43_069_571_603,
489
- 1_850_000_000 => 43_375_710_643, 1_862_500_000 => 43_681_898_699,
490
- 1_875_000_000 => 43_988_172_667, 1_887_500_000 => 44_294_549_347,
491
- 1_900_000_000 => 44_601_021_791, 1_912_500_000 => 44_907_564_593,
492
- 1_925_000_000 => 45_214_177_441, 1_937_500_000 => 45_520_935_011,
493
- 1_950_000_000 => 45_827_700_419, 1_962_500_000 => 46_134_655_219,
494
- 1_975_000_000 => 46_441_643_177, 1_987_500_000 => 46_748_693_981,
495
- 2_000_000_000 => 47_055_833_459, 2_012_500_000 => 47_363_059_687,
496
- 2_125_000_000 => 50_131_763_837, 2_250_000_000 => 53_215_141_519,
497
- 2_375_000_000 => 56_305_859_821, 2_500_000_000 => 59_403_556_879,
498
- 2_625_000_000 => 62_507_768_977, 2_750_000_000 => 65_618_159_808,
499
- 2_875_000_000 => 68_734_481_527, 3_000_000_000 => 71_856_445_751,
500
- 3_125_000_000 => 74_983_924_661, 3_250_000_000 => 78_116_541_127,
501
- 3_375_000_000 => 81_254_172_953, 3_500_000_000 => 84_396_675_733,
502
- 3_625_000_000 => 87_543_835_147, 3_750_000_000 => 90_695_492_941,
503
- 3_875_000_000 => 93_851_412_433, 4_000_000_000 => 97_011_687_217,
504
- 4_125_000_000 =>100_175_917_301, 4_250_000_000 => 103_344_103_553,
505
- 4_375_000_000 =>106_516_393_597, 4_500_000_000 => 109_692_247_799,
506
- 4_625_000_000 =>112_871_634_437, 4_750_000_000 => 116_054_419_753,
507
- 4_875_000_000 =>119_240_825_947, 5_000_000_000 => 122_430_513_841,
508
- 5_125_000_000 =>125_623_420_333, 5_250_000_000 => 128_819_622_391,
509
- 5_375_000_000 =>132_018_808_321, 5_500_000_000 => 135_221_143_753,
510
- 5_625_000_000 =>138_426_461_137, 5_750_000_000 => 141_634_567_969,
511
- 5_875_000_000 =>144_845_535_431, 6_000_000_000 => 148_059_109_201,
512
- 6_125_000_000 =>151_275_700_969, 6_250_000_000 => 154_494_952_609,
513
- 6_375_000_000 =>157_716_628_943, 6_500_000_000 => 160_940_840_461,
514
- 6_625_000_000 =>164_167_763_329, 6_750_000_000 => 167_397_013_051,
515
- 6_875_000_000 =>170_628_613_009, 7_000_000_000 => 173_862_636_221 }
421
+ { 1_000_000 => 15_485_863, 2_500_000 => 41_161_739,
422
+ 5_000_000 => 86_028_121, 7_500_000 => 132_276_691,
423
+ 10_000_000 => 179_424_673, 12_500_000 => 227_254_201,
424
+ 15_000_000 => 275_604_541, 17_500_000 => 324_407_071,
425
+ 20_000_000 => 373_587_883, 22_500_000 => 423_087_251,
426
+ 25_000_000 => 472_882_027, 27_500_000 => 522_960_521,
427
+ 31_000_000 => 593_441_843, 37_500_000 => 725_420_401,
428
+ 43_500_000 => 848_321_917, 50_000_000 => 982_451_653,
429
+ 56_000_000 => 1_107_029_837, 62_500_000 => 1_242_809_749,
430
+ 68_500_000 => 1_368_724_829, 75_000_000 => 1_505_776_939,
431
+ 81_500_000 => 1_643_429_659, 87_500_000 => 1_770_989_609,
432
+ 91_000_000 => 1_845_587_707, 95_500_000 => 1_941_743_593,
433
+ 100_000_000 => 2_038_074_743, 106_250_000 => 2_172_252_527,
434
+ 112_500_000 => 2_306_797_469, 118_750_000 => 2_441_736_961,
435
+ 125_000_000 => 2_576_983_867, 131_250_000 => 2_712_589_223,
436
+ 137_500_000 => 2_848_518_523, 143_750_000 => 2_984_727_947,
437
+ 150_000_000 => 3_121_238_909, 156_250_000 => 3_258_002_933,
438
+ 162_500_000 => 3_395_057_291, 168_750_000 => 3_532_313_509,
439
+ 175_000_000 => 3_669_829_403, 181_250_000 => 3_807_579_749,
440
+ 187_500_000 => 3_945_592_087, 193_750_000 => 4_083_820_723,
441
+ 200_000_000 => 4_222_234_741, 206_250_000 => 4_360_844_731,
442
+ 212_500_000 => 4_499_683_009, 218_750_000 => 4_638_696_967,
443
+ 225_000_000 => 4_777_890_881, 231_250_000 => 4_917_286_597,
444
+ 237_500_000 => 5_056_862_311, 243_750_000 => 5_196_588_437,
445
+ 250_000_000 => 5_336_500_537, 256_250_000 => 5_476_565_287,
446
+ 262_500_000 => 5_616_787_769, 268_750_000 => 5_757_149_341,
447
+ 275_000_000 => 5_897_707_297, 281_250_000 => 6_038_399_501,
448
+ 287_500_000 => 6_179_208_157, 293_750_000 => 6_320_167_471,
449
+ 300_000_000 => 6_461_335_109, 306_250_000 => 6_602_538_337,
450
+ 312_500_000 => 6_743_943_629, 318_750_000 => 6_885_467_689,
451
+ 325_000_000 => 7_027_107_881, 331_250_000 => 7_168_869_523,
452
+ 337_500_000 => 7_310_793_337, 343_750_000 => 7_452_779_041,
453
+ 350_000_000 => 7_594_955_549, 356_250_000 => 7_737_220_201,
454
+ 362_500_000 => 7_879_581_839, 368_750_000 => 8_022_019_693,
455
+ 375_000_000 => 8_164_628_191, 381_250_000 => 8_307_284_749,
456
+ 387_500_000 => 8_450_100_349, 393_750_000 => 8_592_999_131,
457
+ 400_000_000 => 8_736_028_057, 406_250_000 => 8_879_163_259,
458
+ 412_500_000 => 9_022_375_487, 418_750_000 => 9_165_714_427,
459
+ 425_000_000 => 9_309_109_471, 431_000_000 => 9_446_878_729,
460
+ 437_500_000 => 9_596_238_593, 443_750_000 => 9_739_892_947,
461
+ 450_000_000 => 9_883_692_017, 456_500_000 => 10_033_327_459,
462
+ 462_500_000 => 10_171_564_687, 468_750_000 => 10_315_624_537,
463
+ 475_000_000 => 10_459_805_417, 481_500_000 => 10_609_826_303,
464
+ 487_500_000 => 10_748_372_137, 493_750_000 => 10_892_768_429,
465
+ 500_000_000 => 11_037_271_757, 506_250_000 => 11_181_815_213,
466
+ 512_500_000 => 11_326_513_039, 519_000_000 => 11_477_051_947,
467
+ 525_000_000 => 11_616_020_609, 531_250_000 => 11_760_892_211,
468
+ 537_500_000 => 11_905_863_799, 543_750_000 => 12_050_939_503,
469
+ 550_000_000 => 12_196_034_771, 556_250_000 => 12_341_214_203,
470
+ 562_500_000 => 12_486_465_863, 568_750_000 => 12_631_810_823,
471
+ 575_000_000 => 12_777_222_833, 581_250_000 => 12_922_677_437,
472
+ 587_500_000 => 13_068_237_251, 593_750_000 => 13_213_860_971,
473
+ 600_000_000 => 13_359_555_403, 606_250_000 => 13_505_300_407,
474
+ 612_500_000 => 13_651_119_389, 619_250_000 => 13_808_675_917,
475
+ 625_000_000 => 13_942_985_677, 631_250_000 => 14_089_055_291,
476
+ 637_500_000 => 14_235_122_851, 643_750_000 => 14_381_273_323,
477
+ 650_000_000 => 14_527_476_781, 656_250_000 => 14_673_746_567,
478
+ 662_500_000 => 14_820_071_503, 668_750_000 => 14_966_474_821,
479
+ 675_000_000 => 15_112_928_683, 681_250_000 => 15_259_429_589,
480
+ 687_500_000 => 15_406_031_899, 693_750_000 => 15_552_667_763,
481
+ 700_000_000 => 15_699_342_107, 706_250_000 => 15_846_115_699,
482
+ 712_500_000 => 15_992_957_251, 716_750_000 => 16_092_830_933,
483
+ 725_000_000 => 16_286_768_243, 731_250_000 => 16_433_777_953,
484
+ 737_500_000 => 16_580_801_137, 743_750_000 => 16_727_906_893,
485
+ 750_000_000 => 16_875_026_921, 756_250_000 => 17_022_234_041,
486
+ 762_500_000 => 17_169_527_171, 768_750_000 => 17_316_837_781,
487
+ 775_000_000 => 17_464_243_799, 781_250_000 => 17_611_642_327,
488
+ 787_500_000 => 17_759_139_259, 793_250_000 => 17_894_866_747,
489
+ 800_000_000 => 18_054_236_957, 806_250_000 => 18_201_899_809,
490
+ 812_500_000 => 18_349_591_409, 817_250_000 => 18_461_848_099,
491
+ 825_000_000 => 18_645_104_897, 831_250_000 => 18_792_939_317,
492
+ 837_500_000 => 18_940_846_207, 843_750_000 => 19_088_754_313,
493
+ 850_000_000 => 19_236_701_629, 856_250_000 => 19_384_721_509,
494
+ 862_500_000 => 19_532_780_327, 868_750_000 => 19_680_906_451,
495
+ 875_000_000 => 19_829_092_147, 881_250_000 => 19_977_299_393,
496
+ 887_500_000 => 20_125_592_731, 893_750_000 => 20_273_868_583,
497
+ 900_000_000 => 20_422_213_579, 906_250_000 => 20_570_597_317,
498
+ 912_500_000 => 20_719_050_323, 918_750_000 => 20_867_520_769,
499
+ 925_000_000 => 21_016_060_633, 931_250_000 => 21_164_606_423,
500
+ 937_500_000 => 21_313_231_963, 943_750_000 => 21_461_910_023,
501
+ 950_000_000 => 21_610_588_367, 956_250_000 => 21_759_307_211,
502
+ 962_500_000 => 21_908_128_993, 968_750_000 => 22_056_948_833,
503
+ 975_000_000 => 22_205_818_561, 981_250_000 => 22_354_799_491,
504
+ 987_500_000 => 22_503_733_657, 993_750_000 => 22_652_687_809,
505
+ 1_000_000_000 => 22_801_763_489, 1_012_500_000 => 23_099_993_743,
506
+ 1_025_000_000 => 23_398_391_231, 1_037_500_000 => 23_696_858_797,
507
+ 1_050_000_000 => 23_995_554_823, 1_062_500_000 => 24_294_392_179,
508
+ 1_075_000_000 => 24_593_421_187, 1_087_500_000 => 24_892_587_403,
509
+ 1_100_000_000 => 25_191_867_719, 1_112_500_000 => 25_491_361_037,
510
+ 1_125_000_000 => 25_790_970_053, 1_137_500_000 => 26_090_709_563,
511
+ 1_150_000_000 => 26_390_560_513, 1_162_500_000 => 26_690_560_601,
512
+ 1_175_000_000 => 26_990_744_987, 1_187_500_000 => 27_291_009_337,
513
+ 1_200_000_000 => 27_591_444_869, 1_212_500_000 => 27_892_051_267,
514
+ 1_225_000_000 => 28_192_760_279, 1_237_500_000 => 28_493_648_629,
515
+ 1_250_000_000 => 28_794_583_627, 1_262_500_000 => 29_095_694_269,
516
+ 1_275_000_000 => 29_396_966_971, 1_287_500_000 => 29_698_366_099,
517
+ 1_300_000_000 => 29_999_858_327, 1_312_500_000 => 30_301_430_881,
518
+ 1_325_000_000 => 30_603_183_581, 1_337_500_000 => 30_905_024_497,
519
+ 1_350_000_000 => 31_207_047_449, 1_362_500_000 => 31_509_131_153,
520
+ 1_375_000_000 => 31_811_397_571, 1_387_500_000 => 32_113_702_069,
521
+ 1_400_000_000 => 32_416_190_071, 1_412_500_000 => 32_718_790_873,
522
+ 1_425_000_000 => 33_021_414_143, 1_437_500_000 => 33_324_275_711,
523
+ 1_450_000_000 => 33_627_220_709, 1_462_500_000 => 33_930_284_893,
524
+ 1_475_000_000 => 34_233_442_279, 1_487_500_000 => 34_536_683_891,
525
+ 1_500_000_000 => 34_840_062_373, 1_512_500_000 => 35_143_545_889,
526
+ 1_525_000_000 => 35_447_088_559, 1_537_500_000 => 35_750_747_297,
527
+ 1_550_000_000 => 36_054_501_641, 1_562_500_000 => 36_358_440_731,
528
+ 1_575_000_000 => 36_662_430_631, 1_587_500_000 => 36_966_563_321,
529
+ 1_600_000_000 => 37_270_791_697, 1_612_500_000 => 37_575_137_933,
530
+ 1_625_000_000 => 37_879_532_671, 1_637_500_000 => 38_184_009_763,
531
+ 1_650_000_000 => 38_488_677_419, 1_662_500_000 => 38_793_413_899,
532
+ 1_675_000_000 => 39_098_225_629, 1_687_500_000 => 39_403_174_463,
533
+ 1_700_000_000 => 39_708_229_123, 1_712_500_000 => 40_013_309_359,
534
+ 1_725_000_000 => 40_318_523_009, 1_737_500_000 => 40_623_800_311,
535
+ 1_750_000_000 => 40_929_166_261, 1_762_500_000 => 41_234_743_751,
536
+ 1_775_000_000 => 41_540_289_619, 1_787_500_000 => 41_845_958_971,
537
+ 1_800_000_000 => 42_151_671_491, 1_812_500_000 => 42_457_500_313,
538
+ 1_825_000_000 => 42_763_499_629, 1_837_500_000 => 43_069_571_603,
539
+ 1_850_000_000 => 43_375_710_643, 1_862_500_000 => 43_681_898_699,
540
+ 1_875_000_000 => 43_988_172_667, 1_887_500_000 => 44_294_549_347,
541
+ 1_900_000_000 => 44_601_021_791, 1_912_500_000 => 44_907_564_593,
542
+ 1_925_000_000 => 45_214_177_441, 1_937_500_000 => 45_520_935_011,
543
+ 1_950_000_000 => 45_827_700_419, 1_962_500_000 => 46_134_655_219,
544
+ 1_975_000_000 => 46_441_643_177, 1_987_500_000 => 46_748_693_081,
545
+ 2_000_000_000 => 47_055_833_459, 2_062_500_000 => 48_592_822_043,
546
+ 2_125_000_000 => 50_131_763_837, 2_187_500_000 => 51_672_463_541,
547
+ 2_250_000_000 => 53_215_141_519, 2_312_500_000 => 54_759_617_681,
548
+ 2_375_000_000 => 56_305_859_821, 2_437_500_000 => 57_853_856_521,
549
+ 2_500_000_000 => 59_403_556_879, 2_562_500_000 => 60_954_821_429,
550
+ 2_625_000_000 => 62_507_768_977, 2_687_500_000 => 64_062_179_743,
551
+ 2_750_000_000 => 65_618_159_808, 2_812_500_000 => 67_175_627_957,
552
+ 2_875_000_000 => 68_734_481_527, 2_937_500_000 => 70_294_765_447,
553
+ 3_000_000_000 => 71_856_445_751, 3_062_500_000 => 73_419_453_619,
554
+ 3_125_000_000 => 74_983_924_661, 3_187_500_000 => 76_549_505_951,
555
+ 3_250_000_000 => 78_116_541_127, 3_312_500_000 => 79_684_708_483,
556
+ 3_375_000_000 => 81_254_172_953, 3_437_500_000 => 82_824_830_279,
557
+ 3_500_000_000 => 84_396_675_733, 3_562_500_000 => 85_969_638_697,
558
+ 3_625_000_000 => 87_543_835_147, 3_687_500_000 => 89_119_062_301,
559
+ 3_750_000_000 => 90_695_492_941, 3_812_500_000 => 92_272_943_291,
560
+ 3_875_000_000 => 93_851_412_433, 3_937_500_000 => 95_431_061_423,
561
+ 4_000_000_000 => 97_011_687_217, 4_062_500_000 => 98_593_232_273,
562
+ 4_125_000_000 =>100_175_917_301, 4_187_500_000 => 101_759_445_239,
563
+ 4_250_000_000 =>103_344_103_553, 4_312_500_000 => 104_929_660_237,
564
+ 4_375_000_000 =>106_516_393_597, 4_437_500_000 => 108_103_847_759,
565
+ 4_500_000_000 =>109_692_247_799, 4_562_500_000 => 111_281_475_367,
566
+ 4_625_000_000 =>112_871_634_437, 4_687_500_000 => 114_462_576_077,
567
+ 4_750_000_000 =>116_054_419_753, 4_812_500_000 => 117_647_215_579,
568
+ 4_875_000_000 =>119_240_825_947, 4_937_500_000 => 120_835_390_561,
569
+ 5_000_000_000 =>122_430_513_841, 5_062_500_000 => 124_026_505_511,
570
+ 5_125_000_000 =>125_623_420_333, 5_187_500_000 => 127_221_145_921,
571
+ 5_250_000_000 =>128_819_622_391, 5_312_500_000 => 130_418_741_759,
572
+ 5_375_000_000 =>132_018_808_321, 5_437_500_000 => 133_619_596_303,
573
+ 5_500_000_000 =>135_221_143_753, 5_562_500_000 => 136_823_413_933,
574
+ 5_625_000_000 =>138_426_461_137, 5_687_500_000 => 140_030_126_603,
575
+ 5_750_000_000 =>141_634_567_969, 5_812_500_000 => 143_239_738_403,
576
+ 5_875_000_000 =>144_845_535_431, 5_937_500_000 => 146_451_972_661,
577
+ 6_000_000_000 =>148_059_109_201, 6_062_500_000 => 149_667_050_623,
578
+ 6_125_000_000 =>151_275_700_969, 6_187_500_000 => 152_885_012_491,
579
+ 6_250_000_000 =>154_494_952_609, 6_312_500_000 => 156_105_425_747,
580
+ 6_375_000_000 =>157_716_628_943, 6_437_500_000 => 159_328_400_423,
581
+ 6_500_000_000 =>160_940_840_461, 6_562_500_000 => 162_554_018_383,
582
+ 6_625_000_000 =>164_167_763_329, 6_687_500_000 => 165_782_087_147,
583
+ 6_750_000_000 =>167_397_013_051, 6_812_500_000 => 169_012_493_731,
584
+ 6_875_000_000 =>170_628_613_009, 6_937_500_000 => 172_245_292_151,
585
+ 7_000_000_000 =>173_862_636_221, 7_062_500_000 => 175_480_437_941,
586
+ 7_125_000_000 =>177_098_901_853, 7_187_500_000 => 178_718_004_559,
587
+ 7_250_000_000 =>180_337_540_729, 7_312_500_000 => 181_957_736_671,
588
+ 7_375_000_000 =>183_578_464_339, 7_437_500_000 => 185_199_695_243,
589
+ 7_500_000_000 =>186_821_628_281, 7_562_500_000 => 188_443_933_631,
590
+ 7_625_000_000 =>190_066_857_349, 7_687_500_000 => 191_690_371_627,
591
+ 7_750_000_000 =>193_314_249_683, 7_812_500_000 => 194_938_683_917,
592
+ 7_875_000_000 =>196_563_769_217, 7_937_500_000 => 198_189_192_449,
593
+ 8_000_000_000 =>199_815_106_433, 8_062_500_000 => 201_441_616_073,
594
+ 8_125_000_000 =>203_068_844_123, 8_187_500_000 => 204_696_410_057,
595
+ 8_250_000_000 =>206_324_421_217, 8_312_500_000 => 207_952_872_601,
596
+ 8_375_000_000 =>209_581_922_889, 8_437_500_000 => 211_211_500_043,
597
+ 8_500_000_000 =>212_841_570_911, 8_562_500_000 => 214_472_070_151,
598
+ 8_625_000_000 =>216_102_910_559, 8_687_500_000 => 217_734_315_107,
599
+ 8_750_000_000 =>219_366_232_937, 8_812_500_000 => 220_998_618_619,
600
+ 8_875_000_000 =>222_631_402_171, 8_937_500_000 => 224_264_794_049,
601
+ 9_000_000_000 =>225_898_512_559, 9_062_500_000 => 227_532_648_853,
602
+ 9_125_000_000 =>229_167_269_077, 9_187_500_000 => 230_802_553_771,
603
+ 9_250_000_000 =>232_438_083_623, 9_312_500_000 => 234_073_993_121,
604
+ 9_375_000_000 =>235_710_242_393, 9_437_500_000 => 237_347_050_547,
605
+ 9_500_000_000 =>238_984_246_139, 9_562_500_000 => 240_621_857_459,
606
+ 9_625_000_000 =>242_259_972_943, 9_687_500_000 => 243_898_743_329,
607
+ 9_750_000_000 =>245_537_657_177, 9_812_500_000 => 247_176_989_299,
608
+ 9_875_000_000 =>248_816_855_407, 9_937_500_000 => 250_457_226_821,
609
+ 10_000_000_000 =>252_097_800_623,10_062_500_000 => 253_738_728_317 }
516
610
  end
517
611
  end
518
612
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primes-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.5
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jabari Zakiya
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  requirements: []
95
- rubygems_version: 3.7.2
95
+ rubygems_version: 4.0.3
96
96
  specification_version: 4
97
97
  summary: suite of extremely fast utility methods for testing and generating primes
98
98
  test_files: []