2024-12-26 16:00:48 +01:00
|
|
|
#include "ordle.h"
|
2024-12-14 14:14:40 +01:00
|
|
|
#include <algorithm>
|
2024-12-26 16:00:48 +01:00
|
|
|
#include <iostream>
|
2024-12-14 14:14:40 +01:00
|
|
|
#include <map>
|
2024-12-26 16:00:48 +01:00
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2024-12-14 14:14:40 +01:00
|
|
|
|
|
|
|
std::vector<std::string> read_candidates(std::istream &input) {
|
|
|
|
std::vector<std::string> candidates;
|
2024-12-26 16:00:48 +01:00
|
|
|
std::string line;
|
|
|
|
|
|
|
|
while (std::getline(input, line)) {
|
|
|
|
if (!line.empty() && line.back() == '\r') {
|
|
|
|
line.pop_back();
|
|
|
|
}
|
2024-12-14 14:14:40 +01:00
|
|
|
|
2024-12-26 16:00:48 +01:00
|
|
|
if (line.size() == 5) {
|
|
|
|
std::transform(line.begin(), line.end(), line.begin(), ::tolower);
|
|
|
|
candidates.push_back(line);
|
2024-12-14 14:14:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort(candidates.begin(), candidates.end());
|
2024-12-26 16:00:48 +01:00
|
|
|
|
|
|
|
candidates.erase(std::unique(candidates.begin(), candidates.end()),
|
|
|
|
candidates.end());
|
2024-12-14 14:14:40 +01:00
|
|
|
|
|
|
|
return candidates;
|
|
|
|
}
|
|
|
|
|
2024-12-26 16:00:48 +01:00
|
|
|
bool wrong_fn::operator()(const std::string &word) const {
|
|
|
|
return contains_any_of(word, l);
|
2024-12-14 14:14:40 +01:00
|
|
|
}
|
|
|
|
|
2024-12-26 16:00:48 +01:00
|
|
|
bool correct_fn::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);
|
|
|
|
});
|
2024-12-14 14:14:40 +01:00
|
|
|
}
|
|
|
|
|
2024-12-26 16:00:48 +01:00
|
|
|
bool misplaced_fn::operator()(const std::string &word) const {
|
|
|
|
return std::all_of(m.begin(), m.end(), [&word](const auto &pair) {
|
|
|
|
auto a = contains_but_not_at(word, pair.second[0], pair.first);
|
|
|
|
if (a)
|
|
|
|
std::cout << "Misplaced: " << word << std::endl;
|
|
|
|
return a;
|
|
|
|
});
|
2024-12-14 14:14:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void do_filter(std::vector<std::string> &candidates, const std::string &wrong,
|
2024-12-26 16:00:48 +01:00
|
|
|
const IndexMap &green, const IndexMap &yellow) {
|
2024-12-14 14:14:40 +01:00
|
|
|
auto predicate = [&wrong, &green, &yellow](const std::string &word) {
|
2024-12-26 16:00:48 +01:00
|
|
|
return wrong_fn(wrong)(word) || !correct_fn(green)(word) ||
|
|
|
|
!misplaced_fn(yellow)(word);
|
2024-12-14 14:14:40 +01:00
|
|
|
};
|
|
|
|
|
2024-12-26 16:00:48 +01:00
|
|
|
// Remove all words that do not satisfy the conditions
|
|
|
|
candidates.erase(
|
|
|
|
std::remove_if(candidates.begin(), candidates.end(), predicate),
|
|
|
|
candidates.end());
|
2024-12-14 14:14:40 +01:00
|
|
|
}
|
|
|
|
|
2024-12-26 16:00:48 +01:00
|
|
|
IndexMap build_list(const std::string &line) {
|
2024-12-14 14:14:40 +01:00
|
|
|
std::istringstream iss(line);
|
2024-12-26 16:00:48 +01:00
|
|
|
IndexMap result;
|
2024-12-14 14:14:40 +01:00
|
|
|
char letter;
|
|
|
|
size_type index;
|
|
|
|
|
|
|
|
while (iss >> letter >> index) {
|
|
|
|
result[index] = std::string(1, letter);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-12-26 16:00:48 +01:00
|
|
|
std::tuple<std::string, IndexMap, IndexMap> prompt() {
|
2024-12-14 14:14:40 +01:00
|
|
|
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};
|
2024-12-26 16:00:48 +01:00
|
|
|
}
|