primes-utils 3.0.4 → 3.1.0

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: bcb2fe6a51dd51f056d5cbbed13be8f50968a3702796f82001fd0f36e1677fd2
4
- data.tar.gz: 07de693031de25d727c3e603739d6edea2ed7357ecc5714bb8ea4a8bbd7f48e7
3
+ metadata.gz: 0d80c687d9af99e83fa89aa6d04b0d5b9f818568f46efb1d80ff31ee5959e348
4
+ data.tar.gz: 5cad72faacddd4ec9ed53c712dfecc337728fea989eaf87d9a42732e7e6b2c02
5
5
  SHA512:
6
- metadata.gz: 5057ba7a07f04a9e51a54823e5b60e72607c8a1efc3855df4e70a62486b637a5851abb5ad875d43172fd55e45bc83d0c121f286031247d485ed49f12bb556705
7
- data.tar.gz: 0f72b07258414880b6880e60f4508a3b696098621a979a0146c86a43a6446dfb46bc1332f427f274795cc4e0d56f558e07c8e8583dee201848a7822747cb8e25
6
+ metadata.gz: e1af46320695654351eca38beeb8efa42b1c08a93399526155e6f6d120945bbcd0af35dcdec176c0f4a686132e073258beaa25b803ed0a486442fdbf32a784ad
7
+ data.tar.gz: 2c2eff694192f3e007c788dd3788a6badce5920fd3539a6f0104e86b9b3f7333a93bb90444027817cb5b45a63062f592f4be361a25683325501f67e2d8a93313
data/README.md CHANGED
@@ -12,9 +12,6 @@ Available for `FREE` to read|download at:
12
12
 
13
13
  https://www.academia.edu/19786419/PRIMES_UTILS_HANDBOOK
14
14
 
15
- https://www.scribd.com/doc/266461408/Primes-Utils-Handbook
16
-
17
-
18
15
  ## Installation
19
16
 
20
17
  Add this line to your application's Gemfile:
@@ -39,8 +36,8 @@ Then require as:
39
36
 
40
37
  **prime?**
41
38
 
42
- Determine if an integer value is prime. Return 'true' or 'false'.
43
- This replaces the `prime?` method in the `prime.rb` standard library.
39
+ Determine if an integer value is prime, and return `true` or `false`.
40
+ This replaces the `prime?` method in the `prime.rb` standard library.
44
41
  Uses PGT residues tests, then Miller-Rabin test using `primemr?`.
45
42
 
46
43
  ```
@@ -53,7 +50,7 @@ Uses PGT residues tests, then Miller-Rabin test using `primemr?`.
53
50
 
54
51
  **primemr?(k=5)**
55
52
 
56
- Optimized deterministic (over 64-bits) implementation of Miller-Rabin algorithm.
53
+ Optimized deterministic (over 64-bits) implementation of Miller-Rabin algorithm.
57
54
  Default non-deterministic reliability set at k = 5, set higher if desired for very large numbers > 64-bts.
58
55
 
59
56
  ```
@@ -62,10 +59,10 @@ n.prime?(6)
62
59
 
63
60
  **factors or prime_division**
64
61
 
65
- Determine the prime factorization of an +|- integer value.
66
- Uses Unix coreutils function `factors` if available.
67
- This replaces the `prime_division` method in the `prime.rb` standard library.
68
- Multiplying the factors back will produce original number.
62
+ Determine the prime factorization of an +|- integer value.
63
+ Uses Unix coreutils function `factor` if available.
64
+ This replaces the `prime_division` method in the `prime.rb` standard library.
65
+ Multiplying the factors back will produce original number.
69
66
  Output is array of tuples of factors and exponents elements: [[p1, e1], [p2, e2],..,[pn, en]].
70
67
 
71
68
  ```
@@ -79,28 +76,27 @@ Output is array of tuples of factors and exponents elements: [[p1, e1], [p2, e2]
79
76
 
80
77
  **factors1**
81
78
 
82
- Pure Ruby version equivalent of `factor`.
83
- Not as fast as `factor` for some values with multiple large prime factors.
84
- Always available if OS doesn't have `factor`
79
+ Pure Ruby version equivalent of `factors`.
80
+ Not as fast as `factors` for some values with multiple large prime factors.
81
+ Always available if OS doesn't have coreutils `factor`.
85
82
 
86
83
  **primes(start=0), primesmr(start=0)**
87
84
 
88
- Return an array of prime values within the inclusive integers range `[start_num - end_num]`.
89
- Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
90
- A single input is taken as `end_num`, and the primes <= to it are returned.
91
- `primes` is generally faster, and uses SSoZ to compute the range primes.
92
- `primesmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
93
- See `PRIMES-UTILS HANDBOOK` for details on best use practices.
85
+ Return an array of prime values within the inclusive integers range `[start_num - end_num]`.
86
+ Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
87
+ A single input is taken as `end_num`, and the primes <= to it are returned.
88
+ `primes` is generally faster, and uses SoZ to compute the range primes.
89
+ `primesmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
90
+ See `PRIMES-UTILS HANDBOOK` for details on best use practices.
94
91
  Also see `Error Handling`.
95
92
 
96
93
  ```
97
94
  50.primes => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
98
- 300.primes 250 => [251, 257, 263, 269, 271, 277, 281, 283, 293]
95
+ 300.primesmr 250 => [251, 257, 263, 269, 271, 277, 281, 283, 293]
99
96
  n=10**100; (n-250).primesmr(n+250) => []
100
97
  541.primes.size => 100
101
98
  1000.primes(5000).size => 501
102
99
  (prms = 1000000.primes(1000100)).size => 6
103
- prms.size => 6
104
100
  prms => [1000003, 1000033, 1000037, 1000039, 1000081, 1000099]
105
101
  101.primes 101 => [101]
106
102
  1.primes => []
@@ -109,11 +105,11 @@ prms => [1000003, 1000033, 1000037, 1000039, 1000081, 1000099]
109
105
 
110
106
  **primescnt(start=0), primescntmr(start=0)**
111
107
 
