aboutsummaryrefslogtreecommitdiff
path: root/src/solve_h48.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/solve_h48.h')
-rw-r--r--src/solve_h48.h176
1 files changed, 85 insertions, 91 deletions
diff --git a/src/solve_h48.h b/src/solve_h48.h
index b04ae47..b95e6ce 100644
--- a/src/solve_h48.h
+++ b/src/solve_h48.h
@@ -1,20 +1,20 @@
1#define COCSEP_CLASSES 3393U 1#define COCSEP_CLASSES 3393U
2#define COCSEP_TABLESIZE (_3p7 << 7U) 2#define COCSEP_TABLESIZE (_3p7 << 7U)
3#define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + 7U) / 8U) 3#define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + 7U) / 8U)
4#define COCSEP_INFOSIZE 12U 4#define COCSEP_INFOSIZE 12U
5#define COCSEP_FULLSIZE (4 * (COCSEP_TABLESIZE + COCSEP_INFOSIZE)) 5#define COCSEP_FULLSIZE (4 * (COCSEP_TABLESIZE + COCSEP_INFOSIZE))
6 6
7#define ESEP_TABLESIZE ((COCSEP_CLASSES * _12c4 * _8c4) / 2U) 7#define ESEP_MAX(h) ((COCSEP_CLASSES * _12c4 * _8c4) << (h))
8#define ESEP_VISITEDSIZE ((ESEP_TABLESIZE * 2U + 7U) / 8U) 8#define ESEP_TABLESIZE(h, k) (ESEP_MAX((h)) >> (k))
9#define ESEP_INFOSIZE 25 /* TODO unknown yet */ 9#define ESEP_INFOSIZE 25 /* TODO unknown yet */
10 10
11#define H48_ESIZE(h) ((_12c4 * _8c4) << (h)) 11#define H48_ESIZE(h) ((_12c4 * _8c4) << (h))
12 12
13#define _esep_ind(i) (i / 8U) 13#define _esep_ind(i) (i / 8U)
14#define _esep_shift(i) (4U * (i % 8U)) 14#define _esep_shift(i) (4U * (i % 8U))
15#define _esep_mask(i) (((1U << 4U) - 1U) << _esep_shift(i)) 15#define _esep_mask(i) (((1U << 4U) - 1U) << _esep_shift(i))
16#define _visited_ind(i) (i / 8U) 16#define _visited_ind(i) (i / 8U)
17#define _visited_mask(i) (1U << (i % 8U)) 17#define _visited_mask(i) (1U << (i % 8U))
18 18
19typedef struct { 19typedef struct {
20 cube_fast_t cube; 20 cube_fast_t cube;
@@ -28,23 +28,21 @@ typedef struct {
28} dfsarg_cocsep_t; 28} dfsarg_cocsep_t;
29 29
30typedef struct { 30typedef struct {
31 cube_fast_t cube;
32 uint8_t *visited;
33 uint8_t *moves;
34 uint8_t nmoves;
35 uint8_t depth; 31 uint8_t depth;
36 uint16_t *nclasses; 32 uint8_t h;
37 uint32_t *cocsepdata; 33 uint32_t *cocsepdata;
38 uint32_t *buf32; 34 uint32_t *buf32;
39} dfsarg_esep_t; 35 uint64_t *selfsim;
36 cube_fast_t *crep;
37} bfsarg_esep_t;
40 38
41_static_inline int64_t coord_h48(cube_fast_t, const uint32_t *, uint8_t); 39_static_inline int64_t coord_h48(cube_fast_t, const uint32_t *, uint8_t);
42_static_inline cube_fast_t invcoord_h48(int64_t, const cube_fast_t *, uint8_t); 40_static_inline cube_fast_t invcoord_h48(int64_t, const cube_fast_t *, uint8_t);
43 41
44_static size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *); 42_static size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *);
45_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); 43_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *);
46_static size_t gendata_esep(void *); 44_static size_t gendata_h48(void *, uint8_t);
47_static uint32_t gendata_esep_dfs(dfsarg_esep_t *); 45_static uint64_t gendata_esep_bfs(bfsarg_esep_t *);
48 46
49_static_inline bool get_visited(const uint8_t *, int64_t); 47_static_inline bool get_visited(const uint8_t *, int64_t);
50_static_inline void set_visited(uint8_t *, int64_t); 48_static_inline void set_visited(uint8_t *, int64_t);
@@ -86,7 +84,7 @@ invcoord_h48(int64_t i, const cube_fast_t *crep, uint8_t h) {
86 cube_fast_t ret; int64_t coclass, ee, esep, eo; 84 cube_fast_t ret; int64_t coclass, ee, esep, eo;
87 85
88 DBG_ASSERT(h <= 11, cubetofast(zero), 86 DBG_ASSERT(h <= 11, cubetofast(zero),
89 "invcoord_h48: h must be between 0 and 11\n"); 87 "invcoord_h48: h must be between 0 and 11\n");
90 88
91 coclass = i / H48_ESIZE(h); 89 coclass = i / H48_ESIZE(h);
92 ee = i % H48_ESIZE(h); 90 ee = i % H48_ESIZE(h);
@@ -164,7 +162,7 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
164{ 162{
165 uint8_t m, t, tinv, olddepth; 163 uint8_t m, t, tinv, olddepth;
166 uint32_t cc; 164 uint32_t cc;
167 int64_t i; 165 int64_t i, ii;
168 uint64_t sim; 166 uint64_t sim;
169 cube_fast_t d; 167 cube_fast_t d;
170 dfsarg_cocsep_t nextarg; 168 dfsarg_cocsep_t nextarg;
@@ -181,13 +179,12 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
181 179
182 for (t = 0, cc = 0; t < 48; t++) { 180 for (t = 0, cc = 0; t < 48; t++) {
183 d = transform(arg->cube, t); 181 d = transform(arg->cube, t);
184 sim = equal_fast(arg->cube, d); 182 ii = coord_fast_cocsep(d);
185 arg->selfsim[*arg->n] |= sim << t; 183 arg->selfsim[*arg->n] |= (i == ii) << t;
186 i = coord_fast_cocsep(d); 184 set_visited(arg->visited, ii);
187 set_visited(arg->visited, i);
188 tinv = inverse_trans(t); 185 tinv = inverse_trans(t);
189 cc += (arg->buf32[i] & 0xFFU) == 0xFFU; 186 cc += (arg->buf32[ii] & 0xFFU) == 0xFFU;
190 arg->buf32[i] = 187 arg->buf32[ii] =
191 (*arg->n << 16U) | (tinv << 8U) | arg->depth; 188 (*arg->n << 16U) | (tinv << 8U) | arg->depth;
192 } 189 }
193 arg->rep[*arg->n] = arg->cube; 190 arg->rep[*arg->n] = arg->cube;
@@ -211,84 +208,81 @@ TODO description
211generating fixed table with h=0, k=4 208generating fixed table with h=0, k=4
212*/ 209*/
213_static size_t 210_static size_t
214gendata_esep(void *buf) 211gendata_h48(void *buf, uint8_t h)
215{ 212{
216 uint32_t *buf32, *info, *cocsepdata, cc; 213 const int k = 1; /* TODO: other cases? */
217 uint8_t moves[20]; 214 uint32_t *buf32, *info, *cocsepdata;
218 dfsarg_esep_t arg; 215 bfsarg_esep_t arg;
216 int64_t sc, cc, tot;
217 uint64_t selfsim[COCSEP_CLASSES];
218 cube_fast_t crep[COCSEP_CLASSES];
219 size_t cocsepsize;
219 220
220 arg.visited = malloc(ESEP_TABLESIZE); 221 cocsepsize = gendata_cocsep(buf, selfsim, crep);
222 DBG_ASSERT(cocsepsize == COCSEP_FULLSIZE, 0,
223 "gendata_h48: error computing cocsep data\n");
221 224
222 cocsepdata = (uint32_t *)buf; 225 cocsepdata = (uint32_t *)buf;
223 buf32 = cocsepdata + COCSEP_FULLSIZE; 226 buf32 = cocsepdata + cocsepsize;
224 info = buf32 + ESEP_TABLESIZE; 227 info = buf32 + ESEP_TABLESIZE(h, k);
225 memset(buf32, 0xFFU, sizeof(uint32_t) * ESEP_TABLESIZE); 228 memset(buf32, 0xFFU, sizeof(uint32_t) * ESEP_TABLESIZE(h, k));
226 memset(info, 0, sizeof(uint32_t) * ESEP_INFOSIZE); 229 memset(info, 0, sizeof(uint32_t) * ESEP_INFOSIZE);
227 230
228 arg.cube = cubetofast(solvedcube()); 231 sc = coord_h48(cubetofast(solved), cocsepdata, h);
229 arg.moves = moves; 232 set_esep_pval(buf32, sc, 0);
230 arg.nmoves = 0; 233 arg = (bfsarg_esep_t) {
231 arg.cocsepdata = cocsepdata; 234 .h = h,
232 arg.buf32 = buf32; 235 .cocsepdata = cocsepdata,
233 /* TODO loop until no more is done, not until 12! (or hardcode limits)*/ 236 .buf32 = buf32,
234 /* TODO use bfs instead 237 .crep = crep,
235 how to work with different k? k=1 is the easiest */ 238 .selfsim = selfsim
236 for (arg.depth = 0, cc = 0; arg.depth < 12; arg.depth++) { 239 };
240 for (tot = 1, arg.depth = 1, cc = 0; tot < ESEP_MAX(h); arg.depth++) {
237 DBG_LOG("esep: generating depth %" PRIu8 "\n", arg.depth); 241 DBG_LOG("esep: generating depth %" PRIu8 "\n", arg.depth);
238 memset(arg.visited, 0, ESEP_VISITEDSIZE); 242 cc = gendata_esep_bfs(&arg);
239 cc = gendata_esep_dfs(&arg); 243 tot += cc;
240 info[arg.depth+1] = cc; 244 info[arg.depth+1] = cc;
241 DBG_LOG("found %" PRIu32 "\n", cc); 245 DBG_LOG("found %" PRIu64 "\n", cc);
242 } 246 }
243 free(arg.visited);
244 247
245 return COCSEP_FULLSIZE + cc; 248 return COCSEP_FULLSIZE + cc;
246} 249}
247 250
248_static uint32_t 251_static uint64_t
249gendata_esep_dfs(dfsarg_esep_t *arg) 252gendata_esep_bfs(bfsarg_esep_t *arg)
250{ 253{
251 uint8_t m, t, olddepth; 254 uint8_t c, m, t, x;
252 uint32_t cc; 255 uint32_t cc;
253 uint64_t i; 256 uint64_t i, j, k, cocsep_coord, sim;
254 cube_fast_t d; 257 cube_fast_t cube, moved, transd;
255 dfsarg_esep_t nextarg;
256
257 if (!allowednextmove(arg->moves, arg->nmoves))
258 return 0;
259 258
260 if (arg->nmoves > 0) 259 for (i = 0, cc = 0; i < ESEP_MAX(arg->h); i++) {
261 arg->cube = move(arg->cube, arg->moves[arg->nmoves-1]); 260 c = get_esep_pval(arg->buf32, i);
262 261 if (c != arg->depth - 1)
263 i = coord_h48(arg->cube, arg->cocsepdata, 0U); 262 continue;
264 olddepth = get_esep_pval(arg->buf32, i); 263 cube = invcoord_h48(i, arg->crep, arg->h);
265 264 for (m = 0; m < 18; m++) {
266 if (olddepth < arg->nmoves || get_visited(arg->visited, i)) 265 moved = move(cube, m);
267 return 0; 266 j = coord_h48(moved, arg->cocsepdata, arg->h);
268 set_visited(arg->visited, i); 267 x = get_esep_pval(arg->buf32, j);
269 268 if (x <= arg->depth)
270 if (arg->nmoves == arg->depth) { 269 continue;
271 if (olddepth != 15U) 270 set_esep_pval(arg->buf32, j, arg->depth);
272 return 0; 271 cc += x != arg->depth;
273 272 cocsep_coord = j / H48_ESIZE(arg->h);
274 for (t = 0, cc = 0; t < 48; t++) { 273 sim = arg->selfsim[cocsep_coord];
275 d = transform(arg->cube, t); 274 for (t = 1; t < 48; t++) { /* Skip trivial trans */
276 i = coord_h48(d, arg->cocsepdata, 0U); 275 if (!(sim & (1 << t)))
277 set_visited(arg->visited, i); 276 continue;
278 cc += get_esep_pval(arg->buf32, i) == 15U; 277 transd = transform(moved, t);
279 set_esep_pval(arg->buf32, i, arg->depth); 278 k = coord_h48(transd, arg->cocsepdata, arg->h);
279 x = get_esep_pval(arg->buf32, k);
280 if (x <= arg->depth)
281 continue;
282 set_esep_pval(arg->buf32, k, arg->depth);
283 cc += x != arg->depth;
284 }
280 } 285 }
281
282 return cc;
283 }
284
285
286 nextarg = *arg;
287 nextarg.nmoves = arg->nmoves + 1;
288 for (m = 0, cc = 0; m < 18; m++) {
289 nextarg.cube = arg->cube;
290 nextarg.moves[arg->nmoves] = m;
291 cc += gendata_esep_dfs(&nextarg);
292 } 286 }
293 287
294 return cc; 288 return cc;

Generated with cgit - Back to sebastiano.tronto.net