《余録》Python3.1 セミナー課題 #4a: ローマ数字
Smalltalk-80, JPython1.1 で作成した例題を、Python3.1 で再構成しました。
■ Python3.1 セミナー課題 #4a: ローマ数字
《付記》K&R には、整数から文字列へと変換する関数 itoa() が、事例として紹介されています。これを参考に、整数からローマ数字へと変換する itor を作成する課題(Smalltalk 版)を作成したものです。そこで今回は、整数からローマ数字へと変換する itor を作成する課題(Python 版)を提示します。
《課題》整数(1..3999)からローマ数字へと変換する itor を作成してください。
- Smalltalk 3分クッキング《問4》ローマ数字, 1988.
class Itor: """ >>> # ローマ数字 Roman numerals >>> # 整数 -> ローマ数字 >>> itor = Itor() >>> s = 0,1,3,4,5,6,8,9,10,14,19,40,50,90,100,400,900,1000,1444,1666,3999 >>> for e in s: "%4d: %s"%(e, itor(e)) ' 0: ' ' 1: I' ' 3: III' ' 4: IV' ' 5: V' ' 6: VI' ' 8: VIII' ' 9: VIV' ' 10: X' ' 14: XIV' ' 19: XVIV' ' 40: XL' ' 50: L' ' 90: LXL' ' 100: C' ' 400: CD' ' 900: DCD' '1000: M' '1444: MCDXLIV' '1666: MDCLXVI' '3999: MMMDCDLXLVIV' """ mapping = {} rating = def __init__(self): class_ = self.__class__ if not class_.mapping: m = {0: "@"} m.update(self.romanNumerals()) class_.mapping = m if not class_.rating: s = for e in range(len("IXCM")): s.append(10**e//2) s.append(10**e) class_.rating = s[::-1][:-1] 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 {v:k for k,v in m1.items()} def _value(self, n): s = [] for e in self.rating: m = n//e; n %= e s.append(self.mapping[e]*m) return self._value1(s) def _value1(self, s): for e,f in zip("IXC","VLD"): t = e*4 if t in s: s[s.index(t)] = e+f return "".join(s)
《付記》残念ながら、Python の組み込み機能は脆弱なので、Smalltalk なら3分クッキングで済むところを、30分以上は掛かりそうです。http://www.nhk.or.jp/sanjushi でも見ながら、しばらくお待ちくださいませ。(_o_)
》こちらに移動中です《
↑TOP