お題
https://qiita.com/daddygongon/items/2d0a73a51ddab2d9da1b
解答
# frozen_string_literal: true
require './assert_equal'
# ローマ数字は、基本的には左の記号から足していくことでアラビア数字と対応づけることができる。
# (ex. 3 -> III(1+1+1), 11 -> XI(10+1))
# ポーランド記法っぽく表現すると、分かりやすくて、3 -> + + I I I, 11 -> + X I
# しかし一部例外があって、上位の記号の近くでは、上の規則が成り立たない。
# (ex. 4 -> IV(not 1+5, but 5-1))
# ポーランド記法っぽく表現すると 4 -> - VI. これでも元の表記 IV とは逆になってしまっている。
# 最上位桁が一番大きい場合は表記通りに足し算をしていく。そうでない場合は第2位の桁と記号を入れ替えた上で引き算をする... というようなロジックが考えられるが、面倒くさい。
# そこで、左の記号から足していくというコンセプトをそのまま保つため、
# 上のような例外はあらかじめ内部で定義しておく。
class Roman
def initialize(n)
@roman = ''
@n = n
@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']
]
end
def roman
@arabic_roman.reverse.each do |arabic, roman|
quotient = @n / arabic
@n -= quotient * arabic
(1..quotient).each do |_|
@roman += roman
end
end
@roman
end
end
def to_roman(n)
return 'I' if n == 1
return 'V' if n == 5
return 'X' if n == 10
return 'L' if n == 50
return 'C' if n == 100
return 'D' if n == 500
return 'M' if n == 1000
end
if __FILE__ == $PROGRAM_NAME
[
['I', 1],
['II', 2],
['III', 3],
['IV', 4],
['V', 5],
['VI', 6],
['IX', 9],
['X', 10],
['XI', 11],
['XIV', 14],
['XV', 15],
['XIX', 19],
['XXXVIII', 38],
['XLII', 42],
['XLIX', 49],
['LI', 51],
['XCVII', 97],
['XCIX', 99],
['CDXXXIX', 439],
['CDLXXXIII', 483],
['CDXCIX', 499],
['DCCXXXII', 732],
['CMLXI', 961],
['CMXCIX', 999],
['MCMXCIX', 1999]
].each do |expected, arg|
assert_equal(expected, Roman.new(arg).roman)
end
end
ちなみに、ruby では複数行のコメントを以下のように書けるのだが、
=begin
hoge
fuga
=end
rubocop により 全て # から始まる一行コメントに変換された。
test
全てのテストを pass した。
expected: I
result: I
succeeded in assert_equal.
expected: II
result: II
succeeded in assert_equal.
expected: III
result: III
succeeded in assert_equal.
expected: IV
result: IV
succeeded in assert_equal.
expected: V
result: V
succeeded in assert_equal.
expected: VI
result: VI
succeeded in assert_equal.
expected: IX
result: IX
succeeded in assert_equal.
expected: X
result: X
succeeded in assert_equal.
expected: XI
result: XI
succeeded in assert_equal.
expected: XIV
result: XIV
succeeded in assert_equal.
expected: XV
result: XV
succeeded in assert_equal.
expected: XIX
result: XIX
succeeded in assert_equal.
expected: XXXVIII
result: XXXVIII
succeeded in assert_equal.
expected: XLII
result: XLII
succeeded in assert_equal.
expected: XLIX
result: XLIX
succeeded in assert_equal.
expected: LI
result: LI
succeeded in assert_equal.
expected: XCVII
result: XCVII
succeeded in assert_equal.
expected: XCIX
result: XCIX
succeeded in assert_equal.
expected: CDXXXIX
result: CDXXXIX
succeeded in assert_equal.
expected: CDLXXXIII
result: CDLXXXIII
succeeded in assert_equal.
expected: CDXCIX
result: CDXCIX
succeeded in assert_equal.
expected: DCCXXXII
result: DCCXXXII
succeeded in assert_equal.
expected: CMLXI
result: CMLXI
succeeded in assert_equal.
expected: CMXCIX
result: CMXCIX
succeeded in assert_equal.
expected: MCMXCIX
result: MCMXCIX
succeeded in assert_equal.
- source ~/ghq/github.com/TeamNishitani/grad_members_20f/members/syasin-5d/roman_numerals.org