ProjectEuler Problem 17: Number letter counts
Mar 19, 2014
Problem 17: Number letter counts #
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.
分析 #
统计 1~1000 所有的英文单词的字符总数。(不算连字符和空格,但是要算 and)
方法1 找规律,遍历统计 #
数字的表示是有规律的
- 1~20:one two three … twenty
- 21~99:twenty-one twenty-two…ninety-nine ,其中又要考虑30,40,…90 几个特殊的
- 100~999:one hundred, one hundred and one,… nine hundred and nice,其中又要考虑100,200,…900 几个特殊的
- 1000:只有一个 one thousand
C++ #
#include <iostream>
#include <map>
#include <string>
using namespace std;
map<int,string> words;
void init()
{
words.insert(pair<int,string>(1,"one"));
words.insert(pair<int,string>(2,"two"));
words.insert(pair<int,string>(3,"three"));
words.insert(pair<int,string>(4,"four"));
words.insert(pair<int,string>(5,"five"));
words.insert(pair<int,string>(6,"six"));
words.insert(pair<int,string>(7,"seven"));
words.insert(pair<int,string>(8,"eight"));
words.insert(pair<int,string>(9,"nine"));
words.insert(pair<int,string>(10,"ten"));
words.insert(pair<int,string>(11,"eleven"));
words.insert(pair<int,string>(12,"twelve"));
words.insert(pair<int,string>(13,"thirteen"));
words.insert(pair<int,string>(14,"fourteen"));
words.insert(pair<int,string>(15,"fifteen"));
words.insert(pair<int,string>(16,"sixteen"));
words.insert(pair<int,string>(17,"seventeen"));
words.insert(pair<int,string>(18,"eighteen"));
words.insert(pair<int,string>(19,"nineteen"));
words.insert(pair<int,string>(20,"twenty"));
words.insert(pair<int,string>(30,"thirty"));
words.insert(pair<int,string>(40,"forty"));
words.insert(pair<int,string>(50,"fifty"));
words.insert(pair<int,string>(60,"sixty"));
words.insert(pair<int,string>(70,"seventy"));
words.insert(pair<int,string>(80,"eighty"));
words.insert(pair<int,string>(90,"ninety"));
}
// 获取 n 的字符数
int getLettleCount(int n)
{
if( n <= 0 || n > 1000){
printf("invalid n: %d\n", n)
return 0;
}
// 1~20:one two three … twenty
if(n >= 1 && n <= 20){
return words[n].size();
}
// 21~99:twenty-one twenty-two…nitety-nine ,其中又要考虑30,40,…90几个特殊的
if(n >= 21 && n <= 99){
// 考虑30/40 ... 90 几个特殊的
if( n % 10 == 0){
return words[n].size();
}
// 其余格式为 xx-xx
int a = n % 10; // 个位上的数字
int b = (n/10) * 10; // 十位上的数字
return words[a].size() + words[b].size();
}
// 100~999:one hundred, one hundred and one,… nine hundred and nice,其中又要考虑100,200,…900几个特殊的
if(n >= 100 && n <= 999){
int a = n / 100; // 百位上的数字
// 考虑 100/200 ... 900 几个特殊的
if( n % 100 == 0){
return words[a].size() + string("hundred").size();
}
// 其余格式为 xx hundred and xx-xx
return words[a].size() + string("hundred").size() + string("and").size() + getLettleCount(n % 100);
}
// 1000:只有一个one thousand
if( n == 1000 ){
return string("one").size() + string("thousand").size();
}
// 忽略
return 0;
}
int main(int argc, char* argv[])
{
init();
int sum = 0;
for(int i = 1; i <= 1000; i++){
sum += getLettleCount(i);
}
printf("%d\n", sum);
return 0;
}
Golang #
package main
import (
"fmt"
)
var words = make(map[int]string, 0)
func init() {
words[1] = "one"
words[2] = "two"
words[3] = "three"
words[4] = "four"
words[5] = "five"
words[6] = "six"
words[7] = "seven"
words[8] = "eight"
words[9] = "nine"
words[10] = "ten"
words[11] = "eleven"
words[12] = "twelve"
words[13] = "thirteen"
words[14] = "fourteen"
words[15] = "fifteen"
words[16] = "sixteen"
words[17] = "seventeen"
words[18] = "eighteen"
words[19] = "nineteen"
words[20] = "twenty"
words[30] = "thirty"
words[40] = "forty"
words[50] = "fifty"
words[60] = "sixty"
words[70] = "seventy"
words[80] = "eighty"
words[90] = "ninety"
}
// 获取 n 的字符数
func getLettleCount(n int) int {
if n <= 0 || n > 1000 {
fmt.Printf("invalid n:%v\n", n)
return 0
}
// 1~20:one two three … twenty
if n >= 1 && n <= 20 {
return len(words[n])
}
// 21~99:twenty-one twenty-two…nitety-nine ,其中又要考虑30,40,…90几个特殊的
if n >= 21 && n <= 99 {
// 考虑30/40 ... 90 几个特殊的
if n%10 == 0 {
return len(words[n])
}
// 其余格式为 xx-xx
a := n % 10 // 个位上的数字
b := (n / 10) * 10 // 十位上的数字
return len(words[a]) + len(words[b])
}
// 100~999:one hundred, one hundred and one,… nine hundred and nice,其中又要考虑100,200,…900几个特殊的
if n >= 100 && n <= 999 {
a := n / 100 // 百位上的数字
// 考虑 100/200 ... 900 几个特殊的
if n%100 == 0 {
return len(words[a]) + len(string("hundred"))
}
// 其余格式为 xx hundred and xx-xx
return len(words[a]) + len(string("hundred")) + len(string("and")) + getLettleCount(n%100)
}
// 1000:只有一个one thousand
if n == 1000 {
return len(string("one")) + len(string("thousand"))
}
return 0
}
func main() {
//init();
sum := 0
for i := 1; i <= 1000; i++ {
sum += getLettleCount(i)
}
fmt.Println(sum)
}
Python #
words = {
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"
}
data ={1000:11} # data[1000] = "one thousand"
#calc the len
for digit,word in words.items():
data[digit] = len(word)
total = 0
#one --> twenty
for i in range(1,21):
total += data[i]
# twenty-one -->ninety-nine
for i in range(21,100):
if (i%10 == 0): #20,30,40...
total += data[i]
else:
bit = list(str(i)) # split
shiwei = int(bit[0])*10 #
gewei = int(bit[1])
data[i] = data[shiwei] + data[gewei] #add to dict
total += data[i]
# one hundred and one --> nine hundred and ninety-nine
for i in range(100,1000):
if (i%100 == 0): #100,200,300...
bit = i/100
data[i] = data[bit] + len("hundred") #add to dict
total += data[i]
else: #110,111,120,130
bit = list(str(i)) #split
baiwei = int(bit[0])*100 #
data[i] = data[baiwei] + len("and")+ data[i%100];
total += data[i]
# one thousand
total += data[1000]
print (data)
print (total)
扩展,获取 1~1000 所有数字的英文拼写 #
改造一下 getLettleCount 即可
#include <iostream>
#include <map>
#include <string>
using namespace std;
map<int,string> words;
void init()
{
words.insert(pair<int,string>(1,"one"));
words.insert(pair<int,string>(2,"two"));
words.insert(pair<int,string>(3,"three"));
words.insert(pair<int,string>(4,"four"));
words.insert(pair<int,string>(5,"five"));
words.insert(pair<int,string>(6,"six"));
words.insert(pair<int,string>(7,"seven"));
words.insert(pair<int,string>(8,"eight"));
words.insert(pair<int,string>(9,"nine"));
words.insert(pair<int,string>(10,"ten"));
words.insert(pair<int,string>(11,"eleven"));
words.insert(pair<int,string>(12,"twelve"));
words.insert(pair<int,string>(13,"thirteen"));
words.insert(pair<int,string>(14,"fourteen"));
words.insert(pair<int,string>(15,"fifteen"));
words.insert(pair<int,string>(16,"sixteen"));
words.insert(pair<int,string>(17,"seventeen"));
words.insert(pair<int,string>(18,"eighteen"));
words.insert(pair<int,string>(19,"nineteen"));
words.insert(pair<int,string>(20,"twenty"));
words.insert(pair<int,string>(30,"thirty"));
words.insert(pair<int,string>(40,"forty"));
words.insert(pair<int,string>(50,"fifty"));
words.insert(pair<int,string>(60,"sixty"));
words.insert(pair<int,string>(70,"seventy"));
words.insert(pair<int,string>(80,"eighty"));
words.insert(pair<int,string>(90,"ninety"));
}
// 获取 n 的拼写字符串
string getNumberString(int n)
{
// 1~20:one two three … twenty
if(n >= 1 && n <= 20){
return words[n];
}
// 21~99:twenty-one twenty-two…nitety-nine ,其中又要考虑30,40,…90几个特殊的
if(n >= 21 && n <= 99){
// 考虑30/40 ... 90 几个特殊的
if( n % 10 == 0){
return words[n];
}
// 其余格式为 xx-xx
int a = n % 10; //个位上的数字
int b = (n/10) * 10; //十位上的数字
return words[a] + "-" + words[b];
}
// 100~999:one hundred, one hundred and one,… nine hundred and nice,其中又要考虑100,200,…900几个特殊的
if(n >= 100 && n <= 999){
int a = n / 100; // 百位上的数字
// 考虑 100/200 ... 900 几个特殊的
if( n % 100 == 0){
return words[a] + " " + string("hundred");
}
// 其余格式为 xx hundred and xx-xx
return words[a] + string(" hundred and ") + getNumberString(n % 100);
}
// 1000:只有一个one thousand
if( n == 1000 ){
return string("one thousand");
}
return "";
}
int main(int argc, char* argv[])
{
init();
for(int i = 1; i <= 1000; i++){
cout << getNumberString(i) << endl;
}
return 0;
}
答案 #
21124