aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cube_public.h11
-rw-r--r--src/solve_generic.h3
-rw-r--r--src/solve_h48.h174
3 files changed, 182 insertions, 6 deletions
diff --git a/src/cube_public.h b/src/cube_public.h
index ea1d28d..a1c4b90 100644
--- a/src/cube_public.h
+++ b/src/cube_public.h
@@ -89,7 +89,7 @@ nissy_frommoves(
89} 89}
90 90
91int64_t 91int64_t
92nissy_convertcube( 92nissy_convert(
93 const char *format_in, 93 const char *format_in,
94 const char *format_out, 94 const char *format_out,
95 const char *cube_string, 95 const char *cube_string,
@@ -155,6 +155,7 @@ nissy_solve(
155{ 155{
156 cube_t c; 156 cube_t c;
157 int64_t ret; 157 int64_t ret;
158 int h;
158 159
159 c = readcube_B32(cube); 160 c = readcube_B32(cube);
160 161
@@ -188,8 +189,12 @@ nissy_solve(
188 return -1; 189 return -1;
189 } 190 }
190 191
191 if (!strcmp(solver, "h48")) { 192 /* TODO define and use solve_options_t */
192 LOG("h48 solver not implemented yet\n"); 193 if (!strcmp(solver, "H48")) {
194 h = atoi(options); /* TODO: better parsing */
195 ret = solve_h48(
196 c, minmoves, maxmoves, maxsolutions,
197 (uint8_t)h, data, solutions);
193 ret = -1; 198 ret = -1;
194 } else if (!strcmp(solver, "simple")) { 199 } else if (!strcmp(solver, "simple")) {
195 ret = solve_simple( 200 ret = solve_simple(
diff --git a/src/solve_generic.h b/src/solve_generic.h
index d1d1469..41d995a 100644
--- a/src/solve_generic.h
+++ b/src/solve_generic.h
@@ -21,7 +21,7 @@ solve_generic_appendsolution(dfsarg_generic_t *arg)
21{ 21{
22 int strl; 22 int strl;
23 23
24 strl = writemoves(arg->moves, arg->depth, *arg->nextsol); 24 strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol);
25 LOG("Solution found: %s\n", *arg->nextsol); 25 LOG("Solution found: %s\n", *arg->nextsol);
26 *arg->nextsol += strl; 26 *arg->nextsol += strl;
27 **arg->nextsol = '\n'; 27 **arg->nextsol = '\n';
@@ -53,7 +53,6 @@ solve_generic_dfs(dfsarg_generic_t *arg)
53 return 1; 53 return 1;
54 } 54 }
55 55
56 /* memcpy(&nextarg, arg, sizeof(dfsarg_generic_t)); */
57 nextarg = *arg; 56 nextarg = *arg;
58 nextarg.nmoves = arg->nmoves + 1; 57 nextarg.nmoves = arg->nmoves + 1;
59 for (m = 0, ret = 0; m < 18; m++) { 58 for (m = 0, ret = 0; m < 18; m++) {
diff --git a/src/solve_h48.h b/src/solve_h48.h
index 1646f49..201c7c6 100644
--- a/src/solve_h48.h
+++ b/src/solve_h48.h
@@ -11,6 +11,8 @@
11#define COCLASS(x) (((x) & COCLASS_MASK) >> UINT32_C(16)) 11#define COCLASS(x) (((x) & COCLASS_MASK) >> UINT32_C(16))
12#define TTREP_MASK (UINT32_C(0xFF) << UINT32_C(8)) 12#define TTREP_MASK (UINT32_C(0xFF) << UINT32_C(8))
13#define TTREP(x) (((x) & TTREP_MASK) >> UINT32_C(8)) 13#define TTREP(x) (((x) & TTREP_MASK) >> UINT32_C(8))
14#define CBOUND_MASK UINT32_C(0xFF)
15#define CBOUND(x) ((x) & CBOUND_MASK)
14#define H48_ESIZE(h) ((_12c4 * _8c4) << (int64_t)(h)) 16#define H48_ESIZE(h) ((_12c4 * _8c4) << (int64_t)(h))
15 17
16#define ESEP_IND(i) ((uint32_t)(i) / UINT32_C(8)) 18#define ESEP_IND(i) ((uint32_t)(i) / UINT32_C(8))
@@ -19,6 +21,8 @@
19#define VISITED_IND(i) ((uint32_t)(i) / UINT32_C(8)) 21#define VISITED_IND(i) ((uint32_t)(i) / UINT32_C(8))
20#define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8))) 22#define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8)))
21 23
24#define MAX_SOLUTION_LENGTH 20
25
22typedef struct { 26typedef struct {
23 cube_t cube; 27 cube_t cube;
24 uint8_t depth; 28 uint8_t depth;
@@ -39,6 +43,20 @@ typedef struct {
39 cube_t *crep; 43 cube_t *crep;
40} bfsarg_esep_t; 44} bfsarg_esep_t;
41 45
46typedef struct {
47 cube_t cube;
48 cube_t inverse;
49 int8_t nmoves;
50 int8_t depth;
51 uint8_t moves[MAX_SOLUTION_LENGTH];
52 int64_t *nsols;
53 int64_t maxsolutions;
54 uint8_t h;
55 uint32_t *cocsepdata;
56 uint32_t *h48data;
57 char **nextsol;
58} dfsarg_solveh48_t;
59
42_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t); 60_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t);
43_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t); 61_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t);
44_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t); 62_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t);
@@ -53,6 +71,13 @@ _static_inline void set_visited(uint8_t *, int64_t);
53_static_inline uint8_t get_esep_pval(const uint32_t *, int64_t); 71_static_inline uint8_t get_esep_pval(const uint32_t *, int64_t);
54_static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); 72_static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t);
55 73
74_static void solve_h48_appendsolution(dfsarg_solveh48_t *);
75_static_inline int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *);
76_static_inline int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint32_t *);
77_static_inline bool solve_h48_stop(dfsarg_solveh48_t *);
78_static int64_t solve_h48_dfs(dfsarg_solveh48_t *);
79_static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *);
80
56_static_inline int64_t 81_static_inline int64_t
57coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h) 82coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h)
58{ 83{
@@ -238,8 +263,11 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
238 cube_t crep[COCSEP_CLASSES]; 263 cube_t crep[COCSEP_CLASSES];
239 size_t cocsepsize, infosize; 264 size_t cocsepsize, infosize;
240 265
266 /* TODO: move info at start of tables (all tables!) */
241 infosize = 4 * maxdepth; 267 infosize = 4 * maxdepth;
242 cocsepsize = gendata_cocsep(buf, selfsim, crep); 268 cocsepsize = gendata_cocsep(buf, selfsim, crep);
269 infosize = 88;
270
243 if (buf == NULL) 271 if (buf == NULL)
244 goto gendata_h48_return_size; 272 goto gendata_h48_return_size;
245 273
@@ -272,7 +300,6 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
272 } 300 }
273 301
274 info[0] = arg.depth-1; 302 info[0] = arg.depth-1;
275 infosize = 4 * (size_t)(info[0] + 2);
276 303
277 LOG("h48 pruning table computed\n"); 304 LOG("h48 pruning table computed\n");
278 LOG("Maximum pruning value: %" PRIu32 "\n", info[0]); 305 LOG("Maximum pruning value: %" PRIu32 "\n", info[0]);
@@ -353,3 +380,148 @@ set_esep_pval(uint32_t *buf32, int64_t i, uint8_t val)
353 buf32[ESEP_IND(i)] = 380 buf32[ESEP_IND(i)] =
354 (buf32[ESEP_IND(i)] & (~ESEP_MASK(i))) | (val << ESEP_SHIFT(i)); 381 (buf32[ESEP_IND(i)] & (~ESEP_MASK(i))) | (val << ESEP_SHIFT(i));
355} 382}
383
384_static void
385solve_h48_appendsolution(dfsarg_solveh48_t *arg)
386{
387 int strl;
388
389 strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol);
390 LOG("Solution found: %s\n", *arg->nextsol);
391 *arg->nextsol += strl;
392 **arg->nextsol = '\n';
393 (*arg->nextsol)++;
394 (*arg->nsols)++;
395}
396
397_static_inline int8_t
398get_h48_cdata(cube_t cube, uint32_t *cocsepdata, uint32_t *cdata)
399{
400 int64_t coord;
401
402 coord = coord_cocsep(cube);
403 *cdata = cocsepdata[coord];
404
405 return CBOUND(*cdata);
406}
407
408_static_inline int8_t
409get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint32_t *h48data)
410{
411 int64_t coord;
412
413 coord = coord_h48_edges(cube, COCLASS(cdata), TTREP(cdata), h);
414 return get_esep_pval(h48data, coord);
415}
416
417_static_inline bool
418solve_h48_stop(dfsarg_solveh48_t *arg)
419{
420 uint32_t data, data_inv;
421 int8_t bound;
422
423 bound = get_h48_cdata(arg->cube, arg->cocsepdata, &data);
424 if (bound + arg->nmoves > arg->depth)
425 return true;
426
427 bound = get_h48_cdata(arg->inverse, arg->cocsepdata, &data_inv);
428 if (bound + arg->nmoves > arg->depth)
429 return true;
430
431/*
432 bound = get_h48_bound(arg->cube, data, arg->h, arg->h48data);
433LOG("Using pval %" PRId8 "\n", bound);
434 if (bound + arg->nmoves > arg->depth)
435 return true;
436
437 bound = get_h48_bound(arg->inverse, data_inv, arg->h, arg->h48data);
438 if (bound + arg->nmoves > arg->depth)
439 return true;
440*/
441
442 return false;
443}
444
445_static int64_t
446solve_h48_dfs(dfsarg_solveh48_t *arg)
447{
448 dfsarg_solveh48_t nextarg;
449 int64_t ret;
450 uint8_t m;
451
452 if (*arg->nsols == arg->maxsolutions)
453 return 0;
454
455 if (solve_h48_stop(arg))
456 return 0;
457
458 if (issolved(arg->cube)) {
459 if (arg->nmoves != arg->depth)
460 return 0;
461 solve_h48_appendsolution(arg);
462 return 1;
463 }
464
465 /* TODO: avoid copy, change arg and undo changes after recursion */
466 nextarg = *arg;
467 nextarg.nmoves = arg->nmoves + 1;
468 ret = 0;
469 for (m = 0; m < 18; m++) {
470 nextarg.moves[arg->nmoves] = m;
471 if (!allowednextmove(nextarg.moves, nextarg.nmoves)) {
472 /* If a move is not allowed, neither are its 180
473 * and 270 degree variations */
474 m += 2;
475 continue;
476 }
477 nextarg.cube = move(arg->cube, m);
478 nextarg.inverse = inverse(nextarg.cube); /* TODO: use premove */
479 ret += solve_h48_dfs(&nextarg);
480 }
481
482 return ret;
483}
484
485_static int64_t
486solve_h48(
487 cube_t cube,
488 int8_t minmoves,
489 int8_t maxmoves,
490 int8_t maxsolutions,
491 uint8_t h,
492 const void *data,
493 char *solutions
494)
495{
496 int64_t nsols;
497 dfsarg_solveh48_t arg;
498
499 arg = (dfsarg_solveh48_t) {
500 .cube = cube,
501 .inverse = inverse(cube),
502 .nsols = &nsols,
503 .maxsolutions = maxsolutions,
504 .h = h,
505 .cocsepdata = (uint32_t *)data,
506 .h48data = ((uint32_t *)data) + COCSEP_FULLSIZE / 4,
507 .nextsol = &solutions
508 };
509
510 nsols = 0;
511 for (arg.depth = minmoves;
512 arg.depth <= maxmoves && nsols < maxsolutions;
513 arg.depth++)
514 {
515 LOG("Found %" PRId64 " solutions, searching at depth %"
516 PRId8 "\n", nsols, arg.depth);
517 arg.nmoves = 0;
518 solve_h48_dfs(&arg);
519 }
520
521/*
522for (int64_t i = 0; i < 4; i++)
523LOG("Data for coord = %" PRId64 ": %" PRIu8 "\n",
524i, get_esep_pval(arg.h48data, i));
525*/
526 return nsols;
527}

Generated with cgit - Back to sebastiano.tronto.net