Wordsearch Solver
solver.hpp
1 #ifndef SOLVER_HPP
2 #define SOLVER_HPP
3 
4 #include "matrix2d/matrix2d.hpp"
5 #include "wordsearch_solver/config.hpp"
6 
7 #include <range/v3/view/all.hpp>
8 #include <range/v3/view/view.hpp>
9 
10 #include <string>
11 #include <string_view>
12 #include <type_traits>
13 #include <unordered_map>
14 #include <utility>
15 #include <variant>
16 #include <vector>
17 
25 namespace solver {
26 
28 using Index = matrix2d::Index;
29 using Tail = std::vector<Index>;
30 using ListOfListsOfIndexes = std::vector<Tail>;
31 using WordToListOfListsOfIndexes =
32  std::unordered_map<std::string, ListOfListsOfIndexes>;
33 // Would like to use heterogenous map here to be able to lookup using
34 // string_view's, but even if use a custom hash with string/string_view
35 // overloads on operator(), and std::equal_to<void> template args, the
36 // std::unordered_map.find() templated version is c++20
37 using WordsearchGrid = matrix2d::Matrix2d<char>;
38 
49 template <class SolverDict>
50 void solve_index(const SolverDict& solver_dict, const WordsearchGrid& grid,
51  const Index start_index,
52  WordToListOfListsOfIndexes& word_to_list_of_indexes);
53 
61 template <class SolverDict>
62 WordToListOfListsOfIndexes solve(const SolverDict& solver_dict,
63  const WordsearchGrid& grid);
64 
66 WordsearchGrid make_grid(const std::vector<std::string>& lines);
67 
76  std::variant<WORDSEARCH_DICTIONARY_CLASSES> t_;
77  static_assert(std::is_move_constructible_v<decltype(t_)>);
78 
79  template <class Func> auto run(Func&& func) const;
80 
81 public:
82  template <class SolverDict, class Words>
83  SolverDictWrapper(const SolverDict& solver_dict, Words&& words);
84 
86  SolverDictWrapper& operator=(SolverDictWrapper&&) = default;
87 
89  std::size_t size() const;
90 
92  bool empty() const;
93 
99  bool contains(const std::string_view word) const;
100 
113  bool further(const std::string_view word) const;
114 
148  template <class OutputIndexIterator>
149  void contains_further(const std::string_view stem,
150  const std::string_view suffixes,
151  OutputIndexIterator contains_further_it) const;
152 };
153 
154 static_assert(std::is_move_constructible_v<SolverDictWrapper>);
155 static_assert(std::is_move_assignable_v<SolverDictWrapper>);
156 
174  std::vector<std::string> solvers;
175 
176 public:
178 
183  bool has_solver(const std::string_view solver) const;
184 
190  auto solver_names() const -> decltype(ranges::views::all(solvers));
191 
198  template <class Words>
199  SolverDictWrapper make(const std::string_view solver,
200  Words&& dictionary) const;
201 };
202 
203 } // namespace solver
204 
205 #include "wordsearch_solver/solver/solver.tpp"
206 
207 #endif // SOLVER_HPP
This class can be used to check if a particular dictionary solver implementation exists,...
Definition: solver.hpp:173
auto solver_names() const -> decltype(ranges::views::all(solvers))
A view onto the names of available solvers.
Definition: solver.cpp:75
SolverDictWrapper make(const std::string_view solver, Words &&dictionary) const
Make a dictionary solver.
Definition: solver.tpp:330
bool has_solver(const std::string_view solver) const
Check if a dictionary solver implementation called solver exists.
Definition: solver.cpp:70
A type erased wrapper around a particular solver dictionary implementation.
Definition: solver.hpp:75
bool further(const std::string_view word) const
Check if this dictionary might contain words with word as a prefix.
Definition: solver.cpp:48
bool contains(const std::string_view word) const
Check if this dictionary contains word.
Definition: solver.cpp:44
bool empty() const
Checks if this dictionary is empty.
Definition: solver.cpp:40
void contains_further(const std::string_view stem, const std::string_view suffixes, OutputIndexIterator contains_further_it) const
For each char in suffix appended to stem, check whether this dictionary contains this word and if it ...
Definition: solver.tpp:321
std::size_t size() const
The number of whole words in this dictionary.
Definition: solver.cpp:36
Classes to solve a wordsearch.
Definition: solver.hpp:25
void solve_index(const SolverDict &solver_dict, const WordsearchGrid &grid, const Index start_index, WordToListOfListsOfIndexes &word_to_list_of_indexes)
Find all possible words using solver_dict that may start at start_index in grid, and write them out t...
Definition: solver.tpp:75
matrix2d::Index Index
2 element coordinate
Definition: solver.hpp:28
WordsearchGrid make_grid(const std::vector< std::string > &lines)
Helper function to construct a WordsearchGrid
Definition: solver.cpp:17
WordToListOfListsOfIndexes solve(const SolverDict &solver_dict, const WordsearchGrid &grid)
Runs solve_index() on every element of grid to solve the whole wordsearch.
Definition: solver.tpp:297