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 [36]:
%matplotlib inline
from matplotlib import pyplot as plt
import numpy as np
number_to_words(554)


Out[36]:
'five hundred and fifty-four'

In [107]:
def number_to_words(n):
    """Given a number n between 1-1000 inclusive return a list of words for the number."""
    N=str(n)
    x=list(N)
    if len(x)==4:
        return'one thousand'
    if len(x)==3:
        if x[0]=='1':
            hundred_digit='one hundred'
        elif x[0]=='2':
            hundred_digit='two hundred' 
        elif x[0]=='3':
            hundred_digit='three hundred'
        elif x[0]=='4':
            hundred_digit='four hundred'
        elif x[0]=='5':
            hundred_digit='five hundred'
        elif x[0]=='6':
            hundred_digit='six hundred'
        elif x[0]=='7':
            hundred_digit='seven hundred'
        elif x[0]=='8':
            hundred_digit='eight hundred'
        elif x[0]=='9':
            hundred_digit='nine hundred'
        if x[1]=='0':
            tens_digit=' '
        elif x[1]=='1':
            if x[2]=='0':
                return hundred_digit+' ten'
            elif x[2]=='1':
                return hundred_digit+' eleven'
            elif x[2]=='2':
                return hundred_digit+' twelve'
            elif x[2]=='3':
                return hundred_digit+' thirteen'
            elif x[2]=='4':
                return hundred_digit+' fourteen'
            elif x[2]=='5':
                return hundred_digit+' fifteen'
            elif x[2]=='6':
                return hundred_digit+' sixteen'
            elif x[2]=='7':
                return hundred_digit+' seventeen'
            elif x[2]=='8':
                return hundred_digit+' eighteen'
            elif x[2]=='9':
                return hundred_digit+' nineteen'
        elif x[1]=='2':
            tens_digit=' twenty-' 
        elif x[1]=='3':
            tens_digit=' thirty-'
        elif x[1]=='4':
            tens_digit=' fourty-'
        elif x[1]=='5':
            tens_digit=' fifty-'
        elif x[1]=='6':
            tens_digit=' sixty-'
        elif x[1]=='7':
            tens_digit=' seventy-'
        elif x[1]=='8':
            tens_digit=' eighty-'
        elif x[1]=='9':
            tens_digit=' ninety-'
        if x[2]=='0':
            return hundred_digit+tens_digit
        elif x[2]=='1':
            return hundred_digit+' and'+tens_digit+'one'
        elif x[2]=='2':
            return hundred_digit+' and'+tens_digit+'two'
        elif x[2]=='3':
            return hundred_digit+' and'+tens_digit+'three'
        elif x[2]=='4':
            return hundred_digit+' and'+tens_digit+'four'
        elif x[2]=='5':
            return hundred_digit+' and'+tens_digit+'five'
        elif x[2]=='6':
            return hundred_digit+' and'+tens_digit+'six'
        elif x[2]=='7':
            return hundred_digit+' and'+tens_digit+'seven'
        elif x[2]=='8':
            return hundred_digit+' and'+tens_digit+'eight'
        elif x[2]=='9':
            return hundred_digit+' and'+tens_digit+'nine'
    if len(x)==2:
        if x[0]=='1':
            if x[1]=='0':
                return 'ten'
            elif x[1]=='1':
                return 'eleven'
            elif x[1]=='2':
                return 'twelve'
            elif x[1]=='3':
                return 'thirteen'
            elif x[1]=='4':
                return 'fourteen'
            elif x[1]=='5':
                return 'fifteen'
            elif x[1]=='6':
                return 'sixteen'
            elif x[1]=='7':
                return 'seventeen'
            elif x[1]=='8':
                return 'eighteen'
            elif x[1]=='9':
                return 'nineteen'
        elif x[0]=='2':
            tens_digit1='twenty-' 
        elif x[0]=='3':
            tens_digit1='thirty-'
        elif x[0]=='4':
            tens_digit1='fourty-'
        elif x[0]=='5':
            tens_digit1='fifty-'
        elif x[0]=='6':
            tens_digit1='sixty-'
        elif x[0]=='7':
            tens_digit1='seventy-'
        elif x[0]=='8':
            tens_digit1='eighty-'
        elif x[0]=='9':
            tens_digit1='ninety-'
        if x[1]=='0':
            return tens_digit1
        elif x[1]=='1':
            return tens_digit1+'one'
        elif x[1]=='2':
            return tens_digit1+'two'
        elif x[1]=='3':
            return tens_digit1+'three'
        elif x[1]=='4':
            return tens_digit1+'four'
        elif x[1]=='5':
            return tens_digit1+'five'
        elif x[1]=='6':
            return tens_digit1+'six'
        elif x[1]=='7':
            return tens_digit1+'seven'
        elif x[1]=='8':
            return tens_digit1+'eight'
        elif x[1]=='9':
            return tens_digit1+'nine'
    if len(x)==1:
        if x[0]=='1':
            return 'one'
        elif x[0]=='2':
            return 'two'
        elif x[0]=='3':
            return 'three'
        elif x[0]=='4':
            return 'four'
        elif x[0]=='5':
            return 'five'
        elif x[0]=='6':
            return 'six'
        elif x[0]=='7':
            return 'seven'
        elif x[0]=='8':
            return 'eight'
        elif x[0]=='9':
            return 'nine'

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


In [108]:
assert number_to_words(3)=='three'
assert number_to_words(2)+number_to_words(4)=='twofour'
assert number_to_words(978)=='nine hundred and seventy-eight'

In [109]:
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 [110]:
def filter_fn(x):
    if x=='-' or x==' ':
        return False
    else:
        return True

In [ ]:


In [111]:
def count_letters(n):
    """Count the number of letters used to write out the words for 1-n inclusive."""
    total_letters=0
    while n>=1:
        x=number_to_words(n)
        y=x.replace(' ','')
        z=y.replace('-','')
        total_letters=total_letters+len(z)
        n=n-1
    return total_letters

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


In [118]:
assert count_letters(1)==3
assert count_letters(5)==19
assert count_letters(1000)==20738

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

Finally used your count_letters function to solve the original question.


In [ ]:
# YOUR CODE HERE
raise NotImplementedError()

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