aboutsummaryrefslogtreecommitdiff
path: root/src/solvers
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-04-01 22:26:44 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-04-01 22:26:44 +0200
commitae0e5295daa7618b6facebac31c3a88eaccfc368 (patch)
tree60ccd4de018a0a36d7204a81cd950c47d31548b2 /src/solvers
parent29f61e2b4e0f73c83d6d86e4f09d79e129358750 (diff)
downloadnissy-core-ae0e5295daa7618b6facebac31c3a88eaccfc368.tar.gz
nissy-core-ae0e5295daa7618b6facebac31c3a88eaccfc368.zip
Make symcoord logic generic
Diffstat (limited to 'src/solvers')
-rw-r--r--src/solvers/coord/common.h133
-rw-r--r--src/solvers/coord/dr.h142
-rw-r--r--src/solvers/coord/eo.h1
-rw-r--r--src/solvers/coord/types_macros.h30
4 files changed, 191 insertions, 115 deletions
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
index 4cfc36f..95c0e6c 100644
--- a/src/solvers/coord/common.h
+++ b/src/solvers/coord/common.h
@@ -1,10 +1,139 @@
1STATIC void append_coord_name(const coord_t *, char *); 1STATIC uint64_t coord_coord_generic(
2 const coord_t [static 1], cube_t, const void *);
3STATIC cube_t coord_cube_generic(
4 const coord_t [static 1], uint64_t, const void *);
5STATIC bool coord_isnasty_generic(
6 const coord_t [static 1], uint64_t, const void *);
7STATIC size_t coord_gendata_generic(const coord_t [static 1], void *);
8
9STATIC void append_coord_name(const coord_t [static 1], char *);
2STATIC bool solution_lastqt_cw(const solution_moves_t [static 1]); 10STATIC bool solution_lastqt_cw(const solution_moves_t [static 1]);
3STATIC bool coord_can_switch( 11STATIC bool coord_can_switch(
4 const coord_t [static 1], const void *, size_t n, const uint8_t [n]); 12 const coord_t [static 1], const void *, size_t n, const uint8_t [n]);
5 13
14STATIC uint64_t
15coord_coord_generic(const coord_t coord[static 1], cube_t c, const void *data)
16{
17 const char *datanoinfo;
18 const uint32_t *data32;
19 uint32_t d;
20 cube_t tr;
21
22 datanoinfo = (const char *)data + INFOSIZE;
23 data32 = (const uint32_t *)datanoinfo;
24 d = data32[coord->sym.coord(c)];
25 tr = transform(c, COORD_TTREP(d));
26
27 return COORD_CLASS(d) * coord->sym.max2 + coord->sym.coord2(tr);
28}
29
30STATIC cube_t
31coord_cube_generic(const coord_t coord[static 1], uint64_t i, const void *data)
32{
33 const char *datanoinfo;
34 const uint32_t *rep32;
35 cube_t c;
36
37 datanoinfo = (const char *)data + INFOSIZE;
38 rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max);
39 c = coord->sym.cube(rep32[i / coord->sym.max2]);
40
41 return coord->sym.merge(c, coord->sym.cube2(i % coord->sym.max2));
42}
43
44STATIC bool
45coord_isnasty_generic(
46 const coord_t coord[static 1],
47 uint64_t i,
48 const void *data
49)
50{
51 const char *datanoinfo;
52 const uint32_t *classttrep, *rep32;
53 uint32_t r;
54
55 datanoinfo = (const char *)data + INFOSIZE;
56 classttrep = (const uint32_t *)datanoinfo;
57 rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max);
58 r = rep32[i / coord->sym.max2];
59
60 return COORD_ISNASTY(classttrep[r]);
61}
62
63STATIC size_t
64coord_gendata_generic(
65 const coord_t coord[static 1],
66 void *data
67)
68{
69 uint64_t i, j, n, t, nasty;
70 char *datanoinfo;
71 uint32_t *classttrep, *rep;
72 size_t coord_datasize;
73 cube_t c;
74 tableinfo_t info;
75
76 coord_datasize = INFOSIZE + 4*(coord->sym.classes + coord->sym.max);
77
78 if (data == NULL)
79 return coord_datasize;
80
81 datanoinfo = (char *)data + INFOSIZE;
82 classttrep = (uint32_t *)datanoinfo;
83 rep = classttrep + coord->sym.max;
84 memset(data, 0xFF, coord_datasize);
85
86 info = (tableinfo_t) {
87 .solver = "coord data for ",
88 .type = TABLETYPE_SPECIAL,
89 .infosize = INFOSIZE,
90 .fullsize = coord_datasize,
91 .hash = 0,
92 .entries = coord->sym.classes + coord->sym.max,
93 .classes = coord->sym.classes,
94 .bits = 32,
95 .base = 0,
96 .maxvalue = 0,
97 .next = 0
98 };
99 append_coord_name(coord, info.solver);
100
101 for (i = 0, n = 0; i < coord->sym.max; i++) {
102 if (classttrep[i] != 0xFFFFFFFF)
103 continue;
104
105 c = coord->sym.cube(i);
106 for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) {
107 if (!((UINT64_C(1) << t) & coord->trans_mask))
108 continue;
109
110 nasty = i == coord->sym.coord(transform(c, t));
111 }
112
113 for (t = 0; t < NTRANS; t++) {
114 if (!((UINT64_C(1) << t) & coord->trans_mask))
115 continue;
116
117 j = coord->sym.coord(transform(c, t));
118 classttrep[j] =
119 (n << COORD_CLASS_SHIFT) |
120 (nasty << COORD_ISNASTY_SHIFT) |
121 (inverse_trans(t) << COORD_TTREP_SHIFT);
122 }
123 rep[n++] = i;
124 }
125
126 writetableinfo(&info, coord_datasize, data);
127
128 DBG_ASSERT(n == coord->sym.classes, 0,
129 "%s coordinate data: computed %" PRIu64 " classes, "
130 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes);
131
132 return coord_datasize;
133}
134
6STATIC void 135STATIC void
7append_coord_name(const coord_t *coord, char *str) 136append_coord_name(const coord_t coord[static 1], char *str)
8{ 137{
9 int i, j; 138 int i, j;
10 139
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
index c6552e3..314d4f1 100644
--- a/src/solvers/coord/dr.h
+++ b/src/solvers/coord/dr.h
@@ -1,30 +1,19 @@
1#define DREOESEP_CLASSES UINT64_C(64430) 1#define DREOESEP_CLASSES UINT64_C(64430)
2#define DREOESEP_MAX (POW_2_11 * COMB_12_4) 2#define DREOESEP_MAX (POW_2_11 * COMB_12_4)
3 3
4#define DR_CLASS_TABLESIZE (sizeof(uint32_t) * (size_t)DREOESEP_MAX)
5#define DR_REP_TABLESIZE (sizeof(uint32_t) * (size_t)DREOESEP_CLASSES)
6#define DR_COORD_DATASIZE (INFOSIZE + DR_CLASS_TABLESIZE + DR_REP_TABLESIZE)
7
8#define DR_CLASS_SHIFT UINT32_C(16)
9#define DR_CLASS_MASK (UINT32_C(0xFFFF) << DR_CLASS_SHIFT)
10#define DR_CLASS(d) (((d) & DR_CLASS_MASK) >> DR_CLASS_SHIFT)
11
12#define DR_TTREP_SHIFT UINT32_C(0)
13#define DR_TTREP_MASK (UINT32_C(0xFF) << DR_TTREP_SHIFT)
14#define DR_TTREP(d) (((d) & DR_TTREP_MASK) >> DR_TTREP_SHIFT)
15
16#define DR_ISNASTY_SHIFT UINT32_C(8)
17#define DR_ISNASTY_MASK (UINT32_C(0xFF) << DR_ISNASTY_SHIFT)
18#define DR_ISNASTY(d) (((d) & DR_ISNASTY_MASK) >> DR_ISNASTY_SHIFT)
19
20STATIC uint64_t coord_dreoesep_nosym(cube_t); 4STATIC uint64_t coord_dreoesep_nosym(cube_t);
21STATIC cube_t invcoord_dreoesep_nosym(uint64_t); 5STATIC cube_t invcoord_dreoesep_nosym(uint64_t);
6STATIC cube_t coordinate_dr_merge(cube_t, cube_t);
22 7
23STATIC uint64_t coordinate_dr_coord(cube_t, const void *); 8STATIC uint64_t coordinate_dr_coord(cube_t, const void *);
24STATIC cube_t coordinate_dr_cube(uint64_t, const void *); 9STATIC cube_t coordinate_dr_cube(uint64_t, const void *);
25STATIC bool coordinate_dr_isnasty(uint64_t, const void *); 10STATIC bool coordinate_dr_isnasty(uint64_t, const void *);
26STATIC size_t coordinate_dr_gendata(void *); 11STATIC size_t coordinate_dr_gendata(void *);
27 12
13/* TODO: remove the following two when all coordinates are converted to unsigned */
14STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); }
15STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); }
16
28STATIC coord_t coordinate_dr = { 17STATIC coord_t coordinate_dr = {
29 .name = "DR", 18 .name = "DR",
30 .coord = &coordinate_dr_coord, 19 .coord = &coordinate_dr_coord,
@@ -40,6 +29,16 @@ STATIC coord_t coordinate_dr = {
40 [AXIS_FB] = TRANS_FDr, 29 [AXIS_FB] = TRANS_FDr,
41 }, 30 },
42 .is_admissible = &solution_lastqt_cw, 31 .is_admissible = &solution_lastqt_cw,
32 .sym = {
33 .classes = DREOESEP_CLASSES,
34 .max = DREOESEP_MAX,
35 .coord = &coord_dreoesep_nosym,
36 .cube = &invcoord_dreoesep_nosym,
37 .max2 = POW_3_7,
38 .coord2 = &coord_co_u,
39 .cube2 = &invcoord_co_u,
40 .merge = &coordinate_dr_merge,
41 },
43}; 42};
44 43
45STATIC uint64_t 44STATIC uint64_t
@@ -67,114 +66,37 @@ invcoord_dreoesep_nosym(uint64_t coord)
67 return cube; 66 return cube;
68} 67}
69 68
69STATIC cube_t
70coordinate_dr_merge(cube_t c1, cube_t c2)
71{
72 cube_t merged;
73
74 merged = c1;
75 copy_corners(&merged, c2);
76
77 return merged;
78}
79
70STATIC uint64_t 80STATIC uint64_t
71coordinate_dr_coord(cube_t cube, const void *data) 81coordinate_dr_coord(cube_t cube, const void *data)
72{ 82{
73 const char *datanoinfo; 83 return coord_coord_generic(&coordinate_dr, cube, data);
74 const uint32_t *data32;
75 uint32_t d;
76 cube_t transformed;
77
78 datanoinfo = (const char *)data + INFOSIZE;
79 data32 = (const uint32_t *)datanoinfo;
80 d = data32[coord_dreoesep_nosym(cube)];
81 transformed = transform(cube, DR_TTREP(d));
82
83 return DR_CLASS(d) * POW_3_7 + coord_co(transformed);
84} 84}
85 85
86STATIC cube_t 86STATIC cube_t
87coordinate_dr_cube(uint64_t coord, const void *data) 87coordinate_dr_cube(uint64_t i, const void *data)
88{ 88{
89 const char *datanoinfo; 89 return coord_cube_generic(&coordinate_dr, i, data);
90 const uint32_t *rep32;
91 cube_t cube;
92
93 datanoinfo = (const char *)data + INFOSIZE;
94 rep32 = (const uint32_t *)(datanoinfo + DR_CLASS_TABLESIZE);
95 cube = invcoord_dreoesep_nosym(rep32[coord / POW_3_7]);
96 copy_corners(&cube, invcoord_co(coord % POW_3_7));
97
98 return cube;
99} 90}
100 91
101STATIC bool 92STATIC bool
102coordinate_dr_isnasty(uint64_t coord, const void *data) 93coordinate_dr_isnasty(uint64_t i, const void *data)
103{ 94{
104 const char *datanoinfo; 95 return coord_isnasty_generic(&coordinate_dr, i, data);
105 const uint32_t *classttrep, *rep32;
106 uint32_t r;
107
108 datanoinfo = (const char *)data + INFOSIZE;
109 classttrep = (const uint32_t *)datanoinfo;
110 rep32 = (const uint32_t *)(datanoinfo + DR_CLASS_TABLESIZE);
111 r = rep32[coord / POW_3_7];
112
113 return DR_ISNASTY(classttrep[r]);
114} 96}
115 97
116STATIC size_t 98STATIC size_t
117coordinate_dr_gendata(void *data) 99coordinate_dr_gendata(void *data)
118{ 100{
119 uint64_t i, j, n, t, nasty; 101 return coord_gendata_generic(&coordinate_dr, data);
120 char *datanoinfo;
121 uint32_t *classttrep, *rep;
122 cube_t c;
123 tableinfo_t info;
124
125 if (data == NULL)
126 goto coordinate_dr_gendata_returnsize;
127
128 datanoinfo = (char *)data + INFOSIZE;
129 classttrep = (uint32_t *)datanoinfo;
130 rep = classttrep + (DR_CLASS_TABLESIZE / sizeof(uint32_t));
131 memset(data, 0xFF, DR_COORD_DATASIZE);
132
133 info = (tableinfo_t) {
134 .solver = "coord data for DR",
135 .type = TABLETYPE_SPECIAL,
136 .infosize = INFOSIZE,
137 .fullsize = DR_COORD_DATASIZE,
138 .hash = 0,
139 .entries = DREOESEP_CLASSES + DREOESEP_MAX,
140 .classes = DREOESEP_CLASSES,
141 .bits = 32,
142 .base = 0,
143 .maxvalue = 0,
144 .next = 0
145 };
146
147 for (i = 0, n = 0; i < COMB_12_4 * POW_2_11; i++) {
148 if (classttrep[i] != 0xFFFFFFFF)
149 continue;
150
151 c = invcoord_dreoesep_nosym(i);
152 for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) {
153 if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask))
154 continue;
155
156 nasty = i == coord_dreoesep_nosym(transform(c, t));
157 }
158
159 for (t = 0; t < NTRANS; t++) {
160 if (!((UINT64_C(1) << t) & coordinate_dr.trans_mask))
161 continue;
162
163 j = coord_dreoesep_nosym(transform(c, t));
164 classttrep[j] =
165 (n << DR_CLASS_SHIFT) |
166 (nasty << DR_ISNASTY_SHIFT) |
167 (inverse_trans(t) << DR_TTREP_SHIFT);
168 }
169 rep[n++] = i;
170 }
171
172 writetableinfo(&info, DR_COORD_DATASIZE, data);
173
174 DBG_ASSERT(n == DREOESEP_CLASSES, 0,
175 "dr coordinate data: computed %" PRIu64 " classes, "
176 "expected %" PRIu64 "\n", n, DREOESEP_CLASSES);
177
178coordinate_dr_gendata_returnsize:
179 return DR_COORD_DATASIZE;
180} 102}
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
index 9703b67..b83be01 100644
--- a/src/solvers/coord/eo.h
+++ b/src/solvers/coord/eo.h
@@ -18,6 +18,7 @@ STATIC coord_t coordinate_eo = {
18 [AXIS_FB] = TRANS_UFr, 18 [AXIS_FB] = TRANS_UFr,
19 }, 19 },
20 .is_admissible = &solution_lastqt_cw, 20 .is_admissible = &solution_lastqt_cw,
21 .sym = {0},
21}; 22};
22 23
23STATIC uint64_t 24STATIC uint64_t
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
index 8741e27..72ca511 100644
--- a/src/solvers/coord/types_macros.h
+++ b/src/solvers/coord/types_macros.h
@@ -1,6 +1,29 @@
1#define COORD_INDEX(i) ((i)/2) 1#define COORD_INDEX(i) ((i)/2)
2#define COORD_SHIFT(i) (UINT8_C(4) * (uint8_t)((i) % 2)) 2#define COORD_SHIFT(i) (UINT8_C(4) * (uint8_t)((i) % 2))
3#define COORD_MASK(i) (UINT8_C(0xF) << COORD_SHIFT(i)) 3#define COORD_MASK(i) (UINT8_C(0xF) << COORD_SHIFT(i))
4
5#define COORD_CLASS_SHIFT UINT32_C(16)
6#define COORD_CLASS_MASK (UINT32_C(0xFFFF) << COORD_CLASS_SHIFT)
7#define COORD_CLASS(d) (((d) & COORD_CLASS_MASK) >> COORD_CLASS_SHIFT)
8
9#define COORD_TTREP_SHIFT UINT32_C(0)
10#define COORD_TTREP_MASK (UINT32_C(0xFF) << COORD_TTREP_SHIFT)
11#define COORD_TTREP(d) (((d) & COORD_TTREP_MASK) >> COORD_TTREP_SHIFT)
12
13#define COORD_ISNASTY_SHIFT UINT32_C(8)
14#define COORD_ISNASTY_MASK (UINT32_C(0xFF) << COORD_ISNASTY_SHIFT)
15#define COORD_ISNASTY(d) (((d) & COORD_ISNASTY_MASK) >> COORD_ISNASTY_SHIFT)
16
17typedef struct {
18 size_t classes;
19 uint64_t max;
20 uint64_t (*coord)(cube_t);
21 cube_t (*cube)(uint64_t);
22 uint64_t max2;
23 uint64_t (*coord2)(cube_t);
24 cube_t (*cube2)(uint64_t);
25 cube_t (*merge)(cube_t, cube_t);
26} symcoord_t;
4 27
5typedef struct { 28typedef struct {
6 const char name[255]; 29 const char name[255];
@@ -13,4 +36,5 @@ typedef struct {
13 uint64_t trans_mask; 36 uint64_t trans_mask;
14 uint8_t axistrans[3]; 37 uint8_t axistrans[3];
15 bool (*is_admissible)(const solution_moves_t[static 1]); 38 bool (*is_admissible)(const solution_moves_t[static 1]);
39 symcoord_t sym;
16} coord_t; 40} coord_t;

Generated with cgit - Back to sebastiano.tronto.net