Skip to content

Commit e4bf177

Browse files
committed
Solve 'Help the bookseller !' kata
1 parent 0c1fd90 commit e4bf177

File tree

3 files changed

+228
-0
lines changed

3 files changed

+228
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef CPP_KATAS_STOCKLIST_H
2+
#define CPP_KATAS_STOCKLIST_H
3+
4+
5+
class StockList
6+
{
7+
public:
8+
static std::string stockSummary(std::vector<std::string> &lstOfArt, std::vector<std::string> &categories);
9+
};
10+
11+
12+
#endif //CPP_KATAS_STOCKLIST_H

src/help_the_bookseller/StockList.cpp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#include <string>
2+
#include <regex>
3+
#include <map>
4+
#include <utility>
5+
6+
/**
7+
* https://www.codewars.com/kata/54dc6f5a224c26032800005c/train/cpp
8+
*/
9+
class StockList {
10+
public:
11+
static std::string stockSummary(std::vector<std::string> &lstOfArt, std::vector<std::string> &categories);
12+
};
13+
14+
namespace help_the_bookseller {
15+
class StockItem {
16+
private:
17+
std::string _category;
18+
int _quantity;
19+
20+
StockItem(std::string category, int quantity) : _category(std::move(category)), _quantity(quantity) {
21+
}
22+
23+
public:
24+
[[nodiscard]] std::string category() const {
25+
return _category;
26+
}
27+
28+
[[nodiscard]] int quantity() const {
29+
return _quantity;
30+
}
31+
32+
static StockItem read_one(const std::string &input);
33+
34+
static std::vector<StockItem> read_many(const std::vector<std::string> &input);
35+
};
36+
37+
class Stock {
38+
private:
39+
std::map<std::string, int> _stock;
40+
41+
explicit Stock(std::map<std::string, int> stock) : _stock(std::move(stock)) {
42+
}
43+
44+
public:
45+
static Stock create_from(const std::vector<StockItem> &stock_items);
46+
47+
std::string format(std::vector<std::string> &categories);
48+
};
49+
50+
class Join {
51+
private:
52+
std::string delimiter;
53+
std::vector<std::string> strings;
54+
55+
Join();
56+
57+
public:
58+
explicit Join(std::string delimiter);
59+
60+
void append(const std::string &str);
61+
62+
std::string build();
63+
};
64+
}
65+
66+
using namespace help_the_bookseller;
67+
68+
std::string StockList::stockSummary(std::vector<std::string> &lstOfArt, std::vector<std::string> &categories) {
69+
if (lstOfArt.empty()) {
70+
return "";
71+
}
72+
73+
const std::vector<StockItem> &stock_items = StockItem::read_many(lstOfArt);
74+
Stock stock = Stock::create_from(stock_items);
75+
76+
return stock.format(categories);
77+
}
78+
79+
StockItem StockItem::read_one(const std::string &input) {
80+
std::regex pattern("([A-Z])[A-Z0-9]* ([0-9]+)");
81+
std::smatch matches;
82+
83+
if (std::regex_search(input, matches, pattern) && matches.size() > 2) {
84+
std::string category = matches[1];
85+
std::string quantity = matches[2];
86+
87+
return {category, std::stoi(quantity)};
88+
} else {
89+
throw std::exception();
90+
}
91+
}
92+
93+
std::vector<StockItem> StockItem::read_many(const std::vector<std::string> &input) {
94+
std::vector<StockItem> items;
95+
96+
for (const auto &item: input) {
97+
items.push_back(read_one(item));
98+
}
99+
100+
return items;
101+
}
102+
103+
Stock Stock::create_from(const std::vector<StockItem> &stock_items) {
104+
std::map<std::string, int> stock;
105+
for (const auto &item: stock_items) {
106+
const auto &found = stock.find(item.category());
107+
108+
int quantity = item.quantity();
109+
110+
if (found != stock.end()) {
111+
quantity += stock.at(found->first);
112+
}
113+
114+
stock[item.category()] = quantity;
115+
}
116+
117+
return Stock(stock);
118+
}
119+
120+
std::string Stock::format(std::vector<std::string> &categories) {
121+
Join joined_items = Join(" - ");
122+
123+
for (const auto &category: categories) {
124+
const auto &found = _stock.find(category);
125+
126+
std::string formatted = "(" + category + " : ";
127+
if (found != _stock.end()) {
128+
int quantity = _stock.at(found->first);
129+
formatted += std::to_string(quantity);
130+
} else {
131+
formatted += "0";
132+
}
133+
134+
joined_items.append(formatted + ")");
135+
}
136+
137+
return joined_items.build();
138+
}
139+
140+
Join::Join() {
141+
this->delimiter = "";
142+
}
143+
144+
Join::Join(std::string delimiter) {
145+
this->delimiter = std::move(delimiter);
146+
}
147+
148+
void Join::append(const std::string &str) {
149+
this->strings.push_back(str);
150+
}
151+
152+
std::string Join::build() {
153+
if (strings.empty()) {
154+
return "";
155+
}
156+
157+
std::string joined;
158+
159+
unsigned int ultimo = strings.size() - 1;
160+
unsigned int index = 0;
161+
162+
for (; index < ultimo; index++) {
163+
joined.append(this->strings[index]);
164+
joined.append(this->delimiter);
165+
}
166+
167+
joined.append(this->strings[index]);
168+
169+
return joined;
170+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <vector>
2+
#include <igloo/igloo_alt.h>
3+
#include "help_the_bookseller/StockList.h"
4+
5+
using namespace igloo;
6+
7+
static void testequal(std::string ans, std::string sol) {
8+
Assert::That(ans, Equals(sol));
9+
}
10+
11+
static void dotest(std::vector<std::string> &lstOfArt, std::vector<std::string> &categories, std::string expected) {
12+
testequal(StockList::stockSummary(lstOfArt, categories), expected);
13+
}
14+
15+
Describe(stockSummary_Tests) {
16+
It(Fixed_Test_1) {
17+
std::vector<std::string> art = {"ABAR 200", "CDXE 500", "BKWR 250", "BTSQ 890", "DRTY 600"};
18+
std::vector<std::string> cd = {"A", "B"};
19+
dotest(art, cd, "(A : 200) - (B : 1140)");
20+
}
21+
22+
It(Fixed_Test_2) {
23+
std::vector<std::string> art = {"BBAR 150", "CDXE 515", "BKWR 250", "BTSQ 890", "DRTY 600"};
24+
std::vector<std::string> cd = {"A", "B", "C", "D"};
25+
dotest(art, cd, "(A : 0) - (B : 1290) - (C : 515) - (D : 600)");
26+
}
27+
28+
It(Fixed_Test_3) {
29+
std::vector<std::string> art = {"BBAR 150", "CDXE 515", "BKW2 250", "BTSQ 890", "DRTY 600"};
30+
std::vector<std::string> cd = {"A", "B", "C", "D"};
31+
dotest(art, cd, "(A : 0) - (B : 1290) - (C : 515) - (D : 600)");
32+
}
33+
34+
It(Empty_art_Test) {
35+
std::vector<std::string> art = {};
36+
std::vector<std::string> cd = {"A", "B"};
37+
dotest(art, cd, "");
38+
}
39+
40+
It(Empty_cat_test) {
41+
std::vector<std::string> art = {"BBAR 150", "CDXE 515", "BKW2 250", "BTSQ 890", "DRTY 600"};
42+
std::vector<std::string> cd = {};
43+
dotest(art, cd, "");
44+
}
45+
};
46+

0 commit comments

Comments
 (0)