commit ae0e5295daa7618b6facebac31c3a88eaccfc368
parent 29f61e2b4e0f73c83d6d86e4f09d79e129358750
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Tue, 1 Apr 2025 22:26:44 +0200
Make symcoord logic generic
Diffstat:
4 files changed, 191 insertions(+), 115 deletions(-)
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
@@ -1,10 +1,139 @@
-STATIC void append_coord_name(const coord_t *, char *);
+STATIC uint64_t coord_coord_generic(
+ const coord_t [static 1], cube_t, const void *);
+STATIC cube_t coord_cube_generic(
+ const coord_t [static 1], uint64_t, const void *);
+STATIC bool coord_isnasty_generic(
+ const coord_t [static 1], uint64_t, const void *);
+STATIC size_t coord_gendata_generic(const coord_t [static 1], void *);
+
+STATIC void append_coord_name(const coord_t [static 1], char *);
STATIC bool solution_lastqt_cw(const solution_moves_t [static 1]);
STATIC bool coord_can_switch(
const coord_t [static 1], const void *, size_t n, const uint8_t [n]);
+STATIC uint64_t
+coord_coord_generic(const coord_t coord[static 1], cube_t c, const void *data)
+{
+ const char *datanoinfo;
+ const uint32_t *data32;
+ uint32_t d;
+ cube_t tr;
+
+ datanoinfo = (const char *)data + INFOSIZE;
+ data32 = (const uint32_t *)datanoinfo;
+ d = data32[coord->sym.coord(c)];
+ tr = transform(c, COORD_TTREP(d));
+
+ return COORD_CLASS(d) * coord->sym.max2 + coord->sym.coord2(tr);
+}
+
+STATIC cube_t
+coord_cube_generic(const coord_t coord[static 1], uint64_t i, const void *data)
+{
+ const char *datanoinfo;
+ const uint32_t *rep32;
+ cube_t c;
+
+ datanoinfo = (const char *)data + INFOSIZE;
+ rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max);
+ c = coord->sym.cube(rep32[i / coord->sym.max2]);
+
+ return coord->sym.merge(c, coord->sym.cube2(i % coord->sym.max2));
+}
+
+STATIC bool
+coord_isnasty_generic(
+ const coord_t coord[static 1],
+ uint64_t i,
+ const void *data
+)
+{
+ const char *datanoinfo;
+ const uint32_t *classttrep, *rep32;
+ uint32_t r;
+
+ datanoinfo = (const char *)data + INFOSIZE;
+ classttrep = (const uint32_t *)datanoinfo;
+ rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max);
+ r = rep32[i / coord->sym.max2];
+
+ return COORD_ISNASTY(classttrep[r]);
+}
+
+STATIC size_t
+coord_gendata_generic(
+ const coord_t coord[static 1],
+ void *data
+)
+{
+ uint64_t i, j, n, t, nasty;
+ char *datanoinfo;
+ uint32_t *classttrep, *rep;
+ size_t coord_datasize;
+ cube_t c;
+ tableinfo_t info;
+
+ coord_datasize = INFOSIZE + 4*(coord->sym.classes + coord->sym.max);
+
+ if (data == NULL)
+ return coord_datasize;
+
+ datanoinfo = (char *)data + INFOSIZE;
+ classttrep = (uint32_t *)datanoinfo;
+ rep = classttrep + coord->sym.max;
+ memset(data, 0xFF, coord_datasize);
+
+ info = (tableinfo_t) {
+ .solver = "coord data for ",
+ .type = TABLETYPE_SPECIAL,
+ .infosize = INFOSIZE,
+ .fullsize = coord_datasize,
+ .hash = 0,
+ .entries = coord->sym.classes + coord->sym.max,
+ .classes = coord->sym.classes,
+ .bits = 32,
+ .base = 0,
+ .maxvalue = 0,
+ .next = 0
+ };
+ append_coord_name(coord, info.solver);
+
+ for (i = 0, n = 0; i < coord->sym.max; i++) {
+ if (classttrep[i] != 0xFFFFFFFF)
+ continue;
+
+ c = coord->sym.cube(i);
+ for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) {
+ if (!((UINT64_C(1) << t) & coord->trans_mask))
+ continue;
+
+ nasty = i == coord->sym.coord(transform(c, t));
+ }
+
+ for (t = 0; t < NTRANS; t++) {
+ if (!((UINT64_C(1) << t) & coord->trans_mask))
+ continue;
+
+ j = coord->sym.coord(transform(c, t));
+ classttrep[j] =
+ (n << COORD_CLASS_SHIFT) |
+ (nasty << COORD_ISNASTY_SHIFT) |
+ (inverse_trans(t) << COORD_TTREP_SHIFT);
+ }
+ rep[n++] = i;
+ }
+
+ writetableinfo(&info, coord_datasize, data);
+
+ DBG_ASSERT(n == coord->sym.classes, 0,
+ "%s coordinate data: computed %" PRIu64 " classes, "
+ "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes);
+
+ return coord_datasize;
+}
+
STATIC void
-append_coord_name(const coord_t *coord, char *str)
+append_coord_name(const coord_t coord[static 1], char *str)
{
int i, j;
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
@@ -1,30 +1,19 @@
#define DREOESEP_CLASSES UINT64_C(64430)
#define DREOESEP_MAX (POW_2_11 * COMB_12_4)
-#define DR_CLASS_TABLESIZE (sizeof(uint32_t) * (size_t)DREOESEP_MAX)
-#define DR_REP_TABLESIZE (sizeof(uint32_t) * (size_t)DREOESEP_CLASSES)
-#define DR_COORD_DATASIZE (INFOSIZE + DR_CLASS_TABLESIZE + DR_REP_TABLESIZE)
-
-#define DR_CLASS_SHIFT UINT32_C(16)
-#define DR_CLASS_MASK (UINT32_C(0xFFFF) << DR_CLASS_SHIFT)
-#define DR_CLASS(d) (((d) & DR_CLASS_MASK) >> DR_CLASS_SHIFT)
-
-#define DR_TTREP_SHIFT UINT32_C(0)
-#define DR_TTREP_MASK (UINT32_C(0xFF) << DR_TTREP_SHIFT)
-#define DR_TTREP(d) (((d) & DR_TTREP_MASK) >> DR_TTREP_SHIFT)
-
-#define DR_ISNASTY_SHIFT UINT32_C(8)
-#define DR_ISNASTY_MASK (UINT32_C(0xFF) << DR_ISNASTY_SHIFT)
-#define DR_ISNASTY(d) (((d) & DR_ISNASTY_MASK) >> DR_ISNASTY_SHIFT)
-
STATIC uint64_t coord_dreoesep_nosym(cube_t);
STATIC cube_t invcoord_dreoesep_nosym(uint64_t);
+STATIC cube_t coordinate_dr_merge(cube_t, cube_t);
STATIC uint64_t coordinate_dr_coord(cube_t, const void *);
STATIC cube_t coordinate_dr_cube(uint64_t, const void *);
STATIC bool coordinate_dr_isnasty(uint64_t, const void *);
STATIC size_t coordinate_dr_gendata(void *);
+/* TODO: remove the following two when all coordinates are converted to unsigned */
+STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); }
+STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); }
+
STATIC coord_t coordinate_dr = {
.name = "DR",
.coord = &coordinate_dr_coord,
@@ -40,6 +29,16 @@ STATIC coord_t coordinate_dr = {
[AXIS_FB] = TRANS_FDr,
},
.is_admissible = &solution_lastqt_cw,
+ .sym = {
+ .classes = DREOESEP_CLASSES,
+ .max = DREOESEP_MAX,
+ .coord = &coord_dreoesep_nosym,
+ .cube = &invcoord_dreoesep_nosym,
+ .max2 = POW_3_7,
+ .coord2 = &coord_co_u,
+ .cube2 = &invcoord_co_u,
+ .merge = &coordinate_dr_merge,
+ },
};
STATIC uint64_t
@@ -67,114 +66,37 @@ invcoord_dreoesep_nosym(uint64_t coord)
return cube;
}
+STATIC cube_t
+coordinate_dr_merge(cube_t c1, cube_t c2)
+{
+ cube_t merged;
+
+ merged = c1;
+ copy_corners(&merged, c2);
+
+ return merged;
+}
+
STATIC uint64_t
coordinate_dr_coord(cube_t cube, const void *data)
{
- const char *datanoinfo;
- const uint32_t *data32;
- uint32_t d;
- cube_t transformed;
-
- datanoinfo = (const char *)data + INFOSIZE;
- data32 = (const uint32_t *)datanoinfo;
- d = data32[coord_dreoesep_nosym(cube)];
- transformed = transform(cube, DR_TTREP(d));
-
- return DR_CLASS(d) * POW_3_7 + coord_co(transformed);
+ return coord_coord_generic(&coordinate_dr, cube, data);
}
STATIC cube_t
-coordinate_dr_cube(uint64_t coord, const void *data)
+coordinate_dr_cube(uint64_t i, const void *data)
{
- const char *datanoinfo;
- const uint32_t *rep32;
- cube_t cube;
-
- datanoinfo = (const char *)data + INFOSIZE;
- rep32 = (const uint32_t *)(datanoinfo + DR_CLASS_TABLESIZE);
- cube = invcoord_dreoesep_nosym(rep32[coord / POW_3_7]);
- copy_corners(&cube, invcoord_co(coord % POW_3_7));
-
- return cube;
+ return coord_cube_generic(&coordinate_dr, i, data);
}
STATIC bool
-coordinate_dr_isnasty(uint64_t coord, const void *data)
+coordinate_dr_isnasty(uint64_t i, const void *data)
{
- const char *datanoinfo;
- const uint32_t *classttrep, *rep32;
- uint32_t r;
-
- datanoinfo = (const char *)data + INFOSIZE;
- classttrep = (const uint32_t *)datanoinfo;
- rep32 = (const uint32_t *)(datanoinfo + DR_CLASS_TABLESIZE);
- r = rep32[coord / POW_3_7];
-
- return DR_ISNASTY(classttrep[r]);
+ return coord_isnasty_generic(&coordinate_dr, i, data);
}
STATIC size_t
coordinate_dr_gendata(void *data)
{
- uint64_t i, j, n, t, nasty;
- char *datanoinfo;
- uint32_t *classttrep, *rep;
- cube_t c;
- tableinfo_t info;
-
- if (data == NULL)
- goto coordinate_dr_gendata_returnsize;
-
- datanoinfo = (char *)data + INFOSIZE;
- classttrep = (uint32_t *)datanoinfo;
- rep = classttrep + (DR_CLASS_TABLESIZE / sizeof(uint32_t));
- memset(data, 0xFF, DR_COORD_DATASIZE);
-
- info = (tableinfo_t) {
- .solver = "coord data for DR",
- .type = TABLETYPE_SPECIAL,
- .infosize = INFOSIZE,
- .fullsize = DR_COORD_DATASIZE,
- .hash = 0,
- .entries = DREOESEP_CLASSES + DREOESEP_MAX,
- .classes = DREOESEP_CLASSES,
- .bits = 32,
- .base = 0,
- .maxvalue = 0,
- .next = 0
- };
-
- for (i = 0, n = 0; i < COMB_12_4 * POW_2_11; i++) {
- if (classttrep[i] != 0xFFFFFFFF)
- continue;
-
- c = invcoord_dreoesep_nosym(i);
- for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) {
- if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask))
- continue;
-
- nasty = i == coord_dreoesep_nosym(transform(c, t));
- }
-
- for (t = 0; t < NTRANS; t++) {
- if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask))
- continue;
-
- j = coord_dreoesep_nosym(transform(c, t));
- classttrep[j] =
- (n << DR_CLASS_SHIFT) |
- (nasty << DR_ISNASTY_SHIFT) |
- (inverse_trans(t) << DR_TTREP_SHIFT);
- }
- rep[n++] = i;
- }
-
- writetableinfo(&info, DR_COORD_DATASIZE, data);
-
- DBG_ASSERT(n == DREOESEP_CLASSES, 0,
- "dr coordinate data: computed %" PRIu64 " classes, "
- "expected %" PRIu64 "\n", n, DREOESEP_CLASSES);
-
-coordinate_dr_gendata_returnsize:
- return DR_COORD_DATASIZE;
+ return coord_gendata_generic(&coordinate_dr, data);
}
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
@@ -18,6 +18,7 @@ STATIC coord_t coordinate_eo = {
[AXIS_FB] = TRANS_UFr,
},
.is_admissible = &solution_lastqt_cw,
+ .sym = {0},
};
STATIC uint64_t
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
@@ -1,6 +1,29 @@
-#define COORD_INDEX(i) ((i)/2)
-#define COORD_SHIFT(i) (UINT8_C(4) * (uint8_t)((i) % 2))
-#define COORD_MASK(i) (UINT8_C(0xF) << COORD_SHIFT(i))
+#define COORD_INDEX(i) ((i)/2)
+#define COORD_SHIFT(i) (UINT8_C(4) * (uint8_t)((i) % 2))
+#define COORD_MASK(i) (UINT8_C(0xF) << COORD_SHIFT(i))
+
+#define COORD_CLASS_SHIFT UINT32_C(16)
+#define COORD_CLASS_MASK (UINT32_C(0xFFFF) << COORD_CLASS_SHIFT)
+#define COORD_CLASS(d) (((d) & COORD_CLASS_MASK) >> COORD_CLASS_SHIFT)
+
+#define COORD_TTREP_SHIFT UINT32_C(0)
+#define COORD_TTREP_MASK (UINT32_C(0xFF) << COORD_TTREP_SHIFT)
+#define COORD_TTREP(d) (((d) & COORD_TTREP_MASK) >> COORD_TTREP_SHIFT)
+
+#define COORD_ISNASTY_SHIFT UINT32_C(8)
+#define COORD_ISNASTY_MASK (UINT32_C(0xFF) << COORD_ISNASTY_SHIFT)
+#define COORD_ISNASTY(d) (((d) & COORD_ISNASTY_MASK) >> COORD_ISNASTY_SHIFT)
+
+typedef struct {
+ size_t classes;
+ uint64_t max;
+ uint64_t (*coord)(cube_t);
+ cube_t (*cube)(uint64_t);
+ uint64_t max2;
+ uint64_t (*coord2)(cube_t);
+ cube_t (*cube2)(uint64_t);
+ cube_t (*merge)(cube_t, cube_t);
+} symcoord_t;
typedef struct {
const char name[255];
@@ -13,4 +36,5 @@ typedef struct {
uint64_t trans_mask;
uint8_t axistrans[3];
bool (*is_admissible)(const solution_moves_t[static 1]);
+ symcoord_t sym;
} coord_t;