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 [3]:
def number_to_words(n):#pair programed with noah miller on this problem
    """Given a number n between 1-1000 inclusive return a list of words for the number."""
    s=[]
    o={1:'one',2:'two',3:'three',4:'four',5:'five',6:'six',7:'seven',8:'eight',9:'nine'}
    t={0:'ten',1:'eleven',2:'twelve',3:'thirteen',4:'fourteen',5:'fifteen',6:'sixteen',7:'seventeen',8:'eightteen',9:'nineteen'}
    h={2:'twenty',3:'thirty',4:'forty',5:'fifty',6:'sixty',7:'seventy',8:'eighty',9:'ninety'}
    i=list(int(x)for x in str(n))[::-1]
    while len(i)<3:
        i.append(0)   #turns all numbers into three didgit numbers so as to run the programs
    if i[2]!=0:
        s.append(o[i[2]]+' hundred')
    if i[2]!=0 and i[1]!=0 or i[2]!=0 and i[0]!=0:
        s.append('and')
    if i[1]==1:
        s.append(t[i[0]])
    if i[1]>1 and i[0]!=0:
        s.append(h[i[1]]+' '+ o[i[0]])
    if i[1]>1 and i[0]==0:
        s.append(h[i[1]])
    if i[1]==0 and i[0]!=0:
        s.append(o[i[0]])
    if len(i)>3:
         s.append('one thousand')
    return ' '.join(s)
print (number_to_words(394))


three hundred and ninety four

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


In [4]:
assert number_to_words(1)=='one'
assert number_to_words(15)=='fifteen'
assert number_to_words(45)=='forty five'
assert number_to_words(394)=='three hundred and ninety four'
assert number_to_words(999)=='nine hundred and ninety nine'

In [5]:
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 [12]:
def count_letters(n):
    """Count the number of letters used to write out the words for 1-n inclusive."""
    w=[]
    for entry in number_to_words(n):
        count=0
        for char in entry:
            if char !=' ':
                count=count+1
        w.append(count)
    return sum(w)
print(count_letters(3))


5

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


In [15]:
assert count_letters(1)==3
assert count_letters(100)==10
assert count_letters(1000)==len('onethousand')

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

Finally used your count_letters function to solve the original question.


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


11

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

In [ ]: