roman_numerals

![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 

# お題

<https://qiita.com/daddygongon/items/2d0a73a51ddab2d9da1b>

# 解答

```ruby
# 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 では複数行のコメントを以下のように書けるのだが、

```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