Project Euler: Problem 17

https://projecteuler.net/problem=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.

First write a number_to_words(n) function that takes an integer n between 1 and 1000 inclusive and returns a list of words for the number as described above


In [29]:
import numpy as np

In [64]:
def number_to_words(n,numlist):
    """Given a number n between 1-1000 inclusive return a list of words for the number."""
    if len(str(n)) == 1:
        if str(n)[-1] == '1':
            numlist.append('one')
        elif str(n)[-1] == '2':                
            numlist.append('two')
        elif str(n)[-1] == '3':                
            numlist.append('three')
        elif str(n)[-1] == '4':                
            numlist.append('four')
        elif str(n)[-1] == '5':                
            numlist.append('five')
        elif str(n)[-1] == '6':                
            numlist.append('six')
        elif str(n)[-1] == '7':                
            numlist.append('seven')
        elif str(n)[-1] == '8':                
            numlist.append('eight')
        elif str(n)[-1] == '9':                
            numlist.append('nine')
        elif str(n)[-1] == '0':
            numlist.append('zero')
    if len(str(n)) == 2:
        if str(n)[-2]=='1':
            if str(n)[-1] == '1':
                numlist.append('eleven')
            elif str(n)[-1] == '2':                
                numlist.append('twelve')
            elif str(n)[-1] == '3':                
                numlist.append('thirteen')
            elif str(n)[-1] == '4':                
                numlist.append('fourteen')
            elif str(n)[-1] == '5':                
                numlist.append('fifteen')
            elif str(n)[-1] == '6':                
                numlist.append('sixteen')
            elif str(n)[-1] == '7':                
                numlist.append('seventeen')
            elif str(n)[-1] == '8':                
                numlist.append('eighteen')
            elif str(n)[-1] == '9':                
                numlist.append('nineteen')
            elif str(n)[-1] == '0':
                numlist.append('ten')
        elif str(n)[-2]=='2':
            numlist.append('twenty')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='3':
            numlist.append('thirty')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='4':
            numlist.append('forty')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='5':
            numlist.append('fifty')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='6':
            numlist.append('sixty')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='7':
            numlist.append('seventy')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='8':
            numlist.append('eighty')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='9':
            numlist.append('ninety')
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
        elif str(n)[-2]=='0':
            if str(n)[-1] != '0':
                number_to_words(str(n)[-1], numlist)
    if len(str(n)) == 3:
        if str(n)[-3] == '1':
            if str(n)[-2:] != '00':
                numlist.append('onehundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('onehundred')
        elif str(n)[-3]=='2':
            if str(n)[-2:] != '00':
                numlist.append('twohundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('twohundred')
        elif str(n)[-3]=='3':
            if str(n)[-2:] != '00':
                numlist.append('threehundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('threehundred')
        elif str(n)[-3]=='4':
            if str(n)[-2:] != '00':
                numlist.append('fourhundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('fourhundred')
        elif str(n)[-3]=='5':
            if str(n)[-2:] != '00':
                numlist.append('fivehundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('fivehundred')
        elif str(n)[-3]=='6':
            if str(n)[-2:] != '00':
                numlist.append('sixhundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('sixhundred')
        elif str(n)[-3]=='7':
            if str(n)[-2:] != '00':
                numlist.append('sevenhundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('sevenhundred')
        elif str(n)[-3]=='8':
            if str(n)[-2:] != '00':
                numlist.append('eighthundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('eighthundred')
        elif str(n)[-3]=='9':
            if str(n)[-2:] != '00':
                numlist.append('ninehundredand')
                number_to_words(str(n)[-2:], numlist)
            else:
                numlist.append('ninehundred')
    if str(n) == '1000':
        numlist.append('onethousand')
    return numlist

Now write a set of assert tests for your number_to_words function that verifies that it is working as expected.


In [65]:
numlist = []
assert number_to_words(221, numlist)==['twohundredand', 'twenty', 'one']

In [66]:
assert True # use this for grading the number_to_words tests.

Now define a count_letters(n) that returns the number of letters used to write out the words for all of the the numbers 1 to n inclusive.


In [71]:
def count_letters(n):
    """Count the number of letters used to write out the words for 1-n inclusive."""
    numlist = []
    for i in range(1,n+1):
        numlist=number_to_words(i, numlist)
    num=np.array(numlist)
    np.ravel(num)
    numsum = ''
    for x in num:
        numsum += x
    return len(numsum)

Now write a set of assert tests for your count_letters function that verifies that it is working as expected.


In [72]:
assert count_letters(5)==19
assert count_letters(10)==39

In [73]:
assert True # use this for grading the count_letters tests.

Finally used your count_letters function to solve the original question.


In [74]:
print(count_letters(1000))


21124

In [59]:
assert True # use this for gradig the answer to the original question.

In [ ]: