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 [1]:
def number_to_words(n):
"""Given a number n between 1-1000 inclusive return a list of words for the number."""
n=str(n)
key = {1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine', 10:'ten', 11:'eleven', 12:'twelve', 13:'thirteen', 14:'fourteen', 15:'fifteen', 16:'sixteen', 17:'seventeen', 18:'eighteen', 19:'nineteen', 20:'twenty', 30:'thirty', 40:'forty', 50:'fifty', 60:'sixty', 70:'seventy', 80:'eighty', 90:'ninety'}
if len(n)==4: # '1000'
return 'one thousand'
elif len(n)==3: # 3-digit numbers
if int(n[1])==0 and int(n[2])==0: # 'n00'
return key[int(n[0])]+' hundred'
elif int(n[1])==0 and not int(n[2])==0: # 'n0l'
return key[int(n[0])]+' hundred and '+key[int(n[2])]
elif not int(n[1])==0 and int(n[2])==0: # 'nm0'
return key[int(n[0])]+' hundred and '+key[int(n[1])*10]
elif not int(n[1])==0 and not int(n[2])==0: # 'nml'
if int(n[1])==1: # 'n1l'
return key[int(n[0])]+' hundred and '+key[int(n[1]+n[2])]
elif not int(n[1])==1:
return key[int(n[0])]+' hundred and '+key[int(n[1])*10]+'-'+key[int(n[2])]
elif len(n)==2: # 2-digit numbers
if int(n[1])==0: # 'n0'
return key[int(n[0])*10]
elif not int(n[1])==0: # 'nm'
if int(n[0])==1: # '1m'
return key[int(n[0]+n[1])]
elif not int(n[0])==1:
return key[int(n[0])*10]+'-'+key[int(n[1])]
elif len(n)==1: # 1-digit numbers
return key[int(n)]
Now write a set of assert
tests for your number_to_words
function that verifies that it is working as expected.
In [2]:
p = range(1,11)
type(p)
Out[2]:
In [3]:
assert number_to_words(1000)=='one thousand'
assert number_to_words(593)=='five hundred and ninety-three'
assert number_to_words(111)=='one hundred and eleven'
assert number_to_words(67)=='sixty-seven'
assert number_to_words(14)=='fourteen'
assert number_to_words(2)=='two'
In [4]:
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 [5]:
l="I am a-string"
len(''.join(l.split()))
Out[5]:
In [6]:
def count_letters(n):
"""Count the number of letters used to write out the words for 1-n inclusive."""
phi = number_to_words(n)
count = len(''.join(phi.split()))
for i in range(len(phi)):
if phi[i]=='-':
count -= 1
return count
Now write a set of assert
tests for your count_letters
function that verifies that it is working as expected.
In [7]:
assert count_letters(1000)==11
assert count_letters(342)==23
assert count_letters(115)==20
assert count_letters(21)==9
In [8]:
assert True # use this for grading the count_letters tests.
Finally used your count_letters
function to solve the original question.
In [9]:
total=0
for i in range(1,1001):
total += count_letters(i)
total
Out[9]:
In [10]:
assert True # use this for gradig the answer to the original question.