From 154318a2710d4b8d6c76d7b12745c439937aea04 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 5 Jan 2010 23:40:40 +0000 Subject: [PATCH] Add a facility in the latin.c solver diagnostics to allow a puzzle 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 | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------ latin.h | 4 ++ 2 files changed, 111 insertions(+), 25 deletions(-) diff --git a/latin.c b/latin.c index a1117e0..1613ebd 100644 --- a/latin.c +++ b/latin.c @@ -16,6 +16,12 @@ * 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 --- 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)]) -- 2.11.0