X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/845a3be0c46976e6769a21657dd0ea145f702cca..be39fd6df763fafcc07131d46fa4a3bd59245b64:/latin.c diff --git a/latin.c b/latin.c index 4f6e1f3..45096e4 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. */ @@ -947,12 +956,12 @@ void latin_solver_debug(unsigned char *cube, int o) #ifdef STANDALONE_SOLVER if (solver_show_working) { struct latin_solver ls, *solver = &ls; - unsigned char *dbg; + char *dbg; int x, y, i, c = 0; ls.cube = cube; ls.o = o; /* for cube() to work */ - dbg = snewn(3*o*o*o, unsigned char); + dbg = snewn(3*o*o*o, char); for (y = 0; y < o; y++) { for (x = 0; x < o; x++) { for (i = 1; i <= o; i++) { @@ -1083,6 +1092,7 @@ digit *latin_generate(int o, random_state *rs) for (j = 0; j < o; j++) col[j] = num[j] = j; shuffle(col, j, sizeof(*col), rs); + shuffle(num, j, sizeof(*num), rs); /* We need the num permutation in both forward and inverse forms. */ for (j = 0; j < o; j++) numinv[num[j]] = j; @@ -1166,7 +1176,7 @@ int latin_check(digit *sq, int order) tree234 *dict = newtree234(latin_check_cmp); int c, r; int ret = 0; - lcparams *lcp, lc; + lcparams *lcp, lc, *aret; /* Use a tree234 as a simple hash table, go through the square * adding elements as we go or incrementing their counts. */ @@ -1178,7 +1188,8 @@ int latin_check(digit *sq, int order) lcp = snew(lcparams); lcp->elt = ELT(sq, c, r); lcp->count = 1; - assert(add234(dict, lcp) == lcp); + aret = add234(dict, lcp); + assert(aret == lcp); } else { lcp->count++; }