Add a facility in the latin.c solver diagnostics to allow a puzzle
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 5 Jan 2010 23:40:40 +0000 (23:40 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 5 Jan 2010 23:40:40 +0000 (23:40 +0000)
to call the digit values by custom names.

git-svn-id: svn://svn.tartarus.org/sgt/puzzles@8811 cda61777-01e9-0310-a592-d414129be87e

latin.c
latin.h

diff --git a/latin.c b/latin.c
index a1117e0..1613ebd 100644 (file)
--- a/latin.c
+++ b/latin.c
  * Solver.
  */
 
+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);
+
 #ifdef STANDALONE_SOLVER
 int solver_show_working, solver_recurse_depth;
 #endif
@@ -72,6 +78,9 @@ int latin_solver_elim(struct latin_solver *solver, int start, int step
                      )
 {
     int o = solver->o;
+#ifdef STANDALONE_SOLVER
+    char **names = solver->names;
+#endif
     int fpos, m, i;
 
     /*
@@ -103,8 +112,9 @@ int latin_solver_elim(struct latin_solver *solver, int start, int step
                 va_start(ap, fmt);
                 vprintf(fmt, ap);
                 va_end(ap);
-                printf(":\n%*s  placing %d at (%d,%d)\n",
-                       solver_recurse_depth*4, "", n, x+1, YUNTRANS(y)+1);
+                printf(":\n%*s  placing %s at (%d,%d)\n",
+                       solver_recurse_depth*4, "", names[n-1],
+                      x+1, YUNTRANS(y)+1);
             }
 #endif
             latin_solver_place(solver, x, y, n);
@@ -145,6 +155,9 @@ int latin_solver_set(struct latin_solver *solver,
                      )
 {
     int o = solver->o;
+#ifdef STANDALONE_SOLVER
+    char **names = solver->names;
+#endif
     int i, j, n, count;
     unsigned char *grid = scratch->grid;
     unsigned char *rowidx = scratch->rowidx;
@@ -292,9 +305,9 @@ int latin_solver_set(struct latin_solver *solver,
                                     px = py / o;
                                     py %= o;
 
-                                    printf("%*s  ruling out %d at (%d,%d)\n",
+                                    printf("%*s  ruling out %s at (%d,%d)\n",
                                           solver_recurse_depth*4, "",
-                                           pn, px+1, YUNTRANS(py)+1);
+                                           names[pn-1], px+1, YUNTRANS(py)+1);
                                 }
 #endif
                                 progress = TRUE;
@@ -365,6 +378,9 @@ int latin_solver_forcing(struct latin_solver *solver,
                          struct latin_solver_scratch *scratch)
 {
     int o = solver->o;
+#ifdef STANDALONE_SOLVER
+    char **names = solver->names;
+#endif
     int *bfsqueue = scratch->bfsqueue;
 #ifdef STANDALONE_SOLVER
     int *bfsprev = scratch->bfsprev;
@@ -485,8 +501,9 @@ int latin_solver_forcing(struct latin_solver *solver,
                                 if (solver_show_working) {
                                     char *sep = "";
                                     int xl, yl;
-                                    printf("%*sforcing chain, %d at ends of ",
-                                           solver_recurse_depth*4, "", orign);
+                                    printf("%*sforcing chain, %s at ends of ",
+                                           solver_recurse_depth*4, "",
+                                          names[orign-1]);
                                     xl = xx;
                                     yl = yy;
                                     while (1) {
@@ -499,9 +516,10 @@ int latin_solver_forcing(struct latin_solver *solver,
                                         xl %= o;
                                         sep = "-";
                                     }
-                                    printf("\n%*s  ruling out %d at (%d,%d)\n",
+                                    printf("\n%*s  ruling out %s at (%d,%d)\n",
                                            solver_recurse_depth*4, "",
-                                           orign, xt+1, YUNTRANS(yt)+1);
+                                           names[orign-1],
+                                          xt+1, YUNTRANS(yt)+1);
                                 }
 #endif
                                 cube(xt, yt, orign) = FALSE;
@@ -563,6 +581,10 @@ void latin_solver_alloc(struct latin_solver *solver, digit *grid, int o)
        for (y = 0; y < o; y++)
            if (grid[y*o+x])
                latin_solver_place(solver, x, YTRANS(y), grid[y*o+x]);
+
+#ifdef STANDALONE_SOLVER
+    solver->names = NULL;
+#endif
 }
 
 void latin_solver_free(struct latin_solver *solver)
@@ -575,6 +597,10 @@ void latin_solver_free(struct latin_solver *solver)
 int latin_solver_diff_simple(struct latin_solver *solver)
 {
     int x, y, n, ret, o = solver->o;
+#ifdef STANDALONE_SOLVER
+    char **names = solver->names;
+#endif
+
     /*
      * Row-wise positional elimination.
      */
@@ -584,7 +610,8 @@ int latin_solver_diff_simple(struct latin_solver *solver)
                 ret = latin_solver_elim(solver, cubepos(0,y,n), o*o
 #ifdef STANDALONE_SOLVER
                                        , "positional elimination,"
-                                       " %d in row %d", n, YUNTRANS(y)+1
+                                       " %s in row %d", names[n-1],
+                                       YUNTRANS(y)+1
 #endif
                                        );
                 if (ret != 0) return ret;
@@ -598,7 +625,7 @@ int latin_solver_diff_simple(struct latin_solver *solver)
                 ret = latin_solver_elim(solver, cubepos(x,0,n), o
 #ifdef STANDALONE_SOLVER
                                        , "positional elimination,"
-                                       " %d in column %d", n, x+1
+                                       " %s in column %d", names[n-1], x+1
 #endif
                                        );
                 if (ret != 0) return ret;
@@ -626,6 +653,9 @@ int latin_solver_diff_set(struct latin_solver *solver,
                           int extreme)
 {
     int x, y, n, ret, o = solver->o;
+#ifdef STANDALONE_SOLVER
+    char **names = solver->names;
+#endif
 
     if (!extreme) {
         /*
@@ -658,7 +688,8 @@ int latin_solver_diff_set(struct latin_solver *solver,
         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 on %s",
+                                  names[n-1]
 #endif
                                   );
             if (ret != 0) return ret;
@@ -685,6 +716,9 @@ static int latin_solver_recurse
 {
     int best, bestcount;
     int o = solver->o, x, y, n;
+#ifdef STANDALONE_SOLVER
+    char **names = solver->names;
+#endif
 
     best = -1;
     bestcount = o+1;
@@ -745,7 +779,7 @@ static int latin_solver_recurse
             printf("%*srecursing on (%d,%d) [",
                    solver_recurse_depth*4, "", x+1, y+1);
             for (i = 0; i < j; i++) {
-                printf("%s%d", sep, list[i]);
+                printf("%s%s", sep, names[list[i]-1]);
                 sep = " or ";
             }
             printf("]\n");
@@ -759,14 +793,15 @@ static int latin_solver_recurse
         for (i = 0; i < j; i++) {
             int ret;
            void *newctx;
+           struct latin_solver subsolver;
 
             memcpy(outgrid, ingrid, o*o);
             outgrid[y*o+x] = list[i];
 
 #ifdef STANDALONE_SOLVER
             if (solver_show_working)
-                printf("%*sguessing %d at (%d,%d)\n",
-                       solver_recurse_depth*4, "", list[i], x+1, y+1);
+                printf("%*sguessing %s at (%d,%d)\n",
+                       solver_recurse_depth*4, "", names[list[i]-1], x+1, y+1);
             solver_recurse_depth++;
 #endif
 
@@ -775,18 +810,23 @@ static int latin_solver_recurse
            } else {
                newctx = ctx;
            }
-            ret = latin_solver(outgrid, o, diff_recursive,
-                              diff_simple, diff_set_0, diff_set_1,
-                              diff_forcing, diff_recursive,
-                              usersolvers, newctx, ctxnew, ctxfree);
+           latin_solver_alloc(&subsolver, outgrid, o);
+#ifdef STANDALONE_SOLVER
+           subsolver.names = solver->names;
+#endif
+            ret = latin_solver_top(&subsolver, diff_recursive,
+                                  diff_simple, diff_set_0, diff_set_1,
+                                  diff_forcing, diff_recursive,
+                                  usersolvers, newctx, ctxnew, ctxfree);
+           latin_solver_free(&subsolver);
            if (ctxnew)
                ctxfree(newctx);
 
 #ifdef STANDALONE_SOLVER
             solver_recurse_depth--;
             if (solver_show_working) {
-                printf("%*sretracting %d at (%d,%d)\n",
-                       solver_recurse_depth*4, "", list[i], x+1, y+1);
+                printf("%*sretracting %s at (%d,%d)\n",
+                       solver_recurse_depth*4, "", names[list[i]-1], x+1, y+1);
             }
 #endif
             /* we recurse as deep as we can, so we should never find
@@ -836,11 +876,11 @@ static int latin_solver_recurse
     }
 }
 
-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)
+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)
 {
     struct latin_solver_scratch *scratch = latin_solver_new_scratch(solver);
     int ret, diff = diff_simple;
@@ -938,6 +978,48 @@ int latin_solver_main(struct latin_solver *solver, int maxdiff,
     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)
+{
+    int diff;
+#ifdef STANDALONE_SOLVER
+    int o = solver->o;
+    char *text = NULL, **names = NULL;
+#endif
+
+#ifdef STANDALONE_SOLVER
+    if (!solver->names) {
+       char *p;
+       int i;
+
+       text = snewn(40 * o, char);
+       p = text;
+
+       solver->names = snewn(o, char *);
+
+       for (i = 0; i < o; i++) {
+           solver->names[i] = p;
+           p += 1 + sprintf(p, "%d", i+1);
+       }
+    }
+#endif
+
+    diff = latin_solver_top(solver, maxdiff,
+                           diff_simple, diff_set_0, diff_set_1,
+                           diff_forcing, diff_recursive,
+                           usersolvers, ctx, ctxnew, ctxfree);
+
+#ifdef STANDALONE_SOLVER
+    sfree(names);
+    sfree(text);
+#endif
+
+    return diff;
+}
+
 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,
diff --git a/latin.h b/latin.h
index 4ec6954..a1b5873 100644 (file)
--- a/latin.h
+++ b/latin.h
@@ -19,6 +19,10 @@ struct latin_solver {
 
   unsigned char *row;   /* o^2: row[y*cr+n-1] TRUE if n is in row y */
   unsigned char *col;   /* o^2: col[x*cr+n-1] TRUE if n is in col x */
+
+#ifdef STANDALONE_SOLVER
+  char **names;         /* o: names[n-1] gives name of 'digit' n */
+#endif
 };
 #define cubepos(x,y,n) (((x)*solver->o+(y))*solver->o+(n)-1)
 #define cube(x,y,n) (solver->cube[cubepos(x,y,n)])