53 lines
1.1 KiB
C++
53 lines
1.1 KiB
C++
#pragma once
|
|
|
|
#include "data.hpp"
|
|
#include "clusters.hpp"
|
|
#include <vector>
|
|
|
|
template <typename Grid>
|
|
struct State {
|
|
using Trace = typename Solutions<Grid>::Trace;
|
|
Trace trace; // current trace being considered
|
|
};
|
|
|
|
template <typename T>
|
|
auto pop(std::vector<T> & v){
|
|
v.erase(v.end()-1);
|
|
}
|
|
|
|
template <typename Grid, typename Rules>
|
|
auto solve_impl(Grid const & grid, Rules const & rules, State<Grid> & state, Solutions<Grid> & solutions){
|
|
if(grid.empty()){
|
|
// solved path
|
|
solutions.traces.push_back(state.trace);
|
|
return;
|
|
}
|
|
|
|
auto&& clusters = all_clusters(grid, rules);
|
|
if(clusters.empty()){
|
|
// unsolvable path
|
|
return;
|
|
}
|
|
|
|
for(auto&& c : clusters){
|
|
// remove the cluster
|
|
state.trace.push_back(*c.begin());
|
|
auto new_grid = make_empty(grid, c);
|
|
|
|
// recurse
|
|
solve_impl(new_grid, rules, state, solutions);
|
|
|
|
// go on with next cluster
|
|
pop(state.trace);
|
|
}
|
|
return;
|
|
}
|
|
|
|
template <typename Grid, typename Rules>
|
|
auto solve(Grid const & grid, Rules const & rules){
|
|
Solutions<Grid> solutions;
|
|
State<Grid> state;
|
|
state.trace.reserve(10);
|
|
solve_impl(grid, rules, state, solutions);
|
|
return solutions;
|
|
}
|