Project Euler Problem 017

http://projecteuler.net/index.php?section=problems&id=17

If the numbers 1 to 5 are written out in words:
  one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words,
  how many letters would be used?
NOTE: Do not count spaces or hyphens. For example,
      342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters.
      The use of "and" when writing out numbers is in compliance with British usage.

数字を文字で書いた時の長さの合計。
地道に文字列を作成しているけど、問題を解くだけなら文字数のデータだけでも良いはず。

import datetime

def letter_number(n):
    
    if 0 <= n < 20:
        return [ 'zero'   , 'one'    , 'two'      , 'three'   , 'four'    ,
                 'five'   , 'six'    , 'seven'    , 'eight'   , 'nine'    ,
                 'ten'    , 'eleven' , 'twelve'   , 'thirteen', 'fourteen',
                 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ][n]
    elif n < 100:
        a = [ [ None, None, 
                'twenty', 'thirty' , 'forty' , 'fifty' ,
                'sixty' , 'seventy', 'eighty', 'ninety' ][n / 10] ]
        
        m = n % 10
        if m: a.append(letter_number(m))
        return a
    
    elif n < 1000:
        a = [ [ letter_number(n / 100), 'hundred' ] ]
        m = n % 100
        if m:
            a.append('and')
            a.append(letter_number(m))
        return a
    
    elif n == 1000:
        a = [ [ letter_number(n / 1000), 'thousand' ]]
        return a


def llen(l):
    def letter_count(l):
        result = 0
        for x in l:
            if isinstance(x, list):
                result += letter_count(x)
            else:
                result += len(x)
        return result
    return letter_count(l)


begin = datetime.datetime.now()

result = 0
for i in xrange(1, 1001):
    s = letter_number(i)
    n = llen(s)
    result += n
    # print i, s, n
print result

end = datetime.datetime.now()

print end - begin


全部数えなくてもいい。

result = 0
for i in xrange(1,100):
    s = letter_number(i)
    n = llen(s)
    result += n
result *= 10

for i in xrange(1,10):
    s = letter_number(i)
    result += (llen(s) + len('hundred')) * 100
    result += len('and') * 99

result += len('one') + len('thousand')
print result

end = datetime.datetime.now()
print end - begin

答え: 21124
実行時間: 0.000802秒くらい