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.h94
1 files changed, 45 insertions, 49 deletions
diff --git a/src/solve_h48.h b/src/solve_h48.h
index c2c541d..5f99d15 100644
--- a/src/solve_h48.h
+++ b/src/solve_h48.h
@@ -36,7 +36,6 @@ typedef struct {
36 36
37typedef struct { 37typedef struct {
38 uint8_t depth; 38 uint8_t depth;
39 uint8_t h;
40 uint32_t *cocsepdata; 39 uint32_t *cocsepdata;
41 uint32_t *buf32; 40 uint32_t *buf32;
42 uint64_t *selfsim; 41 uint64_t *selfsim;
@@ -63,6 +62,7 @@ typedef struct {
63 int8_t depth; 62 int8_t depth;
64 uint8_t moves[MAX_SOLUTION_LENGTH]; 63 uint8_t moves[MAX_SOLUTION_LENGTH];
65 uint32_t *cocsepdata; 64 uint32_t *cocsepdata;
65 uint32_t *h48data;
66 char *s; 66 char *s;
67} dfsarg_solveh48stats_t; 67} dfsarg_solveh48stats_t;
68 68
@@ -72,8 +72,8 @@ _static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t);
72 72
73_static size_t gendata_cocsep(void *, uint64_t *, cube_t *); 73_static size_t gendata_cocsep(void *, uint64_t *, cube_t *);
74_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); 74_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *);
75_static size_t gendata_h48(void *, uint8_t, uint8_t); 75_static size_t gendata_h48h0k4(void *, uint8_t);
76_static uint64_t gendata_esep_bfs(bfsarg_esep_t *); 76_static uint64_t gendata_h48h0k4_bfs(bfsarg_esep_t *);
77 77
78_static_inline bool get_visited(const uint8_t *, int64_t); 78_static_inline bool get_visited(const uint8_t *, int64_t);
79_static_inline void set_visited(uint8_t *, int64_t); 79_static_inline void set_visited(uint8_t *, int64_t);
@@ -88,7 +88,7 @@ _static int64_t solve_h48_dfs(dfsarg_solveh48_t *);
88_static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *); 88_static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *);
89 89
90_static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); 90_static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *);
91_static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 13]); 91_static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]);
92 92
93_static_inline int64_t 93_static_inline int64_t
94coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h) 94coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h)
@@ -119,12 +119,6 @@ coord_h48_edges(cube_t c, int64_t coclass, uint8_t t, uint8_t h)
119 edges = (esep << 11) + eo; 119 edges = (esep << 11) + eo;
120 120
121 return (coclass * H48_ESIZE(11) + edges) >> (11 - (int64_t)h); 121 return (coclass * H48_ESIZE(11) + edges) >> (11 - (int64_t)h);
122
123/*
124TODO: decide which alternative is better, if above or below
125 edges = (esep << (int64_t)h) + (eo >> (11 - (int64_t)h));
126 return coclass * H48_ESIZE(h) + edges;
127*/
128} 122}
129 123
130/* 124/*
@@ -133,7 +127,8 @@ the given value, because it works up to symmetry. This means that the
133returned cube is a transformed cube of one that gives the correct value. 127returned cube is a transformed cube of one that gives the correct value.
134*/ 128*/
135_static_inline cube_t 129_static_inline cube_t
136invcoord_h48(int64_t i, const cube_t *crep, uint8_t h) { 130invcoord_h48(int64_t i, const cube_t *crep, uint8_t h)
131{
137 cube_t ret; 132 cube_t ret;
138 int64_t hh, coclass, ee, esep, eo; 133 int64_t hh, coclass, ee, esep, eo;
139 134
@@ -274,9 +269,8 @@ TODO description
274generating fixed table with h=0, k=4 269generating fixed table with h=0, k=4
275*/ 270*/
276_static size_t 271_static size_t
277gendata_h48(void *buf, uint8_t h, uint8_t maxdepth) 272gendata_h48h0k4(void *buf, uint8_t maxdepth)
278{ 273{
279 const int k = 4; /* TODO: other cases? */
280 uint32_t j, *buf32, *info, *cocsepdata; 274 uint32_t j, *buf32, *info, *cocsepdata;
281 bfsarg_esep_t arg; 275 bfsarg_esep_t arg;
282 int64_t sc, cc, tot, esep_max; 276 int64_t sc, cc, tot, esep_max;
@@ -290,19 +284,18 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
290 infosize = 88; 284 infosize = 88;
291 285
292 if (buf == NULL) 286 if (buf == NULL)
293 goto gendata_h48_return_size; 287 goto gendata_h48h0k4_return_size;
294 288
295 esep_max = (int64_t)ESEP_MAX(h); 289 esep_max = (int64_t)ESEP_MAX(0);
296 cocsepdata = (uint32_t *)buf; 290 cocsepdata = (uint32_t *)buf;
297 buf32 = cocsepdata + cocsepsize / 4; 291 buf32 = cocsepdata + cocsepsize / 4;
298 info = buf32 + (ESEP_TABLESIZE(h, k) / sizeof(uint32_t)); 292 info = buf32 + (ESEP_TABLESIZE(0, 4) / sizeof(uint32_t));
299 memset(buf32, 0xFF, ESEP_TABLESIZE(h, k)); 293 memset(buf32, 0xFF, ESEP_TABLESIZE(0, 4));
300 294
301 sc = coord_h48(solved, cocsepdata, h); 295 sc = coord_h48(solved, cocsepdata, 0);
302 set_esep_pval(buf32, sc, 0); 296 set_esep_pval(buf32, sc, 0);
303 info[1] = 1; 297 info[1] = 1;
304 arg = (bfsarg_esep_t) { 298 arg = (bfsarg_esep_t) {
305 .h = h,
306 .cocsepdata = cocsepdata, 299 .cocsepdata = cocsepdata,
307 .buf32 = buf32, 300 .buf32 = buf32,
308 .crep = crep, 301 .crep = crep,
@@ -314,7 +307,7 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
314 arg.depth++ 307 arg.depth++
315 ) { 308 ) {
316 LOG("esep: generating depth %" PRIu8 "\n", arg.depth); 309 LOG("esep: generating depth %" PRIu8 "\n", arg.depth);
317 cc = gendata_esep_bfs(&arg); 310 cc = gendata_h48h0k4_bfs(&arg);
318 tot += cc; 311 tot += cc;
319 info[arg.depth+1] = cc; 312 info[arg.depth+1] = cc;
320 LOG("found %" PRIu64 "\n", cc); 313 LOG("found %" PRIu64 "\n", cc);
@@ -328,25 +321,25 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
328 for (j = 0; j <= info[0]; j++) 321 for (j = 0; j <= info[0]; j++)
329 LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+1]); 322 LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+1]);
330 323
331gendata_h48_return_size: 324gendata_h48h0k4_return_size:
332 return cocsepsize + ESEP_TABLESIZE(h, k) + infosize; 325 return cocsepsize + ESEP_TABLESIZE(0, 4) + infosize;
333} 326}
334 327
335_static uint64_t 328_static uint64_t
336gendata_esep_bfs(bfsarg_esep_t *arg) 329gendata_h48h0k4_bfs(bfsarg_esep_t *arg)
337{ 330{
338 uint8_t c, m, x; 331 uint8_t c, m, x;
339 uint32_t cc; 332 uint32_t cc;
340 int64_t i, j, k, t, cocsep_coord, sim, esep_max; 333 int64_t i, j, k, t, cocsep_coord, sim, esep_max;
341 cube_t cube, moved, transd; 334 cube_t cube, moved, transd;
342 335
343 esep_max = (uint64_t)ESEP_MAX(arg->h); 336 esep_max = (uint64_t)ESEP_MAX(0);
344 337
345 for (i = 0, cc = 0; i < esep_max; i++) { 338 for (i = 0, cc = 0; i < esep_max; i++) {
346 c = get_esep_pval(arg->buf32, i); 339 c = get_esep_pval(arg->buf32, i);
347 if (c != arg->depth - 1) 340 if (c != arg->depth - 1)
348 continue; 341 continue;
349 cube = invcoord_h48(i, arg->crep, arg->h); 342 cube = invcoord_h48(i, arg->crep, 0);
350 for (m = 0; m < 18; m++) { 343 for (m = 0; m < 18; m++) {
351 /* 344 /*
352 * TODO: here we can optimize by computing at first 345 * TODO: here we can optimize by computing at first
@@ -354,19 +347,19 @@ gendata_esep_bfs(bfsarg_esep_t *arg)
354 * the edge parts for each transformation. 347 * the edge parts for each transformation.
355 */ 348 */
356 moved = move(cube, m); 349 moved = move(cube, m);
357 j = coord_h48(moved, arg->cocsepdata, arg->h); 350 j = coord_h48(moved, arg->cocsepdata, 0);
358 x = get_esep_pval(arg->buf32, j); 351 x = get_esep_pval(arg->buf32, j);
359 if (x <= arg->depth) 352 if (x <= arg->depth)
360 continue; 353 continue;
361 set_esep_pval(arg->buf32, j, arg->depth); 354 set_esep_pval(arg->buf32, j, arg->depth);
362 cc += x != arg->depth; 355 cc += x != arg->depth;
363 cocsep_coord = j / H48_ESIZE(arg->h); 356 cocsep_coord = j / H48_ESIZE(0);
364 sim = arg->selfsim[cocsep_coord] >> 1; 357 sim = arg->selfsim[cocsep_coord] >> 1;
365 for (t = 1; t < 48 && sim; t++, sim >>= 1) { 358 for (t = 1; t < 48 && sim; t++, sim >>= 1) {
366 if (!(sim & 1)) 359 if (!(sim & 1))
367 continue; 360 continue;
368 transd = transform(moved, t); 361 transd = transform(moved, t);
369 k = coord_h48(transd, arg->cocsepdata, arg->h); 362 k = coord_h48(transd, arg->cocsepdata, 0);
370 x = get_esep_pval(arg->buf32, k); 363 x = get_esep_pval(arg->buf32, k);
371 if (x <= arg->depth) 364 if (x <= arg->depth)
372 continue; 365 continue;
@@ -539,46 +532,45 @@ solve_h48(
539 solve_h48_dfs(&arg); 532 solve_h48_dfs(&arg);
540 } 533 }
541 534
542/*
543for (int64_t i = 0; i < 4; i++)
544LOG("Data for coord = %" PRId64 ": %" PRIu8 "\n",
545i, get_esep_pval(arg.h48data, i));
546*/
547 return nsols; 535 return nsols;
548} 536}
549 537
550/* 538/*
551The h48stats solver computes how many moves it takes to solve to each of 539The h48stats solver computes how many moves it takes to solve to
552the 13 h48 coordinates: the corner-only coordinate, and 12 cocsep+esep 540each of the 12 h48 coordinates, one for each value of h from 0 to 11.
553coordinates with h from 0 to 11. The solutions array is filled with 541The solutions array is filled with the length of the solutions. The
554the length of the solutions: solutions[0] contains the value for the 542solution array is therefore not a printable string.
555corner-only coordinate, and for i>0 solutions[i] contains the value for
556the cocsep+esep coordinate with h=i-1. The solution array is therefore
557not a printable string.
558*/ 543*/
559_static int64_t 544_static int64_t
560solve_h48stats_dfs(dfsarg_solveh48stats_t *arg) 545solve_h48stats_dfs(dfsarg_solveh48stats_t *arg)
561{ 546{
547 const int64_t limit = 11;
548
562 int8_t bound, u; 549 int8_t bound, u;
563 uint8_t m; 550 uint8_t m;
564 uint32_t d; 551 uint32_t d;
565 int64_t coord, h; 552 int64_t coord, h;
566 dfsarg_solveh48stats_t nextarg; 553 dfsarg_solveh48stats_t nextarg;
567 554
555 /* Check cocsep lower bound (corners only) */
568 bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d); 556 bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d);
569 if (bound + arg->nmoves > arg->depth) 557 if (bound + arg->nmoves > arg->depth)
570 return 0; 558 return 0;
571 559
572 u = COCLASS(d) == 0 && arg->s[0] == 99; 560 /* Check h48 lower bound for h=0 (esep, but no eo) */
573 arg->s[0] = u * arg->nmoves + (1-u) * arg->s[0]; 561 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0);
562 bound = get_esep_pval(arg->h48data, coord);
563 if (bound + arg->nmoves > arg->depth)
564 return 0;
574 565
566 /* Update all other values, if solved */
575 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11); 567 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11);
576 for (h = 0; h <= 11; h++) { 568 for (h = 0; h <= limit; h++) {
577 u = coord >> (11-h) == 0 && arg->s[h+1] == 99; 569 u = coord >> (11-h) == 0 && arg->s[h] == 99;
578 arg->s[h+1] = u * arg->nmoves + (1-u) * arg->s[h+1]; 570 arg->s[h] = u * arg->nmoves + (1-u) * arg->s[h];
579 } 571 }
580 572
581 if (arg->s[12] != 99) 573 if (arg->s[limit] != 99)
582 return 0; 574 return 0;
583 575
584 nextarg = *arg; 576 nextarg = *arg;
@@ -603,23 +595,27 @@ solve_h48stats(
603 cube_t cube, 595 cube_t cube,
604 int8_t maxmoves, 596 int8_t maxmoves,
605 const void *data, 597 const void *data,
606 char solutions[static 13] 598 char solutions[static 12]
607) 599)
608{ 600{
609 int i; 601 int i;
602 size_t cocsepsize;
610 dfsarg_solveh48stats_t arg; 603 dfsarg_solveh48stats_t arg;
611 604
605 cocsepsize = gendata_cocsep(NULL, NULL, NULL);
606
612 arg = (dfsarg_solveh48stats_t) { 607 arg = (dfsarg_solveh48stats_t) {
613 .cube = cube, 608 .cube = cube,
614 .cocsepdata = (uint32_t *)data, 609 .cocsepdata = (uint32_t *)data,
610 .h48data = ((uint32_t *)data) + (cocsepsize/4),
615 .s = solutions 611 .s = solutions
616 }; 612 };
617 613
618 for (i = 0; i < 13; i++) 614 for (i = 0; i < 12; i++)
619 solutions[i] = (char)99; 615 solutions[i] = (char)99;
620 616
621 for (arg.depth = 0; 617 for (arg.depth = 0;
622 arg.depth <= maxmoves && solutions[12] == 99; 618 arg.depth <= maxmoves && solutions[11] == 99;
623 arg.depth++) 619 arg.depth++)
624 { 620 {
625 arg.nmoves = 0; 621 arg.nmoves = 0;

Generated with cgit - Back to sebastiano.tronto.net