prime 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69c11faf9d0618a701ec125b9e6f4166770ade54b7868896535b75ef549c7beb
4
- data.tar.gz: f86764a32b94750b27444875ec6282cdfb2398de1bf55f643eb26c225b5a532d
3
+ metadata.gz: 145fdb7bf35cfc518b2ab469df94b560ee67199edccaef17caf2b20cc5adfd0f
4
+ data.tar.gz: c266767b310ed54143941a36449e0bb013d8b23a585dedc73662708056ba300e
5
5
  SHA512:
6
- metadata.gz: f5aa14e41c4c80c3c95828b2d7f019f220e1ba2ad461ab638ab32af7e98296e233ef390b90c13847e78b639e24fc47df8052e8f7c10c72181de743b3f78342e5
7
- data.tar.gz: 74d959b3a3d2ddb296dbf116cc8bed6314ca43fcedd98a7667ed520d3efa1340077b567a197ce0e164e21b2c7be43be28fb718ed80660d903b86d795a75c0bfb
6
+ metadata.gz: e8fa1c530cea6fa87d14911a9e5e98ca323ab81e680e8132a822b1ca9c1195469995948e9245dba45668864b4b08797a3f9bac713b8999b0e4a7a5ac9b772603
7
+ data.tar.gz: 0b7c4426d5f509d411fe8658f05811b6b1f7ce8b2d49125ef7f702725708ac4bc52b7a92c39e45633bab1d37adeb0e4f38bde72cb48d399682d9e50d430b065b
@@ -4,10 +4,10 @@ Redistribution and use in source and binary forms, with or without
4
4
  modification, are permitted provided that the following conditions
5
5
  are met:
6
6
  1. Redistributions of source code must retain the above copyright
7
- notice, this list of conditions and the following disclaimer.
7
+ notice, this list of conditions and the following disclaimer.
8
8
  2. Redistributions in binary form must reproduce the above copyright
9
- notice, this list of conditions and the following disclaimer in the
10
- documentation and/or other materials provided with the distribution.
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
11
 
12
12
  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
13
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
data/COPYING ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a. place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b. use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c. give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d. make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a. distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b. accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c. give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d. make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Prime
2
2
 
