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 [98]:
#First I define a dictionary of all the necessary words to make numbers
numbers = {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', 0:''}
#print (numbers[11])
numword = ''
def number_to_words(n):
"""Given a number n between 1-1000 inclusive return a list of words for the number."""
numword = ''
n = str(n)
if 99 < int(n) < 1000 and int(n)%100 != 0: #In this range the hundreds place is added to the string and removed from n
numword = numbers[int(n[0])] + 'hundredand'
n = n[1:]
elif 99 < int(n) < 1000 and int(n)%100 == 0: #There is a special case for exact 100's
numword = numbers[int(n[0])] + 'hundred'
n = '0'
elif int(n) == 1000: #I could have programmed in a section for the thousands but I felt it sufficient to make it a special case
numword = 'onethousand'
if int(n) < 20:
numword = numword + numbers[int(n)]
elif 19 < int(n) < 100:
numword = numword + numbers[int(n[0] + '0')] + numbers[int(n[1])]
return numword
Now write a set of assert tests for your number_to_words function that verifies that it is working as expected.
In [99]:
assert number_to_words(14) == 'fourteen'
assert number_to_words(458) == 'fourhundredandfiftyeight' #It made more sense to me to make a single space-free word
#raise NotImplementedError()
In [100]:
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 [94]:
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))
Now write a set of assert tests for your count_letters function that verifies that it is working as expected.
In [95]:
assert count_letters(342) == 23
assert count_letters(115) == 20
#raise NotImplementedError()
In [72]:
assert True # use this for grading the count_letters tests.
Finally used your count_letters function to solve the original question.
In [97]:
n = 0
x = 0
while n < 1000:
n = n + 1
x = x + count_letters(n)
print(x)
#raise NotImplementedError()
In [54]:
assert True # use this for gradig the answer to the original question.