Last active
November 9, 2023 10:01
-
-
Save david-meza/67124a0ff783f386a01d to your computer and use it in GitHub Desktop.
Convert arabic to roman numerals in Ruby
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 Fixnum | |
# Constant variable with 'unique' roman numerals, plus some special cases (e.g. "IV, IX, XC, CM...") | |
ROMANS = { 1000 => "M", | |
900 => "CM", | |
500 => "D", | |
400 => "CD", | |
100 => "C", | |
90 => "XC", | |
50 => "L", | |
40 => "XL", | |
10 => "X", | |
9 => "IX", | |
5 => "V", | |
4 => "IV", | |
1 => "I" } | |
def to_roman | |
# If the number's already on the hash return the value, otherwise decompose it into numbers that are in it. | |
ROMANS[self] || break_composite_roman(self) | |
end | |
private | |
def break_composite_roman(num) | |
# We start with an empty string and divide by the largest roman numeral possible in the hash | |
# Then we keep breaking down the remainder until it is 0 | |
ROMANS.reduce("") do | memo, (arabic, roman) | | |
quotient, num = num.divmod(arabic) | |
# We multiply the quotient by the key's value (e.g. "I" * 3 = "III") and push it to the end of the string | |
memo << roman * quotient | |
end | |
end | |
end |
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
#!/usr/bin/env ruby | |
gem 'minitest', '>= 5.0.0' | |
require 'minitest/autorun' | |
require_relative 'roman_numerals' | |
class RomanNumeralsTest < Minitest::Test | |
def test_1 | |
assert_equal 'I', 1.to_roman | |
end | |
def test_2 | |
assert_equal 'II', 2.to_roman | |
end | |
def test_3 | |
assert_equal 'III', 3.to_roman | |
end | |
def test_4 | |
assert_equal 'IV', 4.to_roman | |
end | |
def test_5 | |
assert_equal 'V', 5.to_roman | |
end | |
def test_6 | |
assert_equal 'VI', 6.to_roman | |
end | |
def test_9 | |
assert_equal 'IX', 9.to_roman | |
end | |
def test_27 | |
assert_equal 'XXVII', 27.to_roman | |
end | |
def test_48 | |
assert_equal 'XLVIII', 48.to_roman | |
end | |
def test_59 | |
assert_equal 'LIX', 59.to_roman | |
end | |
def test_93 | |
assert_equal 'XCIII', 93.to_roman | |
end | |
def test_141 | |
assert_equal 'CXLI', 141.to_roman | |
end | |
def test_163 | |
assert_equal 'CLXIII', 163.to_roman | |
end | |
def test_402 | |
assert_equal 'CDII', 402.to_roman | |
end | |
def test_575 | |
assert_equal 'DLXXV', 575.to_roman | |
end | |
def test_911 | |
assert_equal 'CMXI', 911.to_roman | |
end | |
def test_1024 | |
assert_equal 'MXXIV', 1024.to_roman | |
end | |
def test_3000 | |
assert_equal 'MMM', 3000.to_roman | |
end | |
def test_99 | |
assert_equal 'XCIX', 99.to_roman | |
end | |
def test_2015 | |
assert_equal 'MMXV', 2015.to_roman | |
end | |
def test_3999 | |
assert_equal 'MMMCMXCIX', 3999.to_roman | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment