《余録》Python3.1 セミナー課題 #4b: ローマ数字
Smalltalk-80, JPython1.1 で作成した例題を、Python3.1 で再構成しました。
■ Python3.1 セミナー課題 #4b: ローマ数字
《付記》K&R には、整数から文字列へと変換する関数 itoa() が、事例として紹介されています。これを参考に、整数からローマ数字へと変換する itor を作成する課題(Smalltalk 版)を作成したものです。そこで今回は、ローマ数字から整数へと変換する rtoi を作成する課題(Python 版)を提示します。
《課題》ローマ数字から整数(1..3999)へと変換する rtoi を作成してください。
- Smalltalk 3分クッキング《問4》ローマ数字, 1988.
class Rtoi: """ >>> # ローマ数字 Roman numerals >>> # ローマ数字 -> 整数 >>> rtoi = Rtoi() >>> s = ",I,IV,V,VI,IX,X,XI,XL,L,LX,XC,C,CX,CD,D,DC,CM,M,MC,MMMCMXCIX" >>> s = s.split(",") >>> for e in s: "%4d: %s"%(rtoi(e), e) ' 0: ' ' 1: I' ' 4: IV' ' 5: V' ' 6: VI' ' 9: IX' ' 10: X' ' 11: XI' ' 40: XL' ' 50: L' ' 60: LX' ' 90: XC' ' 100: C' ' 110: CX' ' 400: CD' ' 500: D' ' 600: DC' ' 900: CM' '1000: M' '1100: MC' '3999: MMMCMXCIX' """ mapping = {} def __init__(self): class_ = self.__class__ if not class_.mapping: m = {"@": 0} m.update(self.romanNumerals()) class_.mapping = m def __call__(self, s): return self._value(s) def romanNumerals(self): s1,s2 = "IXCM","VLD" m1 = {e: 10**s1.index(e) for e in s1} m2 = {e:5*10**s2.index(e) for e in s2} m1.update(m2) return m1 def _value(self, s): acc = 0 c = "@" for e in s: acc += self._value1(c, e) c = e return acc def _value1(self, c1, c2): n1 = self.mapping[c1] n2 = self.mapping[c2] return (n2, n2-n1*2)[n1 < n2]
《付記》残念ながら、Python の組み込み機能は脆弱なので、Smalltalk なら3分クッキングで済むところを、30分以上は掛かりそうです。「名探偵コナン」でも見ながら、しばらくお待ちくださいませ。(_o_)
》こちらに移動中です《
↑TOP