In a nutshell, "Convert Arabic numerals to Roman numerals." How Roman numerals work
See around.
Consider the 1000s, 100s, 10s, and 1s. Roman numerals are treated as exceptions because they are written irregularly only for 4 and 9 (why) no matter how much. When the digit of the digit is 5 or more, it is necessary to add a character representing 5, 50, 500 at the beginning.
As for the structure, the notation for each place is added to the array, and it is output collectively later.
output = []
input = ARGV[0].to_i
if input >= 1000
  th = input / 1000
  output.push("M" * th)
  input = input - th * 1000
end
if input >= 100
  ha = input / 100
  if ha == 4
    output.push("CD")
  elsif ha == 9
    output.push("CM")
  elsif ha > 5
    output.push("D")
    output.push("C"*(ha - 5))
  else
   output.push("C"*ha)
  end
  input = input - ha * 100
end
if input >= 10
  te = input / 10
  if te == 4
    output.push("XL")
  elsif te == 9
    output.push("XC")
  elsif te > 5
    output.push("L")
    output.push("X"*(te - 5))
  else
   output.push("X"*te)
  end
  input = input - te * 10
end
if input == 4
  output.push("IV")
elsif input == 9
  output.push("IX")
elsif input > 5
  output.push("V")
  output.push("I"*(input - 5))
else
 output.push("I"*input)
end
result = ""
for string in output
  result = result + string
end
puts result
If you use
> ruby roman_numerals.rb 439
CDXXXIX
Was output correctly.
Looking at the code above, you can see that the processing is the same except for the characters. Therefore, we made a method to change the character string to be saved in the array for each rank = rank. The array that is the save location is not called in the 1000s and 100s & # x2026; in main, but by making it a recursive method, all the processing can be done with one method call. How to get out of recursion
--Input is 0 --Currently processing is the 1st place
Also, by making the output a method, it is output when exiting recursion. Code below
$output = []
def roman(input,rank)
  if input < rank
    return roman(input,rank / 10)
  end
  if rank == 1000
    word = ["M", "", ""]
  elsif rank == 100
    word = ["C", "D", "M"]
  elsif rank == 10
    word = ["X", "L", "C"]
  else
    word = ["I", "V", "X"]
  end
  if input == 0
    print_result($output)
    return
  end
  num = input / rank
  if num == 4
    $output.push(word[0] + word[1])
  elsif num == 9
    $output.push(word[0] + word[2])
  elsif num > 5
    $output.push(word[1])
    $output.push(word[0] * (num - 5))
  else
   $output.push(word[0] * num)
  end
  if rank != 1
    input = input - num * rank
    return roman(input,rank / 10)
  end
  print_result($output)
  return
end
def print_result(output)
  result = ""
  for string in output
    result = result + string
  end
  puts result
end
input = ARGV[0].to_i
roman(input,1000)
When I try to use it
> ruby roman_numerals.rb 439
CDXXXIX
Was output correctly. I feel like I can still refactor it, but for the time being, here
Recommended Posts