mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Actually make DSF an opaque structure type.
This makes good on all the previous preparatory commits, which I did separately so that each one individually has a reasonably readable diff, and all the mechanical changes are separated out from the rewrites that needed actual thought. Still no functional change, however: the DSF type wraps nothing but the same int pointer that 'DSF *' used to store directly.
This commit is contained in:
39
dsf.c
39
dsf.c
@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
#include "puzzles.h"
|
#include "puzzles.h"
|
||||||
|
|
||||||
|
struct DSF {
|
||||||
|
int *p;
|
||||||
|
};
|
||||||
|
|
||||||
/*void print_dsf(int *dsf, int size)
|
/*void print_dsf(int *dsf, int size)
|
||||||
{
|
{
|
||||||
int *printed_elements = snewn(size, int);
|
int *printed_elements = snewn(size, int);
|
||||||
@ -65,7 +69,7 @@ void dsf_init(DSF *dsf, int size)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < size; i++) dsf[i] = 6;
|
for (i = 0; i < size; i++) dsf->p[i] = 6;
|
||||||
/* Bottom bit of each element of this array stores whether that
|
/* Bottom bit of each element of this array stores whether that
|
||||||
* element is opposite to its parent, which starts off as
|
* element is opposite to its parent, which starts off as
|
||||||
* false. Second bit of each element stores whether that element
|
* false. Second bit of each element stores whether that element
|
||||||
@ -76,14 +80,14 @@ void dsf_init(DSF *dsf, int size)
|
|||||||
|
|
||||||
void dsf_copy(DSF *to, DSF *from, int size)
|
void dsf_copy(DSF *to, DSF *from, int size)
|
||||||
{
|
{
|
||||||
memcpy(to, from, size * sizeof(int));
|
memcpy(to->p, from->p, size * sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
DSF *snew_dsf(int size)
|
DSF *snew_dsf(int size)
|
||||||
{
|
{
|
||||||
int *ret;
|
DSF *ret = snew(DSF);
|
||||||
|
ret->p = snewn(size, int);
|
||||||
|
|
||||||
ret = snewn(size, int);
|
|
||||||
dsf_init(ret, size);
|
dsf_init(ret, size);
|
||||||
|
|
||||||
/*print_dsf(ret, size); */
|
/*print_dsf(ret, size); */
|
||||||
@ -93,8 +97,11 @@ DSF *snew_dsf(int size)
|
|||||||
|
|
||||||
void dsf_free(DSF *dsf)
|
void dsf_free(DSF *dsf)
|
||||||
{
|
{
|
||||||
|
if (dsf) {
|
||||||
|
sfree(dsf->p);
|
||||||
sfree(dsf);
|
sfree(dsf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int dsf_canonify(DSF *dsf, int index)
|
int dsf_canonify(DSF *dsf, int index)
|
||||||
{
|
{
|
||||||
@ -107,7 +114,7 @@ void dsf_merge(DSF *dsf, int v1, int v2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dsf_size(DSF *dsf, int index) {
|
int dsf_size(DSF *dsf, int index) {
|
||||||
return dsf[dsf_canonify(dsf, index)] >> 2;
|
return dsf->p[dsf_canonify(dsf, index)] >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
|
int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
|
||||||
@ -123,9 +130,9 @@ int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
|
|||||||
/* Find the index of the canonical element of the 'equivalence class' of
|
/* Find the index of the canonical element of the 'equivalence class' of
|
||||||
* which start_index is a member, and figure out whether start_index is the
|
* which start_index is a member, and figure out whether start_index is the
|
||||||
* same as or inverse to that. */
|
* same as or inverse to that. */
|
||||||
while ((dsf[index] & 2) == 0) {
|
while ((dsf->p[index] & 2) == 0) {
|
||||||
inverse ^= (dsf[index] & 1);
|
inverse ^= (dsf->p[index] & 1);
|
||||||
index = dsf[index] >> 2;
|
index = dsf->p[index] >> 2;
|
||||||
/* fprintf(stderr, "index = %2d, ", index); */
|
/* fprintf(stderr, "index = %2d, ", index); */
|
||||||
/* fprintf(stderr, "inverse = %d\n", inverse); */
|
/* fprintf(stderr, "inverse = %d\n", inverse); */
|
||||||
}
|
}
|
||||||
@ -138,9 +145,9 @@ int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
|
|||||||
* canonical member. */
|
* canonical member. */
|
||||||
index = start_index;
|
index = start_index;
|
||||||
while (index != canonical_index) {
|
while (index != canonical_index) {
|
||||||
int nextindex = dsf[index] >> 2;
|
int nextindex = dsf->p[index] >> 2;
|
||||||
bool nextinverse = inverse ^ (dsf[index] & 1);
|
bool nextinverse = inverse ^ (dsf->p[index] & 1);
|
||||||
dsf[index] = (canonical_index << 2) | inverse;
|
dsf->p[index] = (canonical_index << 2) | inverse;
|
||||||
inverse = nextinverse;
|
inverse = nextinverse;
|
||||||
index = nextindex;
|
index = nextindex;
|
||||||
}
|
}
|
||||||
@ -160,10 +167,10 @@ void edsf_merge(DSF *dsf, int v1, int v2, bool inverse)
|
|||||||
/* fprintf(stderr, "Merge [%2d,%2d], %d\n", v1, v2, inverse); */
|
/* fprintf(stderr, "Merge [%2d,%2d], %d\n", v1, v2, inverse); */
|
||||||
|
|
||||||
v1 = edsf_canonify(dsf, v1, &i1);
|
v1 = edsf_canonify(dsf, v1, &i1);
|
||||||
assert(dsf[v1] & 2);
|
assert(dsf->p[v1] & 2);
|
||||||
inverse ^= i1;
|
inverse ^= i1;
|
||||||
v2 = edsf_canonify(dsf, v2, &i2);
|
v2 = edsf_canonify(dsf, v2, &i2);
|
||||||
assert(dsf[v2] & 2);
|
assert(dsf->p[v2] & 2);
|
||||||
inverse ^= i2;
|
inverse ^= i2;
|
||||||
|
|
||||||
/* fprintf(stderr, "Doing [%2d,%2d], %d\n", v1, v2, inverse); */
|
/* fprintf(stderr, "Doing [%2d,%2d], %d\n", v1, v2, inverse); */
|
||||||
@ -190,13 +197,13 @@ void edsf_merge(DSF *dsf, int v1, int v2, bool inverse)
|
|||||||
v1 = v2;
|
v1 = v2;
|
||||||
v2 = v3;
|
v2 = v3;
|
||||||
}
|
}
|
||||||
dsf[v1] += (dsf[v2] >> 2) << 2;
|
dsf->p[v1] += (dsf->p[v2] >> 2) << 2;
|
||||||
dsf[v2] = (v1 << 2) | inverse;
|
dsf->p[v2] = (v1 << 2) | inverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
v2 = edsf_canonify(dsf, v2, &i2);
|
v2 = edsf_canonify(dsf, v2, &i2);
|
||||||
assert(v2 == v1);
|
assert(v2 == v1);
|
||||||
assert(i2 == inverse);
|
assert(i2 == inverse);
|
||||||
|
|
||||||
/* fprintf(stderr, "dsf[%2d] = %2d\n", v2, dsf[v2]); */
|
/* fprintf(stderr, "dsf[%2d] = %2d\n", v2, dsf->p[v2]); */
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user