From 481628b3d92ae1c7738bb51fe24a236245cd3d54 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 15 Jan 2007 20:07:18 +0000 Subject: [PATCH] Patch from James H to fix the occasional generation of puzzles harder than requested. git-svn-id: svn://svn.tartarus.org/sgt/puzzles@7113 cda61777-01e9-0310-a592-d414129be87e --- latin.c | 79 +++++++++++++++++++++++++++++++++++---------------------------- latin.h | 2 +- unequal.c | 16 ++++++++++--- 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/latin.c b/latin.c index 4f6e1f3..22488a7 100644 --- a/latin.c +++ b/latin.c @@ -619,46 +619,46 @@ int latin_solver_diff_simple(struct latin_solver *solver) 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 @@ enum { diff_simple = 1, diff_set, diff_extreme, diff_recursive }; 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,18 +859,27 @@ static int latin_solver_sub(struct latin_solver *solver, int maxdiff, void *ctx) 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. */ diff --git a/latin.h b/latin.h index f312cf9..decf2d7 100644 --- a/latin.h +++ b/latin.h @@ -86,7 +86,7 @@ int latin_solver_diff_simple(struct latin_solver *solver); * 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; diff --git a/unequal.c b/unequal.c index 74eba79..81720e4 100644 --- a/unequal.c +++ b/unequal.c @@ -631,7 +631,7 @@ static int solver_grid(digit *grid, int o, int maxdiff, void *ctx) 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,18 +668,28 @@ cont: 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. */ -- 2.11.0