JavaScript Implementation of Problem 17

View source code here on GitHub!

p0017()

Project Euler Problem 17

I feel like there is a better way to recurse this problem, but I could not think of one at the time

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.

Returns:

number --

 1/**
 2 * Project Euler Problem 17
 3 *
 4 * I feel like there is a better way to recurse this problem, but I could not
 5 * think of one at the time
 6 *
 7 * Problem:
 8 *
 9 * If the numbers 1 to 5 are written out in words: one, two, three, four, five,
10 * then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
11 *
12 * If all the numbers from 1 to 1000 (one thousand) inclusive were written out in
13 * words, how many letters would be used?
14 *
15 * NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and
16 * forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20
17 * letters. The use of "and" when writing out numbers is in compliance with
18 * British usage.
19 *
20 * @return {number}
21 */
22exports.p0017 = function() {
23    let answer = 0;
24    for (let x = 1; x < 1001; x += 1) {
25        const string = toString(x);
26        answer += string.split(' ').join('').split('-').join('').length;
27    }
28    return answer;
29};
30
31/**
32 * This function takes in a number and returns the British English string
33 * that represents it.
34 *
35 * @param {number} n - The number to be converted.
36 *
37 * @return {string}
38 */
39function toString(n) {
40    if (n >= 1000) {
41        const thousands = `${toString(0 | (n / 1000 % 100))} thousand`;
42        if (n % 1000) {
43            return `${thousands} {toString(n % 1000)}`;
44        }
45        return thousands;
46    } else if (n >= 100) {
47        const hundreds = `${toString(0 | (n / 100 % 10))} hundred`;
48        if (n % 100) {
49            return `${hundreds} and ${toString(n % 100)}`;
50        }
51        return hundreds;
52    } else if (n >= 20) {
53        const tens = {
54            2: 'twenty',
55            3: 'thirty',
56            4: 'forty',
57            5: 'fifty',
58            6: 'sixty',
59            7: 'seventy',
60            8: 'eighty',
61            9: 'ninety',
62        }[0 | (n / 10)];
63        if (n % 10) {
64            return `${tens}-${toString(n % 10)}`;
65        }
66        return tens;
67    } else if (n > 12) {
68        const prefix = {
69            13: 'thir',
70            14: 'four',
71            15: 'fif',
72            16: 'six',
73            17: 'seven',
74            18: 'eigh',
75            19: 'nine',
76        };
77        return `${prefix[n]}teen`;
78    } else {
79        return {
80            0: 'zero',
81            1: 'one',
82            2: 'two',
83            3: 'three',
84            4: 'four',
85            5: 'five',
86            6: 'six',
87            7: 'seven',
88            8: 'eight',
89            9: 'nine',
90            10: 'ten',
91            11: 'eleven',
92            12: 'twelve',
93        }[n];
94    }
95}

Tags: word-problem, combinatorics