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 [25]:
import math as math
In [26]:
def ones_to_words(n):
onesdict = {0: "",
1: "one",
2: "two",
3: "three",
4: "four",
5: "five",
6: "six",
7: "seven",
8: "eight",
9: "nine",
}
return onesdict[n]
def teens_to_words(n):
teendict = {10: "ten",
11: "eleven",
12: "twelve",
13: "thirteen",
14: "fourteen",
15: "fifteen",
16: "sixteen",
17: "seventeen",
18: "eighteen",
19: "nineteen",
}
return teendict[n]
def tens_to_words(n):
tensdict = {2: "twenty",
3: "thirty",
4: "forty",
5: "fifty",
6: "sixty",
7: "seventy",
8: "eighty",
9: "ninety",
}
return tensdict[n]
def number_to_words(n):
"""Given a number n between 1-1000 inclusive return a list of words for the number."""
cent = n // 100
tens = int(n % 100) // 10
ones = int(n % 10)
words = ""
if cent > 0:
# hundreds
if cent == 10:
words += "one thousand"
else:
words += (ones_to_words(cent) + " hundred ")
# tens and ones
if tens == 0:
if ones == 0:
return words
else:
words += "and " + ones_to_words(ones)
elif tens == 1:
words += "and " + teens_to_words(10 * tens + ones)
else:
words += "and " + tens_to_words(tens) + "-" + ones_to_words(ones)
else:
# tens and ones
if tens == 0:
words += ones_to_words(ones)
elif tens == 1:
words += teens_to_words(10 * tens + ones)
else:
words += tens_to_words(tens) + "-" + ones_to_words(ones)
return words
#raise NotImplementedError()
Now write a set of assert tests for your number_to_words function that verifies that it is working as expected.
In [27]:
assert number_to_words(4) == "four"
assert number_to_words(58) == "fifty-eight"
assert number_to_words(409) == "four hundred and nine"
assert number_to_words(1000) == "one thousand"
assert number_to_words(712) == "seven hundred and twelve"
#raise NotImplementedError()
In [28]:
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 [29]:
def count_letters(n):
"""Count the number of letters used to write out the words for 1-n inclusive."""
x = number_to_words(n)
x = x.replace("-", " ")
return sum([len(y) for y in x.split(" ")])
#raise NotImplementedError()
Now write a set of assert tests for your count_letters function that verifies that it is working as expected.
In [30]:
assert count_letters(4) == 4
assert count_letters(58) == 10
assert count_letters(409) == 18
assert count_letters(1000) == 11
assert count_letters(712) == 21
#raise NotImplementedError()
In [31]:
assert True # use this for grading the count_letters tests.
Finally used your count_letters function to solve the original question.
In [32]:
total_letters = 0
for i in range(1, 1001):
total_letters += count_letters(i)
print(total_letters)
#raise NotImplementedError()
In [33]:
assert True # use this for gradig the answer to the original question.