112
- Provide count of primes within the inclusive integers range `[start_num - end_num]`.
113
- Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
114
- A single input is taken as `end_num`, and the primes count <= to it are returned.
115
- `primescnt` is faster; uses SSoZ to identify|count primes from closest hashed value starting point.
116
- `primescntmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
108
+ Provide count of primes within the inclusive integers range `[start_num - end_num]`.
109
+ Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
110
+ 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.
117
113
  See `PRIMES-UTILS HANDBOOK` for details on best use practices.
118
114
  Also see `Error Handling`.
119
115
 
@@ -130,24 +126,24 @@ n=10**8; (25*n).primescnt => 121443371
130
126
 
131
127
  **primenth(p=0) or nthprime(p=0)**
132
128
 
133
- Return value of the nth prime.
134
- Default Strictly Prime (SP) Prime Generator (PG) is adaptively selected.
135
- Can change SP PG used on input. Acceptable primes range: [5, 7].
136
- Indexed nth primes now upto 7 billionth.
137
- With 16GB mem can compute upto at least 35.7+ billionth prime (using `bitarray`).
138
- Returns `nil` for negative nth inputs.
139
- Also see `Error Handling`.
129
+ Return value of the nth prime.
130
+ Default Strictly Prime (SP) Prime Generator (PG) is adaptively selected.
131
+ Can change SP PG used on input. Default is 7. (Usable are 5, 7, 11, but normally just use default.)
132
+ Indexed nth primes now up to 7 billionth.
133
+ With 16GB mem can compute up to about 30.7+ billionth prime (using `bitarray`).
134
+ Returns `nil` for negative nth inputs. Also see `Error Handling`.
140
135
 
141
136
  ```
142
137
  1000000.primenth => 15485863
143
138
  1500000.nthprime => 23879519
144
- 2000000.nthprime 11 => 32452843
139
+ 2000000.nthprime(7) => 32452843
145
140
  1122951705.nthprime => 25741879847
146
141
  n = 10**11; n.primenth -> #<NoMemoryError: failed to allocate memory>
147
142
  2_123_409_000.nthprime => 50092535639
148
143
  4_762_719_305.nthprime => 116378528093
149
- 0.nthprime => 0
144
+ 7_123_456_789.nthprime => 177058934933
150
145
  1.primenth => 2
146
+ 0.nthprime => nil
151
147
  -1.nthprime => nil
152
148
  ```
153
149
  **next_prime**
@@ -175,7 +171,7 @@ Return value of previous prime < n > 2. Returns `nil` for n < 2 (and negatives)
175
171
 
176
172
  **primes_utils**
177
173
 
178
- Displays a list of all the `primes-utils` methods available for a system.
174
+ Displays a list of all the `primes-utils` methods available for a system.
179
175
  Use as eg: `0.primes_utils` where input n is any `class Integer` value.
180
176
 
181
177
  Available methods for 3.0.0.
@@ -187,7 +183,7 @@ Available methods for 3.0.0.
187
183
  ## Error Handling
188
184
  With 3.0.0 the Rubygem `bitarray` is used to extend useable memory for `primes`, `primescnt`, and `nthprime`.
189
185
  They use private method `sozcores2` to compute the SoZ over the ranges, and returns an array of prime residues positions.
190
- If an input range exceeds system memory to create the array, it switches to using a `bitarray`.
186
+ If an input range exceeds system memory to create the array, it switches to using a `bitarray`.
191
187
  This greatly extends the computable range sizes, at the expense of being slower than using system memory.
192
188
 
193
189
  There is also the rare possibility you could get a `NoMemoryError: failed to allocate memory` for the methods
@@ -212,7 +208,10 @@ All the `primes-utils` methods are `instance_methods` for `Class Integer`.
212
208
 
213
209
  ## History
214
210
  ```
215
- 3.0.0 – YJIT enabled for Ruby >= 3.3, added new methods: next_prime, prev_prime.
211
+ 3.1.0 – major performance enhancements for methods primescnt, primescntmr, and nthprimes,
212
+ primarily by extending nth primes hash values up to 10.1 billion. Can now find nth primes
213
+ over ranges up to 10.1 billion, and thus prime counts up to 253+ billion, in < 30 secs at ~5Ghz.
214
+ 3.0.5 – YJIT enabled for Ruby >= 3.3, added new methods: next_prime, prev_prime.
216
215
  Uses 'bitarray' to extend memory use for methods 'nthprime', 'primes', and 'primescnt'.
217
216
  2.7.0 – more tweaking adaptive pg selection ranges in select_pg; coded using between? instead of cover?
218
217
  2.6.0 – much, much better adaptive pg selection algorithm used in select_pg
@@ -228,7 +227,7 @@ All the `primes-utils` methods are `instance_methods` for `Class Integer`.
228
227
  significantly faster resulting from sozcore2 changes; massive code cleanups all-arround; added
229
228
  private methods select_pg (to adaptively select the pg used in primes), and array_check (used in
230
229
  sozcore2 to catch array creation out-of-memory errors)
231
- 2.3.0 – primescnt now finds primes upto some integer much faster, and for much larger integers
230
+ 2.3.0 – primescnt now finds primes up to some integer much faster, and for much larger integers
232
231
  increased index nth primes to over 2 billionth; used in nthprime|primenth and primescnt
233
232
  2.2.0 – for sozcore2: refactored to include more common code; changed output api; added memory
234
233
  error messages when prms and prms_range arrays creation fails; for primenth: used new
@@ -1,5 +1,5 @@
1
1
  module Primes
2
2
  module Utils
3
- VERSION = "3.0.4"
3
+ VERSION = "3.1.0"
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,60 +59,55 @@ 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
67
- seeds = [2, 3, 5, 7, 11, 13]
68
- return n > 0 ? seeds[n - 1] : 0 if n <= seeds.size
66
+ seeds = PRIMES
67
+ return seeds[n - 1] if n <= seeds.size
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)
@@ -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,8 +144,8 @@ 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
 
@@ -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,6 +247,8 @@ 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
+ # Retunr 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
@@ -284,6 +281,15 @@ module Primes
284
281
  [rescnt * k + r, r, modk] # [num pcs, r index, num modulus]
285
282
  end
286
283
 
284
+ # Determine number of pcs upto the effective start, end, and range width.
285
+ # The effective start_num is first pc >= start_num, first pc <= end_num,
286
+ # and effective range is number of pcs between them (inclusive).
287
+ # inputs: end_num and start_num of range, and PGs residues array
288
+ # outputs: pcs_to_end - number of pcs in <= end_num pc for PG
289
+ # pcs_to_start - number of pcs < effective start_num pc for range
290
+ # r1 - residue index for effective start_num pc
291
+ # modk1 - mod resgroup value for effective start_num pc
292
+ # pcs_in_range - total number of pcs in effective range
287
293
  def pcs_to_nums(end_num, start_num, residues)
288
294
  modpg, rescnt = residues[-1] - 1, residues.size
289
295
  end_num = 2 if end_num < residues[0]
@@ -292,23 +298,26 @@ module Primes
292
298
  end_num -= 1; k2 = (end_num |= 1 )/modpg; modk2 = modpg * k2
293
299
  r1 = 0; r1 = r1.succ while start_num >= modk1 + residues[r1]
294
300
  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]
301
+ pcs_to_end = k2 * rescnt + r2; pcs_to_start = k1 * rescnt + r1
302
+ pcs_in_range = pcs_to_end - pcs_to_start
303
+ [pcs_to_end, pcs_to_start, r1, modk1, pcs_in_range]
298
304
  end
299
305
 
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
306
+ # Select SP Prime Generator to parametize the pcs within inputs range
307
+ # inputs: end_num and start_num of range
308
+ # outputs: r - residue index value for start_num of pc inputs range
309
+ # modk - resgroup base value for start_num
310
+ # residues - array of residues [r0...mod+1] for PG
311
+ # primes - array of modulus primes in range, if any
307
312
  def sozcore1(end_num, start_num)
308
313
  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) }
314
+ modpg = if range < 100_001; 210 # P7; Math.isqrt(10_000_200_001)
315
+ elsif range < 7_071_267; 30_030 # P13; Math.isqrt(50_002_816_985_289)
316
+ elsif range < 24_494_897; 510_510 # P17; Math.isqrt(600_000_000_000_000)
317
+ else 9_699_690 # P19
318
+ end
319
+ residues = make_residues(modpg) # chosen PG residues
320
+ primes = PRIMES.select { |p| p < residues[0] && p.between?(start_num, end_num) }
312
321
  start_num = 2 if start_num < residues[0]
313
322
  k = (start_num - 2) / modpg; modk = k * modpg; r = 0
314
323
  while (start_num - 1) >= modk + residues[r]; r = r.succ end
@@ -316,7 +325,7 @@ module Primes
316
325
  end
317
326
 
318
327
  # 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
328
+ # inputs: end_num and start_num of inputs range and modulus value for PG
320
329
  # outputs: prms - binary (0,1) array of pcs within a range or to end_num
321
330
  # m - num of pcs in prms < start_num; so prms[m] = start_num
322
331
  # modks - modulus value for start_num's resgroup
@@ -324,171 +333,69 @@ module Primes
324
333
  # pcs2start- number of pcs < start_num pc
325
334
  # rs - residue index location for first pc >= start_num
326
335
  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 = Integer.sqrt(end_num)
330
- pcs2sqrtN, _ = pcs_to_nums(sqrtN, 0, residues) # num pcs <= sqrtN
336
+ residues = make_residues(modpg); rescnt = residues.size
337
+ maxpcs, pcs_to_start, rs, modks, pcs_range = pcs_to_nums(end_num, start_num, residues)
338
+ sqrtN, inputs_range = Integer.sqrt(end_num), end_num - start_num
339
+ pcs_to_sqrtN, _ = pcs_to_nums(sqrtN, 0, residues) # num pcs <= sqrtN
331
340
 
332
- m = pcs2start # index to start retrieving primes in prms array
341
+ m = pcs_to_start # index to start retrieving primes in prms array
333
342
  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
343
+ if split_arrays # if start_num > sqrtN create two arrays
344
+ maxpcs = pcs_to_sqrtN # array size now for primary sieve array prms
336
345
  prms_range = array_check(pcs_range) # array for pcs in range
337
346
  raise 'ERROR1: range too big for free sys mem.' unless prms_range
338
- m = 0 # index to start retrieving primes in split array
347
+ m = 0 # address to start of split array
339
348
  end
340
349
  prms = array_check(maxpcs) # array for pcs upto sqrtN, or end_num
341
350
  raise 'ERROR2: end_num too big for available sys mem.' unless prms
342
351
 
343
352
  # Sieve of Zakiya (SoZ) to eliminate nonprimes from prms, prms_range
344
- pcs2sqrtN.times do |i| # sieve primes from pcs upto sqrt(end_num)
353
+ pcs_to_sqrtN.times do |i| # sieve primes from pcs upto sqrt(end_num)
345
354
  next unless prms[i].zero? # if pc not prime, get next one
346
355
  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 <= end_num - start_num) || rem == 0 # skip prime mults not in range
356
+ prime = modpg*(k=i/rescnt) + prm_r # numerate its value; set k resgroup value
357
+ rem = start_num % prime # prime's modular distance to start_num
358
+ next unless (prime - rem <= inputs_range) || rem == 0 # skip prime if no mulitple in range
350
359
  prmstep = prime * rescnt # compute its primestep
351
360
  residues.each do |ri| # find|mark its multiples
352
361
  # convert (prime * (modk + ri)) pc value to its address in prms
353
362
  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
363
+ prm_mult = (k*(prime + ri) + kn)*rescnt + residues.index(rr+2) # 1st prime mult
364
+ while prm_mult < maxpcs; prms[prm_mult] = 1; prm_mult += prmstep end
365
+ if split_arrays # when start_num > sqrtN(pcs2sqrtN+1)
366
+ prm_mult = (pcs_to_start - prm_mult) % prmstep # (start_num - last mult) pcs
367
+ prm_mult = prmstep - prm_mult if prm_mult != 0 # location in range, or beyond
368
+ while prm_mult < pcs_range; prms_range[prm_mult] = 1; prm_mult += prmstep end
360
369
  end end end
361
370
  # select prms array and start location val m for start_num in it
362
- [(split_arrays ? prms_range : prms), m, modks, residues, pcs2start, rs]
371
+ [(split_arrays ? prms_range : prms), m, modks, residues, pcs_to_start, rs]
363
372
  end
364
373
 
365
- def approximate_nth(n)
366
- b = 0.5722 * n**0.0088
374
+ # Compute close approximate nthprime value >= real value
375
+ def approx_nthprime(n)
376
+ e = if n <= 26_800_000; 0.008702
377
+ elsif n.between?( 26_800_001, 144_000_000 - 0); 0.0088
378
+ elsif n.between?( 144_000_001, 250_000_000 - 1); 0.00881
379
+ elsif n.between?( 250_000_000, 800_000_000 - 1); 0.008798
380
+ elsif n.between?( 800_000_000, 1_000_000_000 - 1); 0.00875
381
+ elsif n.between?(1_000_000_000, 2_000_000_000 - 1); 0.008732
382
+ elsif n.between?(2_000_000_000, 3_000_000_000 - 1); 0.0086806
383
+ elsif n.between?(3_000_000_000, 4_000_000_000 - 1); 0.0086448
384
+ elsif n.between?(4_000_000_000, 5_000_000_000 - 1); 0.00862
385
+ elsif n.between?(5_000_000_000, 5_500_000_000 - 0); 0.008596
386
+ elsif n.between?(5_500_000_001, 6_500_000_000 - 0); 0.0085859
387
+ elsif n.between?(6_500_000_001, 7_500_000_000 - 0); 0.0085687
388
+ elsif n.between?(7_500_000_001, 8_500_000_000 - 0); 0.008554
389
+ elsif n.between?(8_500_000_001, 9_500_000_000 - 0); 0.008541
390
+ elsif n.between?(9_500_000_001, 100_000_000_000 - 0); 0.0085283
391
+ else 0.00825
392
+ end
393
+ b = 0.5722 * (n**e)
367
394
  a = b * Math.log(log_n = Math.log(n))
368
395
  (n * (log_n + a) + 3).to_i
369
396
  end
370
397
 
371
- # Find largest index nthprime|val <= n; return [start_num, nth, f/t]
372
- def set_start_value(n, hshflag)
373
- if hshflag
374
- nth = nths.keys.sort.reverse.find { |k| k <= n } # largest key <= n
375
- [nth ? nths[nth] : 0, nth || (n + 1), nth == n]
376
- else
377
- val = nths.values.sort.reverse.find { |v| v <= n } # largest val <= n
378
- [val || 0, val ? nths.key(val) : 0, val != n]
379
- end
380
- end
381
-
382
- def nths # hash table index of reference nth primes
383
- { 1_000_000 => 15_485_863, 5_000_000 => 86_028_121,
384
- 7_500_000 => 132_276_691, 10_000_000 => 179_424_673,
385
- 12_500_000 => 227_254_201, 15_000_000 => 275_604_541,
386
- 18_500_000 => 344_032_387, 25_000_000 => 472_882_027,
387
- 31_000_000 => 593_441_843, 37_500_000 => 725_420_401,
388
- 43_500_000 => 848_321_917, 50_000_000 => 982_451_653,
389
- 56_000_000 => 1_107_029_837, 62_500_000 => 1_242_809_749,
390
- 68_500_000 => 1_368_724_829, 75_000_000 => 1_505_776_939,
391
- 81_500_000 => 1_643_429_659, 87_500_000 => 1_770_989_609,
392
- 93_500_000 => 1_898_979_367, 100_000_000 => 2_038_074_743,
393
- 106_500_000 => 2_177_624_377, 112_500_000 => 2_306_797_469,
394
- 125_000_000 => 2_576_983_867, 137_500_000 => 2_848_518_523,
395
- 150_000_000 => 3_121_238_909, 162_500_000 => 3_395_057_291,
396
- 175_000_000 => 3_669_829_403, 187_500_000 => 3_945_592_087,
397
- 200_000_000 => 4_222_234_741, 212_500_000 => 4_499_683_009,
398
- 225_000_000 => 4_777_890_881, 237_500_000 => 5_056_862_311,
399
- 250_000_000 => 5_336_500_537, 262_500_000 => 5_616_787_769,
400
- 275_000_000 => 5_897_707_297, 287_500_000 => 6_179_208_157,
401
- 300_000_000 => 6_461_335_109, 312_500_000 => 6_743_943_629,
402
- 325_000_000 => 7_027_107_881, 337_500_000 => 7_310_793_337,
403
- 350_000_000 => 7_594_955_549, 362_500_000 => 7_879_581_839,
404
- 375_000_000 => 8_164_628_191, 387_500_000 => 8_450_100_349,
405
- 400_000_000 => 8_736_028_057, 412_500_000 => 9_022_375_487,
406
- 425_000_000 => 9_309_109_471, 437_500_000 => 9_596_238_593,
407
- 450_000_000 => 9_883_692_017, 462_500_000 => 10_171_564_687,
408
- 475_000_000 => 10_459_805_417, 487_500_000 => 10_748_372_137,
409
- 500_000_000 => 11_037_271_757, 512_500_000 => 11_326_513_039,
410
- 525_000_000 => 11_616_020_609, 537_500_000 => 11_905_863_799,
411
- 550_000_000 => 12_196_034_771, 562_500_000 => 12_486_465_863,
412
- 575_000_000 => 12_777_222_833, 587_500_000 => 13_068_237_251,
413
- 600_000_000 => 13_359_555_403, 612_500_000 => 13_651_119_389,
414
- 625_000_000 => 13_942_985_677, 637_500_000 => 14_235_122_851,
415
- 650_000_000 => 14_527_476_781, 662_500_000 => 14_820_071_503,
416
- 675_000_000 => 15_112_928_683, 687_500_000 => 15_406_031_899,
417
- 700_000_000 => 15_699_342_107, 712_500_000 => 15_992_957_251,
418
- 725_000_000 => 16_286_768_243, 737_500_000 => 16_580_801_137,
419
- 750_000_000 => 16_875_026_921, 762_500_000 => 17_169_527_171,
420
- 775_000_000 => 17_464_243_799, 787_500_000 => 17_759_139_259,
421
- 800_000_000 => 18_054_236_957, 812_500_000 => 18_349_591_409,
422
- 825_000_000 => 18_645_104_897, 837_500_000 => 18_940_846_207,
423
- 850_000_000 => 19_236_701_629, 862_500_000 => 19_532_780_327,
424
- 875_000_000 => 19_829_092_147, 887_500_000 => 20_125_592_731,
425
- 900_000_000 => 20_422_213_579, 912_500_000 => 20_719_050_323,
426
- 925_000_000 => 21_016_060_633, 937_500_000 => 21_313_231_963,
427
- 950_000_000 => 21_610_588_367, 962_500_000 => 21_908_128_993,
428
- 975_000_000 => 22_205_818_561, 987_500_000 => 22_503_733_657,
429
- 1_000_000_000 => 22_801_763_489, 1_012_500_000 => 23_099_993_743,
430
- 1_025_000_000 => 23_398_391_231, 1_037_500_000 => 23_696_858_797,
431
- 1_050_000_000 => 23_995_554_823, 1_062_500_000 => 24_294_392_179,
432
- 1_075_000_000 => 24_593_421_187, 1_087_500_000 => 24_892_587_403,
433
- 1_100_000_000 => 25_191_867_719, 1_112_500_000 => 25_491_361_037,
434
- 1_125_000_000 => 25_790_970_053, 1_137_500_000 => 26_090_709_563,
435
- 1_150_000_000 => 26_390_560_513, 1_162_500_000 => 26_690_560_601,
436
- 1_175_000_000 => 26_990_744_987, 1_187_500_000 => 27_291_009_337,
437
- 1_200_000_000 => 27_591_444_869, 1_212_500_000 => 27_892_051_267,
438
- 1_225_000_000 => 28_192_760_279, 1_237_500_000 => 28_493_648_629,
439
- 1_250_000_000 => 28_794_583_627, 1_262_500_000 => 29_095_694_269,
440
- 1_275_000_000 => 29_396_966_971, 1_287_500_000 => 29_698_366_099,
441
- 1_300_000_000 => 29_999_858_327, 1_312_500_000 => 30_301_430_881,
442
- 1_325_000_000 => 30_603_183_581, 1_337_500_000 => 30_905_024_497,
443
- 1_350_000_000 => 31_207_047_449, 1_362_500_000 => 31_509_131_153,
444
- 1_375_000_000 => 31_811_397_571, 1_387_500_000 => 32_113_702_069,
445
- 1_400_000_000 => 32_416_190_071, 1_412_500_000 => 32_718_790_873,
446
- 1_425_000_000 => 33_021_414_143, 1_437_500_000 => 33_324_275_711,
447
- 1_450_000_000 => 33_627_220_709, 1_462_500_000 => 33_930_284_893,
448
- 1_475_000_000 => 34_233_442_279, 1_487_500_000 => 34_536_683_891,
449
- 1_500_000_000 => 34_840_062_373, 1_512_500_000 => 35_143_545_889,
450
- 1_525_000_000 => 35_447_088_559, 1_537_500_000 => 35_750_747_297,
451
- 1_550_000_000 => 36_054_501_641, 1_562_500_000 => 36_358_440_731,
452
- 1_575_000_000 => 36_662_430_631, 1_587_500_000 => 36_966_563_321,
453
- 1_600_000_000 => 37_270_791_697, 1_612_500_000 => 37_575_137_933,
454
- 1_625_000_000 => 37_879_532_671, 1_637_500_000 => 38_184_009_763,
455
- 1_650_000_000 => 38_488_677_419, 1_662_500_000 => 38_793_413_899,
456
- 1_675_000_000 => 39_098_225_629, 1_687_500_000 => 39_403_174_463,
457
- 1_700_000_000 => 39_708_229_123, 1_712_500_000 => 40_013_309_359,
458
- 1_725_000_000 => 40_318_523_009, 1_737_500_000 => 40_623_800_311,
459
- 1_750_000_000 => 40_929_166_261, 1_762_500_000 => 41_234_743_751,
460
- 1_775_000_000 => 41_540_289_619, 1_787_500_000 => 41_845_958_971,
461
- 1_800_000_000 => 42_151_671_491, 1_812_500_000 => 42_457_500_313,
462
- 1_825_000_000 => 42_763_499_629, 1_837_500_000 => 43_069_571_603,
463
- 1_850_000_000 => 43_375_710_643, 1_862_500_000 => 43_681_898_699,
464
- 1_875_000_000 => 43_988_172_667, 1_887_500_000 => 44_294_549_347,
465
- 1_900_000_000 => 44_601_021_791, 1_912_500_000 => 44_907_564_593,
466
- 1_925_000_000 => 45_214_177_441, 1_937_500_000 => 45_520_935_011,
467
- 1_950_000_000 => 45_827_700_419, 1_962_500_000 => 46_134_655_219,
468
- 1_975_000_000 => 46_441_643_177, 1_987_500_000 => 46_748_693_981,
469
- 2_000_000_000 => 47_055_833_459, 2_012_500_000 => 47_363_059_687,
470
- 2_125_000_000 => 50_131_763_837, 2_250_000_000 => 53_215_141_519,
471
- 2_375_000_000 => 56_305_859_821, 2_500_000_000 => 59_403_556_879,
472
- 2_625_000_000 => 62_507_768_977, 2_750_000_000 => 65_618_159_808,
473
- 2_875_000_000 => 68_734_481_527, 3_000_000_000 => 71_856_445_751,
474
- 3_125_000_000 => 74_983_924_661, 3_250_000_000 => 78_116_541_127,
475
- 3_375_000_000 => 81_254_172_953, 3_500_000_000 => 84_396_675_733,
476
- 3_625_000_000 => 87_543_835_147, 3_750_000_000 => 90_695_492_941,
477
- 3_875_000_000 => 93_851_412_433, 4_000_000_000 => 97_011_687_217,
478
- 4_125_000_000 =>100_175_917_301, 4_250_000_000 => 103_344_103_553,
479
- 4_375_000_000 =>106_516_393_597, 4_500_000_000 => 109_692_247_799,
480
- 4_625_000_000 =>112_871_634_437, 4_750_000_000 => 116_054_419_753,
481
- 4_875_000_000 =>119_240_825_947, 5_000_000_000 => 122_430_513_841,
482
- 5_125_000_000 =>125_623_420_333, 5_250_000_000 => 128_819_622_391,
483
- 5_375_000_000 =>132_018_808_321, 5_500_000_000 => 135_221_143_753,
484
- 5_625_000_000 =>138_426_461_137, 5_750_000_000 => 141_634_567_969,
485
- 5_875_000_000 =>144_845_535_431, 6_000_000_000 => 148_059_109_201,
486
- 6_125_000_000 =>151_275_700_969, 6_250_000_000 => 154_494_952_609,
487
- 6_375_000_000 =>157_716_628_943, 6_500_000_000 => 160_940_840_461,
488
- 6_625_000_000 =>164_167_763_329, 6_750_000_000 => 167_397_013_051,
489
- 6_875_000_000 =>170_628_613_009, 7_000_000_000 => 173_862_636_221 }
490
- end
491
-
398
+ # Adaptively select Strictly Prime (SP) Prime Generator
492
399
  def select_pg(end_num, start_num) # adaptively select PG
