summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi SHIBATA <[email protected]>2021-05-26 15:33:42 +0900
committerHiroshi SHIBATA <[email protected]>2021-05-27 14:42:11 +0900
commitc9178c11271ccd3410c53687dd9cb2508e180a98 (patch)
treec0c0d1888e17e7f0dfe2e07ae2c8db4261c38e55
parenteae7fd0ea3081378ee20ad76eee08e9301fbd638 (diff)
Promote prime to the bundled gems
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4530
-rw-r--r--doc/maintainers.rdoc6
-rw-r--r--doc/standard_library.rdoc2
-rw-r--r--gems/bundled_gems1
-rw-r--r--lib/prime.gemspec28
-rw-r--r--lib/prime.rb561
-rw-r--r--test/test_prime.rb298
-rw-r--r--tool/sync_default_gems.rb1
7 files changed, 4 insertions, 893 deletions
diff --git a/doc/maintainers.rdoc b/doc/maintainers.rdoc
index 975f4d4091..805fbc227b 100644
--- a/doc/maintainers.rdoc
+++ b/doc/maintainers.rdoc
@@ -205,10 +205,6 @@ Yukihiro Matsumoto (matz)
Tanaka Akira (akr)
https://github.com/ruby/prettyprint
https://rubygems.org/gems/prettyprint
-[lib/prime.rb]
- Marc-André Lafortune (marcandre)
- https://github.com/ruby/prime
- https://rubygems.org/gems/prime
[lib/pstore.rb]
_unmaintained_
https://github.com/ruby/pstore
@@ -399,6 +395,8 @@ Yukihiro Matsumoto (matz)
https://github.com/ruby/rexml
[rss]
https://github.com/ruby/rss
+[prime]
+ https://github.com/ruby/prime
[rbs]
https://github.com/ruby/rbs
[typeprof]
diff --git a/doc/standard_library.rdoc b/doc/standard_library.rdoc
index 127ba76d31..28dedcb24f 100644
--- a/doc/standard_library.rdoc
+++ b/doc/standard_library.rdoc
@@ -58,7 +58,6 @@ OpenStruct:: Class to build custom data structures, similar to a Hash
OpenURI:: An easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP
PP:: Provides a PrettyPrinter for Ruby objects
PrettyPrinter:: Implements a pretty printing algorithm for readable structure
-Prime:: Prime numbers and factorization library
PStore:: Implements a file based persistence mechanism based on a Hash
Resolv:: Thread-aware DNS resolver library in Ruby
resolv-replace.rb:: Replace Socket DNS with Resolv
@@ -111,5 +110,6 @@ Rake:: Ruby build program with capabilities similar to make
Test::Unit:: A compatibility layer for MiniTest
REXML:: An XML toolkit for Ruby
RSS:: Family of libraries that support various formats of XML "feeds"
+Prime:: Prime numbers and factorization library
RBS:: RBS is a language to describe the structure of Ruby programs
TypeProf:: A type analysis tool for Ruby code based on abstract interpretation
diff --git a/gems/bundled_gems b/gems/bundled_gems
index c7f79fbb92..982faeb8f0 100644
--- a/gems/bundled_gems
+++ b/gems/bundled_gems
@@ -5,5 +5,6 @@ rake 13.0.3 https://github.com/ruby/rake
test-unit 3.4.1 https://github.com/test-unit/test-unit 3.4.1
rexml 3.2.5 https://github.com/ruby/rexml
rss 0.2.9 https://github.com/ruby/rss 0.2.9
+prime 0.1.2 https://github.com/ruby/prime
typeprof 0.14.1 https://github.com/ruby/typeprof
rbs 1.2.0 https://github.com/ruby/rbs
diff --git a/lib/prime.gemspec b/lib/prime.gemspec
deleted file mode 100644
index 8369d4d3d5..0000000000
--- a/lib/prime.gemspec
+++ /dev/null
@@ -1,28 +0,0 @@
-begin
- require_relative "lib/prime"
-rescue LoadError
- # for Ruby core repository
- require_relative "prime"
-end
-
-Gem::Specification.new do |spec|
- spec.name = "prime"
- spec.version = Prime::VERSION
- spec.authors = ["Marc-Andre Lafortune"]
- spec.email = ["[email protected]"]
-
- spec.summary = %q{Prime numbers and factorization library.}
- spec.description = %q{Prime numbers and factorization library.}
- spec.homepage = "https://github.com/ruby/prime"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/prime.rb", "prime.gemspec"]
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
-
- spec.required_ruby_version = ">= 2.5.0"
-
- spec.add_dependency "singleton"
- spec.add_dependency "forwardable"
-end
diff --git a/lib/prime.rb b/lib/prime.rb
deleted file mode 100644
index fd9d6ac7be..0000000000
--- a/lib/prime.rb
+++ /dev/null
@@ -1,561 +0,0 @@
-# frozen_string_literal: false
-#
-# = prime.rb
-#
-# Prime numbers and factorization library.
-#
-# Copyright::
-# Copyright (c) 1998-2008 Keiju ISHITSUKA(SHL Japan Inc.)
-# Copyright (c) 2008 Yuki Sonoda (Yugui) <[email protected]>
-#
-# Documentation::
-# Yuki Sonoda
-#
-
-require "singleton"
-require "forwardable"
-
-class Integer
- # Re-composes a prime factorization and returns the product.
- #
- # See Prime#int_from_prime_division for more details.
- def Integer.from_prime_division(pd)
- Prime.int_from_prime_division(pd)
- end
-
- # Returns the factorization of +self+.
- #
- # See Prime#prime_division for more details.
- def prime_division(generator = Prime::Generator23.new)
- Prime.prime_division(self, generator)
- end
-
- # Returns true if +self+ is a prime number, else returns false.
- # Not recommended for very big integers (> 10**23).
- def prime?
- return self >= 2 if self <= 3
-
- if (bases = miller_rabin_bases)
- return miller_rabin_test(bases)
- end
-
- return true if self == 5
- return false unless 30.gcd(self) == 1
- (7..Integer.sqrt(self)).step(30) do |p|
- return false if
- self%(p) == 0 || self%(p+4) == 0 || self%(p+6) == 0 || self%(p+10) == 0 ||
- self%(p+12) == 0 || self%(p+16) == 0 || self%(p+22) == 0 || self%(p+24) == 0
- end
- true
- end
-
- MILLER_RABIN_BASES = [
- [2],
- [2,3],
- [31,73],
- [2,3,5],
- [2,3,5,7],
- [2,7,61],
- [2,13,23,1662803],
- [2,3,5,7,11],
- [2,3,5,7,11,13],
- [2,3,5,7,11,13,17],
- [2,3,5,7,11,13,17,19,23],
- [2,3,5,7,11,13,17,19,23,29,31,37],
- [2,3,5,7,11,13,17,19,23,29,31,37,41],
- ].map!(&:freeze).freeze
- private_constant :MILLER_RABIN_BASES
-
- private def miller_rabin_bases
- # Miller-Rabin's complexity is O(k log^3n).
- # So we can reduce the complexity by reducing the number of bases tested.
- # Using values from https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
- i = case
- when self < 0xffff then
- # For small integers, Miller Rabin can be slower
- # There is no mathematical significance to 0xffff
- return nil
- # when self < 2_047 then 0
- when self < 1_373_653 then 1
- when self < 9_080_191 then 2
- when self < 25_326_001 then 3
- when self < 3_215_031_751 then 4
- when self < 4_759_123_141 then 5
- when self < 1_122_004_669_633 then 6
- when self < 2_152_302_898_747 then 7
- when self < 3_474_749_660_383 then 8
- when self < 341_550_071_728_321 then 9
- when self < 3_825_123_056_546_413_051 then 10
- when self < 318_665_857_834_031_151_167_461 then 11
- when self < 3_317_044_064_679_887_385_961_981 then 12
- else return nil
- end
- MILLER_RABIN_BASES[i]
- end
-
- private def miller_rabin_test(bases)
- return false if even?
-
- r = 0
- d = self >> 1
- while d.even?
- d >>= 1
- r += 1
- end
-
- self_minus_1 = self-1
- bases.each do |a|
- x = a.pow(d, self)
- next if x == 1 || x == self_minus_1 || a == self
-
- return false if r.times do
- x = x.pow(2, self)
- break if x == self_minus_1
- end
- end
- true
- end
-
- # Iterates the given block over all prime numbers.
- #
- # See +Prime+#each for more details.
- def Integer.each_prime(ubound, &block) # :yields: prime
- Prime.each(ubound, &block)
- end
-end
-
-#
-# The set of all prime numbers.
-#
-# == Example
-#
-# Prime.each(100) do |prime|
-# p prime #=> 2, 3, 5, 7, 11, ...., 97
-# end
-#
-# Prime is Enumerable:
-#
-# Prime.first 5 # => [2, 3, 5, 7, 11]
-#
-# == Retrieving the instance
-#
-# For convenience, each instance method of +Prime+.instance can be accessed
-# as a class method of +Prime+.
-#
-# e.g.
-# Prime.instance.prime?(2) #=> true
-# Prime.prime?(2) #=> true
-#
-# == Generators
-#
-# A "generator" provides an implementation of enumerating pseudo-prime
-# numbers and it remembers the position of enumeration and upper bound.
-# Furthermore, it is an external iterator of prime enumeration which is
-# compatible with an Enumerator.
-#
-# +Prime+::+PseudoPrimeGenerator+ is the base class for generators.
-# There are few implementations of generator.
-#
-# [+Prime+::+EratosthenesGenerator+]
-# Uses Eratosthenes' sieve.
-# [+Prime+::+TrialDivisionGenerator+]
-# Uses the trial division method.
-# [+Prime+::+Generator23+]
-# Generates all positive integers which are not divisible by either 2 or 3.
-# This sequence is very bad as a pseudo-prime sequence. But this
-# is faster and uses much less memory than the other generators. So,
-# it is suitable for factorizing an integer which is not large but
-# has many prime factors. e.g. for Prime#prime? .
-
-class Prime
-
- VERSION = "0.1.2"
-
- include Enumerable
- include Singleton
-
- class << self
- extend Forwardable
- include Enumerable
-
- def method_added(method) # :nodoc:
- (class<< self;self;end).def_delegator :instance, method
- end
- end
-
- # Iterates the given block over all prime numbers.
- #
- # == Parameters
- #
- # +ubound+::
- # Optional. An arbitrary positive number.
- # The upper bound of enumeration. The method enumerates
- # prime numbers infinitely if +ubound+ is nil.
- # +generator+::
- # Optional. An implementation of pseudo-prime generator.
- #
- # == Return value
- #
- # An evaluated value of the given block at the last time.
- # Or an enumerator which is compatible to an +Enumerator+
- # if no block given.
- #
- # == Description
- #
- # Calls +block+ once for each prime number, passing the prime as
- # a parameter.
- #
- # +ubound+::
- # Upper bound of prime numbers. The iterator stops after it
- # yields all prime numbers p <= +ubound+.
- #
- def each(ubound = nil, generator = EratosthenesGenerator.new, &block)
- generator.upper_bound = ubound
- generator.each(&block)
- end
-
- # Returns true if +obj+ is an Integer and is prime. Also returns
- # true if +obj+ is a Module that is an ancestor of +Prime+.
- # Otherwise returns false.
- def include?(obj)
- case obj
- when Integer
- prime?(obj)
- when Module
- Module.instance_method(:include?).bind(Prime).call(obj)
- else
- false
- end
- end
-
- # Returns true if +value+ is a prime number, else returns false.
- # Integer#prime? is much more performant.
- #
- # == Parameters
- #
- # +value+:: an arbitrary integer to be checked.
- # +generator+:: optional. A pseudo-prime generator.
- def prime?(value, generator = Prime::Generator23.new)
- raise ArgumentError, "Expected a prime generator, got #{generator}" unless generator.respond_to? :each
- raise ArgumentError, "Expected an integer, got #{value}" unless value.respond_to?(:integer?) && value.integer?
- return false if value < 2
- generator.each do |num|
- q,r = value.divmod num
- return true if q < num
- return false if r == 0
- end
- end
-
- # Re-composes a prime factorization and returns the product.
- #
- # For the decomposition:
- #
- # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]],
- #
- # it returns:
- #
- # p_1**e_1 * p_2**e_2 * ... * p_n**e_n.
- #
- # == Parameters
- # +pd+:: Array of pairs of integers.
- # Each pair consists of a prime number -- a prime factor --
- # and a natural number -- its exponent (multiplicity).
- #
- # == Example
- # Prime.int_from_prime_division([[3, 2], [5, 1]]) #=> 45
- # 3**2 * 5 #=> 45
- #
- def int_from_prime_division(pd)
- pd.inject(1){|value, (prime, index)|
- value * prime**index
- }
- end
-
- # Returns the factorization of +value+.
- #
- # For an arbitrary integer:
- #
- # p_1**e_1 * p_2**e_2 * ... * p_n**e_n,
- #
- # prime_division returns an array of pairs of integers:
- #
- # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]].
- #
- # Each pair consists of a prime number -- a prime factor --
- # and a natural number -- its exponent (multiplicity).
- #
- # == Parameters
- # +value+:: An arbitrary integer.
- # +generator+:: Optional. A pseudo-prime generator.
- # +generator+.succ must return the next
- # pseudo-prime number in ascending order.
- # It must generate all prime numbers,
- # but may also generate non-prime numbers, too.
- #
- # === Exceptions
- # +ZeroDivisionError+:: when +value+ is zero.
- #
- # == Example
- #
- # Prime.prime_division(45) #=> [[3, 2], [5, 1]]
- # 3**2 * 5 #=> 45
- #
- def prime_division(value, generator = Prime::Generator23.new)
- raise ZeroDivisionError if value == 0
- if value < 0
- value = -value
- pv = [[-1, 1]]
- else
- pv = []
- end
- generator.each do |prime|
- count = 0
- while (value1, mod = value.divmod(prime)
- mod) == 0
- value = value1
- count += 1
- end
- if count != 0
- pv.push [prime, count]
- end
- break if value1 <= prime
- end
- if value > 1
- pv.push [value, 1]
- end
- pv
- end
-
- # An abstract class for enumerating pseudo-prime numbers.
- #
- # Concrete subclasses should override succ, next, rewind.
- class PseudoPrimeGenerator
- include Enumerable
-
- def initialize(ubound = nil)
- @ubound = ubound
- end
-
- def upper_bound=(ubound)
- @ubound = ubound
- end
- def upper_bound
- @ubound
- end
-
- # returns the next pseudo-prime number, and move the internal
- # position forward.
- #
- # +PseudoPrimeGenerator+#succ raises +NotImplementedError+.
- def succ
- raise NotImplementedError, "need to define `succ'"
- end
-
- # alias of +succ+.
- def next
- raise NotImplementedError, "need to define `next'"
- end
-
- # Rewinds the internal position for enumeration.
- #
- # See +Enumerator+#rewind.
- def rewind
- raise NotImplementedError, "need to define `rewind'"
- end
-
- # Iterates the given block for each prime number.
- def each
- return self.dup unless block_given?
- if @ubound
- last_value = nil
- loop do
- prime = succ
- break last_value if prime > @ubound
- last_value = yield prime
- end
- else
- loop do
- yield succ
- end
- end
- end
-
- # see +Enumerator+#with_index.
- def with_index(offset = 0, &block)
- return enum_for(:with_index, offset) { Float::INFINITY } unless block
- return each_with_index(&block) if offset == 0
-
- each do |prime|
- yield prime, offset
- offset += 1
- end
- end
-
- # see +Enumerator+#with_object.
- def with_object(obj)
- return enum_for(:with_object, obj) { Float::INFINITY } unless block_given?
- each do |prime|
- yield prime, obj
- end
- end
-
- def size
- Float::INFINITY
- end
- end
-
- # An implementation of +PseudoPrimeGenerator+.
- #
- # Uses +EratosthenesSieve+.
- class EratosthenesGenerator < PseudoPrimeGenerator
- def initialize
- @last_prime_index = -1
- super
- end
-
- def succ
- @last_prime_index += 1
- EratosthenesSieve.instance.get_nth_prime(@last_prime_index)
- end
- def rewind
- initialize
- end
- alias next succ
- end
-
- # An implementation of +PseudoPrimeGenerator+ which uses
- # a prime table generated by trial division.
- class TrialDivisionGenerator < PseudoPrimeGenerator
- def initialize
- @index = -1
- super
- end
-
- def succ
- TrialDivision.instance[@index += 1]
- end
- def rewind
- initialize
- end
- alias next succ
- end
-
- # Generates all integers which are greater than 2 and
- # are not divisible by either 2 or 3.
- #
- # This is a pseudo-prime generator, suitable on
- # checking primality of an integer by brute force
- # method.
- class Generator23 < PseudoPrimeGenerator
- def initialize
- @prime = 1
- @step = nil
- super
- end
-
- def succ
- if (@step)
- @prime += @step
- @step = 6 - @step
- else
- case @prime
- when 1; @prime = 2
- when 2; @prime = 3
- when 3; @prime = 5; @step = 2
- end
- end
- @prime
- end
- alias next succ
- def rewind
- initialize
- end
- end
-
- # Internal use. An implementation of prime table by trial division method.
- class TrialDivision
- include Singleton
-
- def initialize # :nodoc:
- # These are included as class variables to cache them for later uses. If memory
- # usage is a problem, they can be put in Prime#initialize as instance variables.
-
- # There must be no primes between @primes[-1] and @next_to_check.
- @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]
- # @next_to_check % 6 must be 1.
- @next_to_check = 103 # @primes[-1] - @primes[-1] % 6 + 7
- @ulticheck_index = 3 # @primes.index(@primes.reverse.find {|n|
- # n < Math.sqrt(@@next_to_check) })
- @ulticheck_next_squared = 121 # @primes[@ulticheck_index + 1] ** 2
- end
-
- # Returns the +index+th prime number.
- #
- # +index+ is a 0-based index.
- def [](index)
- while index >= @primes.length
- # Only check for prime factors up to the square root of the potential primes,
- # but without the performance hit of an actual square root calculation.
- if @next_to_check + 4 > @ulticheck_next_squared
- @ulticheck_index += 1
- @ulticheck_next_squared = @primes.at(@ulticheck_index + 1) ** 2
- end
- # Only check numbers congruent to one and five, modulo six. All others
-
- # are divisible by two or three. This also allows us to skip checking against
- # two and three.
- @primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
- @next_to_check += 4
- @primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
- @next_to_check += 2
- end
- @primes[index]
- end
- end
-
- # Internal use. An implementation of Eratosthenes' sieve
- class EratosthenesSieve
- include Singleton
-
- def initialize
- @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]
- # @max_checked must be an even number
- @max_checked = @primes.last + 1
- end
-
- def get_nth_prime(n)
- compute_primes while @primes.size <= n
- @primes[n]
- end
-
- private
- def compute_primes
- # max_segment_size must be an even number
- max_segment_size = 1e6.to_i
- max_cached_prime = @primes.last
- # do not double count primes if #compute_primes is interrupted
- # by Timeout.timeout
- @max_checked = max_cached_prime + 1 if max_cached_prime > @max_checked
-
- segment_min = @max_checked
- segment_max = [segment_min + max_segment_size, max_cached_prime * 2].min
- root = Integer.sqrt(segment_max)
-
- segment = ((segment_min + 1) .. segment_max).step(2).to_a
-
- (1..Float::INFINITY).each do |sieving|
- prime = @primes[sieving]
- break if prime > root
- composite_index = (-(segment_min + 1 + prime) / 2) % prime
- while composite_index < segment.size do
- segment[composite_index] = nil
- composite_index += prime
- end
- end
-
- @primes.concat(segment.compact!)
-
- @max_checked = segment_max
- end
- end
-end
diff --git a/test/test_prime.rb b/test/test_prime.rb
deleted file mode 100644
index a0e8af59be..0000000000
--- a/test/test_prime.rb
+++ /dev/null
@@ -1,298 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'prime'
-require 'timeout'
-
-class TestPrime < Test::Unit::TestCase
- # The first 100 prime numbers
- 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, 107, 109, 113, 127, 131,
- 137, 139, 149, 151, 157, 163, 167, 173, 179,
- 181, 191, 193, 197, 199, 211, 223, 227, 229,
- 233, 239, 241, 251, 257, 263, 269, 271, 277,
- 281, 283, 293, 307, 311, 313, 317, 331, 337,
- 347, 349, 353, 359, 367, 373, 379, 383, 389,
- 397, 401, 409, 419, 421, 431, 433, 439, 443,
- 449, 457, 461, 463, 467, 479, 487, 491, 499,
- 503, 509, 521, 523, 541,
- ]
- def test_each
- primes = []
- Prime.each do |p|
- break if p > 541
- primes << p
- end
- assert_equal PRIMES, primes
- end
-
- def test_include?
- assert_equal(false, Prime.include?(nil))
- assert_equal(true, Prime.include?(3))
- assert_equal(false, Prime.include?(4))
- assert_equal(true, Prime.include?(Enumerable))
- assert_equal(false, Prime.include?(Comparable))
- end
-
- def test_integer_each_prime
- primes = []
- Integer.each_prime(1000) do |p|
- break if p > 541
- primes << p
- end
- assert_equal PRIMES, primes
- end
-
- def test_each_by_prime_number_theorem
- 3.upto(15) do |i|
- max = 2**i
- primes = []
- Prime.each do |p|
- break if p >= max
- primes << p
- end
-
- # Prime number theorem
- assert_operator primes.length, :>=, max/Math.log(max)
- delta = 0.05
- li = (2..max).step(delta).inject(0){|sum,x| sum + delta/Math.log(x)}
- assert_operator primes.length, :<=, li
- end
- end
-
- def test_each_without_block
- enum = Prime.each
- assert_respond_to(enum, :each)
- assert_kind_of(Enumerable, enum)
- assert_respond_to(enum, :with_index)
- assert_respond_to(enum, :next)
- assert_respond_to(enum, :succ)
- assert_respond_to(enum, :rewind)
- end
-
- def test_instance_without_block
- enum = Prime.instance.each
- assert_respond_to(enum, :each)
- assert_kind_of(Enumerable, enum)
- assert_respond_to(enum, :with_index)
- assert_respond_to(enum, :next)
- assert_respond_to(enum, :succ)
- assert_respond_to(enum, :rewind)
- end
-
- def test_new
- assert_raise(NoMethodError) { Prime.new }
- end
-
- def test_enumerator_succ
- enum = Prime.each
- assert_equal PRIMES[0, 50], 50.times.map{ enum.succ }
- assert_equal PRIMES[50, 50], 50.times.map{ enum.succ }
- enum.rewind
- assert_equal PRIMES[0, 100], 100.times.map{ enum.succ }
- end
-
- def test_enumerator_with_index
- enum = Prime.each
- last = -1
- enum.with_index do |p,i|
- break if i >= 100
- assert_equal last+1, i
- assert_equal PRIMES[i], p
- last = i
- end
- end
-
- def test_enumerator_with_index_with_offset
- enum = Prime.each
- last = 5-1
- enum.with_index(5).each do |p,i|
- break if i >= 100+5
- assert_equal last+1, i
- assert_equal PRIMES[i-5], p
- last = i
- end
- end
-
- def test_enumerator_with_object
- object = Object.new
- enum = Prime.each
- enum.with_object(object).each do |p, o|
- assert_equal object, o
- break
- end
- end
-
- def test_enumerator_size
- enum = Prime.each
- assert_equal Float::INFINITY, enum.size
- assert_equal Float::INFINITY, enum.with_object(nil).size
- assert_equal Float::INFINITY, enum.with_index(42).size
- end
-
- def test_default_instance_does_not_have_compatibility_methods
- assert_not_respond_to(Prime.instance, :succ)
- assert_not_respond_to(Prime.instance, :next)
- end
-
- def test_prime_each_basic_argument_checking
- assert_raise(ArgumentError) { Prime.prime?(1,2) }
- assert_raise(ArgumentError) { Prime.prime?(1.2) }
- end
-
- def test_prime?
- assert_equal Prime.prime?(1), false
- assert_equal Prime.prime?(2), true
- assert_equal Prime.prime?(4), false
- end
-
- class TestPseudoPrimeGenerator < Test::Unit::TestCase
- def test_upper_bound
- pseudo_prime_generator = Prime::PseudoPrimeGenerator.new(42)
- assert_equal pseudo_prime_generator.upper_bound, 42
- end
-
- def test_succ
- pseudo_prime_generator = Prime::PseudoPrimeGenerator.new(42)
- assert_raise(NotImplementedError) { pseudo_prime_generator.succ }
- end
-
- def test_next
- pseudo_prime_generator = Prime::PseudoPrimeGenerator.new(42)
- assert_raise(NotImplementedError) { pseudo_prime_generator.next }
- end
-
- def test_rewind
- pseudo_prime_generator = Prime::PseudoPrimeGenerator.new(42)
- assert_raise(NotImplementedError) { pseudo_prime_generator.rewind }
- end
- end
-
- class TestTrialDivisionGenerator < Test::Unit::TestCase
- # The first 100 prime numbers
- 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, 107, 109, 113, 127, 131,
- 137, 139, 149, 151, 157, 163, 167, 173, 179,
- 181, 191, 193, 197, 199, 211, 223, 227, 229,
- 233, 239, 241, 251, 257, 263, 269, 271, 277,
- 281, 283, 293, 307, 311, 313, 317, 331, 337,
- 347, 349, 353, 359, 367, 373, 379, 383, 389,
- 397, 401, 409, 419, 421, 431, 433, 439, 443,
- 449, 457, 461, 463, 467, 479, 487, 491, 499,
- 503, 509, 521, 523, 541,
- ]
-
- def test_each
- primes = []
- Prime.each(nil, Prime::TrialDivisionGenerator.new) do |p|
- break if p > 541
- primes << p
- end
- assert_equal PRIMES, primes
- end
-
- def test_rewind
- generator = Prime::TrialDivisionGenerator.new
- assert_equal generator.next, 2
- assert_equal generator.next, 3
- generator.rewind
- assert_equal generator.next, 2
- end
- end
-
- class TestGenerator23 < Test::Unit::TestCase
- def test_rewind
- generator = Prime::Generator23.new
- assert_equal generator.next, 2
- assert_equal generator.next, 3
- generator.rewind
- assert_equal generator.next, 2
- end
- end
-
- class TestInteger < Test::Unit::TestCase
- def test_prime_division
- pd = PRIMES.inject(&:*).prime_division
- assert_equal PRIMES.map{|p| [p, 1]}, pd
-
- pd = (-PRIMES.inject(&:*)).prime_division
- assert_equal [-1, *PRIMES].map{|p| [p, 1]}, pd
- end
-
- def test_from_prime_division
- assert_equal PRIMES.inject(&:*), Integer.from_prime_division(PRIMES.map{|p| [p,1]})
-
- assert_equal(-PRIMES.inject(&:*), Integer.from_prime_division([[-1, 1]] + PRIMES.map{|p| [p,1]}))
- end
-
- def test_prime?
- PRIMES.each do |p|
- assert_predicate(p, :prime?)
- end
-
- composites = (0..PRIMES.last).to_a - PRIMES
- composites.each do |c|
- assert_not_predicate(c, :prime?)
- end
-
- # mersenne numbers
- assert_predicate((2**31-1), :prime?)
- assert_not_predicate((2**32-1), :prime?)
-
- # fermat numbers
- assert_predicate((2**(2**4)+1), :prime?)
- assert_not_predicate((2**(2**5)+1), :prime?) # Euler!
-
- # large composite
- assert_not_predicate(((2**13-1) * (2**17-1)), :prime?)
-
- # factorial
- assert_not_predicate((2...100).inject(&:*), :prime?)
-
- # negative
- assert_not_predicate(-1, :prime?)
- assert_not_predicate(-2, :prime?)
- assert_not_predicate(-3, :prime?)
- assert_not_predicate(-4, :prime?)
-
- assert_equal 1229, (1..10_000).count(&:prime?)
- assert_equal 861, (100_000..110_000).count(&:prime?)
- end
-
- def test_prime_in_ractor
- assert_ractor(<<~RUBY, require: 'prime')
- # Test usage of private constant...
- assert_equal false, Ractor.new { ((2**13-1) * (2**17-1)).prime? }.take
- RUBY
- end if defined?(Ractor)
- end
-
- def test_eratosthenes_works_fine_after_timeout
- sieve = Prime::EratosthenesSieve.instance
- sieve.send(:initialize)
- # simulates that Timeout.timeout interrupts Prime::EratosthenesSieve#compute_primes
- class << Integer
- alias_method :org_sqrt, :sqrt
- end
- begin
- def Integer.sqrt(n)
- sleep 10 if /compute_primes/ =~ caller.first
- org_sqrt(n)
- end
- assert_raise(Timeout::Error) do
- Timeout.timeout(0.5) { Prime.each(7*37){} }
- end
- ensure
- class << Integer
- remove_method :sqrt
- alias_method :sqrt, :org_sqrt
- remove_method :org_sqrt
- end
- end
-
- assert_not_include Prime.each(7*37).to_a, 7*37, "[ruby-dev:39465]"
- end
-end
diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb
index ad5b6c402a..37737b9711 100644
--- a/tool/sync_default_gems.rb
+++ b/tool/sync_default_gems.rb
@@ -24,7 +24,6 @@ REPOSITORIES = {
strscan: 'ruby/strscan',
ipaddr: 'ruby/ipaddr',
logger: 'ruby/logger',
- prime: 'ruby/prime',
matrix: 'ruby/matrix',
ostruct: 'ruby/ostruct',
irb: 'ruby/irb',