Project Euler 17
1 から 5 までの数字を英単語で書けば one, two, three, four, five であり、全部で 3 + 3 + 4 + 4 + 5 = 19 の文字が使われている。 では 1 から 1000 (one thousand) までの数字をすべて英単語で書けば、全部で何文字になるか。 注: 空白文字やハイフンを数えないこと。例えば、342 (three hundred and forty-two) は 23 文字、115 (one hundred and fifteen) は20文字と数える。なお、"and" を使用するのは英国の慣習。
NtoS[i_] := Which[ i == 1000, "onethousand", (* 100の倍数のとき *) i >= 100 && IntegerQ[i/100] == True, {NtoS[(i - Mod[i, 100])/100] <> "hundred"}, (* 100以上で、100の倍数でないとき *) i >= 100 && IntegerQ[i/100] == False, {NtoS[(i - Mod[i, 100])/100] <> "hundredand" <> NtoS[Mod[i, 100]]}, (* 20以上で、10の倍数のとき *) i >= 20 && IntegerQ[i/10] == True, {NtoS2[i]}, (* 20以上で、10の倍数でないとき *) i >= 20 && IntegerQ[i/10] == False, {NtoS2[i - Mod[i, 10]] <> NtoS[Mod[i, 10]]}, i == 1, "one", i == 2, "two", i == 3, "three", i == 4, "four", i == 5, "five", i == 6, "six", i == 7, "seven", i == 8, "eight", i == 9, "nine", i == 10, "ten", i == 11, "eleven", i == 12, "twelve", i == 13, "thirteen", i == 14, "fourteen", i == 15, "fifteen", i == 16, "sixteen", i == 17, "seventeen", i == 18, "eighteen", i == 19, "nineteen", i == 0, "" ]; NtoS2[i_] := Switch[i, 20, "twenty", 30, "thirty", 40, "forty", 50, "fifty", 60, "sixty", 70, "seventy", 80, "eighty", 90, "ninety"]; Total[Flatten[Table[StringLength[NtoS[i]], {i, 1000}]]]
数字を英単語列にしてくれるような関数はMathematicaでもさすがにないので、普通に関数を作りました。
「 <> 」は、Mathematicaでの文字列の連結です。
C/C++
#include <iostream> #include <string> using namespace std; string NumbertoString2dig(int n){ switch(n){ case 20: return "twenty"; break; case 30: return "thirty"; break; case 40: return "forty"; break; case 50: return "fifty"; break; case 60: return "sixty"; break; case 70: return "seventy"; break; case 80: return "eighty"; break; case 90: return "ninety"; break; } return ""; } string NumbertoString(int n){ if(n == 1000) return "onethousand"; // 100の倍数のとき else if( n%100 == 0) return NumbertoString(n/100)+"hundred"; // 100以上で100の倍数でないとき else if( n>100 ) return NumbertoString(n/100)+"hundredand"+NumbertoString(n%100); // 20以上で10の倍数のとき else if( n>=20 && n%10==0 ) return NumbertoString2dig(n); // 20以上で10の倍数でないとき else if( n>=20) return NumbertoString2dig(n-n%10)+NumbertoString(n%10); else{ switch(n){ case 1: return "one"; break; case 2: return "two"; break; case 3: return "three"; break; case 4: return "four"; break; case 5: return "five"; break; case 6: return "six"; break; case 7: return "seven"; break; case 8: return "eight"; break; case 9: return "nine"; break; case 10: return "ten"; break; case 11: return "eleven"; break; case 12: return "twelve"; break; case 13: return "thirteen"; break; case 14: return "fourteen"; break; case 15: return "fifteen"; break; case 16: return "sixteen"; break; case 17: return "seventeen"; break; case 18: return "eighteen"; break; case 19: return "nineteen"; break; case 0: return ""; break; } } return ""; } int main(){ string str; int sum=0; for(int i=1 ; i<=1000 ; i++){ str = NumbertoString(i); sum += str.length(); } cout << sum << endl; int end; cin >> end; return 0; }
クラスを作ろうと思ったんだけど、どんなクラスを作ればいいかよくわからなかったので、結局愚直に関数。