aboutsummaryrefslogtreecommitdiff
path: root/src/utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.cc')
-rw-r--r--src/utils.cc71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/utils.cc b/src/utils.cc
new file mode 100644
index 0000000..009754b
--- /dev/null
+++ b/src/utils.cc
@@ -0,0 +1,71 @@
+#include "utils.h"
+#include "json.hpp"
+#include <sstream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <filesystem>
+#include <stdexcept>
+#include <map>
+
+nlohmann::json utils::loadJson(const std::string& path) {
+ std::ifstream f(path);
+ nlohmann::json j;
+ f >> j;
+ return j;
+}
+
+void utils::saveJson(const nlohmann::json& data, const std::string& path) {
+ std::ofstream f(path);
+ f << std::setw(4) << data << std::endl;
+}
+
+/*std::string utils::join(std::vector<std::string> parts, std::string joiner) {
+ std::stringstream out;
+ bool isFirst = true;
+ for(std::string p : parts) {
+ if(! isFirst) {
+ out << joiner;
+ }
+ isFirst = false;
+ out << p;
+ }
+ return out.str();
+}*/
+
+// Accepts coins formatted "X Yp" where X is an integer and Y is any of c, s, e, g, p.
+int utils::coins2copper(const std::string& coins) {
+ int num = std::stoi(coins.substr(0, coins.find(" ")));
+ std::string denomination(coins.substr(coins.find(" ") + 1));
+ if(! cpValue.contains(denomination)) {
+ throw std::invalid_argument("Unknown coin type: " + denomination);
+ }
+ return num * cpValue.at(denomination);
+}
+
+// Greedily selects highest coin values to minimize total number of coins
+// Returns a vector of pairs mapping coin type to coint
+std::vector<std::pair<std::string, int>> utils::copper2coins(int coppers) {
+ std::vector<std::pair<std::string, int>> ret;
+ while(coppers > 0) {
+ // Find the largest denomination in cpValue under coppers
+ std::pair<std::string, int> largest("", 0);
+ for(auto pair : cpValue) {
+ if(pair.second <= coppers && pair.second > largest.second) {
+ largest = pair;
+ }
+ }
+ std::pair<std::string, int> amnt(largest.first, coppers / largest.second);
+ coppers -= amnt.second * largest.second;
+ ret.push_back(amnt);
+ }
+ return ret;
+}
+
+std::string utils::getCostString(int coppers) {
+ std::vector<std::string> parts;
+ for(auto pair : utils::copper2coins(coppers)) {
+ parts.push_back(std::to_string(pair.second) + " " + pair.first);
+ }
+ return utils::join(parts, ", ");
+}