ref: 472deca37cef4e5f5c8cd865406fab71a44d0668
parent: 7a4170260687cfbbc0481e725a046afb5cbf4663
author: Simon Tatham <[email protected]>
date: Mon Jan 15 15:07:18 EST 2007
Patch from James H to fix the occasional generation of puzzles harder than requested. [originally from svn r7113]
--- a/latin.c
+++ b/latin.c
@@ -619,46 +619,46 @@
int latin_solver_diff_set(struct latin_solver *solver,
struct latin_solver_scratch *scratch,
- int *extreme)
+ int extreme)
{
int x, y, n, ret, o = solver->o;
- /*
- * Row-wise set elimination.
- */
- for (y = 0; y < o; y++) {
- ret = latin_solver_set(solver, scratch, cubepos(0,y,1), o*o, 1
+
+ if (!extreme) {
+ /*
+ * Row-wise set elimination.
+ */
+ for (y = 0; y < o; y++) {
+ ret = latin_solver_set(solver, scratch, cubepos(0,y,1), o*o, 1
#ifdef STANDALONE_SOLVER
- , "set elimination, row %d", YUNTRANS(y)
+ , "set elimination, row %d", YUNTRANS(y)
#endif
- );
- if (ret > 0) *extreme = 0;
- if (ret != 0) return ret;
- }
-
- /*
- * Column-wise set elimination.
- */
- for (x = 0; x < o; x++) {
- ret = latin_solver_set(solver, scratch, cubepos(x,0,1), o, 1
+ );
+ if (ret != 0) return ret;
+ }
+ /*
+ * Column-wise set elimination.
+ */
+ for (x = 0; x < o; x++) {
+ ret = latin_solver_set(solver, scratch, cubepos(x,0,1), o, 1
#ifdef STANDALONE_SOLVER
- , "set elimination, column %d", x
+ , "set elimination, column %d", x
#endif
- );
- if (ret > 0) *extreme = 0;
- if (ret != 0) return ret;
- }
-
- /*
- * Row-vs-column set elimination on a single number.
- */
- for (n = 1; n <= o; n++) {
- ret = latin_solver_set(solver, scratch, cubepos(0,0,n), o*o, o
+ );
+ if (ret != 0) return ret;
+ }
+ } else {
+ /*
+ * Row-vs-column set elimination on a single number
+ * (much tricker for a human to do!)
+ */
+ for (n = 1; n <= o; n++) {
+ ret = latin_solver_set(solver, scratch, cubepos(0,0,n), o*o, o
#ifdef STANDALONE_SOLVER
- , "positional set elimination, number %d", n
+ , "positional set elimination, number %d", n
#endif
- );
- if (ret > 0) *extreme = 1;
- if (ret != 0) return ret;
+ );
+ if (ret != 0) return ret;
+ }
}
return 0;
}
@@ -826,7 +826,7 @@
static int latin_solver_sub(struct latin_solver *solver, int maxdiff, void *ctx)
{
struct latin_solver_scratch *scratch = latin_solver_new_scratch(solver);
- int ret, diff = diff_simple, extreme;
+ int ret, diff = diff_simple;
assert(maxdiff <= diff_recursive);
/*
@@ -859,17 +859,26 @@
if (maxdiff <= diff_simple)
break;
- ret = latin_solver_diff_set(solver, scratch, &extreme);
+ ret = latin_solver_diff_set(solver, scratch, 0);
if (ret < 0) {
diff = diff_impossible;
goto got_result;
} else if (ret > 0) {
- diff = max(diff, extreme ? diff_extreme : diff_set);
+ diff = max(diff, diff_set);
goto cont;
}
if (maxdiff <= diff_set)
break;
+
+ ret = latin_solver_diff_set(solver, scratch, 1);
+ if (ret < 0) {
+ diff = diff_impossible;
+ goto got_result;
+ } else if (ret > 0) {
+ diff = max(diff, diff_extreme);
+ goto cont;
+ }
/*
* Forcing chains.
--- a/latin.h
+++ b/latin.h
@@ -86,7 +86,7 @@
* the more difficult single-number elimination. */
int latin_solver_diff_set(struct latin_solver *solver,
struct latin_solver_scratch *scratch,
- int *extreme);
+ int extreme);
typedef int (latin_solver_callback)(digit *, int, int, void*);
/* Use to provide a standard way of dealing with solvers which can recurse;
--- a/unequal.c
+++ b/unequal.c
@@ -631,7 +631,7 @@
game_solver *solver;
struct latin_solver *lsolver;
struct latin_solver_scratch *scratch;
- int ret, diff = DIFF_LATIN, extreme;
+ int ret, diff = DIFF_LATIN;
assert(maxdiff <= DIFF_RECURSIVE);
@@ -668,17 +668,27 @@
if (maxdiff <= DIFF_EASY)
break;
- ret = latin_solver_diff_set(lsolver, scratch, &extreme);
+ /* Row- and column-wise set elimination */
+ ret = latin_solver_diff_set(lsolver, scratch, 0);
if (ret < 0) {
diff = DIFF_IMPOSSIBLE;
goto got_result;
} else if (ret > 0) {
- diff = max(diff, extreme ? DIFF_EXTREME : DIFF_SET);
+ diff = max(diff, DIFF_SET);
goto cont;
}
if (maxdiff <= DIFF_SET)
break;
+
+ ret = latin_solver_diff_set(lsolver, scratch, 1);
+ if (ret < 0) {
+ diff = DIFF_IMPOSSIBLE;
+ goto got_result;
+ } else if (ret > 0) {
+ diff = max(diff, DIFF_EXTREME);
+ goto cont;
+ }
/*
* Forcing chains.