Table of contents
Problem
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.
Problem Description
Well, writing the numbers in words form and counting the number of alphabets used is our problem here. Looks interesting, right?!
Yeah, we have to write out all the numbers from 1
to 1000
in words. And count the total number of alphabets, ignoring spaces and hyphens.
Approach
Yes, this problem can be approached in N different ways.
The way I approached this(inspired by a freecodecamp article/video ๐) is to split the number into thousands, hundreds and tens. Convert the number to words, append it to a string and then count the number of alphabets using String.prototype.length
.
The Hackerrank version of this problem is quite different. Their word spelling, using space and and
rules vary too. The Numbers in their test cases are quite big - 0 <= N <= 1,000,000,000,000
For the Hackerrank solution, I used Map
object in Javascript and split the given number in 100s
before combining them with proper denominations like billion
, million
etc.
Note: Please note that the solution provided is only for learning purposes. Once you understand the problem, please try it on your own before referring to my solution below.
Solution
let words = {
'units': ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'],
'tenth': ['', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']
}
let numToWordsCount = (limit) => {
let sum = 0;
for (let i = 1; i <= limit; i++) {
let num = i
let numStr = ''
let thousands = Math.floor(num / 1000)
if (thousands > 0) {
numStr = numStr + words['units'][thousands] + 'thousand'
num = num - (thousands * 1000)
}
let hundreds = Math.floor(num / 100)
if (hundreds > 0) {
numStr = numStr + words['units'][hundreds] + 'hundred'
num = num - (hundreds * 100)
if (num > 0) {
numStr = numStr + 'and'
}
}
if (num < 20) {
numStr = numStr + words['units'][num]
} else {
let tens = Math.floor(num / 10)
numStr = numStr + words['tenth'][tens]
num = num - (tens * 10)
numStr = numStr + words['units'][num]
}
sum = sum + numStr.length
}
return sum
}
console.log(numToWordsCount(1000))
You can find my solution on GitHub 17
If you have any feedback, please leave it below.
If you have any suggestions to improve my code or another way to approach this problem, leave it in the comment.
For the other Project Euler Solutions, please follow the series Project Euler Solutions in JS.
Thank you!
Reference:
- More on Javascript Maps at MDN.