講義サイト
お題:数字の変換
アラビア数字を受け取り、ローマ数字を返すmethodを作る.
アラビア数字は1や2など、ローマ数字はIやIIなど.
ローマ数字の特徴として、
・1:I, 2:II, 3:III など特定のアルファベットを重ねて数字を表現する.
・桁が繰り上がる時(10:X)と、その中間(5:V)で文字が切り変わる.
・大きい順に並べて書かれる(6:VI, 13:XIII).
・ただし↑↑の節目の直前には小さい数を大きい数の左に書く(4:IV, 9:IX).
理屈では分かりにくいので、詳しくはwikipedia参照.
実装例
使う文字は I, V, X, L, C, D, M のVII種類
特に曲者なのが IV や IX など、単純にアルファベットを重ねるだけでは表せない数字たち なので、この数字たちも特別扱いして記述する.
class Integer
def to_roman
romannum = ['I','IV','V','IX','X','XL','L','XC','C','CD','D','CM','M']
romanval = [ 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000]
romannum = romannum.reverse
romanval = romanval.reverse
result = ''
len = romannum.length
i = self
for j in 0...13
case
when i == 0;
break
else;
for k in 0...13
case
when i - romanval[k] >= 0
result += romannum[k]
i = i - romanval[k]
break
end
end
end
end
result
end
end
input = [1,2,4,5,6,9,10,11,14,15,19,38,42,
49,51,97,99,439,483,499,732,961,999,1999]
if $PROGRAM_NAME == __FILE__
input.each do |i|
puts "#{i} #{i.to_roman}"
end
end
引ける数を大きい順から引いていく処理を繰り返した,
実行結果はこんな感じ. 確認した限りでは数は合っている
1 I
2 II
4 IV
5 V
6 VI
9 IX
10 X
11 XI
14 XIV
15 XV
19 XIX
38 XXXVIII
42 XLII
49 XLIX
51 LI
97 XCVII
99 XCIX
439 CDXXXIX
483 CDLXXXIII
499 CDXCIX
732 DCCXXXII
961 CMLXI
999 CMXCIX
1999 MCMXCIX
note
・正直プログラムの出来としては悪い方だと思う.
2重forループを使っているので計算量の面で不安
(ローマ数字は4000未満の数字しか表せないため、今回に限っては問題ないのだが).
時間かけすぎる為打ち切っているが精度のよいプログラムの作成を心掛けたい.
・どうも乗除算を駆使すればより簡単に求められるらしい?
- source ~/grad_members_20f/members/batamon-427/roman_numerals.org