Skip to content

Commit

Permalink
Merge pull request #934 from ksss/prime
Browse files Browse the repository at this point in the history
Fix Prime signature
  • Loading branch information
soutaro authored Mar 22, 2022
2 parents 3c8c16f + 5b5ac90 commit ddad41d
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 36 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ gem "goodcheck"
gem "dbm"
gem 'digest'
gem 'tempfile'
gem "prime"

# Test gems
gem "rbs-amber", path: "test/assets/test-gem"
Expand Down
119 changes: 115 additions & 4 deletions stdlib/prime/0/prime.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,66 @@ class Prime
# : Upper bound of prime numbers. The iterator stops after it yields all prime
# numbers p <= `ubound`.
#
def self?.each: (?Integer? ubound, ?PseudoPrimeGenerator generator) { (Integer) -> void } -> void
def self.each: (?Integer? ubound, ?PseudoPrimeGenerator generator) { (Integer) -> void } -> void
| (?Integer? ubound, ?PseudoPrimeGenerator generator) -> PseudoPrimeGenerator

# <!--
# rdoc-file=lib/prime.rb
# - each(ubound = nil, generator = EratosthenesGenerator.new, &block)
# -->
# 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: (?Integer? ubound, ?PseudoPrimeGenerator generator) { (Integer) -> void } -> void
| (?Integer? ubound, ?PseudoPrimeGenerator generator) -> PseudoPrimeGenerator

# <!--
# rdoc-file=lib/prime.rb
# - int_from_prime_division(pd)
# -->
# 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 self.int_from_prime_division: (Array[[ Integer, Integer ]]) -> Integer

# <!--
# rdoc-file=lib/prime.rb
# - int_from_prime_division(pd)
Expand All @@ -103,7 +160,7 @@ class Prime
# Prime.int_from_prime_division([[3, 2], [5, 1]]) #=> 45
# 3**2 * 5 #=> 45
#
def self?.int_from_prime_division: (Array[[ Integer, Integer ]]) -> Integer
def int_from_prime_division: (Array[[ Integer, Integer ]]) -> Integer

# <!--
# rdoc-file=lib/prime.rb
Expand All @@ -119,7 +176,61 @@ class Prime
# `generator`
# : optional. A pseudo-prime generator.
#
def self?.prime?: (Integer value, ?PseudoPrimeGenerator generator) -> bool
def self.prime?: (Integer value, ?PseudoPrimeGenerator generator) -> bool

# <!--
# rdoc-file=lib/prime.rb
# - prime?(value, generator = Prime::Generator23.new)
# -->
# 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?: (Integer value, ?PseudoPrimeGenerator generator) -> bool

# <!--
# rdoc-file=lib/prime.rb
# - prime_division(value, generator = Prime::Generator23.new)
# -->
# 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 self.prime_division: (Integer, ?PseudoPrimeGenerator generator) -> Array[[ Integer, Integer ]]

# <!--
# rdoc-file=lib/prime.rb
Expand Down Expand Up @@ -157,7 +268,7 @@ class Prime
# Prime.prime_division(45) #=> [[3, 2], [5, 1]]
# 3**2 * 5 #=> 45
#
def self?.prime_division: (Integer, ?PseudoPrimeGenerator generator) -> Array[[ Integer, Integer ]]
def prime_division: (Integer, ?PseudoPrimeGenerator generator) -> Array[[ Integer, Integer ]]

# Returns the singleton instance.
#
Expand Down
104 changes: 72 additions & 32 deletions test/stdlib/Prime_test.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,75 @@
require_relative "test_helper"

begin
require "prime"

class PrimeTest < StdlibTest
target Prime
library "prime"

def test_each
Prime.each { break }
Prime.each(10) { }
Prime.each(100, Prime::TrialDivisionGenerator.new)
end

def test_prime?
Prime.prime?(10)
Prime.prime?(11)
end

def test_int_from_prime_division
Prime.int_from_prime_division([[2, 3], [3, 4]])
end

def test_prime_division
Prime.prime_division(6)
end

def test_instance
Prime.instance.prime?(100)
end
end
rescue LoadError
# for Ruby 3.1
require "prime"

class PrimeSingletonTest < Test::Unit::TestCase
include TypeAssertions

library "singleton", "prime"
testing "singleton(::Prime)"

def test_each
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) { (::Integer) -> void } -> void",
Prime, :each do break end
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) { (::Integer) -> void } -> void",
Prime, :each, 10 do break end
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) { (::Integer) -> void } -> void",
Prime, :each, 10, Prime::TrialDivisionGenerator.new do break end
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) -> ::Prime::PseudoPrimeGenerator",
Prime, :each
end

def test_int_from_prime_division
assert_send_type "(::Array[[ ::Integer, ::Integer ]]) -> ::Integer",
Prime, :int_from_prime_division, [[3, 1], [19, 1]]
end

def test_prime?
assert_send_type "(::Integer value, ?::Prime::PseudoPrimeGenerator generator) -> bool",
Prime, :prime?, 57
end

def test_prime_division
assert_send_type "(::Integer, ?::Prime::PseudoPrimeGenerator generator) -> ::Array[[ ::Integer, ::Integer ]]",
Prime, :prime_division, 57
end

def test_instance
assert_send_type "() -> ::Prime",
Prime, :instance
end
end

class PrimeTest < Test::Unit::TestCase
include TypeAssertions

library "singleton", "prime"
testing "::Prime"


def test_each
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) { (::Integer) -> void } -> void",
Prime.instance, :each do break end
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) { (::Integer) -> void } -> void",
Prime.instance, :each, 10 do break end
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) { (::Integer) -> void } -> void",
Prime.instance, :each, 10, Prime::TrialDivisionGenerator.new do break end
assert_send_type "(?::Integer? ubound, ?::Prime::PseudoPrimeGenerator generator) -> ::Prime::PseudoPrimeGenerator",
Prime.instance, :each
end

def test_int_from_prime_division
assert_send_type "(::Array[[ ::Integer, ::Integer ]]) -> ::Integer",
Prime.instance, :int_from_prime_division, [[3, 1], [19, 1]]
end

def test_prime?
assert_send_type "(::Integer value, ?::Prime::PseudoPrimeGenerator generator) -> bool",
Prime.instance, :prime?, 57
end

def test_prime_division
assert_send_type "(::Integer, ?::Prime::PseudoPrimeGenerator generator) -> ::Array[[ ::Integer, ::Integer ]]",
Prime.instance, :prime_division, 57
end
end

0 comments on commit ddad41d

Please sign in to comment.