Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Prime signature #934

Merged
merged 2 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏


# 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