The following converts Arabic numbers to Roman numerals.
I decided to factor each digit into its place value, then use a mapping to convert it to its Roman equivalent.
For example, 1997 is factored to:
\$(1 \times 10^3) + (9 \times 10^2) + (9 \times 10^1) + (7 \times 10^0) = 1000 + 900 + 90 + 7\$
The Roman numerals for those numbers are then retrieved from the mapping.
class Integer
def to_roman
mappings = {
1 => 'I',
2 => 'II',
3 => 'III',
4 => 'IV',
5 => 'V',
6 => 'VI',
7 => 'VII',
8 => 'VIII',
9 => 'IX',
10 => 'X',
20 => 'XX',
30 => 'XXX',
40 => 'XL',
50 => 'L',
60 => 'LX',
70 => 'LXX',
80 => 'LXXX',
90 => 'XC',
100 => 'C',
200 => 'CC',
300 => 'CCC',
400 => 'CD',
500 => 'D',
600 => 'DC',
700 => 'DCC',
800 => 'DCCC',
900 => 'CM',
1000 => 'M',
2000 => 'MM',
3000 => 'MMM'
}
roman = []
to_s.chars.reverse.each.with_index(0) do |digit, i|
roman.unshift(mappings[digit.to_i * 10**i])
end
roman.join
end
end
I like using exponents to factor each digit into its value place. I don't like having to define a mapping for each number from 1 to 3 and 6 to 8, and repeat that for the 10s, 100s, and 1000s digits.