493
400
  range = end_num - start_num
494
401
  pg = 5
@@ -503,7 +410,7 @@ module Primes
503
410
  pg = 11 if (range.between?(10**8, 10**9 - 1) && start_num < 55 * 10**7) ||
504
411
  (range >= 10**9 && start_num < 45 * 10**9)
505
412
  end
506
- primes = [2, 3, 5, 7, 11, 13].select! { |p| p <= pg }
413
+ primes = PRIMES.select { |p| p <= pg }
507
414
  [primes, primes.reduce(:*)] # [base primes, mod] for PG
508
415
  end
509
416
 
@@ -512,7 +419,211 @@ module Primes
512
419
  Array.new(len, 0) # use Array when enough mem for given length
513
420
  rescue Exception
514
421
  return BitArray.new(len) # use BitArray when memory-error for Array
515
- end end
422
+ end
423
+ end
424
+
425
+ # Find largest index nthprime|val <= n; return [start_num, nth, f/t]
426
+ def set_start_value(n, hshflag)
427
+ if hshflag
428
+ nth = nths.keys.sort.reverse.find { |k| k <= n } # largest key <= n
429
+ [nth ? nths[nth] : 0, nth || (n + 1), nth == n]
430
+ else
431
+ val = nths.values.sort.reverse.find { |v| v <= n } # largest val <= n
432
+ [val || 0, val ? nths.key(val) : 0, val != n]
433
+ end
434
+ end
435
+
436
+ def nths # hash table index of reference nth primes
437
+ { 1_000_000 => 15_485_863, 2_500_000 => 41_161_739,
438
+ 5_000_000 => 86_028_121, 7_500_000 => 132_276_691,
439
+ 10_000_000 => 179_424_673, 12_500_000 => 227_254_201,
440
+ 15_000_000 => 275_604_541, 17_500_000 => 324_407_071,
441
+ 20_000_000 => 373_587_883, 22_500_000 => 423_087_251,
442
+ 25_000_000 => 472_882_027, 27_500_000 => 522_960_521,
443
+ 31_000_000 => 593_441_843, 37_500_000 => 725_420_401,
444
+ 43_500_000 => 848_321_917, 50_000_000 => 982_451_653,
445
+ 56_000_000 => 1_107_029_837, 62_500_000 => 1_242_809_749,
446
+ 68_500_000 => 1_368_724_829, 75_000_000 => 1_505_776_939,
447
+ 81_500_000 => 1_643_429_659, 87_500_000 => 1_770_989_609,
448
+ 91_000_000 => 1_845_587_707, 95_500_000 => 1_941_743_593,
449
+ 100_000_000 => 2_038_074_743, 106_250_000 => 2_172_252_527,
450
+ 112_500_000 => 2_306_797_469, 118_750_000 => 2_441_736_961,
451
+ 125_000_000 => 2_576_983_867, 131_250_000 => 2_712_589_223,
452
+ 137_500_000 => 2_848_518_523, 143_750_000 => 2_984_727_947,
453
+ 150_000_000 => 3_121_238_909, 156_250_000 => 3_258_002_933,
454
+ 162_500_000 => 3_395_057_291, 168_750_000 => 3_532_313_509,
455
+ 175_000_000 => 3_669_829_403, 181_250_000 => 3_807_579_749,
456
+ 187_500_000 => 3_945_592_087, 193_750_000 => 4_083_820_723,
457
+ 200_000_000 => 4_222_234_741, 206_250_000 => 4_360_844_731,
458
+ 212_500_000 => 4_499_683_009, 218_750_000 => 4_638_696_967,
459
+ 225_000_000 => 4_777_890_881, 231_250_000 => 4_917_286_597,
460
+ 237_500_000 => 5_056_862_311, 243_750_000 => 5_196_588_437,
461
+ 250_000_000 => 5_336_500_537, 256_250_000 => 5_476_565_287,
462
+ 262_500_000 => 5_616_787_769, 268_750_000 => 5_757_149_341,
463
+ 275_000_000 => 5_897_707_297, 281_250_000 => 6_038_399_501,
464
+ 287_500_000 => 6_179_208_157, 293_750_000 => 6_320_167_471,
465
+ 300_000_000 => 6_461_335_109, 306_250_000 => 6_602_538_337,
466
+ 312_500_000 => 6_743_943_629, 318_750_000 => 6_885_467_689,
467
+ 325_000_000 => 7_027_107_881, 331_250_000 => 7_168_869_523,
468
+ 337_500_000 => 7_310_793_337, 343_750_000 => 7_452_779_041,
469
+ 350_000_000 => 7_594_955_549, 356_250_000 => 7_737_220_201,
470
+ 362_500_000 => 7_879_581_839, 368_750_000 => 8_022_019_693,
471
+ 375_000_000 => 8_164_628_191, 381_250_000 => 8_307_284_749,
472
+ 387_500_000 => 8_450_100_349, 393_750_000 => 8_592_999_131,
473
+ 400_000_000 => 8_736_028_057, 406_250_000 => 8_879_163_259,
474
+ 412_500_000 => 9_022_375_487, 418_750_000 => 9_165_714_427,
475
+ 425_000_000 => 9_309_109_471, 431_000_000 => 9_446_878_729,
476
+ 437_500_000 => 9_596_238_593, 443_750_000 => 9_739_892_947,
477
+ 450_000_000 => 9_883_692_017, 456_500_000 => 10_033_327_459,
478
+ 462_500_000 => 10_171_564_687, 468_750_000 => 10_315_624_537,
479
+ 475_000_000 => 10_459_805_417, 481_500_000 => 10_609_826_303,
480
+ 487_500_000 => 10_748_372_137, 493_750_000 => 10_892_768_429,
481
+ 500_000_000 => 11_037_271_757, 506_250_000 => 11_181_815_213,
482
+ 512_500_000 => 11_326_513_039, 519_000_000 => 11_477_051_947,
483
+ 525_000_000 => 11_616_020_609, 531_250_000 => 11_760_892_211,
484
+ 537_500_000 => 11_905_863_799, 543_750_000 => 12_050_939_503,
485
+ 550_000_000 => 12_196_034_771, 556_250_000 => 12_341_214_203,
486
+ 562_500_000 => 12_486_465_863, 568_750_000 => 12_631_810_823,
487
+ 575_000_000 => 12_777_222_833, 581_250_000 => 12_922_677_437,
488
+ 587_500_000 => 13_068_237_251, 593_750_000 => 13_213_860_971,
489
+ 600_000_000 => 13_359_555_403, 606_250_000 => 13_505_300_407,
490
+ 612_500_000 => 13_651_119_389, 619_250_000 => 13_808_675_917,
491
+ 625_000_000 => 13_942_985_677, 631_250_000 => 14_089_055_291,
492
+ 637_500_000 => 14_235_122_851, 643_750_000 => 14_381_273_323,
493
+ 650_000_000 => 14_527_476_781, 656_250_000 => 14_673_746_567,
494
+ 662_500_000 => 14_820_071_503, 668_750_000 => 14_966_474_821,
495
+ 675_000_000 => 15_112_928_683, 681_250_000 => 15_259_429_589,
496
+ 687_500_000 => 15_406_031_899, 693_750_000 => 15_552_667_763,
497
+ 700_000_000 => 15_699_342_107, 706_250_000 => 15_846_115_699,
498
+ 712_500_000 => 15_992_957_251, 716_750_000 => 16_092_830_933,
499
+ 725_000_000 => 16_286_768_243, 731_250_000 => 16_433_777_953,
500
+ 737_500_000 => 16_580_801_137, 743_750_000 => 16_727_906_893,
501
+ 750_000_000 => 16_875_026_921, 756_250_000 => 17_022_234_041,
502
+ 762_500_000 => 17_169_527_171, 768_750_000 => 17_316_837_781,
503
+ 775_000_000 => 17_464_243_799, 781_250_000 => 17_611_642_327,
504
+ 787_500_000 => 17_759_139_259, 793_250_000 => 17_894_866_747,
505
+ 800_000_000 => 18_054_236_957, 806_250_000 => 18_201_899_809,
506
+ 812_500_000 => 18_349_591_409, 817_250_000 => 18_461_848_099,
507
+ 825_000_000 => 18_645_104_897, 831_250_000 => 18_792_939_317,
508
+ 837_500_000 => 18_940_846_207, 843_750_000 => 19_088_754_313,
509
+ 850_000_000 => 19_236_701_629, 856_250_000 => 19_384_721_509,
510
+ 862_500_000 => 19_532_780_327, 868_750_000 => 19_680_906_451,
511
+ 875_000_000 => 19_829_092_147, 881_250_000 => 19_977_299_393,
512
+ 887_500_000 => 20_125_592_731, 893_750_000 => 20_273_868_583,
513
+ 900_000_000 => 20_422_213_579, 906_250_000 => 20_570_597_317,
514
+ 912_500_000 => 20_719_050_323, 918_750_000 => 20_867_520_769,
515
+ 925_000_000 => 21_016_060_633, 931_250_000 => 21_164_606_423,
516
+ 937_500_000 => 21_313_231_963, 943_750_000 => 21_461_910_023,
517
+ 950_000_000 => 21_610_588_367, 956_250_000 => 21_759_307_211,
518
+ 962_500_000 => 21_908_128_993, 968_750_000 => 22_056_948_833,
519
+ 975_000_000 => 22_205_818_561, 981_250_000 => 22_354_799_491,
520
+ 987_500_000 => 22_503_733_657, 993_750_000 => 22_652_687_809,
521
+ 1_000_000_000 => 22_801_763_489, 1_012_500_000 => 23_099_993_743,
522
+ 1_025_000_000 => 23_398_391_231, 1_037_500_000 => 23_696_858_797,
523
+ 1_050_000_000 => 23_995_554_823, 1_062_500_000 => 24_294_392_179,
524
+ 1_075_000_000 => 24_593_421_187, 1_087_500_000 => 24_892_587_403,
525
+ 1_100_000_000 => 25_191_867_719, 1_112_500_000 => 25_491_361_037,
526
+ 1_125_000_000 => 25_790_970_053, 1_137_500_000 => 26_090_709_563,
527
+ 1_150_000_000 => 26_390_560_513, 1_162_500_000 => 26_690_560_601,
528
+ 1_175_000_000 => 26_990_744_987, 1_187_500_000 => 27_291_009_337,
529
+ 1_200_000_000 => 27_591_444_869, 1_212_500_000 => 27_892_051_267,
530
+ 1_225_000_000 => 28_192_760_279, 1_237_500_000 => 28_493_648_629,
531
+ 1_250_000_000 => 28_794_583_627, 1_262_500_000 => 29_095_694_269,
532
+ 1_275_000_000 => 29_396_966_971, 1_287_500_000 => 29_698_366_099,
533
+ 1_300_000_000 => 29_999_858_327, 1_312_500_000 => 30_301_430_881,
534
+ 1_325_000_000 => 30_603_183_581, 1_337_500_000 => 30_905_024_497,
535
+ 1_350_000_000 => 31_207_047_449, 1_362_500_000 => 31_509_131_153,
536
+ 1_375_000_000 => 31_811_397_571, 1_387_500_000 => 32_113_702_069,
537
+ 1_400_000_000 => 32_416_190_071, 1_412_500_000 => 32_718_790_873,
538
+ 1_425_000_000 => 33_021_414_143, 1_437_500_000 => 33_324_275_711,
539
+ 1_450_000_000 => 33_627_220_709, 1_462_500_000 => 33_930_284_893,
540
+ 1_475_000_000 => 34_233_442_279, 1_487_500_000 => 34_536_683_891,
541
+ 1_500_000_000 => 34_840_062_373, 1_512_500_000 => 35_143_545_889,
542
+ 1_525_000_000 => 35_447_088_559, 1_537_500_000 => 35_750_747_297,
543
+ 1_550_000_000 => 36_054_501_641, 1_562_500_000 => 36_358_440_731,
544
+ 1_575_000_000 => 36_662_430_631, 1_587_500_000 => 36_966_563_321,
545
+ 1_600_000_000 => 37_270_791_697, 1_612_500_000 => 37_575_137_933,
546
+ 1_625_000_000 => 37_879_532_671, 1_637_500_000 => 38_184_009_763,
547
+ 1_650_000_000 => 38_488_677_419, 1_662_500_000 => 38_793_413_899,
548
+ 1_675_000_000 => 39_098_225_629, 1_687_500_000 => 39_403_174_463,
549
+ 1_700_000_000 => 39_708_229_123, 1_712_500_000 => 40_013_309_359,
550
+ 1_725_000_000 => 40_318_523_009, 1_737_500_000 => 40_623_800_311,
551
+ 1_750_000_000 => 40_929_166_261, 1_762_500_000 => 41_234_743_751,
552
+ 1_775_000_000 => 41_540_289_619, 1_787_500_000 => 41_845_958_971,
553
+ 1_800_000_000 => 42_151_671_491, 1_812_500_000 => 42_457_500_313,
554
+ 1_825_000_000 => 42_763_499_629, 1_837_500_000 => 43_069_571_603,
555
+ 1_850_000_000 => 43_375_710_643, 1_862_500_000 => 43_681_898_699,
556
+ 1_875_000_000 => 43_988_172_667, 1_887_500_000 => 44_294_549_347,
557
+ 1_900_000_000 => 44_601_021_791, 1_912_500_000 => 44_907_564_593,
558
+ 1_925_000_000 => 45_214_177_441, 1_937_500_000 => 45_520_935_011,
559
+ 1_950_000_000 => 45_827_700_419, 1_962_500_000 => 46_134_655_219,
560
+ 1_975_000_000 => 46_441_643_177, 1_987_500_000 => 46_748_693_081,
561
+ 2_000_000_000 => 47_055_833_459, 2_062_500_000 => 48_592_822_043,
562
+ 2_125_000_000 => 50_131_763_837, 2_187_500_000 => 51_672_463_541,
563
+ 2_250_000_000 => 53_215_141_519, 2_312_500_000 => 54_759_617_681,
564
+ 2_375_000_000 => 56_305_859_821, 2_437_500_000 => 57_853_856_521,
565
+ 2_500_000_000 => 59_403_556_879, 2_562_500_000 => 60_954_821_429,
566
+ 2_625_000_000 => 62_507_768_977, 2_687_500_000 => 64_062_179_743,
567
+ 2_750_000_000 => 65_618_159_808, 2_812_500_000 => 67_175_627_957,
568
+ 2_875_000_000 => 68_734_481_527, 2_937_500_000 => 70_294_765_447,
569
+ 3_000_000_000 => 71_856_445_751, 3_062_500_000 => 73_419_453_619,
570
+ 3_125_000_000 => 74_983_924_661, 3_187_500_000 => 76_549_505_951,
571
+ 3_250_000_000 => 78_116_541_127, 3_312_500_000 => 79_684_708_483,
572
+ 3_375_000_000 => 81_254_172_953, 3_437_500_000 => 82_824_830_279,
573
+ 3_500_000_000 => 84_396_675_733, 3_562_500_000 => 85_969_638_697,
574
+ 3_625_000_000 => 87_543_835_147, 3_687_500_000 => 89_119_062_301,
575
+ 3_750_000_000 => 90_695_492_941, 3_812_500_000 => 92_272_943_291,
576
+ 3_875_000_000 => 93_851_412_433, 3_937_500_000 => 95_431_061_423,
577
+ 4_000_000_000 => 97_011_687_217, 4_062_500_000 => 98_593_232_273,
578
+ 4_125_000_000 =>100_175_917_301, 4_187_500_000 => 101_759_445_239,
579
+ 4_250_000_000 =>103_344_103_553, 4_312_500_000 => 104_929_660_237,
580
+ 4_375_000_000 =>106_516_393_597, 4_437_500_000 => 108_103_847_759,
581
+ 4_500_000_000 =>109_692_247_799, 4_562_500_000 => 111_281_475_367,
582
+ 4_625_000_000 =>112_871_634_437, 4_687_500_000 => 114_462_576_077,
583
+ 4_750_000_000 =>116_054_419_753, 4_812_500_000 => 117_647_215_579,
584
+ 4_875_000_000 =>119_240_825_947, 4_937_500_000 => 120_835_390_561,
585
+ 5_000_000_000 =>122_430_513_841, 5_062_500_000 => 124_026_505_511,
586
+ 5_125_000_000 =>125_623_420_333, 5_187_500_000 => 127_221_145_921,
587
+ 5_250_000_000 =>128_819_622_391, 5_312_500_000 => 130_418_741_759,
588
+ 5_375_000_000 =>132_018_808_321, 5_437_500_000 => 133_619_596_303,
589
+ 5_500_000_000 =>135_221_143_753, 5_562_500_000 => 136_823_413_933,
590
+ 5_625_000_000 =>138_426_461_137, 5_687_500_000 => 140_030_126_603,
591
+ 5_750_000_000 =>141_634_567_969, 5_812_500_000 => 143_239_738_403,
592
+ 5_875_000_000 =>144_845_535_431, 5_937_500_000 => 146_451_972_661,
593
+ 6_000_000_000 =>148_059_109_201, 6_062_500_000 => 149_667_050_623,
594
+ 6_125_000_000 =>151_275_700_969, 6_187_500_000 => 152_885_012_491,
595
+ 6_250_000_000 =>154_494_952_609, 6_312_500_000 => 156_105_425_747,
596
+ 6_375_000_000 =>157_716_628_943, 6_437_500_000 => 159_328_400_423,
597
+ 6_500_000_000 =>160_940_840_461, 6_562_500_000 => 162_554_018_383,
598
+ 6_625_000_000 =>164_167_763_329, 6_687_500_000 => 165_782_087_147,
599
+ 6_750_000_000 =>167_397_013_051, 6_812_500_000 => 169_012_493_731,
600
+ 6_875_000_000 =>170_628_613_009, 6_937_500_000 => 172_245_292_151,
601
+ 7_000_000_000 =>173_862_636_221, 7_062_500_000 => 175_480_437_941,
602
+ 7_125_000_000 =>177_098_901_853, 7_187_500_000 => 178_718_004_559,
603
+ 7_250_000_000 =>180_337_540_729, 7_312_500_000 => 181_957_736_671,
604
+ 7_375_000_000 =>183_578_464_339, 7_437_500_000 => 185_199_695_243,
605
+ 7_500_000_000 =>186_821_628_281, 7_562_500_000 => 188_443_933_631,
606
+ 7_625_000_000 =>190_066_857_349, 7_687_500_000 => 191_690_371_627,
607
+ 7_750_000_000 =>193_314_249_683, 7_812_500_000 => 194_938_683_917,
608
+ 7_875_000_000 =>196_563_769_217, 7_937_500_000 => 198_189_192_449,
609
+ 8_000_000_000 =>199_815_106_433, 8_062_500_000 => 201_441_616_073,
610
+ 8_125_000_000 =>203_068_844_123, 8_187_500_000 => 204_696_410_057,
611
+ 8_250_000_000 =>206_324_421_217, 8_312_500_000 => 207_952_872_601,
612
+ 8_375_000_000 =>209_581_922_889, 8_437_500_000 => 211_211_500_043,
613
+ 8_500_000_000 =>212_841_570_911, 8_562_500_000 => 214_472_070_151,
614
+ 8_625_000_000 =>216_102_910_559, 8_687_500_000 => 217_734_315_107,
615
+ 8_750_000_000 =>219_366_232_937, 8_812_500_000 => 220_998_618_619,
616
+ 8_875_000_000 =>222_631_402_171, 8_937_500_000 => 224_264_794_049,
617
+ 9_000_000_000 =>225_898_512_559, 9_062_500_000 => 227_532_648_853,
618
+ 9_125_000_000 =>229_167_269_077, 9_187_500_000 => 230_802_553_771,
619
+ 9_250_000_000 =>232_438_083_623, 9_312_500_000 => 234_073_993_121,
620
+ 9_375_000_000 =>235_710_242_393, 9_437_500_000 => 237_347_050_547,
621
+ 9_500_000_000 =>238_984_246_139, 9_562_500_000 => 240_621_857_459,
622
+ 9_625_000_000 =>242_259_972_943, 9_687_500_000 => 243_898_743_329,
623
+ 9_750_000_000 =>245_537_657_177, 9_812_500_000 => 247_176_989_299,
624
+ 9_875_000_000 =>248_816_855_407, 9_937_500_000 => 250_457_226_821,
625
+ 10_000_000_000 =>252_097_800_623,10_062_500_000 => 253_738_728_317 }
626
+ end
516
627
  end
517
628
  end
518
629
 
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.files = FileList['lib/primes/utils.rb', 'lib/primes/utils/*.rb','bin/*', 'README.md', 'Gemfile', 'Rakefile', 'CODE_OF_CONDUCT.md', 'primes-utils-3.0.0.gemspec']
18
18
  spec.require_paths = ["lib"]
19
19
  spec.license = "LGPL-2.0-or-later"
20
- spec.required_ruby_version = ">= 3.0.1"
20
+ spec.required_ruby_version = ">= 3.0.0"
21
21
 
22
22
  spec.add_dependency "bitarray", "~> 1.3", ">= 1.3.1"
23
23
  spec.add_development_dependency "bundler", "~> 1.9"
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.4
4
+ version: 3.1.0
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: 3.6.9
96
96
  specification_version: 4
97
97
  summary: suite of extremely fast utility methods for testing and generating primes
98
98
  test_files: []