[RUBY] roman numerals

theme

Write a method that takes arabic numerals and returns roman numerals. (Issues in https://qiita.com/daddygongon/items/2d0a73a51ddab2d9da1b)

The code I wrote this time

For the time being, I will paste the code I wrote this time before the explanation.


def to_roman (arabic_numerals)
  pair_arabic_roman = [[1,"I"],[4,"IV"],[5,"V"],[9,"IX"],[10,"X"],[40,"XL"],[50,"L"],
		       [90,"XC"],[100,"C"],[400,"CD"],[500,"D"],[900,"CM"],[1000,"M"]]
  roman_numerals = ""

  pair_arabic_roman.reverse_each do |p_a, p_r|
    while arabic_numerals >= p_a do
      arabic_numerals	= arabic_numerals - p_a
      roman_numerals	= roman_numerals  + p_r
    end
  end

  return roman_numerals
end

if $PROGRAM_NAME == __FILE__
  arabic_numerals = ARGV[0].to_i
  print "#{arabic_numerals}\t : #{to_roman(arabic_numerals)}\n"
end

(The version incorporated in Integer class is pasted at the end of the page)

Commentary

First, organize the outline of the method to be created

-** Function name : Anything is fine (here, to \ _roman) - Input : Arabic numerals - Output **: Roman numerals

Let's make it now

Output I for 1

If you write it as you like, it will be like this.


def to_roman (arabic_numerals)
  if arabic_numerals==1
    print "I\n"
  else
    print "hoge\n"
  end
end

if $PROGRAM_NAME == __FILE__
  arabic_numerals = ARGV[0].to_i
  print "#{arabic_numerals}\n"
  to_roman(arabic_numerals)
end

Of course it runs. By the way, it is somehow outputting " hoge " when it is other than 1.

Output II for 2 and IV for 4

When I wrote it obediently, it became like this.


def to_roman (arabic_numerals)
  if arabic_numerals==1
    print "I\n"
  elsif arabic_numerals==2
    print "II\n"
  elsif arabic_numerals==4
    print "IV\n"
  else
    print "hoge\n"
  end
end

if $PROGRAM_NAME == __FILE__
  arabic_numerals = ARGV[0].to_i
  print "#{arabic_numerals}\n"
  to_roman(arabic_numerals)
end

Of course it runs.

Returns V for 5

elsif I got tired of writing, so I wrote it in a loop. Also, instead of outputting in the function, the return value is returned.


def to_roman (arabic_numerals)
  pair_arabic_roman = [[1,"I"],
		       [2,"II"],
		       [4,"IV"],
		       [5,"V"]]

  pair_arabic_roman.each do |arabic, roman|
    if arabic_numerals==arabic
      return roman
    end
  end

  return "hoge"
end

if $PROGRAM_NAME == __FILE__
  arabic_numerals = ARGV[0].to_i
  print "#{arabic_numerals}\n"
  print "#{to_roman(arabic_numerals)}\n"
end

Of course it runs.

Returns Roman numerals for 1 to 10

It is too tedious to write all the correspondence between Arabic numerals and Roman numerals in the correspondence table pair_arabic_roman. So, like this.


def to_roman (arabic_numerals)
  pair_arabic_roman = [[1,"I"],[2,"II"],[4,"IV"],[5,"V"],[6,"VI"],[9,"IX"],[10,"X"]]
  roman_numerals = ""

  pair_arabic_roman.reverse_each do |arabic, roman| #Reverse each
    if arabic_numerals >= arabic
      arabic_numerals	= arabic_numerals - arabic
      roman_numerals	= roman_numerals  + roman
    end
  end

  return roman_numerals
end

if $PROGRAM_NAME == __FILE__
  arabic_numerals = ARGV[0].to_i
  print "#{arabic_numerals}\n"
  print "#{to_roman(arabic_numerals)}\n"
end

Strategy to concatenate character strings steadily by setting the initial value of roman_numerals to"". I referred to the string concatenation operation by seeing it written on this site (https://eigo.rumisunheart.com/2018/03/30/integer-to-roman-number-converter/).

-** For 3 : 3 = 2 + 1, so " " becomes"II"and then"III". - For 8 **: 8 = 6 + 2, so " " becomes"VI"and then"VIII".

For 1 to 20

Improved if to while.


def to_roman (arabic_numerals)
  pair_arabic_roman = [[1,"I"],[2,"II"],[4,"IV"],[5,"V"],[6,"VI"],[9,"IX"],[10,"X"]]
  roman_numerals = ""

  pair_arabic_roman.reverse_each do |p_a, p_r|
    while arabic_numerals >= p_a do
      arabic_numerals	= arabic_numerals - p_a
      roman_numerals	= roman_numerals  + p_r
    end
  end

  return roman_numerals
end

if $PROGRAM_NAME == __FILE__
  arabic_numerals = Range.new(1,20)
  arabic_numerals.each do |i|
    print "#{i}\t : #{to_roman(i)}\n"
  end
end

Almost completed when you come here.

By the way, Range is often seen in python.

For 1 ~ 2000

After organizing the correspondence table pair_arabic_roman to some extent, it became like this.


def to_roman (arabic_numerals)
  pair_arabic_roman = [[1,"I"],[4,"IV"],[5,"V"],[9,"IX"],[10,"X"],[40,"XL"],[50,"L"],
		       [90,"XC"],[100,"C"],[400,"CD"],[500,"D"],[900,"CM"],[1000,"M"]]
  roman_numerals = ""

  pair_arabic_roman.reverse_each do |p_a, p_r|
    while arabic_numerals >= p_a do
      arabic_numerals	= arabic_numerals - p_a
      roman_numerals	= roman_numerals  + p_r
    end
  end

  return roman_numerals
end

if $PROGRAM_NAME == __FILE__
  arabic_numerals = [51,97,99,439,483,499,500,732,961,999,1000,1999,2000]
  arabic_numerals.each do |i|
    print "#{i}\t : #{to_roman(i)}\n"
  end
end

Of course I did it. I did it. With this feeling, the code listed at the beginning is completed.

Development issues

Integer Integer class is extended to

999.to_roman #=> CMXCIX

To return.

I slammed the method I just created into an Integer class.


class Integer
  def to_roman
    arabic_numerals = self
    pair_arabic_roman = [[1,"I"],[4,"IV"],[5,"V"],[9,"IX"],[10,"X"],[40,"XL"],[50,"L"],
			 [90,"XC"],[100,"C"],[400,"CD"],[500,"D"],[900,"CM"],[1000,"M"]]
    roman_numerals = ""

    pair_arabic_roman.reverse_each do |p_a, p_r|
      while arabic_numerals >= p_a do
	arabic_numerals	= arabic_numerals - p_a
	roman_numerals	= roman_numerals  + p_r
      end
    end

    return roman_numerals
  end
end

if $PROGRAM_NAME == __FILE__
  a = ARGV[0].to_i
  print "#{a}\t : #{a.to_roman}\n"
end

Of course, the output is as expected.

Reference material


Recommended Posts

roman numerals
roman numerals
roman numerals
roman numerals
roman numerals
roman numerals
Roman Numerals
roman numerals
roman numerals
EX1: roman numerals
Let's solve the roman numerals
Find Roman numerals in Ruby
Convert numbers to Roman numerals in Ruby
roman numerals (I tried to simplify it with hash)