diff --git a/cpp_impl/Makefile b/cpp_impl/Makefile index c0e5794..0e38582 100644 --- a/cpp_impl/Makefile +++ b/cpp_impl/Makefile @@ -7,7 +7,7 @@ endif OBJECTS = \ src/main.o \ - src/argparse.o + src/helpers.o all: GreedyTextJustification diff --git a/cpp_impl/src/argparse.cpp b/cpp_impl/src/argparse.cpp deleted file mode 100644 index 611ab24..0000000 --- a/cpp_impl/src/argparse.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "argparse.hpp" - -#include -#include - -std::unordered_map ArgParse::parseArgs( - int argc, - char **argv, - const std::vector &simpleArgs, - const std::vector &pairedArgs) { - std::unordered_map mapping; - - --argc; ++argv; - std::string temp; - bool mappingFound; - while(argc > 0) { - mappingFound = false; - for(const auto &s : simpleArgs) { - if(s.size() == 1) { - temp = std::string("-") + s; - } else { - temp = std::string("--") + s; - } - if(std::strcmp(temp.c_str(), argv[0]) == 0) { - mapping.insert({s, ""}); - mappingFound = true; - break; - } - } - if(mappingFound) { - --argc; ++argv; - continue; - } - for(const auto &s : pairedArgs) { - if(s.size() == 1) { - temp = std::string("-") + s; - } else { - temp = std::string("--") + s; - } - if(std::strncmp(temp.c_str(), argv[0], temp.size()) == 0) { - std::string arg; - if(argv[0][temp.size()] == '=') { - arg = argv[0] + temp.size() + 1; - } else { - if(argc > 1) { - --argc; - ++argv; - arg = argv[0]; - } else { - throw std::invalid_argument("Paired arg missing pair"); - } - } - mapping.insert({s, arg}); - mappingFound = true; - break; - } - } - - if(!mappingFound) { - throw std::invalid_argument("Got invalid arg"); - } - - --argc; ++argv; - } - - return mapping; -} diff --git a/cpp_impl/src/argparse.hpp b/cpp_impl/src/argparse.hpp deleted file mode 100644 index 485778d..0000000 --- a/cpp_impl/src/argparse.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GREEDY_TEXT_JUSTIFICATION_ARG_PARSE_HPP -#define GREEDY_TEXT_JUSTIFICATION_ARG_PARSE_HPP - -#include -#include -#include - -namespace ArgParse { - std::unordered_map parseArgs( - int argc, - char **argv, - const std::vector &simpleArgs, - const std::vector &pairedArgs); -} // namespace ArgParse - -#endif diff --git a/cpp_impl/src/helpers.cpp b/cpp_impl/src/helpers.cpp new file mode 100644 index 0000000..daca483 --- /dev/null +++ b/cpp_impl/src/helpers.cpp @@ -0,0 +1,152 @@ +#include "helpers.hpp" + +#include +#include +#include +#include + +std::unordered_map Helpers::parseArgs( + int argc, + char **argv, + const std::vector &simpleArgs, + const std::vector &pairedArgs) { + std::unordered_map mapping; + + --argc; ++argv; + std::string temp; + bool mappingFound; + while(argc > 0) { + mappingFound = false; + for(const auto &s : simpleArgs) { + if(s.size() == 1) { + temp = std::string("-") + s; + } else { + temp = std::string("--") + s; + } + if(std::strcmp(temp.c_str(), argv[0]) == 0) { + mapping.insert({s, ""}); + mappingFound = true; + break; + } + } + if(mappingFound) { + --argc; ++argv; + continue; + } + for(const auto &s : pairedArgs) { + if(s.size() == 1) { + temp = std::string("-") + s; + } else { + temp = std::string("--") + s; + } + if(std::strncmp(temp.c_str(), argv[0], temp.size()) == 0) { + std::string arg; + if(argv[0][temp.size()] == '=') { + arg = argv[0] + temp.size() + 1; + } else { + if(argc > 1) { + --argc; + ++argv; + arg = argv[0]; + } else { + throw std::invalid_argument("Paired arg missing pair"); + } + } + mapping.insert({s, arg}); + mappingFound = true; + break; + } + } + + if(!mappingFound) { + throw std::invalid_argument("Got invalid arg"); + } + + --argc; ++argv; + } + + return mapping; +} + +std::vector Helpers::strSplit(const std::string &s, std::vector delimeters) { + std::vector result; + std::string temp; + + std::sort(delimeters.begin(), delimeters.end()); + + for(char c : s) { + if(std::binary_search(delimeters.begin(), delimeters.end(), c)) { + if(!temp.empty()) { + result.push_back(temp); + temp.clear(); + } + } else { + temp += c; + } + } + if(!temp.empty()) { + result.push_back(temp); + } + + return result; +} + +void Helpers::printDividers(unsigned long long width) { + for(unsigned long long i = 0; i < width; ++i) { + if((i + 1) % 5 == 0) { + std::cout << "+"; + } else { + std::cout << "-"; + } + } + std::cout << std::endl; +} + +void Helpers::printGreedyTextJustification(unsigned long long width, const std::vector &tokens) { + const auto printCurrentLine = [width] (std::vector &words) { + unsigned long long spaces = width; + for(const auto &word : words) { + if(word.size() > spaces) { + spaces = 0; + } else { + spaces -= word.size(); + } + } + for(unsigned int i = 0; i < words.size(); ++i) { + std::cout << words.at(i); + for(unsigned int j = 0; j < spaces / words.size(); ++j) { + std::cout << ' '; + } + if(i == words.size() - 1) { + for(unsigned int j = 0; j < spaces % words.size(); ++j) { + std::cout << ' '; + } + } + } + std::cout << std::endl; + words.clear(); + }; + + std::vector currentLine; + unsigned long long currentToken = 0; + unsigned long long size = 0; + while(true) { + size += tokens.at(currentToken).size(); + if(size + 1 >= width) { + printCurrentLine(currentLine); + size = 0; + continue; + } else { + currentLine.push_back(tokens.at(currentToken)); + size += 1; + ++currentToken; + if(currentToken >= tokens.size()) { + break; + } + } + } + if(!currentLine.empty()) { + printCurrentLine(currentLine); + } +} + diff --git a/cpp_impl/src/helpers.hpp b/cpp_impl/src/helpers.hpp new file mode 100644 index 0000000..c3b5469 --- /dev/null +++ b/cpp_impl/src/helpers.hpp @@ -0,0 +1,22 @@ +#ifndef GREEDY_TEXT_JUSTIFICATION_ARG_HELPERS_HPP +#define GREEDY_TEXT_JUSTIFICATION_ARG_HELPERS_HPP + +#include +#include +#include + +namespace Helpers { + std::unordered_map parseArgs( + int argc, + char **argv, + const std::vector &simpleArgs, + const std::vector &pairedArgs); + + std::vector strSplit(const std::string &s, std::vector delimeters); + + void printDividers(unsigned long long width); + + void printGreedyTextJustification(unsigned long long width, const std::vector &tokens); +} // namespace Helpers + +#endif diff --git a/cpp_impl/src/main.cpp b/cpp_impl/src/main.cpp index b36f90e..c6fddaa 100644 --- a/cpp_impl/src/main.cpp +++ b/cpp_impl/src/main.cpp @@ -1,13 +1,44 @@ #include +#include +#include -#include "argparse.hpp" +#include "helpers.hpp" int main(int argc, char **argv) { - auto parsed = ArgParse::parseArgs(argc, argv, {"a", "b"}, {"apple"}); + auto parsed = Helpers::parseArgs(argc, argv, {}, {"w", "string"}); - for(auto pair : parsed) { - std::cout << pair.first << ", " << pair.second << std::endl; +// for(auto pair : parsed) { +// std::cout << pair.first << ", " << pair.second << std::endl; +// } + + unsigned long long width; + if(auto iter = parsed.find("w"); iter != parsed.end()) { + width = std::stoull(iter->second); + std::cout << "Got width == " << width << std::endl; + } else { + return 1; } + std::string str; + if(auto iter = parsed.find("string"); iter != parsed.end()) { + str = iter->second; + std::cout << "Got string == \"" << str << "\"" << std::endl; + } else { + return 2; + } + + Helpers::printDividers(width); + + std::vector tokens = Helpers::strSplit(str, {' ', '\n', '\r'}); + +// for(auto token : tokens) { +// std::cout << token << '\n'; +// } +// std::cout << std::endl; + + Helpers::printGreedyTextJustification(width, tokens); + + Helpers::printDividers(width); + return 0; }