say: passes tests

This commit is contained in:
Dmitry Kokorin 2016-04-08 14:12:40 +03:00
parent 41ab570e93
commit f77d5a95e7
2 changed files with 46 additions and 51 deletions

View file

@ -1,8 +1,8 @@
#include "say.h" #include "say.h"
#include <stdexcept>
#include <unordered_map> #include <unordered_map>
#include <iostream>
namespace say { namespace say {
@ -10,75 +10,70 @@ using namespace std;
namespace { namespace {
const unordered_map<number_t, string> numbers_map = { const unordered_map<number_t, string> number_map = {
{0, "zero"}, {0, "zero"},
{1, "one"}, {1, "one"},
{2, "two"}, {2, "two"},
{3, "three"}, {3, "three"},
{4, "four"}, {4, "four"},
{5, "five"}, {5, "five"},
{6, "six"}, {6, "six"},
{7, "seven"}, {7, "seven"},
{8, "eight"}, {8, "eight"},
{9, "nine"}, {9, "nine"},
{10, "ten"}, {10, "ten"},
{11, "eleven"}, {11, "eleven"},
{12, "twelve"}, {12, "twelve"},
{13, "thirteen"}, {13, "thirteen"},
{20, "twenty"}, {20, "twenty"},
{30, "thirty"}, {30, "thirty"},
{40, "forty"},
{50, "fifty"}, {50, "fifty"},
{80, "eighty"} {80, "eighty"}
}; };
struct order_t
{
number_t divisor;
number_t max;
string separator;
string suffix;
};
const order_t orders[] = {
{10, 100, "-", "ty"},
{100, 1000, " ", " hundred"},
{1000, 1000000, " ", " thousand"},
{1000000, 1000000000, " ", " million"},
{1000000000, 1000000000000, " ", " billion"}
};
} }
string in_english(number_t number) string in_english(number_t number)
{ {
if (number_map.count(number))
return number_map.at(number);
if (number > 13 && number < 20) if (number > 13 && number < 20)
return numbers_map.at(number - 10) + "teen"; return number_map.at(number - 10) + "teen";
if (number >= 20 && number < 100 && (number % 10 == 0)) { for (auto o : orders) {
if (numbers_map.count(number)) if (number >= o.divisor && number < o.max) {
return numbers_map.at(number);
return numbers_map.at(number / 10) + "ty"; if (number % o.divisor == 0)
return in_english(number / o.divisor) + o.suffix;
number_t reminder = number % o.divisor;
number_t div_part = number - reminder;
return in_english(div_part) + o.separator + in_english(reminder);
}
} }
if (number > 20 && number < 100) { throw domain_error("can't say the number");
number_t ones = number % 10;
number_t tens = number - ones;
return in_english(tens) + '-' + in_english(ones);
}
if (number >= 100 && number < 1000) {
if (number % 100 == 0)
return in_english(number / 100) + " hundred";
number_t rest = number % 100;
number_t hundreds = number - rest;
return in_english(hundreds) + ' ' + in_english(rest);
}
if (number >= 1000 && number < 1000000) {
cout << number << endl;
if (number % 1000 == 0)
return in_english(number / 1000) + " thousand";
number_t rest = number % 1000;
number_t thousands = number - rest;
return in_english(thousands) + ' ' + in_english(rest);
}
return numbers_map.at(number);
} }

View file

@ -6,7 +6,7 @@
namespace say { namespace say {
typedef unsigned long long number_t; typedef long long number_t;
std::string in_english(number_t number); std::string in_english(number_t number);