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.
Additional Notes
This problem requires counting the letters in the written form of numbers from 1 to 1000, following British conventions including the word βandβ. The C++ solution uses template metaprogramming to compute the letter counts at compile time, while the Ruby version manually constructs word representations using a recursive approach.
Implementations
#include <iostream>
template <int n> int count_letter(){ int x = 0; if( n < 100 ){ return count_letter<(n/10)*10>() + count_letter<n%10>(); }
x = (count_letter<n/100>()+7);//+count_letter<100>()); if( 0 != (n%100)){ x += 3 + count_letter<n-((n/100)*100)>(); } return x;}
template <> int count_letter<0>(){return 0;}template <> int count_letter<1>(){return 3;} // onetemplate <> int count_letter<2>(){return 3;} // twotemplate <> int count_letter<3>(){return 5;} // threetemplate <> int count_letter<4>(){return 4;} // fourtemplate <> int count_letter<5>(){return 4;} // fivetemplate <> int count_letter<6>(){return 3;} // sixtemplate <> int count_letter<7>(){return 5;} // seventemplate <> int count_letter<8>(){return 5;} // eighttemplate <> int count_letter<9>(){return 4;} // ninetemplate <> int count_letter<10>(){return 3;} // tentemplate <> int count_letter<11>(){return 6;} // eleventemplate <> int count_letter<12>(){return 6;} // twelvetemplate <> int count_letter<13>(){return 8;} // thirteentemplate <> int count_letter<14>(){return 8;} // fourteentemplate <> int count_letter<15>(){return 7;} // fifteentemplate <> int count_letter<16>(){return 7;} // sixteentemplate <> int count_letter<17>(){return 9;} // seventeentemplate <> int count_letter<18>(){return 8;} // eighteentemplate <> int count_letter<19>(){return 8;} // nineteentemplate <> int count_letter<20>(){return 6;} // twentytemplate <> int count_letter<30>(){return 6;} // thirtytemplate <> int count_letter<40>(){return 5;} // fortytemplate <> int count_letter<50>(){return 5;} // fiftytemplate <> int count_letter<60>(){return 5;} // sixtytemplate <> int count_letter<70>(){return 7;} // seventytemplate <> int count_letter<80>(){return 6;} // eightytemplate <> int count_letter<90>(){return 6;} // ninetytemplate <> int count_letter<100>(){return 10;} // onehundredtemplate <> int count_letter<1000>(){return 11;} // onethousand
static int g_letter_count = 0;
template<int from,int to> struct mp_for{ void operator()() { g_letter_count += count_letter<from>(); mp_for<from+1,to>()(); }};
// Recursive template stoptemplate<int from> struct mp_for<from,from>{ void operator()(){};};
int main(int argc, char const *argv[]) { mp_for<1,1001>()(); // Template recursion stops at <1001,1001> std::cout << "Answer: " << g_letter_count << std::endl;}def simple_humanize_length(number) raise ArgumentError, 'Only supports (1..99999)' unless (1..99_999).cover?(number)
result = '' working = number
while working.positive? case working when (1000..99_999) how_many = (working / 1000).floor working -= 1000 * how_many result += "#{simple_humanize_length(how_many)}thousand" when (100..999) how_many = (working / 100).floor working -= 100 * how_many result += "#{simple_humanize_length(how_many)}hundred#{'and' unless working.zero?}" when (20..99) how_many = (working / 10).floor working -= 10 * how_many result += case how_many when 4, 5, 6 # forty, fifty, sixty = 5 'aaaaa' when 2, 3, 8, 9 # twenty, thirty, eighty, ninety = 6 'bbbbbb' when 7 # seventy = 7 'ccccccc' end else result += case working when 1, 2, 6, 10 # one, two, six, ten = 3 'ddd' when 4, 5, 9 # four, five, nine = 4 'eeee' when 3, 7, 8 # three, seven, eight = 5 'fffff' when 11, 12 # eleven, twelve = 6 'gggggg' when 15, 16 # fifteen, sixteen = 7 'hhhhhhh' when 13, 14, 18, 19 # thirteen, fourteen, eighteen, nineteen = 8 'iiiiiiii' when 17 'jjjjjjjjj' # seventeen = 9 end working = 0 end end resultend
def number_letter_counts(upper) (1..upper).reduce(0) do |sum, digit| sum + simple_humanize_length(digit).length endend
puts number_letter_counts(1000) if __FILE__ == $PROGRAM_NAME