say: passes tests
This commit is contained in:
parent
41ab570e93
commit
f77d5a95e7
2 changed files with 46 additions and 51 deletions
|
|
@ -1,8 +1,8 @@
|
|||
#include "say.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace say {
|
||||
|
||||
|
|
@ -10,75 +10,70 @@ using namespace std;
|
|||
|
||||
namespace {
|
||||
|
||||
const unordered_map<number_t, string> numbers_map = {
|
||||
{0, "zero"},
|
||||
{1, "one"},
|
||||
{2, "two"},
|
||||
{3, "three"},
|
||||
{4, "four"},
|
||||
{5, "five"},
|
||||
{6, "six"},
|
||||
{7, "seven"},
|
||||
{8, "eight"},
|
||||
{9, "nine"},
|
||||
const unordered_map<number_t, string> number_map = {
|
||||
{0, "zero"},
|
||||
{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"},
|
||||
{20, "twenty"},
|
||||
{30, "thirty"},
|
||||
{40, "forty"},
|
||||
{50, "fifty"},
|
||||
{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)
|
||||
{
|
||||
if (number_map.count(number))
|
||||
return number_map.at(number);
|
||||
|
||||
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))
|
||||
return numbers_map.at(number);
|
||||
if (number >= o.divisor && number < o.max) {
|
||||
|
||||
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) {
|
||||
|
||||
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);
|
||||
throw domain_error("can't say the number");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace say {
|
||||
|
||||
typedef unsigned long long number_t;
|
||||
typedef long long number_t;
|
||||
|
||||
std::string in_english(number_t number);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue