static int latin_solver_top(struct latin_solver *solver, int maxdiff,
int diff_simple, int diff_set_0, int diff_set_1,
int diff_forcing, int diff_recursive,
- usersolver_t const *usersolvers, void *ctx,
- ctxnew_t ctxnew, ctxfree_t ctxfree);
+ usersolver_t const *usersolvers, validator_t valid,
+ void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree);
#ifdef STANDALONE_SOLVER
int solver_show_working, solver_recurse_depth;
static int latin_solver_recurse
(struct latin_solver *solver, int diff_simple, int diff_set_0,
int diff_set_1, int diff_forcing, int diff_recursive,
- usersolver_t const *usersolvers, void *ctx,
+ usersolver_t const *usersolvers, validator_t valid, void *ctx,
ctxnew_t ctxnew, ctxfree_t ctxfree)
{
int best, bestcount;
ret = latin_solver_top(&subsolver, diff_recursive,
diff_simple, diff_set_0, diff_set_1,
diff_forcing, diff_recursive,
- usersolvers, newctx, ctxnew, ctxfree);
+ usersolvers, valid, newctx,
+ ctxnew, ctxfree);
latin_solver_free(&subsolver);
if (ctxnew)
ctxfree(newctx);
static int latin_solver_top(struct latin_solver *solver, int maxdiff,
int diff_simple, int diff_set_0, int diff_set_1,
int diff_forcing, int diff_recursive,
- usersolver_t const *usersolvers, void *ctx,
- ctxnew_t ctxnew, ctxfree_t ctxfree)
+ usersolver_t const *usersolvers, validator_t valid,
+ void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree)
{
struct latin_solver_scratch *scratch = latin_solver_new_scratch(solver);
int ret, diff = diff_simple;
int nsol = latin_solver_recurse(solver,
diff_simple, diff_set_0, diff_set_1,
diff_forcing, diff_recursive,
- usersolvers, ctx, ctxnew, ctxfree);
+ usersolvers, valid, ctx,
+ ctxnew, ctxfree);
if (nsol < 0) diff = diff_impossible;
else if (nsol == 1) diff = diff_recursive;
else if (nsol > 1) diff = diff_ambiguous;
}
#endif
+ if (diff != diff_impossible && diff != diff_unfinished &&
+ diff != diff_ambiguous && valid && !valid(solver, ctx)) {
+#ifdef STANDALONE_SOLVER
+ if (solver_show_working) {
+ printf("%*ssolution failed final validation!\n",
+ solver_recurse_depth*4, "");
+ }
+#endif
+ diff = diff_impossible;
+ }
+
latin_solver_free_scratch(scratch);
return diff;
int latin_solver_main(struct latin_solver *solver, int maxdiff,
int diff_simple, int diff_set_0, int diff_set_1,
int diff_forcing, int diff_recursive,
- usersolver_t const *usersolvers, void *ctx,
- ctxnew_t ctxnew, ctxfree_t ctxfree)
+ usersolver_t const *usersolvers, validator_t valid,
+ void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree)
{
int diff;
#ifdef STANDALONE_SOLVER
diff = latin_solver_top(solver, maxdiff,
diff_simple, diff_set_0, diff_set_1,
diff_forcing, diff_recursive,
- usersolvers, ctx, ctxnew, ctxfree);
+ usersolvers, valid, ctx, ctxnew, ctxfree);
#ifdef STANDALONE_SOLVER
sfree(names);
int latin_solver(digit *grid, int o, int maxdiff,
int diff_simple, int diff_set_0, int diff_set_1,
int diff_forcing, int diff_recursive,
- usersolver_t const *usersolvers, void *ctx,
- ctxnew_t ctxnew, ctxfree_t ctxfree)
+ usersolver_t const *usersolvers, validator_t valid,
+ void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree)
{
struct latin_solver solver;
int diff;
diff = latin_solver_main(&solver, maxdiff,
diff_simple, diff_set_0, diff_set_1,
diff_forcing, diff_recursive,
- usersolvers, ctx, ctxnew, ctxfree);
+ usersolvers, valid, ctx, ctxnew, ctxfree);
latin_solver_free(&solver);
return diff;
}
bool extreme);
typedef int (*usersolver_t)(struct latin_solver *solver, void *ctx);
+typedef bool (*validator_t)(struct latin_solver *solver, void *ctx);
typedef void *(*ctxnew_t)(void *ctx);
typedef void (*ctxfree_t)(void *ctx);
int latin_solver(digit *grid, int o, int maxdiff,
int diff_simple, int diff_set_0, int diff_set_1,
int diff_forcing, int diff_recursive,
- usersolver_t const *usersolvers, void *ctx,
- ctxnew_t ctxnew, ctxfree_t ctxfree);
+ usersolver_t const *usersolvers, validator_t valid,
+ void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree);
/* Version you can call if you want to alloc and free latin_solver yourself */
int latin_solver_main(struct latin_solver *solver, int maxdiff,
int diff_simple, int diff_set_0, int diff_set_1,
int diff_forcing, int diff_recursive,
- usersolver_t const *usersolvers, void *ctx,
- ctxnew_t ctxnew, ctxfree_t ctxfree);
+ usersolver_t const *usersolvers, validator_t valid,
+ void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree);
void latin_solver_debug(unsigned char *cube, int o);
#define SOLVER(upper,title,func,lower) func,
static usersolver_t const unequal_solvers[] = { DIFFLIST(SOLVER) };
+static bool unequal_valid(struct latin_solver *solver, void *ctx)
+{
+ return true; /* FIXME */
+}
+
static int solver_state(game_state *state, int maxdiff)
{
struct solver_ctx *ctx = new_ctx(state);
diff = latin_solver_main(&solver, maxdiff,
DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
DIFF_EXTREME, DIFF_RECURSIVE,
- unequal_solvers, ctx, clone_ctx, free_ctx);
+ unequal_solvers, unequal_valid, ctx,
+ clone_ctx, free_ctx);
memcpy(state->hints, solver.cube, state->order*state->order*state->order);
diff = latin_solver_main(&solver, DIFF_RECURSIVE,
DIFF_LATIN, DIFF_SET, DIFF_EXTREME,
DIFF_EXTREME, DIFF_RECURSIVE,
- unequal_solvers, ctx, clone_ctx, free_ctx);
+ unequal_solvers, unequal_valid, ctx,
+ clone_ctx, free_ctx);
free_ctx(ctx);