Question
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.
JavaScript
const ones = {
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'
}
const tens = {
2: 'twenty',
3: 'thirty',
4: 'forty',
5: 'fifty',
6: 'sixty',
7: 'seventy',
8: 'eighty',
9: 'ninety'
}
function english(number) {
let parts = []
if (number >= 1000) {
.push(ones[Math.floor(number / 1000)])
parts.push("thousand")
parts%= 1000
number
}
if (number >= 100) {
.push(ones[Math.floor(number / 100)])
parts.push("hundred")
partsif (number % 100 !== 0) {
.push("and")
parts
}%= 100
number
}
if (number >= 20) {
.push(tens[Math.floor(number / 10)])
parts%= 10
number
}
if (ones[number]) {
.push(ones[number])
parts
}
return parts.join("")
}
const words = []
for (let i = 1; i <= 1000; i++) {
.push(english(i))
words
}console.log(words.join("").length)
$ time node --use-strict english-numbers.js
real 0m0.054s
user 0m0.055s
sys 0m0.000s
Python
#!/usr/bin/env python
def to_english(number):
= {
_ones 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',
}
= {
_tens 2: 'twenty',
3: 'thirty',
4: 'forty',
5: 'fifty',
6: 'sixty',
7: 'seventy',
8: 'eighty',
9: 'ninety'
}if abs(number) >= 10000:
return str(number)
elif number == 0:
return 'zero'
else:
= ''
output
if number < 0:
+= 'negative '
output = abs(number)
number
if number >= 1000:
+= _ones[number // 1000]
output if number % 1000 == 0:
+= " thousand"
output else:
+= " thousand "
output %= 1000
number
if number >= 100:
+= _ones[number // 100]
output if number % 100 == 0:
+= " hundred"
output else:
+= " hundred and "
output %= 100
number
if number >= 20:
+= _tens[number // 10]
output %= 10
number if number % 10 in _ones:
+= '-'
output
if number in _ones:
+= _ones[number]
output
return output
def cleanse_string(string):
'''remove spaces and hyphens'''
= string.replace(' ', '')
string = string.replace('-', '')
string return string
print(sum(len(cleanse_string(to_english(i))) for i in range(1, 1001)))
$ time python3 num-string-sum.py
real 0m0.019s
user 0m0.019s
sys 0m0.000s
Ruby
#!/usr/bin/env ruby
require 'linguistics' # gem install linguistics
Linguistics::use( :en )
puts (1..1000).map { |i| i.en.numwords.gsub(/[ -]/, '').length }.reduce(:+)
$ time ruby number-to-words.rb
real 0m0.130s
user 0m0.123s
sys 0m0.008s