#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}; }