shithub: puzzles

Download patch

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.