Created
December 2, 2024 16:52
-
-
Save havenwood/e7dac3aff1ed73b0c90683813e9387f8 to your computer and use it in GitHub Desktop.
A Ruby implementation of Integer#each_digit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Integer | |
def each_digit(base = 10, &block) | |
raise Math::DomainError, 'out of domain' if negative? | |
raise TypeError, "wrong argument type #{base.class} (expected Integer)" unless base.respond_to?(:to_int) | |
radix = base.to_int | |
raise ArgumentError, 'negative radix' if radix.negative? | |
raise ArgumentError, "invalid radix #{radix}" if radix < 2 | |
return enum_for(__method__, base) unless block_given? | |
div = self | |
until div.zero? | |
div, mod = div.divmod(radix) | |
block.call(mod) | |
end | |
end | |
end | |
require 'minitest/autorun' | |
require 'minitest/pride' | |
class TestEachDigit < Minitest::Test | |
def test_without_block | |
enum = 42.each_digit | |
assert_kind_of Enumerator, enum | |
assert_equal [2, 4], enum.to_a | |
end | |
def test_base_without_block | |
assert_equal [0, 1, 0, 1, 0, 1], 42.each_digit(2).to_a | |
assert_equal [2, 5], 42.each_digit(8).to_a | |
assert_equal [10, 2], 42.each_digit(16).to_a | |
assert_equal [0, 17, 2], 4242.each_digit(42).to_a | |
end | |
def test_with_block | |
result = [] | |
42.each_digit { |digit| result << digit * 2 } | |
assert_equal [4, 8], result | |
end | |
def test_base_with_block | |
result = [] | |
42.each_digit(2) { |digit| result << digit + 1 } | |
assert_equal [1, 2, 1, 2, 1, 2], result | |
end | |
def test_negative_value | |
e = assert_raises(Math::DomainError) { -42.each_digit } | |
assert_equal 'out of domain', e.message | |
end | |
def test_non_integer_base | |
e = assert_raises(TypeError) { 42.each_digit(:x) } | |
assert_equal 'wrong argument type Symbol (expected Integer)', e.message | |
end | |
def test_negative_radix | |
e = assert_raises(ArgumentError) { 42.each_digit(-2) } | |
assert_equal 'negative radix', e.message | |
end | |
def test_invalid_radix0 | |
e = assert_raises(ArgumentError) { 42.each_digit(0) } | |
assert_equal 'invalid radix 0', e.message | |
end | |
def test_invalid_radix1 | |
e = assert_raises(ArgumentError) { 42.each_digit(1) } | |
assert_equal 'invalid radix 1', e.message | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment