Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
class Integer
def to_roman
RomanNumeral.for(self)
end
end
class RomanNumeral
ARABIC_ROMAN = {
1000 => 'M',
500 => 'D',
100 => 'C',
50 => 'L',
10 => 'X',
5 => 'V',
1 => 'I'
}
def self.for(arabic_num)
self.new(arabic_num).to_s
end
attr_reader :arabic_num
def initialize(arabic_num)
@arabic_num = arabic_num
end
def to_s
result = ''.tap do |s|
num = arabic_num
loop do
break if num == 0
next_arabic = next_arabic_num(num)
s << ARABIC_ROMAN[next_arabic]
num -= next_arabic
end
end
transform_roman(result)
end
def next_arabic_num(num)
ARABIC_ROMAN.keys.select { |n| n <= num }.max
end
def transform_roman(roman_numeral)
roman_numeral.tap do |s|
transformations = {
'DCCCC' => 'CM', # 900
'CCCC' => 'CD', # 400
'LXXXX' => 'XC', # 90
'XXXX' => 'XL', # 40
'VIIII' => 'IX', # 9
'IIII' => 'IV' # 4
}.each { |from, to| s.gsub!(from, to) }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment