# Roman numerals

Create a method that takes Arabic numerals as input and returns Roman numerals.

## Answer (before refactoring)

It's wasteful and it's a level that shouldn't be seen for a long time, so I fold it.
``````def getNums()
lines = readlines
len = lines.length

(0..len-1).each do |i|
lines[i] = lines[i].chomp.to_i
end

return lines
end

class Integer
def to_roman
sym = ['I', 'V', 'X', 'L', 'C', 'D', 'M']
roman = ''
to_arr(4).each_with_index do |num, i|
case i
when 0 then
roman += sym[6] * num
when 1 then
case num
when 0..3 then
roman += sym[4] * num
when 4 then
roman += sym[4] + sym[5]
when 5..8 then
roman += sym[5] + sym[4] * (num-5)
when 9 then
roman += sym[4] + sym[6]
end
when 2 then
case num
when 0..3 then
roman += sym[2] * num
when 4 then
roman += sym[2] + sym[3]
when 5..8 then
roman += sym[3] + sym[2] * (num-5)
when 9 then
roman += sym[2] + sym[4]
end
when 3 then
case num
when 0..3 then
roman += sym[0] * num
when 4 then
roman += sym[0] + sym[1]
when 5..8 then
roman += sym[1] + sym[0] * (num-5)
when 9 then
roman += sym[0] + sym[2]
end
end
end
roman
end

def to_arr(n)
arr = []
(Math.log10(self).to_i + 1).upto(n-1) do
arr.unshift(0)
end
arr + digits.reverse
end
end

if \$PROGRAM_NAME == __FILE__
getNums().each do |i|
puts i.to_roman
end
end
``````

## Answer (after refactoring)

``````def getNums()
lines = readlines

(0..lines.length-1).each do |i|
lines[i] = lines[i].chomp.to_i
end
lines
end

class Integer
def to_roman
sym = ['I', 'V', 'X', 'L', 'C', 'D', 'M']
roman = ''
base = sym.length-1
to_arr(4).each_with_index do |num, i|
case num
when 0..3 then
roman += sym[base-i*2] * num
when 4 then
roman += sym[base-i*2] + sym[base-i*2+1]
when 5..8 then
roman += sym[base-i*2+1] + sym[base-i*2] * (num-5)
when 9 then
roman += sym[base-i*2] + sym[base-(i-1)*2]
end
end
roman
end

def to_arr(n)
arr = Array.new(n - Math.log10(self).to_i - 1, 0)
arr + digits.reverse
end
end

if \$PROGRAM_NAME == __FILE__
getNums().each do |i|
# puts "#{i} => #{i.to_roman}"
printf("%4d => %s\n", i, i.to_roman)
end
end
``````

## Commentary

### Receive input of Arabic numerals

``````def getNums()
lines = readlines

(0..lines.length-1).each do |i|
lines[i] = lines[i].chomp.to_i
end
lines
end
``````

This is the part that receives input from standard input.

--Since it is intended for multi-line input, you can enter it separated by line breaks. --Cast the string with the line feed code removed to Integer and store it as an array in lines.

### Execution part

``````if \$PROGRAM_NAME == __FILE__
getNums().each do |i|
# puts "#{i} => #{i.to_roman}"
printf("%4d => %s\n", i, i.to_roman)
end
end
``````

This is the part that is executed when the program is executed with `\$ ruby ​​roman_numerals.rb` etc.

--Receive the input with `getNums ()` and output it to the return object (array) as standard output. --As will be described later, since it is overridden to the Integer class, you can get Roman numerals as a character string with `(Integer) .to_roman`.

### Method to return Roman numerals

``````class Integer
def to_roman
sym = ['I', 'V', 'X', 'L', 'C', 'D', 'M']
roman = ''
base = sym.length-1
to_arr(4).each_with_index do |num, i|
case num
when 0..3 then
roman += sym[base-i*2] * num
when 4 then
roman += sym[base-i*2] + sym[base-i*2+1]
when 5..8 then
roman += sym[base-i*2+1] + sym[base-i*2] * (num-5)
when 9 then
roman += sym[base-i*2] + sym[base-(i-1)*2]
end
end
roman
end

def to_arr(n)
arr = Array.new(n - Math.log10(self).to_i - 1, 0)
arr + digits.reverse
end
end
``````

This is the implementation part of this time.

--Implemented to override the Integer class.

#### To an array of 4 elements (to \ _arr (n))

--Roman numerals can represent 1 to 3999. - `to_arr(n)` --This method arranges the entered Arabic numerals by dividing them into digits. --` n` means the maximum number of digits, and numbers less than that digit are padded with zeros. --Example

``````n = 8
n.to_arr(4) # [0, 0, 0, 8]
``````

#### To Roman numerals

--Refer to Wikipedia etc. for each symbol of Roman numerals. --The Roman numerals to be assembled are stored in the string variable `roman`. - `to_arr(4).each_with_index` --` self` can be omitted, so it is omitted. --Convert to a 4-element array with `to_arr (4)`, and then process each digit. --Cases are classified according to the `case` statement. The most important Roman numerals are 4 and 9. --The processing for each number is the concept and array of Roman numerals in Wikipedia above `sym = ['I','V','X','L','C','D','M' You can understand it by comparing with] `. --The final Roman numeral `roman` is output. --Example

``````n = 8
n.to_roman # "VIII"
n = 1999
n.to_roman # "MCMXCIX"
``````

## Execution result

First, prepare the following text file (in.txt) as input.

``````1
2
4
5
6
9
10
11
14
15
19
38
42
49
51
97
99
439
483
499
732
961
999
1999
``````

The execution result when this is given as input is as follows.

``````\$ ruby roman_numerals.rb < in.text
1 => I
2 => II
4 => IV
5 => V
6 => VI
9 => IX
10 => X
11 => XI
14 => XIV
15 => XV
19 => XIX
38 => XXXVIII
42 => XLII
49 => XLIX
51 => LI
97 => XCVII
99 => XCIX
439 => CDXXXIX
483 => CDLXXXIII
499 => CDXCIX
732 => DCCXXXII
961 => CMLXI
999 => CMXCIX
1999 => MCMXCIX
``````

moved!!!!!

• source ~/Library/Mobile Documents/com~apple~CloudDocs/KG/class/M1/multi_scale_sim/grad_members_20f/members/ryomichi56/./qiita/roman_numerals.org