From 348aac4c85da21e09c29c58866d178df3204d73c Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 20 Apr 2023 14:46:46 +0100 Subject: [PATCH] Remove size parameter from dsf init and copy functions. Now that the dsf knows its own size internally, there's no need to tell it again when one is copied or reinitialised. This makes dsf_init much more about *re*initialising a dsf, since now dsfs are always allocated using a function that will initialise them anyway. So I think it deserves a rename. --- bridges.c | 13 ++++++------- dominosa.c | 2 +- dsf.c | 12 +++++++----- filling.c | 6 +++--- galaxies.c | 4 ++-- keen.c | 5 ++--- loopy.c | 4 ++-- pearl.c | 2 +- puzzles.h | 6 ++++-- signpost.c | 6 +++--- singles.c | 2 +- slant.c | 4 ++-- tents.c | 2 +- tracks.c | 2 +- unfinished/separate.c | 2 +- 15 files changed, 37 insertions(+), 35 deletions(-) diff --git a/bridges.c b/bridges.c index 225233b..800e75a 100644 --- a/bridges.c +++ b/bridges.c @@ -1140,13 +1140,13 @@ static bool map_hasloops(game_state *state, bool mark) static void map_group(game_state *state) { - int i, wh = state->w*state->h, d1, d2; + int i, d1, d2; int x, y, x2, y2; DSF *dsf = state->solver->dsf; struct island *is, *is_join; /* Initialise dsf. */ - dsf_init(dsf, wh); + dsf_reinit(dsf); /* For each island, find connected islands right or down * and merge the dsf for the island squares as well as the @@ -1532,7 +1532,6 @@ static bool solve_island_stage3(struct island *is, bool *didsth_r) { int i, n, x, y, missing, spc, curr, maxb; bool didsth = false; - int wh = is->state->w * is->state->h; struct solver_state *ss = is->state->solver; assert(didsth_r); @@ -1556,7 +1555,7 @@ static bool solve_island_stage3(struct island *is, bool *didsth_r) maxb = -1; /* We have to squirrel the dsf away and restore it afterwards; * it is additive only, and can't be removed from. */ - dsf_copy(ss->tmpdsf, ss->dsf, wh); + dsf_copy(ss->tmpdsf, ss->dsf); for (n = curr+1; n <= curr+spc; n++) { solve_join(is, i, n, false); map_update_possibles(is->state); @@ -1572,7 +1571,7 @@ static bool solve_island_stage3(struct island *is, bool *didsth_r) } } solve_join(is, i, curr, false); /* put back to before. */ - dsf_copy(ss->dsf, ss->tmpdsf, wh); + dsf_copy(ss->dsf, ss->tmpdsf); if (maxb != -1) { /*debug_state(is->state);*/ @@ -1641,7 +1640,7 @@ static bool solve_island_stage3(struct island *is, bool *didsth_r) is->adj.points[j].dx ? G_LINEH : G_LINEV); if (before[i] != 0) continue; /* this idea is pointless otherwise */ - dsf_copy(ss->tmpdsf, ss->dsf, wh); + dsf_copy(ss->tmpdsf, ss->dsf); for (j = 0; j < is->adj.npoints; j++) { spc = island_adjspace(is, true, missing, j); @@ -1656,7 +1655,7 @@ static bool solve_island_stage3(struct island *is, bool *didsth_r) for (j = 0; j < is->adj.npoints; j++) solve_join(is, j, before[j], false); - dsf_copy(ss->dsf, ss->tmpdsf, wh); + dsf_copy(ss->dsf, ss->tmpdsf); if (got) { debug(("island at (%d,%d) must connect in direction (%d,%d) to" diff --git a/dominosa.c b/dominosa.c index 8b3c83e..82e8639 100644 --- a/dominosa.c +++ b/dominosa.c @@ -1438,7 +1438,7 @@ static bool deduce_forcing_chain(struct solver_scratch *sc) * class for each entire forcing chain, with the two possible sets * of dominoes for the chain listed as inverses. */ - dsf_init(sc->dsf_scratch, sc->pc); + dsf_reinit(sc->dsf_scratch); for (si = 0; si < sc->wh; si++) { struct solver_square *sq = &sc->squares[si]; if (sq->nplacements == 2) diff --git a/dsf.c b/dsf.c index 5fbb6d0..2d37c91 100644 --- a/dsf.c +++ b/dsf.c @@ -66,11 +66,12 @@ done: sfree(inverse_elements); }*/ -void dsf_init(DSF *dsf, int size) +void dsf_reinit(DSF *dsf) { int i; - for (i = 0; i < size; i++) dsf->p[i] = 6; + for (i = 0; i < dsf->size; i++) + dsf->p[i] = 6; /* Bottom bit of each element of this array stores whether that * element is opposite to its parent, which starts off as * false. Second bit of each element stores whether that element @@ -79,9 +80,10 @@ void dsf_init(DSF *dsf, int size) * bits are the number of elements in the tree. */ } -void dsf_copy(DSF *to, DSF *from, int size) +void dsf_copy(DSF *to, DSF *from) { - memcpy(to->p, from->p, size * sizeof(int)); + assert(to->size == from->size && "Mismatch in dsf_copy"); + memcpy(to->p, from->p, to->size * sizeof(int)); } DSF *snew_dsf(int size) @@ -90,7 +92,7 @@ DSF *snew_dsf(int size) ret->size = size; ret->p = snewn(size, int); - dsf_init(ret, size); + dsf_reinit(ret); /*print_dsf(ret, size); */ diff --git a/filling.c b/filling.c index b2f08b5..f95949c 100644 --- a/filling.c +++ b/filling.c @@ -411,7 +411,7 @@ static void make_board(int *board, int w, int h, random_state *rs) { dsf = snew_dsf(sz); retry: - dsf_init(dsf, sz); + dsf_reinit(dsf); shuffle(board, sz, sizeof (int), rs); do { @@ -946,7 +946,7 @@ static bool learn_bitmap_deductions(struct solver_state *s, int w, int h) * have a completely new n-region in it. */ for (n = 1; n <= 9; n++) { - dsf_init(dsf, sz); + dsf_reinit(dsf); /* Build the dsf */ for (y = 0; y < h; y++) @@ -1137,7 +1137,7 @@ static DSF *make_dsf(DSF *dsf, int *board, const int w, const int h) { if (!dsf) dsf = snew_dsf(w * h); else - dsf_init(dsf, w * h); + dsf_reinit(dsf); for (i = 0; i < sz; ++i) { int j; diff --git a/galaxies.c b/galaxies.c index 2e0c9f2..025bacf 100644 --- a/galaxies.c +++ b/galaxies.c @@ -2283,7 +2283,7 @@ static int solver_extend_exclaves(game_state *state, solver_ctx *sctx) * doesn't contain its own dot is an 'exclave', and will need some * kind of path of tiles to connect it back to the dot. */ - dsf_init(sctx->dsf, sctx->sz); + dsf_reinit(sctx->dsf); for (x = 1; x < state->sx; x += 2) { for (y = 1; y < state->sy; y += 2) { int dotx, doty; @@ -3084,7 +3084,7 @@ static bool check_complete(const game_state *state, DSF *dsf, int *colours) dsf = snew_dsf(w*h); free_dsf = true; } else { - dsf_init(dsf, w*h); + dsf_reinit(dsf); free_dsf = false; } diff --git a/keen.c b/keen.c index 22fd94b..d4d2809 100644 --- a/keen.c +++ b/keen.c @@ -821,11 +821,10 @@ static char *encode_block_structure(char *p, int w, DSF *dsf) static const char *parse_block_structure(const char **p, int w, DSF *dsf) { - int a = w*w; int pos = 0; int repc = 0, repn = 0; - dsf_init(dsf, a); + dsf_reinit(dsf); while (**p && (repn > 0 || **p != ',')) { int c; @@ -960,7 +959,7 @@ done for (i = 0; i < a; i++) singletons[i] = true; - dsf_init(dsf, a); + dsf_reinit(dsf); /* Place dominoes. */ for (i = 0; i < a; i++) { diff --git a/loopy.c b/loopy.c index 11500e1..903fb5a 100644 --- a/loopy.c +++ b/loopy.c @@ -457,7 +457,7 @@ static solver_state *dup_solver_state(const solver_state *sstate) { ret->dotdsf = snew_dsf(num_dots); ret->looplen = snewn(num_dots, int); - dsf_copy(ret->dotdsf, sstate->dotdsf, num_dots); + dsf_copy(ret->dotdsf, sstate->dotdsf); memcpy(ret->looplen, sstate->looplen, num_dots * sizeof(int)); @@ -486,7 +486,7 @@ static solver_state *dup_solver_state(const solver_state *sstate) { if (sstate->linedsf) { ret->linedsf = snew_dsf(num_edges); - dsf_copy(ret->linedsf, sstate->linedsf, num_edges); + dsf_copy(ret->linedsf, sstate->linedsf); } else { ret->linedsf = NULL; } diff --git a/pearl.c b/pearl.c index 0c44d14..ea80ac0 100644 --- a/pearl.c +++ b/pearl.c @@ -593,7 +593,7 @@ static int pearl_solve(int w, int h, char *clues, char *result, { int nonblanks, loopclass; - dsf_init(dsf, w*h); + dsf_reinit(dsf); for (x = 0; x < w*h; x++) dsfsize[x] = 1; diff --git a/puzzles.h b/puzzles.h index 8a949de..add58b2 100644 --- a/puzzles.h +++ b/puzzles.h @@ -432,7 +432,7 @@ void dsf_free(DSF *dsf); void print_dsf(DSF *dsf, int size); -void dsf_copy(DSF *to, DSF *from, int size); +void dsf_copy(DSF *to, DSF *from); /* Return the canonical element of the equivalence class containing element * val. If 'inverse' is non-NULL, this function will put into it a flag @@ -448,7 +448,9 @@ int dsf_size(DSF *dsf, int val); * be both opposite and non-opposite. */ void edsf_merge(DSF *dsf, int v1, int v2, bool inverse); void dsf_merge(DSF *dsf, int v1, int v2); -void dsf_init(DSF *dsf, int len); + +/* Reinitialise a dsf to the starting 'all elements distinct' state. */ +void dsf_reinit(DSF *dsf); /* * tdq.c diff --git a/signpost.c b/signpost.c index 7374db8..51c49d7 100644 --- a/signpost.c +++ b/signpost.c @@ -282,7 +282,7 @@ static void strip_nums(game_state *state) { memset(state->next, -1, state->n*sizeof(int)); memset(state->prev, -1, state->n*sizeof(int)); memset(state->numsi, -1, (state->n+1)*sizeof(int)); - dsf_init(state->dsf, state->n); + dsf_reinit(state->dsf); } static bool check_nums(game_state *orig, game_state *copy, bool only_immutable) @@ -482,7 +482,7 @@ static void dup_game_to(game_state *to, const game_state *from) memcpy(to->next, from->next, to->n*sizeof(int)); memcpy(to->prev, from->prev, to->n*sizeof(int)); - dsf_copy(to->dsf, from->dsf, to->n); + dsf_copy(to->dsf, from->dsf); memcpy(to->numsi, from->numsi, (to->n+1)*sizeof(int)); } @@ -1018,7 +1018,7 @@ static void connect_numbers(game_state *state) { int i, di, dni; - dsf_init(state->dsf, state->n); + dsf_reinit(state->dsf); for (i = 0; i < state->n; i++) { if (state->next[i] != -1) { assert(state->prev[state->next[i]] == i); diff --git a/singles.c b/singles.c index 06333b6..376d744 100644 --- a/singles.c +++ b/singles.c @@ -439,7 +439,7 @@ static void connect_dsf(game_state *state, DSF *dsf) /* Construct a dsf array for connected blocks; connections * tracked to right and down. */ - dsf_init(dsf, state->n); + dsf_reinit(dsf); for (x = 0; x < state->w; x++) { for (y = 0; y < state->h; y++) { i = y*state->w + x; diff --git a/slant.c b/slant.c index a53813a..51b8b4a 100644 --- a/slant.c +++ b/slant.c @@ -472,13 +472,13 @@ static int slant_solve(int w, int h, const signed char *clues, * Establish a disjoint set forest for tracking connectedness * between grid points. */ - dsf_init(sc->connected, W*H); + dsf_reinit(sc->connected); /* * Establish a disjoint set forest for tracking which squares * are known to slant in the same direction. */ - dsf_init(sc->equiv, w*h); + dsf_reinit(sc->equiv); /* * Clear the slashval array. diff --git a/tents.c b/tents.c index d45c456..191484b 100644 --- a/tents.c +++ b/tents.c @@ -2267,7 +2267,7 @@ static int *find_errors(const game_state *state, char *grid) * start of the game, before the user had done anything wrong!) */ #define TENT(x) ((x)==TENT || (x)==BLANK) - dsf_init(dsf, w*h); + dsf_reinit(dsf); /* Construct the equivalence classes. */ for (y = 0; y < h; y++) { for (x = 0; x < w-1; x++) { diff --git a/tracks.c b/tracks.c index ecd639f..6759c21 100644 --- a/tracks.c +++ b/tracks.c @@ -1466,7 +1466,7 @@ static int solve_bridge_sub(game_state *state, int x, int y, int d, if (!sc->dsf) sc->dsf = snew_dsf(wh); - dsf_init(sc->dsf, wh); + dsf_reinit(sc->dsf); for (xi = 0; xi < w; xi++) { for (yi = 0; yi < h; yi++) { diff --git a/unfinished/separate.c b/unfinished/separate.c index fdee409..088f0ac 100644 --- a/unfinished/separate.c +++ b/unfinished/separate.c @@ -331,7 +331,7 @@ static void solver_init(struct solver_scratch *sc) * contents array, however, because this will change if we * adjust the letter arrangement and re-run the solver. */ - dsf_init(sc->dsf, wh); + dsf_reinit(sc->dsf); for (i = 0; i < wh; i++) sc->size[i] = 1; memset(sc->disconnect, 0, wh*wh * sizeof(bool)); }