ordle/ordle.cc

103 lines
2.8 KiB
C++
Raw Normal View History

#include "ordle.h"
2024-12-14 14:14:40 +01:00
#include <algorithm>
#include <iostream>
2024-12-26 19:34:21 +01:00
#include <iterator>
#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;
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
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());
candidates.erase(std::unique(candidates.begin(), candidates.end()),
candidates.end());
2024-12-14 14:14:40 +01:00
return candidates;
}
bool wrong_fn::operator()(const std::string &word) const {
2024-12-26 19:34:21 +01:00
return contains_any_of(word, letter_set);
2024-12-14 14:14:40 +01:00
}
bool correct_fn::operator()(const std::string &word) const {
2024-12-26 19:34:21 +01:00
return std::all_of(map.begin(), map.end(), [&word](const auto &pair) {
return contains_at(word, pair.second, pair.first);
});
2024-12-14 14:14:40 +01:00
}
2024-12-26 19:34:21 +01:00
// TODO:Correct but ugly
bool misplaced_fn::operator()(const std::string &word) const {
2024-12-26 19:34:21 +01:00
if (std::all_of(map.begin(), map.end(), [&word](const auto &pair) {
return pair.first < word.size() && word[pair.first] == pair.second;
})) {
return false;
}
if (std::any_of(map.begin(), map.end(), [&word](const auto &pair) {
return std::find(word.begin(), word.end(), pair.second) !=
word.end();
})) {
return true;
}
return false;
2024-12-14 14:14:40 +01:00
}
void do_filter(std::vector<std::string> &candidates, const std::string &wrong,
const IndexMap &green, const IndexMap &yellow) {
2024-12-14 14:14:40 +01:00
auto predicate = [&wrong, &green, &yellow](const std::string &word) {
return wrong_fn(wrong)(word) || !correct_fn(green)(word) ||
!misplaced_fn(yellow)(word);
2024-12-14 14:14:40 +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
}
IndexMap build_list(const std::string &line) {
2024-12-14 14:14:40 +01:00
std::istringstream iss(line);
IndexMap result;
2024-12-14 14:14:40 +01:00
char letter;
size_type index;
while (iss >> letter >> index) {
2024-12-26 19:34:21 +01:00
result[index] = letter;
2024-12-14 14:14:40 +01:00
}
return result;
}
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};
}