Fixing and extending tests
This commit is contained in:
parent
91a796d2cc
commit
8bbe5591c3
3 changed files with 79 additions and 30 deletions
31
ordle.cc
31
ordle.cc
|
@ -1,7 +1,7 @@
|
||||||
#include "ordle.h"
|
#include "ordle.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -30,22 +30,31 @@ std::vector<std::string> read_candidates(std::istream &input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wrong_fn::operator()(const std::string &word) const {
|
bool wrong_fn::operator()(const std::string &word) const {
|
||||||
return contains_any_of(word, l);
|
return contains_any_of(word, letter_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool correct_fn::operator()(const std::string &word) const {
|
bool correct_fn::operator()(const std::string &word) const {
|
||||||
return std::all_of(m.begin(), m.end(), [&word](const auto &pair) {
|
return std::all_of(map.begin(), map.end(), [&word](const auto &pair) {
|
||||||
return contains_at(word, pair.second[0], pair.first);
|
return contains_at(word, pair.second, pair.first);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:Correct but ugly
|
||||||
bool misplaced_fn::operator()(const std::string &word) const {
|
bool misplaced_fn::operator()(const std::string &word) const {
|
||||||
return std::all_of(m.begin(), m.end(), [&word](const auto &pair) {
|
if (std::all_of(map.begin(), map.end(), [&word](const auto &pair) {
|
||||||
auto a = contains_but_not_at(word, pair.second[0], pair.first);
|
return pair.first < word.size() && word[pair.first] == pair.second;
|
||||||
if (a)
|
})) {
|
||||||
std::cout << "Misplaced: " << word << std::endl;
|
return false;
|
||||||
return a;
|
}
|
||||||
});
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_filter(std::vector<std::string> &candidates, const std::string &wrong,
|
void do_filter(std::vector<std::string> &candidates, const std::string &wrong,
|
||||||
|
@ -68,7 +77,7 @@ IndexMap build_list(const std::string &line) {
|
||||||
size_type index;
|
size_type index;
|
||||||
|
|
||||||
while (iss >> letter >> index) {
|
while (iss >> letter >> index) {
|
||||||
result[index] = std::string(1, letter);
|
result[index] = letter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
16
ordle.h
16
ordle.h
|
@ -27,7 +27,7 @@ using size_type = std::string::size_type;
|
||||||
*
|
*
|
||||||
* @see correct_fn, misplaced_fn, build_list
|
* @see correct_fn, misplaced_fn, build_list
|
||||||
*/
|
*/
|
||||||
using IndexMap = std::map<size_type, std::string>;
|
using IndexMap = std::map<size_type, char>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a list of words from an input stream where each word is separated by a
|
* Reads a list of words from an input stream where each word is separated by a
|
||||||
|
@ -92,7 +92,7 @@ struct wrong_fn {
|
||||||
* @param letters A string containing the letters that words should not
|
* @param letters A string containing the letters that words should not
|
||||||
* contain.
|
* contain.
|
||||||
*/
|
*/
|
||||||
wrong_fn(const std::string &letters) : l{letters} {}
|
wrong_fn(const std::string &letters) : letter_set{letters} {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a word contains any of the specified "wrong" letters.
|
* Checks if a word contains any of the specified "wrong" letters.
|
||||||
|
@ -103,7 +103,7 @@ struct wrong_fn {
|
||||||
bool operator()(const std::string &word) const;
|
bool operator()(const std::string &word) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string l; ///< The letters considered "wrong".
|
std::string letter_set; ///< The letters considered "wrong".
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,7 +116,7 @@ struct correct_fn {
|
||||||
* @param idxs A map of indices to characters representing the exact
|
* @param idxs A map of indices to characters representing the exact
|
||||||
* matches.
|
* matches.
|
||||||
*/
|
*/
|
||||||
correct_fn(const IndexMap &idxs) : m{idxs} {}
|
correct_fn(const IndexMap &idxs) : map{idxs} {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a word contains the correct characters at the specified
|
* Checks if a word contains the correct characters at the specified
|
||||||
|
@ -128,7 +128,7 @@ struct correct_fn {
|
||||||
bool operator()(const std::string &word) const;
|
bool operator()(const std::string &word) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IndexMap m; ///< Map of indices to expected characters.
|
IndexMap map; ///< Map of indices to expected characters.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,20 +141,20 @@ struct misplaced_fn {
|
||||||
* @param idxs A map of indices to characters representing misplaced
|
* @param idxs A map of indices to characters representing misplaced
|
||||||
* matches.
|
* matches.
|
||||||
*/
|
*/
|
||||||
misplaced_fn(const IndexMap &idxs) : m{idxs} {}
|
misplaced_fn(const IndexMap &idxs) : map{idxs} {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a word contains the specified characters but at incorrect
|
* Checks if a word contains the specified characters but at incorrect
|
||||||
* positions.
|
* positions.
|
||||||
*
|
*
|
||||||
* @param word The word to be checked.
|
* @param word The word to be checked.
|
||||||
* @return True if the word contains the characters but at incorrect
|
* @return True if the word contains ALL of the characters but at incorrect
|
||||||
* positions; false otherwise.
|
* positions; false otherwise.
|
||||||
*/
|
*/
|
||||||
bool operator()(const std::string &word) const;
|
bool operator()(const std::string &word) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IndexMap m; ///< Map of indices to misplaced characters.
|
IndexMap map; ///< Map of indices to misplaced characters.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
62
test/test.cc
62
test/test.cc
|
@ -29,6 +29,7 @@ void test_contains_at() {
|
||||||
void test_contains_but_not_at() {
|
void test_contains_but_not_at() {
|
||||||
assert(contains_but_not_at("apple", 'p', 0));
|
assert(contains_but_not_at("apple", 'p', 0));
|
||||||
assert(!contains_but_not_at("apple", 'a', 0));
|
assert(!contains_but_not_at("apple", 'a', 0));
|
||||||
|
assert(!contains_but_not_at("abc", 'k', 1000));
|
||||||
std::cout << "test_contains_but_not_at passed.\n";
|
std::cout << "test_contains_but_not_at passed.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ void test_wrong_fn() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_correct_fn() {
|
void test_correct_fn() {
|
||||||
IndexMap green = {{0, "a"}, {4, "e"}};
|
IndexMap green = {{0, 'a'}, {4, 'e'}};
|
||||||
correct_fn correct(green);
|
correct_fn correct(green);
|
||||||
assert(correct("apple"));
|
assert(correct("apple"));
|
||||||
assert(correct("ample"));
|
assert(correct("ample"));
|
||||||
|
@ -49,11 +50,12 @@ void test_correct_fn() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_misplaced_fn() {
|
void test_misplaced_fn() {
|
||||||
IndexMap yellow = {{1, "p"}, {2, "p"}};
|
IndexMap yellow = {{1, 'p'}, {2, 'p'}};
|
||||||
misplaced_fn misplaced(yellow);
|
misplaced_fn misplaced(yellow);
|
||||||
|
|
||||||
assert(!misplaced("apple"));
|
assert(!misplaced("apple"));
|
||||||
assert(misplaced("puppy"));
|
assert(misplaced("puppy"));
|
||||||
|
assert(!misplaced("joink"));
|
||||||
|
|
||||||
std::cout << "test_misplaced_fn passed.\n";
|
std::cout << "test_misplaced_fn passed.\n";
|
||||||
}
|
}
|
||||||
|
@ -61,20 +63,58 @@ void test_misplaced_fn() {
|
||||||
void test_do_filter() {
|
void test_do_filter() {
|
||||||
std::vector<std::string> candidates = {"apple", "ample", "angle"};
|
std::vector<std::string> candidates = {"apple", "ample", "angle"};
|
||||||
std::string wrong = "iou";
|
std::string wrong = "iou";
|
||||||
IndexMap green = {{0, "a"}};
|
IndexMap green = {{0, 'a'}, {1, 'p'}};
|
||||||
IndexMap yellow = {{4, "e"}};
|
IndexMap yellow = {{3, 'e'}};
|
||||||
|
|
||||||
do_filter(candidates, wrong, green, yellow);
|
do_filter(candidates, wrong, green, yellow);
|
||||||
|
|
||||||
|
std::for_each(candidates.begin(), candidates.end(),
|
||||||
|
[&](auto &word) { std::cout << word << std::endl; });
|
||||||
|
|
||||||
assert(candidates == std::vector<std::string>{"apple"});
|
assert(candidates == std::vector<std::string>{"apple"});
|
||||||
std::cout << "test_do_filter passed.\n";
|
std::cout << "test_do_filter passed.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_build_list() {
|
void test_build_list() {
|
||||||
auto result = build_list("a:0 e:4");
|
{
|
||||||
auto l = IndexMap{{0, "a"}, {4, "e"}};
|
std::string input = "a0 b1 c2";
|
||||||
assert(result == l);
|
IndexMap result = build_list(input);
|
||||||
std::cout << "test_build_list passed.\n";
|
|
||||||
|
assert(result.size() == 3);
|
||||||
|
assert(result[0] == 'a');
|
||||||
|
assert(result[1] == 'b');
|
||||||
|
assert(result[2] == 'c');
|
||||||
|
|
||||||
|
std::cout << "Test case 1 passed.\n";
|
||||||
|
}
|
||||||
|
{ // Empty input
|
||||||
|
std::string input = "";
|
||||||
|
IndexMap result = build_list(input);
|
||||||
|
|
||||||
|
assert(result.empty());
|
||||||
|
|
||||||
|
std::cout << "Test case 2 passed.\n";
|
||||||
|
}
|
||||||
|
{ // Single input
|
||||||
|
std::string input = "z9";
|
||||||
|
IndexMap result = build_list(input);
|
||||||
|
|
||||||
|
assert(result.size() == 1);
|
||||||
|
assert(result[9] == 'z');
|
||||||
|
|
||||||
|
std::cout << "Test case 3 passed.\n";
|
||||||
|
}
|
||||||
|
{ // Irregular spacing
|
||||||
|
std::string input = "x3 y4 z5";
|
||||||
|
IndexMap result = build_list(input);
|
||||||
|
|
||||||
|
assert(result.size() == 3);
|
||||||
|
assert(result[3] == 'x');
|
||||||
|
assert(result[4] == 'y');
|
||||||
|
assert(result[5] == 'z');
|
||||||
|
|
||||||
|
std::cout << "Test case 4 passed.\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -84,9 +124,9 @@ int main() {
|
||||||
test_contains_but_not_at();
|
test_contains_but_not_at();
|
||||||
test_wrong_fn();
|
test_wrong_fn();
|
||||||
test_correct_fn();
|
test_correct_fn();
|
||||||
// test_misplaced_fn(); // Misbehaves
|
test_misplaced_fn();
|
||||||
// test_do_filter(); // Misbehaves
|
test_do_filter();
|
||||||
// test_build_list(); // Misbehaves
|
test_build_list();
|
||||||
|
|
||||||
std::cout << "All tests passed!\n";
|
std::cout << "All tests passed!\n";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue