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."""
num_to_word={'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'}
w=[]
for i in range(1,n+1):
a=str(i)#change either n's to i's or leave as n's
if i==1000:
w.append('one thousand')
elif i in range(1,20): #prints the first 19 natural numbers
w.append(num_to_word[a])
elif i not in range(20,100,10) and i<100: #prints the numbers between values of 10 ie: 21-29
w.append(num_to_word[str(i-i%10)]+'-'+num_to_word[str(i%10)])
elif i in range(20,100,10): #prints double digit number ending in zero ie: 20,30,...,90
w.append(num_to_word[a])
elif (i%100) in range(10,21): #prints ten to twenty ie: 410-420
w.append(num_to_word[a[0]]+' hundred'+ ' and '+ num_to_word[str(i%100)])
elif (i%10==0) and (i%100 in range(10,100,10)): #prints number if last number is zero ie: 480
w.append(num_to_word[a[0]]+' hundred'+' and '+ num_to_word[str(i%100)])
elif (int(a[1])==0) and (i%10 in range(1,10)): #prints number if middle digit is zero ie: 401-409
w.append(num_to_word[a[0]]+' hundred'+' and '+ num_to_word[str(i%10)])
elif i%100==0 and i%10==0: #prints number if it has two trailing zeros ie: 100
w.append(num_to_word[a[0]]+' hundred')
else: #prints the rest of the numbers
w.append(num_to_word[a[0]]+' hundred'+' and '+ num_to_word[str(i%100-i%10)] +'-'+ num_to_word[a[2]])
return w
Now write a set of assert tests for your number_to_words function that verifies that it is working as expected.
In [11]:
assert len(number_to_words(1000))==1000
assert number_to_words(1000)[10]=='eleven'
assert number_to_words(1000)[999]=='one thousand'
In [3]:
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 [4]:
def count_letters(n):
"""Count the number of letters used to write out the words for 1-n inclusive."""
f=[]
for i in number_to_words(n):
if (' ' and '-') in i:
f.append(len(i.replace(' ','').replace('-','')))
elif ' ' in i:
f.append(len(i.replace(' ','')))
elif '-' in i:
f.append(len(i.replace('-','')))
else:
f.append(len(i))
return f
Now write a set of assert tests for your count_letters function that verifies that it is working as expected.
In [10]:
assert count_letters(5)[4]==4
assert len(count_letters(1000))==1000
assert count_letters(1000)[999]==11
In [7]:
assert True # use this for grading the count_letters tests.
Finally used your count_letters function to solve the original question.
In [12]:
n=1000
sum(count_letters(n))
Out[12]:
In [ ]:
assert True # use this for gradig the answer to the original question.