scosant
12/17/2012 - 11:43 AM

projecteuler017 - number letter counts

projecteuler017 - number letter counts

/** 
 *
 * projecteuler017 - 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.
 */

#include <iostream>
#include <cmath>


int getValueOf1to19(int num);
int getValueOf20to99(int num);
int getValueOf1to9999(int num);


int main(int argc, char* argv[]) {
    int number_value = 0;
    int sum = 0;
    for (int i = 0; i <= 1000; i++) {
        number_value = getValueOf1to9999(i);
        sum += number_value;
        std::cout << " - num: " << i
            << " value: " << number_value << " - total: " << sum << std::endl;
    }
    std::cout << "sum: " << sum << std::endl;
    return 0;
}


int getValueOf1to9999(int num) {
    if (num >= 0 && num <= 19) {
        return getValueOf1to19(num);  
    } else if (num >= 20 && num <= 99) {
        return getValueOf20to99(num);
    } else if (num >= 100 && num <= 999) {
        int hundreds_value = getValueOf1to19(int(floor(num / 100)));
        hundreds_value += 7; // "hundred"
        std::cout <<"hundred";
        int tens_and_ones_value = getValueOf1to9999(num % 100);
        if (tens_and_ones_value > 0 && tens_and_ones_value <= 19) {
            hundreds_value += 3;
            std::cout << "and";
        }
        return hundreds_value + tens_and_ones_value;
    } else if (num >= 1000 && num <= 9999) {
        int thousands_value = getValueOf1to19(int(floor(num / 1000)));
        thousands_value += 8; // "thousand" 
        std::cout << "thousand";
        int hundreds_tens_and_ones_value = num % 1000;

        return thousands_value
            + getValueOf1to9999(hundreds_tens_and_ones_value);
    }
}


int getValueOf20to99(int num) {
    int tens_value = 0;
    switch (int(floor(num / 10))) {
    case 2:
        tens_value = 6; // "twenty"
        std::cout << "twenty";
        break;
    case 3:
        tens_value = 6; // "thirty"
        std::cout << "thirty";
        break;
    case 4:
        tens_value = 5;  // "forty"
        std::cout << "forty";
        break;
    case 5:
        tens_value = 5; // "fifty"
        std::cout << "fifty";
        break;
    case 6:
        tens_value = 5; // "sixty"
        std::cout << "sixty";
        break;
    case 7:
        tens_value = 7; // "seventy"
        std::cout << "seventy";
        break;
    case 8:
        tens_value = 6; // "eighty"
        std::cout << "eighty";
        break;
    case 9:
        tens_value = 6; // "ninety"
        std::cout << "ninety";
        break;
    default:
        tens_value = 0;
        break;
    }

    return tens_value + getValueOf1to19(num % 10);
}

int getValueOf1to19(int num) {
    switch (num) {
    case 1:
        std::cout << "one";
        return 3; // "one"
        break;
    case 2:
        std::cout << "two";
        return 3; // "two"
        break;
    case 3:
        std::cout << "three";
        return 5; // "three"
        break;
    case 4:
        std::cout << "four";
        return 4; // "four"
        break;
    case 5:
        std::cout << "five";
        return 4; // "five"
        break;
    case 6:
        std::cout << "six";
        return 3; // "six"
        break;
    case 7:
        std::cout << "seven";
        return 5; // "seven"
        break;
    case 8:
        std::cout << "eight";
        return 5; // "eight"
        break;
    case 9:
        std::cout << "nine";
        return 4; // "nine"
        break;
    case 10:
        std::cout << "ten";
        return 3; // "ten"
        break;
    case 11:
        std::cout << "eleven";
        return 6; // "eleven"
        break;
    case 12:
        std::cout << "twelve";
        return 6; // "twelve"
        break;
    case 13:
        std::cout << "thirteen";
        return 8; // "thirteen"
        break;
    case 14:
        std::cout << "fourteen";
        return 8; // "fourteen"
        break;
    case 15:
        std::cout << "fifteen";
        return 7; // "fifteen"
        break;
    case 16:
        std::cout << "sixteen";
        return 7; // "sixteen"
        break;
    case 17:
        std::cout << "seventeen";
        return 9; // "seventeen"
        break;
    case 18:
        std::cout << "eighteen";
        return 8; // "eighteen"
        break;
    case 19:
        std::cout << "nineteen";
        return 8; // "nineteen"
        break;
    default:
        return 0;
        break;
    }
}