Project-Euler-017

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.

Answer

1
21124

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/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:
output += 'negative '
number = abs(number)

if number >= 1000:
output += _ones[number // 1000]
if number % 1000 == 0:
output += " thousand"
else:
output += " thousand "
number %= 1000

if number >= 100:
output += _ones[number // 100]
if number % 100 == 0:
output += " hundred"
else:
output += " hundred and "
number %= 100

if number >= 20:
output += _tens[number // 10]
number %= 10
if number % 10 in _ones:
output += '-'

if number in _ones:
output += _ones[number]

return output

def cleanse_string(string):
'''remove spaces and hyphens'''
string = string.replace(' ', '')
string = string.replace('-', '')
return string

print(sum(len(cleanse_string(to_english(i))) for i in range(1, 1001)))


JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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) {
parts.push(ones[Math.floor(number / 1000)])
parts.push("thousand")
number %= 1000
}

if (number >= 100) {
parts.push(ones[Math.floor(number / 100)])
parts.push("hundred")
if (number % 100 !== 0) {
parts.push("and")
}
number %= 100
}

if (number >= 20) {
parts.push(tens[Math.floor(number / 10)])
number %= 10
}

if (ones[number]) {
parts.push(ones[number])
}

return parts.join("")
}

const words = []
for (let i = 1; i <= 1000; i++) {
words.push(english(i))
}
console.log(words.join("").length)


Ruby

1
2
3
4
#!/usr/bin/env ruby
require 'linguistics' # gem install linguistics
Linguistics::use( :en )
puts (1..1000).map { |i| i.en.numwords.gsub(/[ -]/, '').length }.reduce(:+)


Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public final class p017 implements EulerSolution {

public static void main(String[] args) {
System.out.println(new p017().run());
}


/*
* - For the numbers 0 to 19, we write the single word:
* {zero, one, two, three, four, five, six, seven, eight, nine,
* ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen}.
* - For the numbers 20 to 99, we write the word for the tens place:
* {twenty, thirty, forty, fifty, sixty, seventy, eighty, ninety}.
* Subsequently if the last digit is not 0, then we write the word for the ones place (one to nine).
* - For the numbers 100 to 999, we write the ones word for the hundreds place followed by "hundred":
* {one hundred, two hundred, three hundred, ..., eight hundred, nine hundred}.
* Subsequently if the last two digits are not 00, then we write the word "and"
* followed by the phrase for the last two digits (from 01 to 99).
* - For the numbers 1000 to 999999, we write the word for the three digits starting at the
* thousands place and going leftward, followed by "thousand". Subsequently if the last three
* digits are not 000, then we write the phrase for the last three digits (from 001 to 999).
*/
public String run() {
int sum = 0;
for (int i = 1; i <= 1000; i++)
sum += toEnglish(i).length();
return Integer.toString(sum);
}


private static String toEnglish(int n) {
if (0 <= n && n < 20)
return ONES[n];
else if (20 <= n && n < 100)
return TENS[n / 10] + (n % 10 != 0 ? ONES[n % 10] : "");
else if (100 <= n && n < 1000)
return ONES[n / 100] + "hundred" + (n % 100 != 0 ? "and" + toEnglish(n % 100) : "");
else if (1000 <= n && n < 1000000)
return toEnglish(n / 1000) + "thousand" + (n % 1000 != 0 ? toEnglish(n % 1000) : "");
else
throw new IllegalArgumentException();
}


private static String[] ONES = {
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};

private static String[] TENS = {
"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};

}


Mathematica

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(* 
* - For the numbers 0 to 19, we write the single word:
* {zero, one, two, three, four, five, six, seven, eight, nine,
* ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen}.
* - For the numbers 20 to 99, we write the word for the tens place:
* {twenty, thirty, forty, fifty, sixty, seventy, eighty, ninety}.
* Subsequently if the last digit is not 0, then we write the word for the ones place (one to nine).
* - For the numbers 100 to 999, we write the ones word for the hundreds place followed by "hundred":
* {one hundred, two hundred, three hundred, ..., eight hundred, nine hundred}.
* Subsequently if the last two digits are not 00, then we write the word "and"
* followed by the phrase for the last two digits (from 01 to 99).
* - For the numbers 1000 to 999999, we write the word for the three digits starting at the
* thousands place and going leftward, followed by "thousand". Subsequently if the last three
* digits are not 000, then we write the phrase for the last three digits (from 001 to 999).
*)

ones = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
tens = {"", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};

ToEnglish[n_] := Piecewise[{
{"zero",
n == 0},
{ones[[n]],
1 <= n < 20},
{tens[[Floor[n / 10]]] <> If[Mod[n, 10] != 0, ones[[Mod[n, 10]]], ""],
20 <= n < 100},
{ones[[Floor[n / 100]]] <> "hundred" <> If[Mod[n, 100] != 0, "and" <> ToEnglish[Mod[n, 100]], ""],
100 <= n < 1000},
{ToEnglish[Floor[n / 1000]] <> "thousand" <> If[Mod[n, 1000] != 0, ToEnglish[Mod[n, 1000]], ""],
1000 <= n < 1000000}}]

Sum[StringLength[ToEnglish[n]], {n, 1000}]

文章作者: Monad Kai
文章链接: onlookerliu.github.io/2018/03/12/Project-Euler-017/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Code@浮生记
支付宝打赏
微信打赏