変換した英単語を集める最後のループでカラ回りする記述が冗長とのことで、これを無くしてみました。
私の解答例は以下です。
-----
D1 = {0:"", 1:"one", 2:"two", 3:"three", 4:"four", 5:"five", 6:"six", 7:"seven", 8:"eight", 9:"nine"} D10 = {10:"ten", 11:"eleven", 12:"twelve", 13:"thirteen", 14:"fourteen", 15:"fifteen", 16:"sixteen", 17:"seventeen", 18:"eighteen", 19:"nineteen"} D20 = {20:"twenty", 30:"thirty", 40:"forty", 50:"fifty", 60:"sixty", 70:"seventy", 80:"eighty", 90:"ninety"} def f(n): t = 0 for i in xrange(1, n+1): L, M = [int(j) for j in str(i).rjust(4, "0")], [] if L[-4]: M += [D1[i//1000], "thousand"] s = i%100 if L[-3]: M += [D1.get(L[-3], ""), "hundred"] if s: M += ["and"] if s<10: M += [D1.get(s, "")] elif s<20: M += [D10.get(s, "")] else: M += [D20.get(L[-2]*10, ""), D1.get(L[-1], "")] t += sum([len(s.replace(" ","")) for s in M]) return t print f(1000)-----
・辞書D1に1桁の数字の部品の英単語を設定しました。同様に、
辞書D10に10代の数字(10~19)、辞書D20に20以上の数字を設定しました。
100と1000は処理中に直書きしています。
・L, M = [int(j) for j in str(i).rjust(4, "0")], []
リストLに変換元の数字を、左0埋めで4桁にしてから1桁ずつを要素に設定します。
リストMは英単語を設定するので初期化しておきます。
・文字列.rjust(桁数, 埋め文字)
文字列を右詰めして指定桁数にします。あいた部分は埋め文字で埋めます。
ここでは、例えば以下のようになります。"1" → "0001"
・if L[-4]: M += [D1[i//1000], "thousand"]
下から4つ目は、千の位の値です。
これが0以外(論理的にTrue)のとき、例えば["one", "thousand"]のように設定します。
・if L[-3]:
M += [D1.get(L[-3], ""), "hundred"]
if s: M += ["and"]
下から3つ目は、百の位の値です。
これが0以外(論理的にTrue)のとき、例えば["one", "hundred"]のように設定します。
また、sは100で割った余りで、これが0以外なら"and"も設定します。
・if s<10: M += [D1.get(s, "")]
elif s<20: M += [D10.get(s, "")]
else: M += [D20.get(L[-2]*10, ""), D1.get(L[-1], "")]
下2桁の処理です。
sは100で割った余りで、これが10未満なら1桁、さらに20未満なら10代、その他は20以上の数字と1桁、といった組合せで英単語に変換します。
・t += sum([len(s.replace(" ","")) for s in M])
ここまで組み立ててきた英単語について、replace関数で半角空白を削除し、len関数で文字数を数え、sum関数で合計を取ります。
解答はこのすぐ下の行です。文字の色を白にしてます。選択状態にすると見えます。
21124
(追記)
・20120715
ソースコード部分にSyntaxHighlighterを導入。