《余録》Smalltalk 3分クッキング《問4》ローマ数字

Smalltalk-80 で作成した例題を、Python3.1 で再構成しました。

■ Python3.1 セミナー課題 #108: 漢数字

《付記》K&R には、整数から文字列へと変換する関数 itoa() が、事例として紹介されています。これを参考に、整数からローマ数字へと変換する itor を作成する課題(Smalltalk 版)を作成したものです。そこで今回は、整数から漢数字(大字)へと変換する itok を作成する課題(Python 版)を提示します。

《課題》4桁の整数から、漢数字(大字)へと変換する itok を作成してください。
  • Smalltalk 3分クッキング《問4》ローマ数字, 1988.
#! /usr/bin/env python
# coding: utf-8
## ----------------------------------------
## (C) Copyright 2000-2010, 小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
## ----------------------------------------
# ..+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8

def itok(n):
    """
    >>> s = 0,1,9,10,12,30,34,99,100,105,110,116,170,178,900,901,1000,1001,9999
    >>> for e in s: "%4d: %s"%(e,itok(e))
    '   0: 零'
    '   1: 壱'
    '   9: 玖'
    '  10: 拾'
    '  12: 拾弐'
    '  30: 参拾'
    '  34: 参拾肆'
    '  99: 玖拾玖'
    ' 100: 佰'
    ' 105: 佰伍'
    ' 110: 佰拾'
    ' 116: 佰拾陸'
    ' 170: 佰漆拾'
    ' 178: 佰漆拾捌'
    ' 900: 玖佰'
    ' 901: 玖佰壱'
    '1000: 阡'
    '1001: 阡壱'
    '9999: 玖阡玖佰玖拾玖'
    """
    dig = "零壱弐参肆伍陸漆捌玖"
    pos = "拾佰阡〇"

    if not n: return dig[n]

    car,*cdr = str(n)[::-1]
    n = int(car)
    acc = [dig[n]] if n else 
    acc = ([dig[n]],)[not n]

    for i,e in enumerate(cdr):
        n = int(e)
        if not n: continue
        acc.append(pos[i])
        if n < 2: continue
        acc.append(dig[n])
    return "".join(acc[::-1])

## ----------------------------------------
from time import ctime

def time_stamp():
    print("="*24)
    print(ctime())
    print("="*24)

## ----------------------------------------
from doctest import testmod

if __name__=='__main__':
    time_stamp()
    testmod()

《Tips》ローマ数字に変換するロジックは、「自動販売機問題」で、釣銭を用意するときに再利用しています。

《付記》残念ながら、Python の組み込み機能は脆弱なので、Smalltalk なら3分クッキングで済むところを、30分以上は掛かりそうです。「名探偵コナン」でも見ながら、しばらくお待ちくださいませ。(_o_)

》作業中です《

Last updated♪2010/01/21