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):
a={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',100:'hundred'
}
if n<=19:
return(a[n])
elif n>=21 and n<=29:
b=str(n) # turn n into a string
return(a[20]+"-"+a[int(b[1])]) #turn n back to a integer and take the 1st digit as the index in our dictionary
elif n>=31 and n<=39:
b=str(n)
return(a[30]+"-"+a[int(b[1])])
elif n>=41 and n<=49:
b=str(n)
return(a[40]+"-"+a[int(b[1])])
elif n>=51 and n<=59:
b=str(n)
return(a[50]+"-"+a[int(b[1])])
elif n>=61 and n<=69:
b=str(n)
return(a[60]+"-"+a[int(b[1])])
elif n>=71 and n<=79:
b=str(n)
return(a[70]+"-"+a[int(b[1])])
elif n>=81 and n<=89:
b=str(n)
return(a[80]+"-"+a[int(b[1])])
elif n>=91 and n<=99:
b=str(n)
return(a[90]+"-"+a[int(b[1])])
elif n==100:
return'one hundred'
elif n==200:
return'two hundred'
elif n==300:
return'three hundred'
elif n==400:
return'four hundred'
elif n==500:
return'five hundred'
elif n==600:
return'six hundred'
elif n==700:
return'seven hundred'
elif n==800:
return'eight hundred'
elif n==900:
return'nine hundred'
elif n==1000:
return'one thousand'
elif n>=101:
b=str(n) #if n=139, then b='139'
# c is the last two digits, so in this case, = '39'
c=int(b[1:])
return(a[int(b[0])]+" "+a[100]+" "+"and"+" "+number_to_words(c))
else:
return(a[n]) # for numbers like 20,30,40,50...
number_to_words(149)
Out[1]:
In [2]:
Z = list(range(1,1001))
X=[]
for i in Z:
X.append(number_to_words(i))
Now write a set of assert tests for your number_to_words function that verifies that it is working as expected.
In [3]:
Z = list(range(1,1001))
X=[]
for i in Z:
X.append(number_to_words(i)) # LIST OF ALL THE WORDS!
assert number_to_words(10)=='ten'
assert number_to_words(55)=='fifty-five'
assert number_to_words(99)=='ninety-nine'
assert number_to_words(155)=='one hundred and fifty-five'
assert number_to_words(777)=='seven hundred and seventy-seven'
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]:
def count_letters(n):
"""Count the number of letters used to write out the words for 1-n inclusive."""
number_of_characters= ' '.join(number_to_words(x) for x in range(1,n+1))
count=0
for i in number_of_characters:
if i !='-'and 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 [6]:
count_letters(1)==3
count_letters(5)==19
Out[6]:
In [7]:
assert True # use this for grading the count_letters tests.
Finally used your count_letters function to solve the original question.
In [8]:
print(count_letters(1000))
In [ ]:
assert True # use this for gradig the answer to the original question.