aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keen.c7
-rw-r--r--latin.c39
-rw-r--r--latin.h9
-rw-r--r--towers.c7
-rw-r--r--unequal.c11
-rw-r--r--unfinished/group.c7
6 files changed, 58 insertions, 22 deletions
diff --git a/keen.c b/keen.c
index baa1d81..4c6e330 100644
--- a/keen.c
+++ b/keen.c
@@ -591,6 +591,11 @@ static int solver_hard(struct latin_solver *solver, void *vctx)
#define SOLVER(upper,title,func,lower) func,
static usersolver_t const keen_solvers[] = { DIFFLIST(SOLVER) };
+static bool keen_valid(struct latin_solver *solver, void *ctx)
+{
+ return true; /* FIXME */
+}
+
static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff)
{
int a = w*w;
@@ -638,7 +643,7 @@ static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff)
ret = latin_solver(soln, w, maxdiff,
DIFF_EASY, DIFF_HARD, DIFF_EXTREME,
DIFF_EXTREME, DIFF_UNREASONABLE,
- keen_solvers, &ctx, NULL, NULL);
+ keen_solvers, keen_valid, &ctx, NULL, NULL);
sfree(ctx.dscratch);
sfree(ctx.iscratch);
diff --git a/latin.c b/latin.c
index 9d06ccd..3993016 100644
--- a/latin.c
+++ b/latin.c
@@ -19,8 +19,8 @@
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;
@@ -711,7 +711,7 @@ int latin_solver_diff_set(struct latin_solver *solver,
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;
@@ -817,7 +817,8 @@ static int latin_solver_recurse
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);
@@ -879,8 +880,8 @@ static int latin_solver_recurse
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;
@@ -941,7 +942,8 @@ static int latin_solver_top(struct latin_solver *solver, int maxdiff,
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;
@@ -990,6 +992,17 @@ static int latin_solver_top(struct latin_solver *solver, int maxdiff,
}
#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;
@@ -998,8 +1011,8 @@ static int latin_solver_top(struct latin_solver *solver, int maxdiff,
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
@@ -1027,7 +1040,7 @@ int latin_solver_main(struct latin_solver *solver, int maxdiff,
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);
@@ -1040,8 +1053,8 @@ int latin_solver_main(struct latin_solver *solver, int maxdiff,
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;
@@ -1050,7 +1063,7 @@ int latin_solver(digit *grid, int o, int maxdiff,
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;
}
diff --git a/latin.h b/latin.h
index ff6f07c..bb172ec 100644
--- a/latin.h
+++ b/latin.h
@@ -85,6 +85,7 @@ int latin_solver_diff_set(struct latin_solver *solver,
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);
@@ -96,15 +97,15 @@ enum { diff_impossible = 10, diff_ambiguous, diff_unfinished };
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);
diff --git a/towers.c b/towers.c
index a72cae6..27d8751 100644
--- a/towers.c
+++ b/towers.c
@@ -574,6 +574,11 @@ static int solver_hard(struct latin_solver *solver, void *vctx)
#define SOLVER(upper,title,func,lower) func,
static usersolver_t const towers_solvers[] = { DIFFLIST(SOLVER) };
+static bool towers_valid(struct latin_solver *solver, void *ctx)
+{
+ return true; /* FIXME */
+}
+
static int solver(int w, int *clues, digit *soln, int maxdiff)
{
int ret;
@@ -589,7 +594,7 @@ static int solver(int w, int *clues, digit *soln, int maxdiff)
ret = latin_solver(soln, w, maxdiff,
DIFF_EASY, DIFF_HARD, DIFF_EXTREME,
DIFF_EXTREME, DIFF_UNREASONABLE,
- towers_solvers, &ctx, NULL, NULL);
+ towers_solvers, towers_valid, &ctx, NULL, NULL);
sfree(ctx.iscratch);
sfree(ctx.dscratch);
diff --git a/unequal.c b/unequal.c
index d5b2bb1..a1b01b8 100644
--- a/unequal.c
+++ b/unequal.c
@@ -816,6 +816,11 @@ static int solver_set(struct latin_solver *solver, void *vctx)
#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);
@@ -827,7 +832,8 @@ static int solver_state(game_state *state, int maxdiff)
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);
@@ -2155,7 +2161,8 @@ static int solve(game_params *p, char *desc, int debug)
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);
diff --git a/unfinished/group.c b/unfinished/group.c
index 3c565cb..3a44a67 100644
--- a/unfinished/group.c
+++ b/unfinished/group.c
@@ -448,6 +448,11 @@ static int solver_normal(struct latin_solver *solver, void *vctx)
#define SOLVER(upper,title,func,lower) func,
static usersolver_t const group_solvers[] = { DIFFLIST(SOLVER) };
+static bool group_valid(struct latin_solver *solver, void *ctx)
+{
+ return true; /* FIXME */
+}
+
static int solver(const game_params *params, digit *grid, int maxdiff)
{
int w = params->w;
@@ -471,7 +476,7 @@ static int solver(const game_params *params, digit *grid, int maxdiff)
ret = latin_solver_main(&solver, maxdiff,
DIFF_TRIVIAL, DIFF_HARD, DIFF_EXTREME,
DIFF_EXTREME, DIFF_UNREASONABLE,
- group_solvers, NULL, NULL, NULL);
+ group_solvers, group_valid, NULL, NULL, NULL);
latin_solver_free(&solver);