diff --git a/divvy.c b/divvy.c index 021956f..91379e4 100644 --- a/divvy.c +++ b/divvy.c @@ -262,7 +262,7 @@ static bool addremcommon(int w, int h, int x, int y, int *own, int val) */ int *divvy_rectangle_attempt(int w, int h, int k, random_state *rs) { - int *order, *queue, *tmp, *own, *sizes, *addable, *retdsf; + int *order, *queue, *tmp, *own, *sizes, *addable, *retdsf, *tmpdsf; bool *removable; int wh = w*h; int i, j, n, x, y, qhead, qtail; @@ -277,6 +277,7 @@ int *divvy_rectangle_attempt(int w, int h, int k, random_state *rs) queue = snewn(n, int); addable = snewn(wh*4, int); removable = snewn(wh, bool); + retdsf = tmpdsf = NULL; /* * Permute the grid squares into a random order, which will be @@ -619,18 +620,18 @@ int *divvy_rectangle_attempt(int w, int h, int k, random_state *rs) * the ominoes really are k-ominoes and we haven't * accidentally split one into two disconnected pieces. */ - dsf_init(tmp, wh); + tmpdsf = snew_dsf(wh); for (y = 0; y < h; y++) for (x = 0; x+1 < w; x++) if (own[y*w+x] == own[y*w+(x+1)]) - dsf_merge(tmp, y*w+x, y*w+(x+1)); + dsf_merge(tmpdsf, y*w+x, y*w+(x+1)); for (x = 0; x < w; x++) for (y = 0; y+1 < h; y++) if (own[y*w+x] == own[(y+1)*w+x]) - dsf_merge(tmp, y*w+x, (y+1)*w+x); + dsf_merge(tmpdsf, y*w+x, (y+1)*w+x); for (i = 0; i < wh; i++) { j = dsf_canonify(retdsf, i); - assert(dsf_canonify(tmp, j) == dsf_canonify(tmp, i)); + assert(dsf_canonify(tmpdsf, j) == dsf_canonify(tmpdsf, i)); } cleanup: @@ -640,6 +641,7 @@ int *divvy_rectangle_attempt(int w, int h, int k, random_state *rs) */ sfree(order); sfree(tmp); + sfree(tmpdsf); sfree(own); sfree(sizes); sfree(queue); diff --git a/dominosa.c b/dominosa.c index eba9465..7a87e4b 100644 --- a/dominosa.c +++ b/dominosa.c @@ -350,7 +350,7 @@ struct solver_scratch { struct solver_square **squares_by_number; struct findloopstate *fls; bool squares_by_number_initialised; - int *wh_scratch, *pc_scratch, *pc_scratch2, *dc_scratch; + int *wh_scratch, *pc_scratch, *pc_scratch2, *dc_scratch, *dsf_scratch; }; static struct solver_scratch *solver_make_scratch(int n) @@ -482,6 +482,7 @@ static struct solver_scratch *solver_make_scratch(int n) sc->wh_scratch = NULL; sc->pc_scratch = sc->pc_scratch2 = NULL; sc->dc_scratch = NULL; + sc->dsf_scratch = NULL; return sc; } @@ -509,6 +510,7 @@ static void solver_free_scratch(struct solver_scratch *sc) sfree(sc->pc_scratch); sfree(sc->pc_scratch2); sfree(sc->dc_scratch); + sfree(sc->dsf_scratch); sfree(sc); } @@ -1425,19 +1427,21 @@ static bool deduce_forcing_chain(struct solver_scratch *sc) sc->pc_scratch2 = snewn(sc->pc, int); if (!sc->dc_scratch) sc->dc_scratch = snewn(sc->dc, int); + if (!sc->dsf_scratch) + sc->dsf_scratch = snew_dsf(sc->pc); /* * Start by identifying chains of placements which must all occur * together if any of them occurs. We do this by making - * pc_scratch2 an edsf binding the placements into an equivalence + * dsf_scratch an edsf binding the placements into an equivalence * class for each entire forcing chain, with the two possible sets * of dominoes for the chain listed as inverses. */ - dsf_init(sc->pc_scratch2, sc->pc); + dsf_init(sc->dsf_scratch, sc->pc); for (si = 0; si < sc->wh; si++) { struct solver_square *sq = &sc->squares[si]; if (sq->nplacements == 2) - edsf_merge(sc->pc_scratch2, + edsf_merge(sc->dsf_scratch, sq->placements[0]->index, sq->placements[1]->index, true); } @@ -1452,7 +1456,7 @@ static bool deduce_forcing_chain(struct solver_scratch *sc) */ for (pi = 0; pi < sc->pc; pi++) { bool inv; - int c = edsf_canonify(sc->pc_scratch2, pi, &inv); + int c = edsf_canonify(sc->dsf_scratch, pi, &inv); sc->pc_scratch[pi] = c * 2 + (inv ? 1 : 0); } diff --git a/map.c b/map.c index fff4486..1122466 100644 --- a/map.c +++ b/map.c @@ -1724,8 +1724,8 @@ static const char *parse_edge_list(const game_params *params, int i, k, pos; bool state; const char *p = *desc; - - dsf_init(map+wh, wh); + const char *err = NULL; + int *dsf = snew_dsf(wh); pos = -1; state = false; @@ -1736,8 +1736,10 @@ static const char *parse_edge_list(const game_params *params, * pairs of squares whenever the edge list shows a non-edge). */ while (*p && *p != ',') { - if (*p < 'a' || *p > 'z') - return "Unexpected character in edge list"; + if (*p < 'a' || *p > 'z') { + err = "Unexpected character in edge list"; + goto out; + } if (*p == 'z') k = 25; else @@ -1760,10 +1762,12 @@ static const char *parse_edge_list(const game_params *params, y = (pos - w*(h-1)) % h; dx = 1; dy = 0; - } else - return "Too much data in edge list"; + } else { + err = "Too much data in edge list"; + goto out; + } if (!state) - dsf_merge(map+wh, y*w+x, (y+dy)*w+(x+dx)); + dsf_merge(dsf, y*w+x, (y+dy)*w+(x+dx)); pos++; } @@ -1772,8 +1776,10 @@ static const char *parse_edge_list(const game_params *params, p++; } assert(pos <= 2*wh-w-h); - if (pos < 2*wh-w-h) - return "Too little data in edge list"; + if (pos < 2*wh-w-h) { + err = "Too little data in edge list"; + goto out; + } /* * Now go through again and allocate region numbers. @@ -1782,17 +1788,22 @@ static const char *parse_edge_list(const game_params *params, for (i = 0; i < wh; i++) map[i] = -1; for (i = 0; i < wh; i++) { - k = dsf_canonify(map+wh, i); + k = dsf_canonify(dsf, i); if (map[k] < 0) map[k] = pos++; map[i] = map[k]; } - if (pos != n) - return "Edge list defines the wrong number of regions"; + if (pos != n) { + err = "Edge list defines the wrong number of regions"; + goto out; + } *desc = p; + err = NULL; /* no error */ - return NULL; + out: + sfree(dsf); + return err; } static const char *validate_desc(const game_params *params, const char *desc) @@ -1802,7 +1813,7 @@ static const char *validate_desc(const game_params *params, const char *desc) int *map; const char *ret; - map = snewn(2*wh, int); + map = snewn(wh, int); ret = parse_edge_list(params, &desc, map); sfree(map); if (ret) diff --git a/tents.c b/tents.c index 9f904f9..ca39401 100644 --- a/tents.c +++ b/tents.c @@ -2006,7 +2006,7 @@ static int *find_errors(const game_state *state, char *grid) { int w = state->p.w, h = state->p.h; int *ret = snewn(w*h + w + h, int); - int *tmp = snewn(w*h*2, int), *dsf = tmp + w*h; + int *tmp = snewn(w*h, int), *dsf; int x, y; /* @@ -2223,7 +2223,7 @@ static int *find_errors(const game_state *state, char *grid) * all the tents in any component which has a smaller tree * count. */ - dsf_init(dsf, w*h); + dsf = snew_dsf(w*h); /* Construct the equivalence classes. */ for (y = 0; y < h; y++) { for (x = 0; x < w-1; x++) { @@ -2302,6 +2302,7 @@ static int *find_errors(const game_state *state, char *grid) #undef TENT sfree(tmp); + sfree(dsf); return ret; }