-
-
Save nikolat/1168248 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://d.hatena.ne.jp/fumokmm/20110822/1314013182 | |
// ローマ数字定義 | |
def romans = [ | |
I :1 , | |
IV:4 , V:5 , IX:9 , X:10 , | |
XL:40 , L:50 , XC:90 , C:100 , | |
CD:400, D:500, CM:900, M:1000 | |
] | |
// シンボル化能力を追加 | |
String.metaClass.getSymbol = { delegate.intern() } | |
Integer.metaClass.getSymbol = { delegate.toString().intern() } | |
// 文字列自体に変換能力を追加 | |
romans.each { r, a -> | |
r.symbol.metaClass.toArabic = { a } | |
a.symbol.metaClass.toRoman = { r } | |
} | |
// アラビア数字 -> ローマ数字 | |
def arabicToRoman = { int arabic -> | |
('1'*arabic).findAll( | |
~/${romans.values().sort{-it}.collect{ "1{$it}" }.join('|')}/ | |
)*.size()*.symbol*.toRoman().join() | |
} | |
// ローマ数字 -> アラビア数字 | |
def romanToArabic = { String roman -> | |
roman.findAll( | |
~/(${romans.keySet().sort{-it.size()}.join('|')})/ | |
)*.symbol*.toArabic().sum() | |
} | |
// テスト | |
assert arabicToRoman(11) == 'XI' | |
assert romanToArabic('XI') == 11 | |
assert arabicToRoman(12) == 'XII' | |
assert romanToArabic('XII') == 12 | |
assert arabicToRoman(14) == 'XIV' | |
assert romanToArabic('XIV') == 14 | |
assert arabicToRoman(18) == 'XVIII' | |
assert romanToArabic('XVIII') == 18 | |
assert arabicToRoman(24) == 'XXIV' | |
assert romanToArabic('XXIV') == 24 | |
assert arabicToRoman(43) == 'XLIII' | |
assert romanToArabic('XLIII') == 43 | |
assert arabicToRoman(99) == 'XCIX' | |
assert romanToArabic('XCIX') == 99 | |
assert arabicToRoman(495) == 'CDXCV' | |
assert romanToArabic('CDXCV') == 495 | |
assert arabicToRoman(1888) == 'MDCCCLXXXVIII' | |
assert romanToArabic('MDCCCLXXXVIII') == 1888 | |
assert arabicToRoman(1945) == 'MCMXLV' | |
assert romanToArabic('MCMXLV') == 1945 | |
assert arabicToRoman(3999) == 'MMMCMXCIX' | |
assert romanToArabic('MMMCMXCIX') == 3999 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
def getArabicRomanTable(): | |
t = { | |
1: 'I', | |
5: 'V', | |
10: 'X', | |
50: 'L', | |
100: 'C', | |
500: 'D', | |
1000: 'M', | |
} | |
for k in [x for x in t.keys() if x > 1]: | |
if str(k)[0] == '1': | |
t[9*k/10] = t[k/10] + t[k] | |
else: | |
t[8*k/10] = t[k/5] + t[k] | |
return t | |
def arabicToRoman(n): | |
if not (isinstance(n, int) and 0 < n < 4000): | |
raise | |
t = getArabicRomanTable() | |
r = '' | |
for k in sorted(t.keys(), reverse=True): | |
r += t[k] * (n / k) | |
n = n % k | |
return r | |
def romanToArabic(s): | |
if not (isinstance(s, str) and re.compile('^[IVXLCDMivxlcdm]+$').match(s)): | |
raise | |
s = s.upper() | |
t = {} | |
r = 0 | |
for k, v in getArabicRomanTable().items(): | |
t[v] = k | |
for k in [x for x in t.keys() if len(x) > 1]: | |
r += t[k] * s.count(k) | |
s = s.replace(k, '') | |
for k in [x for x in t.keys() if len(x) == 1]: | |
r += t[k] * s.count(k) | |
return r | |
if __name__ == '__main__': | |
assert arabicToRoman(11) == 'XI' | |
assert arabicToRoman(12) == 'XII' | |
assert arabicToRoman(14) == 'XIV' | |
assert arabicToRoman(18) == 'XVIII' | |
assert arabicToRoman(24) == 'XXIV' | |
assert arabicToRoman(43) == 'XLIII' | |
assert arabicToRoman(99) == 'XCIX' | |
assert arabicToRoman(495) == 'CDXCV' | |
assert arabicToRoman(1888) == 'MDCCCLXXXVIII' | |
assert arabicToRoman(1945) == 'MCMXLV' | |
assert arabicToRoman(3999) == 'MMMCMXCIX' | |
assert romanToArabic('XI') == 11 | |
assert romanToArabic('XII') == 12 | |
assert romanToArabic('XIV') == 14 | |
assert romanToArabic('XVIII') == 18 | |
assert romanToArabic('XXIV') == 24 | |
assert romanToArabic('XLIII') == 43 | |
assert romanToArabic('XCIX') == 99 | |
assert romanToArabic('CDXCV') == 495 | |
assert romanToArabic('MDCCCLXXXVIII') == 1888 | |
assert romanToArabic('MCMXLV') == 1945 | |
assert romanToArabic('MMMCMXCIX') == 3999 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment