mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-20 23:51:29 -07:00
Keen: fill in the latin.c validator function.
This seems to make no difference that I can detect: a test generation run of the form 'keen --generate 1000 6du#12345' outputs an identical list of 1000 puzzle ids before and after. So the missing validation in this puzzle seems to have been benign.
This commit is contained in:
85
keen.c
85
keen.c
@ -591,9 +591,90 @@ static int solver_hard(struct latin_solver *solver, void *vctx)
|
|||||||
#define SOLVER(upper,title,func,lower) func,
|
#define SOLVER(upper,title,func,lower) func,
|
||||||
static usersolver_t const keen_solvers[] = { DIFFLIST(SOLVER) };
|
static usersolver_t const keen_solvers[] = { DIFFLIST(SOLVER) };
|
||||||
|
|
||||||
static bool keen_valid(struct latin_solver *solver, void *ctx)
|
static int transpose(int index, int w)
|
||||||
{
|
{
|
||||||
return true; /* FIXME */
|
return (index % w) * w + (index / w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool keen_valid(struct latin_solver *solver, void *vctx)
|
||||||
|
{
|
||||||
|
struct solver_ctx *ctx = (struct solver_ctx *)vctx;
|
||||||
|
int w = ctx->w;
|
||||||
|
int box, i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate over each clue box and check it's satisfied.
|
||||||
|
*/
|
||||||
|
for (box = 0; box < ctx->nboxes; box++) {
|
||||||
|
int *sq = ctx->boxlist + ctx->boxes[box];
|
||||||
|
int n = ctx->boxes[box+1] - ctx->boxes[box];
|
||||||
|
long value = ctx->clues[box] & ~CMASK;
|
||||||
|
long op = ctx->clues[box] & CMASK;
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case C_ADD: {
|
||||||
|
long sum = 0;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
sum += solver->grid[transpose(sq[i], w)];
|
||||||
|
fail = (sum != value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case C_MUL: {
|
||||||
|
long remaining = value;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (remaining % solver->grid[transpose(sq[i], w)]) {
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
remaining /= solver->grid[transpose(sq[i], w)];
|
||||||
|
}
|
||||||
|
if (remaining != 1)
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case C_SUB:
|
||||||
|
assert(n == 2);
|
||||||
|
if (value != labs(solver->grid[transpose(sq[0], w)] -
|
||||||
|
solver->grid[transpose(sq[1], w)]))
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case C_DIV: {
|
||||||
|
int num, den;
|
||||||
|
assert(n == 2);
|
||||||
|
num = max(solver->grid[transpose(sq[0], w)],
|
||||||
|
solver->grid[transpose(sq[1], w)]);
|
||||||
|
den = min(solver->grid[transpose(sq[0], w)],
|
||||||
|
solver->grid[transpose(sq[1], w)]);
|
||||||
|
if (den * value != num)
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fail) {
|
||||||
|
#ifdef STANDALONE_SOLVER
|
||||||
|
if (solver_show_working) {
|
||||||
|
printf("%*sclue at (%d,%d) is violated\n",
|
||||||
|
solver_recurse_depth*4, "",
|
||||||
|
sq[0]/w+1, sq[0]%w+1);
|
||||||
|
printf("%*s (%s clue with target %ld containing [",
|
||||||
|
solver_recurse_depth*4, "",
|
||||||
|
(op == C_ADD ? "addition" : op == C_SUB ? "subtraction":
|
||||||
|
op == C_MUL ? "multiplication" : "division"), value);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
printf(" %d", (int)solver->grid[transpose(sq[i], w)]);
|
||||||
|
printf(" ]\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff)
|
static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff)
|
||||||
|
Reference in New Issue
Block a user