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 [44]:
def number_to_words(n):
    """Given a number n between 1-1000 inclusive return a list of words for the number."""
    s=['','one','two','three','four','five','six','seven','eight','nine']
    ten=['ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen']
    ty=['twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety']

    if n in range(1,10):
        return s[n]
    elif n in range(10,20):
        return ten[n-10]
    elif n in range(20,100):
        a=str(n)
        o=int(a[1])
        t=int(a[0])
        return ty[t-2]+ s[o]
    elif n in range(100,1000):
        a=str(n)
        o=int(a[2])
        t=int(a[1])
        h=int(a[0])
        if t==0:
            if o==0:
                return s[h]+'hundred'
            else:
                return s[h]+'hundredand'+s[o]
        elif t==1:
            return s[h]+'hundredand'+ten[o]
        else:
            return s[h]+'hundredand'+ty[t-2]+s[o]
    elif n==1000:
        return 'onethousand'

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


In [45]:
assert number_to_words(1)=='one'
assert number_to_words(13)=='thirteen'
assert number_to_words(22)=='twentytwo'
assert number_to_words(100)=='onehundred'
assert number_to_words(205)=='twohundredandfive'
assert number_to_words(345)=='threehundredandfortyfive'
assert number_to_words(1000)=='onethousand'

In [ ]:
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 [46]:
def count_letters(n):
    """Count the number of letters used to write out the words for 1-n inclusive."""
    return len(number_to_words(n))
    raise NotImplementedError()

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


In [49]:
assert count_letters(2)==3
assert count_letters(15)==7
assert count_letters(22)==9
assert count_letters(100)==10
assert count_letters(222)==22

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

Finally used your count_letters function to solve the original question.


In [48]:
T=0
for n in range(1,1001):
    T+=count_letters(n)
print(T)


21124

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