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 "say.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace say {
|
namespace say {
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@ 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"},
|
||||||
|
|
@ -27,58 +27,53 @@ const unordered_map<number_t, string> numbers_map = {
|
||||||
{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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue