先日、表記関連のqiita投稿を拝見しました。
http://qiita.com/Saayaman/items/b8390cf4b5050694ae9f
ローマ数字からアラビアへの変換に興味深々で、自分流でやってみました!
ローマ数字とアラビア数字の互換
###アラビア数字からローマ数字へ (mode = 1)
例:943 = CMXLIII
Input = 943
roman | arabic | value |
---|---|---|
M | 1000 | 0 |
CM | 900 | 1 |
D | 500 | 0 |
CD | 400 | 0 |
C | 100 | 0 |
XC | 90 | 0 |
L | 50 | 0 |
XL | 40 | 1 |
X | 10 | 0 |
IX | 9 | 0 |
V | 5 | 0 |
IV | 4 | 0 |
I | 1 | 3 |
答えは roman * valueです。ここで、Output = CMXLIII
###ローマ数字からアラビア数字へ (mode = 2)
mode1より少し複雑なので、2stepを分けて変換します。
step1
例:IX = 9
Input = IX
roman | arabic | sign |
---|---|---|
I | 1 | -1 |
X | 10 | 1 |
次の数字より値が小さい場合、signを-1にする。(sign)
arabic * signalの合計を計算する。
Output = 1*(-1)+10*1 = 9
step2
step1で得られたOutputをもう一度ローマ数字に変換する。
変換されたローマ数字はInputと一致すれば、Outputは答えとなる。
ここで、
変換されたローマ数字 = IX = Input
なので、
Output = 9
例(×): Input = VX
step1で Output = 5 得られるが、step2で、 もう一度ローマ変換の答え「V」と一致しないので、VXはローマ数字として存在しない。
演習
>>> Rom_Arab(Input = 'DCXXI', mode = 2)
>>> 621
>>> Rom_Arab(Input = 939, mode = 1)
>>> 'CMXXXIX'
>>> Rom_Arab(Input = 'IIXV', mode = 2)
>>> 'error'
>>> Rom_Arab(Input = arab, mode = 1)
>>> 'error'
コード
def Rom_Arab(Input,mode):
import numpy as np
romanValues = np.array(['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'])
arabicValues = np.array([1000,900,500,400,100,90,50,40,10,9,5,4,1],dtype = int)
def RomantoArabic(roman):
result_arabic = 0
if isinstance(roman,str) == True:
n = len(roman)
value = np.array([0] * n)
sign = np.array([1] * n)
for i in range(0,n):
if sum(romanValues == roman[i]) == 1:
value[i] = arabicValues[romanValues == roman[i]]
else:
result_arabic = 'error'
break
if i > 0 and value[i-1] < value[i]:
sign[i-1] = -1
if result_arabic != 'error':
result_arabic = int(value.dot(sign))
else:
result_arabic = 'error'
return result_arabic
def ArabictoRoman(arabic):
result_roman = ''
if isinstance(arabic,int) == True and arabic >0:
for i in range(0,len(arabicValues)):
k = arabic // arabicValues[i]
if k > 0:
arabic = arabic - arabicValues[i] * k
result_roman = result_roman + str(romanValues[i]) * k
else:
result_roman = 'error'
return str(result_roman)
if mode == 1:
result = ArabictoRoman(Input)
if mode == 2:
Output = RomantoArabic(Input)
if ArabictoRoman(Output) == Input:
result = Output
else:
result = 'error'
return result