From 17944c4d424ee63eb13c98ca7af22cd49503b384 Mon Sep 17 00:00:00 2001 From: dDogge Date: Sat, 14 Dec 2024 14:14:40 +0100 Subject: [PATCH] ordle.cc and ordle.h implemented --- ordle.cc | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ordle.h | 54 ++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 ordle.cc create mode 100644 ordle.h diff --git a/ordle.cc b/ordle.cc new file mode 100644 index 0000000..5c24777 --- /dev/null +++ b/ordle.cc @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include +#include + +// Helper types and aliases +using size_type = std::string::size_type; +using letters_and_indices = std::map; + +// Function to read candidates from a file +std::vector read_candidates(std::istream &input) { + std::vector candidates; + std::string word; + + while (input >> word) { + if (word.size() == 5) { + std::transform(word.begin(), word.end(), word.begin(), ::tolower); + candidates.push_back(word); + } + } + + // Remove duplicates + std::sort(candidates.begin(), candidates.end()); + candidates.erase(std::unique(candidates.begin(), candidates.end()), candidates.end()); + + return candidates; +} + +// Helper functions +bool contains_any_of(const std::string &s, const std::string &cs) { + return std::any_of(cs.begin(), cs.end(), [&s](char c) { return s.find(c) != std::string::npos; }); +} + +bool contains_at(const std::string &s, char c, size_type pos) { + return pos < s.size() && s[pos] == c; +} + +bool contains_but_not_at(const std::string &s, char c, size_type pos) { + return s.find(c) != std::string::npos && !contains_at(s, c, pos); +} + +// Functor for wrong letters +struct wrong_fn { + explicit wrong_fn(const std::string &letters) : l{letters} {} + + bool operator()(const std::string &word) const { + return contains_any_of(word, l); + } + +private: + std::string l; +}; + +// Functor for correct letters +struct correct_fn { + explicit correct_fn(const letters_and_indices &idxs) : m{idxs} {} + + bool operator()(const std::string &word) const { + return std::all_of(m.begin(), m.end(), [&word](const auto &pair) { + return contains_at(word, pair.second[0], pair.first); + }); + } + +private: + letters_and_indices m; +}; + +// Functor for misplaced letters +struct misplaced_fn { + explicit misplaced_fn(const letters_and_indices &idxs) : m{idxs} {} + + bool operator()(const std::string &word) const { + return std::all_of(m.begin(), m.end(), [&word](const auto &pair) { + return contains_but_not_at(word, pair.second[0], pair.first); + }); + } + +private: + letters_and_indices m; +}; + +// Function to filter candidates +void do_filter(std::vector &candidates, const std::string &wrong, + const letters_and_indices &green, const letters_and_indices &yellow) { + auto predicate = [&wrong, &green, &yellow](const std::string &word) { + return wrong_fn(wrong)(word) || !correct_fn(green)(word) || !misplaced_fn(yellow)(word); + }; + + candidates.erase(std::remove_if(candidates.begin(), candidates.end(), predicate), candidates.end()); +} + +// User interaction function +letters_and_indices build_list(const std::string &line) { + std::istringstream iss(line); + letters_and_indices result; + char letter; + size_type index; + + while (iss >> letter >> index) { + result[index] = std::string(1, letter); + } + + return result; +} + +std::tuple prompt() { + std::string wrong; + std::cout << "Enter wrong letters:\n"; + std::getline(std::cin, wrong); + + std::string correct; + std::cout << "Enter correct letters (letter index)*:\n"; + std::getline(std::cin, correct); + auto green = build_list(correct); + + std::string misplaced; + std::cout << "Enter misplaced letters (letter index)*:\n"; + std::getline(std::cin, misplaced); + auto yellow = build_list(misplaced); + + return {wrong, green, yellow}; +} \ No newline at end of file diff --git a/ordle.h b/ordle.h new file mode 100644 index 0000000..e328e96 --- /dev/null +++ b/ordle.h @@ -0,0 +1,54 @@ +#ifndef ORDLE_H +#define ORDLE_H + +#include +#include +#include +#include +#include +#include +#include + +// Helper types and aliases +using size_type = std::string::size_type; +using letters_and_indices = std::map; + +// Function declarations +std::vector read_candidates(std::istream &input); + +bool contains_any_of(const std::string &s, const std::string &cs); +bool contains_at(const std::string &s, char c, size_type pos); +bool contains_but_not_at(const std::string &s, char c, size_type pos); + +// Functors +struct wrong_fn { + explicit wrong_fn(const std::string &letters); + bool operator()(const std::string &word) const; + +private: + std::string l; +}; + +struct correct_fn { + explicit correct_fn(const letters_and_indices &idxs); + bool operator()(const std::string &word) const; + +private: + letters_and_indices m; +}; + +struct misplaced_fn { + explicit misplaced_fn(const letters_and_indices &idxs); + bool operator()(const std::string &word) const; + +private: + letters_and_indices m; +}; + +void do_filter(std::vector &candidates, const std::string &wrong, + const letters_and_indices &green, const letters_and_indices &yellow); + +letters_and_indices build_list(const std::string &line); +std::tuple prompt(); + +#endif // ORDLE_H