課題
アラビア数字(arabic numerals)を受け取って,ローマ数字(roman numerals)を返すmethodを書きなさい
ほほぉ、なかなか面白い。ということで、これを解いてみる。
大晦日だし、たまにはこういうのもいいですよね!
digittoarabic.rb
DigitToRoman = Struct.new(:arabic, :roman )
def roman(n)
# 対応しているのは、1~3999まで
if n <= 0 || n >= 4000 then
raise "Invalid input(" + n.to_s + ")"
end
# 変換用のテーブルつくる。
# 本当はClassでinitilizeタイミングでした方がよいが。
v = Array.new()
v.push ( DigitToRoman.new( 1000, "M") )
v.push ( DigitToRoman.new( 900, "CM") )
v.push ( DigitToRoman.new( 500, "D") )
v.push ( DigitToRoman.new( 400, "CD") )
v.push ( DigitToRoman.new( 100, "C") )
v.push ( DigitToRoman.new( 90, "XC") )
v.push ( DigitToRoman.new( 50, "L") )
v.push ( DigitToRoman.new( 40, "XL") )
v.push ( DigitToRoman.new( 10, "X") )
v.push ( DigitToRoman.new( 9, "IX") )
v.push ( DigitToRoman.new( 5, "V") )
v.push ( DigitToRoman.new( 4, "IV") )
v.push ( DigitToRoman.new( 1, "I") )
# 逆順ソート
# ソートしてからReverseしてもいいけど、コストが…
# ソートをしないと、上のpushの順番が変わると結果も変わる
v = v.sort{|a,b| -( a.arabic <=> b.arabic ) }
# ローマ数字文字列への変換。
# injectを使う事で、変換用テーブルでのループを無くす
# あと、文字列*数字で、繰り返しになるのを使って文字列作る
v.inject("") { |ret, m|
i = n / m.arabic
n = n % m.arabic
ret + m.roman * i
}
end
num = ARGV[0].to_i
puts ARGV[0] + " = " + roman(num)