11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Roman numerals

Last updated at Posted at 2020-12-02

Document Links

Roman numerals

ローマ数字の基礎知識

ローマ数字って格好いいよね.

ただ,私自身10ちょっとまでしか見たこと無いんですよね.

では,ローマ数字にはどんなのがあるのか.

arabic roman
1 I
5 V
10 X
50 L
100 C
500 D
1000 M

ローマ数字で扱われる基本的な文字は上記のもので,2 >> II,8 >> VIII というように表される.

ただ,4と9のときだけ異なり,4 >> IV, 9 >> IX と表される.(知ってた)

2桁ではどうなるのか?

私は単純なので,38 >> XXXVIII を見て,なるほど, 49 >> XXXXIX だ!と思ったわけです.

正解は 49 >> XLIX に当然なるわけです.(1桁のときと考え方同じですもん)

てなわけで,幾つか例を上げると,

arabic roman
4 IV
15 XV
32 XXXII
44 XLIV
99 XCIX
439 CDXXXIX
499 CDXCIX
961 CMLXI
2254 MMCCLIV
3782 MMMDCCLXXXII

みたいな感じになるわけです.

ちなみに,現代の一般的な表記法では 1以上4000未満 まで表せるらしい.

アラビア数字をローマ数字に変換

解説

ローマ数字で使われる文字は決まっているので,配列で扱う.

次は,各桁をどのように処理するかだが,

前述したように,ローマ数字では4,9かそれ以外かで表記パターンが異なるので,条件分岐する.

条件に合えば,文字列に文字を追加していく.

考えたのはこれぐらい.

roman_numerals.rb
def arab_to_roma(n)
    roman = ['I','V','X','L','C','D','M']
    to_roman = ""

    if n >= 4000 then
	puts"4000未満の数字にしてね"
    else
	i = 0
	while n > 0 and i < 5 do
	    r = n%10

	    if r == 9 then
		to_roman.insert(0,(roman[i] << roman[i+2]))
	    elsif r == 4 then
		to_roman.insert(0,(roman[i] << roman[i+1]))
	    elsif r != 0 then
		for j in 0..(r%5-1) do
		    to_roman.insert(0,roman[i])
		end

		if r >= 5 then
		    to_roman.insert(0,roman[i+1])
		end
	    end

	    i += 2
	    n = n/10
	end

	for i in 0..n-1 do
	    to_roman .insert(0,"M")
	end

	return to_roman
    end
end

num = ARGV[0].to_i
puts arab_to_roma(num)

# for num in 1..3999 do
#     puts arab_to_roma(num)
# end

こんな感じになりました.

正誤判定するには,コメントアウト部分を走らせて,out.txtに出力,roman_ans.txt(Excelとかで値を取れるよ),diffを取る.

$ ruby roman_numerals.rb > roman_out.txt
$ diff roman_ans.txt roman_out.txt

何も返さなかったら合ってる.

Update

コメントをいただいたので,修正を加える.

roman_numerals_update.rb
def arab_to_roma(n)
    roman = %w[I V X L C D M]
    to_roman = ""

    if n >= 4000 then
	puts"4000未満の数字にしてね"
	return
    end

    0.step(to: 4, by: 2) do |i|
	r = n%10

	case r
	when 0
	when 9
	    to_roman.prepend roman[i] + roman[i+2]
	when 4
	    to_roman.prepend roman[i] + roman[i+1]
	else
	    (r%5).times do
		to_roman.prepend roman[i]
	    end

	    if r >= 5
		to_roman.prepend roman[i+1]
	    end
	end

	n = n/10
	if n == 0 
	    break
	end
    end

    to_roman.prepend "M" * n
    return to_roman
end

num = ARGV[0].to_i
puts arab_to_roma(num)

# for num in 1..3999 do
#     puts arab_to_roma(num)
# end

発展

Class化について学んでから解きます.

締め

今回はアラビア数字をローマ数字に変換するCodeをRubyで書いた.

他に良い方法があれば,教えてください.


  • source ~/school/multi/my_ruby/grad_members_20f/members/evendemiaire/post/roman_numerals.org
11
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?