3
+ [![CI](https://github.com/ruby/prime/actions/workflows/test.yml/badge.svg)](https://github.com/ruby/prime/actions/workflows/test.yml)
4
+
3
5
  Prime numbers and factorization library.
4
6
 
5
7
  ## Installation
@@ -33,8 +35,9 @@ Prime.prime?(7) #=> true
33
35
  8.prime? #=> false
34
36
 
35
37
  # Factorization in prime numbers
36
- Prime.prime_division(779) #=> [[19, 1], [41, 1]]
37
- Prime.int_from_prime_division([[19, 1], [41, 1]]) #=> 779
38
+ Prime.prime_division(8959) #=> [[17, 2], [31, 1]]
39
+ Prime.int_from_prime_division([[17, 2], [31, 1]]) #=> 8959
40
+ 17**2 * 31 #=> 8959
38
41
  ```
39
42
 
40
43
  ## Contributing
data/Rakefile CHANGED
@@ -2,8 +2,8 @@ require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
5
+ t.libs << "test/lib"
6
+ t.ruby_opts << "-rhelper"
7
7
  t.test_files = FileList["test/**/test_*.rb"]
8
8
  end
9
9
 
data/lib/prime.rb CHANGED
@@ -31,8 +31,14 @@ class Integer
31
31
  end
32
32
 
33
33
  # Returns true if +self+ is a prime number, else returns false.
34
+ # Not recommended for very big integers (> 10**23).
34
35
  def prime?
35
36
  return self >= 2 if self <= 3
37
+
38
+ if (bases = miller_rabin_bases)
39
+ return miller_rabin_test(bases)
40
+ end
41
+
36
42
  return true if self == 5
37
43
  return false unless 30.gcd(self) == 1
38
44
  (7..Integer.sqrt(self)).step(30) do |p|
@@ -43,6 +49,73 @@ class Integer
43
49
  true
44
50
  end
45
51
 
52
+ MILLER_RABIN_BASES = [
53
+ [2],
54
+ [2,3],
55
+ [31,73],
56
+ [2,3,5],
57
+ [2,3,5,7],
58
+ [2,7,61],
59
+ [2,13,23,1662803],
60
+ [2,3,5,7,11],
61
+ [2,3,5,7,11,13],
62
+ [2,3,5,7,11,13,17],
63
+ [2,3,5,7,11,13,17,19,23],
64
+ [2,3,5,7,11,13,17,19,23,29,31,37],
65
+ [2,3,5,7,11,13,17,19,23,29,31,37,41],
66
+ ].map!(&:freeze).freeze
67
+ private_constant :MILLER_RABIN_BASES
68
+
69
+ private def miller_rabin_bases
70
+ # Miller-Rabin's complexity is O(k log^3n).
71
+ # So we can reduce the complexity by reducing the number of bases tested.
72
+ # Using values from https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
73
+ i = case
74
+ when self < 0xffff then
75
+ # For small integers, Miller Rabin can be slower
76
+ # There is no mathematical significance to 0xffff
77
+ return nil
78
+ # when self < 2_047 then 0
79
+ when self < 1_373_653 then 1
80
+ when self < 9_080_191 then 2
81
+ when self < 25_326_001 then 3
82
+ when self < 3_215_031_751 then 4
83
+ when self < 4_759_123_141 then 5
84
+ when self < 1_122_004_669_633 then 6
85
+ when self < 2_152_302_898_747 then 7
86
+ when self < 3_474_749_660_383 then 8
87
+ when self < 341_550_071_728_321 then 9
88
+ when self < 3_825_123_056_546_413_051 then 10
89
+ when self < 318_665_857_834_031_151_167_461 then 11
90
+ when self < 3_317_044_064_679_887_385_961_981 then 12
91
+ else return nil
92
+ end
93
+ MILLER_RABIN_BASES[i]
94
+ end
95
+
96
+ private def miller_rabin_test(bases)
97
+ return false if even?
98
+
99
+ r = 0
100
+ d = self >> 1
101
+ while d.even?
102
+ d >>= 1
103
+ r += 1
104
+ end
105
+
106
+ self_minus_1 = self-1
107
+ bases.each do |a|
108
+ x = a.pow(d, self)
109
+ next if x == 1 || x == self_minus_1 || a == self
110
+
111
+ return false if r.times do
112
+ x = x.pow(2, self)
113
+ break if x == self_minus_1
114
+ end
115
+ end
116
+ true
117
+ end
118
+
46
119
  # Iterates the given block over all prime numbers.
47
120
  #
48
121
  # See +Prime+#each for more details.
@@ -84,7 +157,7 @@ end
84
157
  # There are few implementations of generator.
85
158
  #
86
159
  # [+Prime+::+EratosthenesGenerator+]
87
- # Uses eratosthenes' sieve.
160
+ # Uses Eratosthenes' sieve.
88
161
  # [+Prime+::+TrialDivisionGenerator+]
89
162
  # Uses the trial division method.
90
163
  # [+Prime+::+Generator23+]
@@ -96,7 +169,7 @@ end
96
169
 
97
170
  class Prime
98
171
 
99
- VERSION = "0.1.0"
172
+ VERSION = "0.1.3"
100
173
 
101
174
  include Enumerable
102
175
  include Singleton
@@ -141,8 +214,22 @@ class Prime
141
214
  generator.each(&block)
142
215
  end
143
216
 
217
+ # Returns true if +obj+ is an Integer and is prime. Also returns
218
+ # true if +obj+ is a Module that is an ancestor of +Prime+.
219
+ # Otherwise returns false.
220
+ def include?(obj)
221
+ case obj
222
+ when Integer
223
+ prime?(obj)
224
+ when Module
225
+ Module.instance_method(:include?).bind(Prime).call(obj)
226
+ else
227
+ false
228
+ end
229
+ end
144
230
 
145
231
  # Returns true if +value+ is a prime number, else returns false.
232
+ # Integer#prime? is much more performant.
146
233
  #
147
234
  # == Parameters
148
235
  #
@@ -161,17 +248,23 @@ class Prime
161
248
 
162
249
  # Re-composes a prime factorization and returns the product.
163
250
  #
251
+ # For the decomposition:
252
+ #
253
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]],
254
+ #
255
+ # it returns:
256
+ #
257
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n.
258
+ #
164
259
  # == Parameters
165
- # +pd+:: Array of pairs of integers. The each internal
166
- # pair consists of a prime number -- a prime factor --
167
- # and a natural number -- an exponent.
260
+ # +pd+:: Array of pairs of integers.
261
+ # Each pair consists of a prime number -- a prime factor --
262
+ # and a natural number -- its exponent (multiplicity).
168
263
  #
169
264
  # == Example
170
- # For <tt>[[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]]</tt>, it returns:
171
- #
172
- # p_1**e_1 * p_2**e_2 * .... * p_n**e_n.
265
+ # Prime.int_from_prime_division([[3, 2], [5, 1]]) #=> 45
266
+ # 3**2 * 5 #=> 45
173
267
  #
174
- # Prime.int_from_prime_division([[2,2], [3,1]]) #=> 12
175
268
  def int_from_prime_division(pd)
176
269
  pd.inject(1){|value, (prime, index)|
177
270
  value * prime**index
@@ -180,27 +273,32 @@ class Prime
180
273
 
181
274
  # Returns the factorization of +value+.
182
275
  #
276
+ # For an arbitrary integer:
277
+ #
278
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n,
279
+ #
280
+ # prime_division returns an array of pairs of integers:
281
+ #
282
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]].
283
+ #
284
+ # Each pair consists of a prime number -- a prime factor --
285
+ # and a natural number -- its exponent (multiplicity).
286
+ #
183
287
  # == Parameters
184
288
  # +value+:: An arbitrary integer.
185
289
  # +generator+:: Optional. A pseudo-prime generator.
186
290
  # +generator+.succ must return the next
187
- # pseudo-prime number in the ascending
188
- # order. It must generate all prime numbers,
189
- # but may also generate non prime numbers too.
291
+ # pseudo-prime number in ascending order.
292
+ # It must generate all prime numbers,
293
+ # but may also generate non-prime numbers, too.
190
294
  #
191
295
  # === Exceptions
192
296
  # +ZeroDivisionError+:: when +value+ is zero.
193
297
  #
194
298
  # == Example
195
- # For an arbitrary integer:
196
- #
197
- # n = p_1**e_1 * p_2**e_2 * .... * p_n**e_n,
198
- #
199
- # prime_division(n) returns:
200
- #
201
- # [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].
202
299
  #
203
- # Prime.prime_division(12) #=> [[2,2], [3,1]]
300
+ # Prime.prime_division(45) #=> [[3, 2], [5, 1]]
301
+ # 3**2 * 5 #=> 45
204
302
  #
205
303
  def prime_division(value, generator = Prime::Generator23.new)
206
304
  raise ZeroDivisionError if value == 0
@@ -283,9 +381,9 @@ class Prime
283
381
  end
284
382
 
285
383
  # see +Enumerator+#with_index.
286
- def with_index(offset = 0)
287
- return enum_for(:with_index, offset) { Float::INFINITY } unless block_given?
288
- return each_with_index(&proc) if offset == 0
384
+ def with_index(offset = 0, &block)
385
+ return enum_for(:with_index, offset) { Float::INFINITY } unless block
386
+ return each_with_index(&block) if offset == 0
289
387
 
290
388
  each do |prime|
291
389
  yield prime, offset
data/prime.gemspec CHANGED
@@ -8,20 +8,21 @@ end
8
8
  Gem::Specification.new do |spec|
9
9
  spec.name = "prime"
10
10
  spec.version = Prime::VERSION
11
- spec.authors = ["Yuki Sonoda"]
12
- spec.email = ["yugui@yugui.jp"]
11
+ spec.authors = ["Marc-Andre Lafortune"]
12
+ spec.email = ["ruby-core@marc-andre.ca"]
13
13
 
14
14
  spec.summary = %q{Prime numbers and factorization library.}
15
15
  spec.description = %q{Prime numbers and factorization library.}
16
16
  spec.homepage = "https://github.com/ruby/prime"
17
- spec.license = "BSD-2-Clause"
17
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
18
18
 
19
- spec.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/prime.rb", "prime.gemspec"]
19
+ spec.files = ["BSDL", "COPYING", "README.md", "Rakefile", "lib/prime.rb", "prime.gemspec", "sig/integer-extension.rbs", "sig/manifest.yaml", "sig/prime.rbs"]
20
20
  spec.bindir = "exe"
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_development_dependency "bundler"
25
- spec.add_development_dependency "rake"
26
- spec.add_development_dependency "test-unit"
24
+ spec.required_ruby_version = ">= 2.5.0"
25
+
26
+ spec.add_dependency "singleton"
27
+ spec.add_dependency "forwardable"
27
28
  end
@@ -0,0 +1,41 @@
1
+ %a{annotate:rdoc:skip}
2
+ class Integer
3
+ # <!--
4
+ # rdoc-file=lib/prime.rb
5
+ # - each_prime(ubound) { |prime| ... }
6
+ # -->
7
+ # Iterates the given block over all prime numbers.
8
+ #
9
+ # See `Prime`#each for more details.
10
+ #
11
+ def self.each_prime: (Integer) { (Integer) -> void } -> void
12
+
13
+ # <!--
14
+ # rdoc-file=lib/prime.rb
15
+ # - from_prime_division(pd)
16
+ # -->
17
+ # Re-composes a prime factorization and returns the product.
18
+ #
19
+ # See Prime#int_from_prime_division for more details.
20
+ #
21
+ def self.from_prime_division: (Array[[ String ]]) -> Integer
22
+
23
+ # <!--
24
+ # rdoc-file=lib/prime.rb
25
+ # - prime_division(generator = Prime::Generator23.new)
26
+ # -->
27
+ # Returns the factorization of `self`.
28
+ #
29
+ # See Prime#prime_division for more details.
30
+ #
31
+ def prime_division: (?Prime::PseudoPrimeGenerator) -> Array[[ Integer, Integer ]]
32
+
33
+ # <!--
34
+ # rdoc-file=lib/prime.rb
35
+ # - prime?()
36
+ # -->
37
+ # Returns true if `self` is a prime number, else returns false. Not recommended
38
+ # for very big integers (> 10**23).
39
+ #
40
+ def prime?: () -> bool
41
+ end
data/sig/manifest.yaml ADDED
@@ -0,0 +1,2 @@
1
+ dependencies:
2
+ - name: singleton
data/sig/prime.rbs ADDED
@@ -0,0 +1,372 @@
1
+ # <!-- rdoc-file=lib/prime.rb -->
2
+ # The set of all prime numbers.
3
+ #
4
+ # ## Example
5
+ #
6
+ # Prime.each(100) do |prime|
7
+ # p prime #=> 2, 3, 5, 7, 11, ...., 97
8
+ # end
9
+ #
10
+ # Prime is Enumerable:
11
+ #
12
+ # Prime.first 5 # => [2, 3, 5, 7, 11]
13
+ #
14
+ # ## Retrieving the instance
15
+ #
16
+ # For convenience, each instance method of `Prime`.instance can be accessed as a
17
+ # class method of `Prime`.
18
+ #
19
+ # e.g.
20
+ # Prime.instance.prime?(2) #=> true
21
+ # Prime.prime?(2) #=> true
22
+ #
23
+ # ## Generators
24
+ #
25
+ # A "generator" provides an implementation of enumerating pseudo-prime numbers
26
+ # and it remembers the position of enumeration and upper bound. Furthermore, it
27
+ # is an external iterator of prime enumeration which is compatible with an
28
+ # Enumerator.
29
+ #
30
+ # `Prime`::`PseudoPrimeGenerator` is the base class for generators. There are
31
+ # few implementations of generator.
32
+ #
33
+ # `Prime`::`EratosthenesGenerator`
34
+ # : Uses Eratosthenes' sieve.
35
+ # `Prime`::`TrialDivisionGenerator`
36
+ # : Uses the trial division method.
37
+ # `Prime`::`Generator23`
38
+ # : Generates all positive integers which are not divisible by either 2 or 3.
39
+ # This sequence is very bad as a pseudo-prime sequence. But this is faster
40
+ # and uses much less memory than the other generators. So, it is suitable
41
+ # for factorizing an integer which is not large but has many prime factors.
42
+ # e.g. for Prime#prime? .
43
+ #
44
+ class Prime
45
+ include Singleton
46
+
47
+ include Enumerable[Integer]
48
+
49
+ extend Enumerable[Integer]
50
+
51
+ # <!--
52
+ # rdoc-file=lib/prime.rb
53
+ # - each(ubound = nil, generator = EratosthenesGenerator.new, &block)
54
+ # -->
55
+ # Iterates the given block over all prime numbers.
56
+ #
57
+ # ## Parameters
58
+ #
59
+ # `ubound`
60
+ # : Optional. An arbitrary positive number. The upper bound of enumeration.
61
+ # The method enumerates prime numbers infinitely if `ubound` is nil.
62
+ # `generator`
63
+ # : Optional. An implementation of pseudo-prime generator.
64
+ #
65
+ #
66
+ # ## Return value
67
+ #
68
+ # An evaluated value of the given block at the last time. Or an enumerator which
69
+ # is compatible to an `Enumerator` if no block given.
70
+ #
71
+ # ## Description
72
+ #
73
+ # Calls `block` once for each prime number, passing the prime as a parameter.
74
+ #
75
+ # `ubound`
76
+ # : Upper bound of prime numbers. The iterator stops after it yields all prime
77
+ # numbers p <= `ubound`.
78
+ #
79
+ def self.each: (?Integer? ubound, ?PseudoPrimeGenerator generator) { (Integer) -> void } -> void
80
+ | (?Integer? ubound, ?PseudoPrimeGenerator generator) -> PseudoPrimeGenerator
81
+
82
+ # <!--
83
+ # rdoc-file=lib/prime.rb
84
+ # - each(ubound = nil, generator = EratosthenesGenerator.new, &block)
85
+ # -->
86
+ # Iterates the given block over all prime numbers.
87
+ #
88
+ # ## Parameters
89
+ #
90
+ # `ubound`
91
+ # : Optional. An arbitrary positive number. The upper bound of enumeration.
92
+ # The method enumerates prime numbers infinitely if `ubound` is nil.
93
+ # `generator`
94
+ # : Optional. An implementation of pseudo-prime generator.
95
+ #
96
+ #
97
+ # ## Return value
98
+ #
99
+ # An evaluated value of the given block at the last time. Or an enumerator which
100
+ # is compatible to an `Enumerator` if no block given.
101
+ #
102
+ # ## Description
103
+ #
104
+ # Calls `block` once for each prime number, passing the prime as a parameter.
105
+ #
106
+ # `ubound`
107
+ # : Upper bound of prime numbers. The iterator stops after it yields all prime
108
+ # numbers p <= `ubound`.
109
+ #
110
+ def each: (?Integer? ubound, ?PseudoPrimeGenerator generator) { (Integer) -> void } -> void
111
+ | (?Integer? ubound, ?PseudoPrimeGenerator generator) -> PseudoPrimeGenerator
112
+
113
+ # <!--
114
+ # rdoc-file=lib/prime.rb
115
+ # - int_from_prime_division(pd)
116
+ # -->
117
+ # Re-composes a prime factorization and returns the product.
118
+ #
119
+ # For the decomposition:
120
+ #
121
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]],
122
+ #
123
+ # it returns:
124
+ #
125
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n.
126
+ #
127
+ # ## Parameters
128
+ # `pd`
129
+ # : Array of pairs of integers. Each pair consists of a prime number -- a
130
+ # prime factor -- and a natural number -- its exponent (multiplicity).
131
+ #
132
+ #
133
+ # ## Example
134
+ # Prime.int_from_prime_division([[3, 2], [5, 1]]) #=> 45
135
+ # 3**2 * 5 #=> 45
136
+ #
137
+ def self.int_from_prime_division: (Array[[ Integer, Integer ]]) -> (Integer | Rational)
138
+
139
+ # <!--
140
+ # rdoc-file=lib/prime.rb
141
+ # - int_from_prime_division(pd)
142
+ # -->
143
+ # Re-composes a prime factorization and returns the product.
144
+ #
145
+ # For the decomposition:
146
+ #
147
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]],
148
+ #
149
+ # it returns:
150
+ #
151
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n.
152
+ #
153
+ # ## Parameters
154
+ # `pd`
155
+ # : Array of pairs of integers. Each pair consists of a prime number -- a
156
+ # prime factor -- and a natural number -- its exponent (multiplicity).
157
+ #
158
+ #
159
+ # ## Example
160
+ # Prime.int_from_prime_division([[3, 2], [5, 1]]) #=> 45
161
+ # 3**2 * 5 #=> 45
162
+ #
163
+ def int_from_prime_division: (Array[[ Integer, Integer ]]) -> (Integer | Rational)
164
+
165
+ # <!--
166
+ # rdoc-file=lib/prime.rb
167
+ # - prime?(value, generator = Prime::Generator23.new)
168
+ # -->
169
+ # Returns true if `value` is a prime number, else returns false. Integer#prime?
170
+ # is much more performant.
171
+ #
172
+ # ## Parameters
173
+ #
174
+ # `value`
175
+ # : an arbitrary integer to be checked.
176
+ # `generator`
177
+ # : optional. A pseudo-prime generator.
178
+ #
179
+ def self.prime?: (Integer value, ?PseudoPrimeGenerator generator) -> bool
180
+
181
+ # <!--
182
+ # rdoc-file=lib/prime.rb
183
+ # - prime?(value, generator = Prime::Generator23.new)
184
+ # -->
185
+ # Returns true if `value` is a prime number, else returns false. Integer#prime?
186
+ # is much more performant.
187
+ #
188
+ # ## Parameters
189
+ #
190
+ # `value`
191
+ # : an arbitrary integer to be checked.
192
+ # `generator`
193
+ # : optional. A pseudo-prime generator.
194
+ #
195
+ def prime?: (Integer value, ?PseudoPrimeGenerator generator) -> bool
196
+
197
+ # <!--
198
+ # rdoc-file=lib/prime.rb
199
+ # - prime_division(value, generator = Prime::Generator23.new)
200
+ # -->
201
+ # Returns the factorization of `value`.
202
+ #
203
+ # For an arbitrary integer:
204
+ #
205
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n,
206
+ #
207
+ # prime_division returns an array of pairs of integers:
208
+ #
209
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]].
210
+ #
211
+ # Each pair consists of a prime number -- a prime factor -- and a natural number
212
+ # -- its exponent (multiplicity).
213
+ #
214
+ # ## Parameters
215
+ # `value`
216
+ # : An arbitrary integer.
217
+ # `generator`
218
+ # : Optional. A pseudo-prime generator. `generator`.succ must return the next
219
+ # pseudo-prime number in ascending order. It must generate all prime
220
+ # numbers, but may also generate non-prime numbers, too.
221
+ #
222
+ #
223
+ # ### Exceptions
224
+ # `ZeroDivisionError`
225
+ # : when `value` is zero.
226
+ #
227
+ #
228
+ # ## Example
229
+ #
230
+ # Prime.prime_division(45) #=> [[3, 2], [5, 1]]
231
+ # 3**2 * 5 #=> 45
232
+ #
233
+ def self.prime_division: (Integer, ?PseudoPrimeGenerator generator) -> Array[[ Integer, Integer ]]
234
+
235
+ # <!--
236
+ # rdoc-file=lib/prime.rb
237
+ # - prime_division(value, generator = Prime::Generator23.new)
238
+ # -->
239
+ # Returns the factorization of `value`.
240
+ #
241
+ # For an arbitrary integer:
242
+ #
243
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n,
244
+ #
245
+ # prime_division returns an array of pairs of integers:
246
+ #
247
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]].
248
+ #
249
+ # Each pair consists of a prime number -- a prime factor -- and a natural number
250
+ # -- its exponent (multiplicity).
251
+ #
252
+ # ## Parameters
253
+ # `value`
254
+ # : An arbitrary integer.
255
+ # `generator`
256
+ # : Optional. A pseudo-prime generator. `generator`.succ must return the next
257
+ # pseudo-prime number in ascending order. It must generate all prime
258
+ # numbers, but may also generate non-prime numbers, too.
259
+ #
260
+ #
261
+ # ### Exceptions
262
+ # `ZeroDivisionError`
263
+ # : when `value` is zero.
264
+ #
265
+ #
266
+ # ## Example
267
+ #
268
+ # Prime.prime_division(45) #=> [[3, 2], [5, 1]]
269
+ # 3**2 * 5 #=> 45
270
+ #
271
+ def prime_division: (Integer, ?PseudoPrimeGenerator generator) -> Array[[ Integer, Integer ]]
272
+
273
+ # Returns the singleton instance.
274
+ #
275
+ def self.instance: () -> Prime
276
+
277
+ # <!-- rdoc-file=lib/prime.rb -->
278
+ # An abstract class for enumerating pseudo-prime numbers.
279
+ #
280
+ # Concrete subclasses should override succ, next, rewind.
281
+ #
282
+ class PseudoPrimeGenerator
283
+ # <!--
284
+ # rdoc-file=lib/prime.rb
285
+ # - new(ubound = nil)
286
+ # -->
287
+ #
288
+ def initialize: (?Integer?) -> void
289
+
290
+ include Enumerable[Integer]
291
+
292
+ # <!--
293
+ # rdoc-file=lib/prime.rb
294
+ # - upper_bound()
295
+ # -->
296
+ # ----
297
+ # <!--
298
+ # rdoc-file=lib/prime.rb
299
+ # - upper_bound=(ubound)
300
+ # -->
301
+ #
302
+ attr_accessor upper_bound(): Integer?
303
+
304
+ # <!--
305
+ # rdoc-file=lib/prime.rb
306
+ # - each() { |prime| ... }
307
+ # -->
308
+ # Iterates the given block for each prime number.
309
+ #
310
+ def each: () { (Integer) -> void } -> void
311
+
312
+ # <!--
313
+ # rdoc-file=lib/prime.rb
314
+ # - next()
315
+ # -->
316
+ # alias of `succ`.
317
+ #
318
+ def next: () -> Integer
319
+
320
+ # <!--
321
+ # rdoc-file=lib/prime.rb
322
+ # - rewind()
323
+ # -->
324
+ # Rewinds the internal position for enumeration.
325
+ #
326
+ # See `Enumerator`#rewind.
327
+ #
328
+ def rewind: () -> void
329
+
330
+ # <!--
331
+ # rdoc-file=lib/prime.rb
332
+ # - size()
333
+ # -->
334
+ #
335
+ def size: () -> Float
336
+
337
+ # <!--
338
+ # rdoc-file=lib/prime.rb
339
+ # - succ()
340
+ # -->
341
+ # returns the next pseudo-prime number, and move the internal position forward.
342
+ #
343
+ # `PseudoPrimeGenerator`#succ raises `NotImplementedError`.
344
+ #
345
+ def succ: () -> Integer
346
+ end
347
+
348
+ # <!-- rdoc-file=lib/prime.rb -->
349
+ # An implementation of `PseudoPrimeGenerator`.
350
+ #
351
+ # Uses `EratosthenesSieve`.
352
+ #
353
+ class EratosthenesGenerator < PseudoPrimeGenerator
354
+ end
355
+
356
+ # <!-- rdoc-file=lib/prime.rb -->
357
+ # An implementation of `PseudoPrimeGenerator` which uses a prime table generated
358
+ # by trial division.
359
+ #
360
+ class TrialDivisionGenerator < PseudoPrimeGenerator
361
+ end
362
+
363
+ # <!-- rdoc-file=lib/prime.rb -->
364
+ # Generates all integers which are greater than 2 and are not divisible by
365
+ # either 2 or 3.
366
+ #
367
+ # This is a pseudo-prime generator, suitable on checking primality of an integer
368
+ # by brute force method.
369
+ #
370
+ class Generator23 < PseudoPrimeGenerator
371
+ end
372
+ end
metadata CHANGED
@@ -1,23 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
- - Yuki Sonoda
7
+ - Marc-Andre Lafortune
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-01 00:00:00.000000000 Z
11
+ date: 2024-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: singleton
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
- type: :development
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
@@ -25,27 +25,13 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: forwardable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: test-unit
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
34
+ type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
@@ -54,23 +40,23 @@ dependencies:
54
40
  version: '0'
55
41
  description: Prime numbers and factorization library.
56
42
  email:
57
- - yugui@yugui.jp
43
+ - ruby-core@marc-andre.ca
58
44
  executables: []
59
45
  extensions: []
60
46
  extra_rdoc_files: []
61
47
  files:
62
- - ".gitignore"
63
- - ".travis.yml"
64
- - Gemfile
65
- - LICENSE.txt
48
+ - BSDL
49
+ - COPYING
66
50
  - README.md
67
51
  - Rakefile
68
- - bin/console
69
- - bin/setup
70
52
  - lib/prime.rb
71
53
  - prime.gemspec
54
+ - sig/integer-extension.rbs
55
+ - sig/manifest.yaml
56
+ - sig/prime.rbs
72
57
  homepage: https://github.com/ruby/prime
73
58
  licenses:
59
+ - Ruby
74
60
  - BSD-2-Clause
75
61
  metadata: {}
76
62
  post_install_message:
@@ -81,14 +67,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
67
  requirements:
82
68
  - - ">="
83
69
  - !ruby/object:Gem::Version
84
- version: '0'
70
+ version: 2.5.0
85
71
  required_rubygems_version: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
88
74
  - !ruby/object:Gem::Version
89
75
  version: '0'
90
76
  requirements: []
91
- rubygems_version: 3.2.0.pre1
77
+ rubygems_version: 3.5.11
92
78
  signing_key:
93
79
  specification_version: 4
94
80
  summary: Prime numbers and factorization library.
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- Gemfile.lock
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.5.1
5
- - ruby-head
6
- before_install: gem install bundler -v 1.16.2
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in prime.gemspec
6
- gemspec
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "prime"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here