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 [72]:
def ones(one,count):
if one == 1 or one == 2 or one == 6:
count += 3
if one == 4 or one == 5 or one == 9:
count += 4
if one == 3 or one == 7 or one == 8:
count += 5
return count
def teens(teen,count):
if teen == 10:
count += 3
if teen == 11 or teen == 12:
count += 6
if teen == 15 or teen == 16:
count += 7
if teen == 13 or teen == 14 or teen == 18 or teen == 19:
count += 8
if teen == 17:
count += 9
return count
def tens(ten,count):
b = str(ten)
if b[0] == '4' or b[0] == '5' or b[0] == '6':
count += 5
one = int(b[1])
count = ones(one,count)
if b[0] == '2' or b[0] == '3' or b[0] == '8' or b[0] == '9' and b[1]:
count += 6
one = int(b[1])
count = ones(one,count)
if b[0] == '7' and b[1]:
count += 7
one = int(b[1])
count = ones(one,count)
return count
def huns(hun,count):
count += 7
a = str(hun)
b = int(a[0])
count = ones(b,count)
return count
def numberlettercounts(nummin,nummax):
nums = []
for i in range(nummin,nummax+1):
nums.append(i)
count = 0
for num in nums:
a = str(num)
if len(a) == 1:
count = ones(num,count)
if len(a) == 2 and a[0] == '1':
count = teens(num,count)
if len(a) == 2 and a[0] != '1':
count = tens(num,count)
if len(a) == 3 and a[1] == '0' and a[2]=='0':
count = huns(num,count)
if len(a) == 3 and a[1] != '0' and a[2] == '0':
count = huns(num,count)
ten = int(a[1:3])
if a[1] == '1':
count = teens(ten,count)
count += 3 #for 'and'
if a[1] != '1':
count = tens(ten,count)
count += 3 #for 'and'
if len(a) == 3 and a[1] != '0' and a[2] != '0':
count = huns(num,count)
ten = int(a[1:3])
if a[1] == '1' :
count = teens(ten,count)
count += 3 #for 'and'
if a[1] != '1' :
count = tens(ten,count)
count += 3 #for 'and'
if len(a) == 3 and a[1] == '0' and a[2] != '0':
count = huns(num,count)
count += 3 #for 'and'
c = int(a[2])
count = ones(c,count)
if len(a) == 4:
count += 11
print (count)
In [75]:
numberlettercounts(1,1000)
In [65]:
def number_to_words(n, join = True):
units = ['','one','two','three','four','five','six','seven','eight','nine']
teens = ['','eleven','twelve','thirteen','fourteen','fifteen','sixteen', \
'seventeen','eighteen','nineteen']
tens = ['','ten','twenty','thirty','forty','fifty','sixty','seventy', \
'eighty','ninety']
thousands = ['','thousand']
words = []
if n==0: words.append('zero')
else:
nStr = '%d'%n
nStrLen = len(nStr)
groups = (nStrLen+2)/3
nStr = nStr.zfill(int(groups)*3)
for i in range(0,int(groups)*3,3):
x,y,z = int(nStr[i]),int(nStr[i+1]),int(nStr[i+2])
g = int(groups)-(i/3+1)
if x>=1:
words.append(units[x])
words.append('hundred')
if y>1:
words.append(tens[y])
if z>=1: words.append(units[z])
elif y==1:
if z>=1: words.append(teens[z])
else: words.append(tens[y])
else:
if z>=1: words.append(units[z])
if (int(g)>=1) and ((int(x)+int(y)+int(z))>0): words.append(thousands[int(g)])
if join: return ' '.join(words)
return words
In [66]:
number_to_words(999)
Out[66]:
Now write a set of assert tests for your number_to_words function that verifies that it is working as expected.
In [71]:
number_to_words(999)
expected ='nine hundred ninety nine'
number_to_words(0)
expected2 ='zero'
number_to_words(1000)
expected3 ='one thousand'
number_to_words(5)
expected4 ='five'
assert (number_to_words(999) == expected)
assert (number_to_words(0) == expected2)
assert (number_to_words(1000) == expected3)
assert (number_to_words(5) == expected4)
In [68]:
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 [ ]:
def ones(one,count):
if one == 1 or one == 2 or one == 6:
count += 3
if one == 4 or one == 5 or one == 9:
count += 4
if one == 3 or one == 7 or one == 8:
count += 5
return count
def teens(teen,count):
if teen == 10:
count += 3
if teen == 11 or teen == 12:
count += 6
if teen == 15 or teen == 16:
count += 7
if teen == 13 or teen == 14 or teen == 18 or teen == 19:
count += 8
if teen == 17:
count += 9
return count
def tens(ten,count):
b = str(ten)
if b[0] == '4' or b[0] == '5' or b[0] == '6':
count += 5
one = int(b[1])
count = ones(one,count)
if b[0] == '2' or b[0] == '3' or b[0] == '8' or b[0] == '9' and b[1]:
count += 6
one = int(b[1])
count = ones(one,count)
if b[0] == '7' and b[1]:
count += 7
one = int(b[1])
count = ones(one,count)
return count
def huns(hun,count):
count += 7
a = str(hun)
b = int(a[0])
count = ones(b,count)
return count
In [85]:
#def count_letters(n): <--I didn't use this...
def count_letters(nummin,nummax):
nums = []
for i in range(nummin,nummax+1):
nums.append(i)
count = 0
for num in nums:
a = str(num)
if len(a) == 1:
count = ones(num,count)
if len(a) == 2 and a[0] == '1':
count = teens(num,count)
if len(a) == 2 and a[0] != '1':
count = tens(num,count)
if len(a) == 3 and a[1] == '0' and a[2]=='0':
count = huns(num,count)
if len(a) == 3 and a[1] != '0' and a[2] == '0':
count = huns(num,count)
ten = int(a[1:3])
if a[1] == '1':
count = teens(ten,count)
count += 3 #for 'and'
if a[1] != '1':
count = tens(ten,count)
count += 3 #for 'and'
if len(a) == 3 and a[1] != '0' and a[2] != '0':
count = huns(num,count)
ten = int(a[1:3])
if a[1] == '1' :
count = teens(ten,count)
count += 3 #for 'and'
if a[1] != '1' :
count = tens(ten,count)
count += 3 #for 'and'
if len(a) == 3 and a[1] == '0' and a[2] != '0':
count = huns(num,count)
count += 3 #for 'and'
c = int(a[2])
count = ones(c,count)
if len(a) == 4:
count += 11
return (count)
In [90]:
count_letters(0,342)
Out[90]:
Now write a set of assert tests for your count_letters function that verifies that it is working as expected.
In [91]:
expected1=3
assert(count_letters(0,1) == expected1)
In [ ]:
assert True # use this for grading the count_letters tests.
Finally used your count_letters function to solve the original question.
In [92]:
count_letters(1,1000)
Out[92]:
In [ ]:
assert True # use this for gradig the answer to the original question.