h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

commit 87de946c47b3b5ef0fb0c5f2289bb033bc8d9038
parent ebe1ef1d2d63c245fb203878d8309f1808d75c42
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Mon, 14 Oct 2024 16:55:15 +0200

Fix solvers for k = 2, and changes to solve tool

Diffstat:
Msrc/solvers/h48/solve.h | 30++++++++++++++++++------------
Msrc/solvers/h48/solve_multithread.h | 1+
Mtools/300_solve_small/solve_small.c | 16++++++++++++----
3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h @@ -8,6 +8,7 @@ typedef struct { int64_t maxsolutions; uint8_t h; uint8_t k; + uint8_t base; const uint32_t *cocsepdata; const uint8_t *h48data; uint64_t solutions_size; @@ -98,27 +99,32 @@ STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *arg) { uint32_t data, data_inv; - int8_t bound; + int8_t cbound, cbound_inv, h48bound, h48bound_inv; arg->nissbranch = MM_NORMAL; - bound = get_h48_cdata(arg->cube, arg->cocsepdata, &data); - if (bound + arg->nmoves + arg->npremoves > arg->depth) + cbound = get_h48_cdata(arg->cube, arg->cocsepdata, &data); + if (cbound + arg->nmoves + arg->npremoves > arg->depth) return true; - bound = get_h48_cdata(arg->inverse, arg->cocsepdata, &data_inv); - if (bound + arg->nmoves + arg->npremoves > arg->depth) + cbound_inv = get_h48_cdata(arg->inverse, arg->cocsepdata, &data_inv); + if (cbound_inv + arg->nmoves + arg->npremoves > arg->depth) return true; - bound = get_h48_bound(arg->cube, data, arg->h, arg->k, arg->h48data); - if (bound + arg->nmoves + arg->npremoves > arg->depth) + h48bound = get_h48_bound(arg->cube, data, arg->h, arg->k, arg->h48data); + + /* If the h48 bound is > 0, we add the base value. */ + /* Otherwise, we use the cbound value instead (fallback). */ + h48bound += h48bound == 0 ? cbound : arg->base; + if (h48bound + arg->nmoves + arg->npremoves > arg->depth) return true; - if (bound + arg->nmoves + arg->npremoves == arg->depth) + if (h48bound + arg->nmoves + arg->npremoves == arg->depth) arg->nissbranch = MM_INVERSEBRANCH; - bound = get_h48_bound(arg->inverse, data_inv, arg->h, arg->k, arg->h48data); - if (bound + arg->nmoves + arg->npremoves > arg->depth) + h48bound_inv = get_h48_bound(arg->inverse, data_inv, arg->h, arg->k, arg->h48data); + h48bound_inv += h48bound_inv == 0 ? cbound_inv : arg->base; + if (h48bound_inv + arg->nmoves + arg->npremoves > arg->depth) return true; - if (bound + arg->nmoves + arg->npremoves == arg->depth) + if (h48bound_inv + arg->nmoves + arg->npremoves == arg->depth) arg->nissbranch = MM_NORMALBRANCH; return false; @@ -144,7 +150,6 @@ solve_h48_dfs(dfsarg_solveh48_t *arg) return 1; } - /* TODO: avoid copy, change arg and undo changes after recursion */ nextarg = *arg; ret = 0; uint32_t allowed; @@ -203,6 +208,7 @@ solve_h48( .maxsolutions = maxsolutions, .h = info.h48h, .k = info.bits, + .base = info.base, .cocsepdata = get_cocsepdata_constptr(data), .h48data = get_h48data_constptr(data), .solutions_size = solutions_size, diff --git a/src/solvers/h48/solve_multithread.h b/src/solvers/h48/solve_multithread.h @@ -277,6 +277,7 @@ solve_h48_multithread( .maxsolutions = maxsolutions, .h = info.h48h, .k = info.bits, + .base = info.base, .cocsepdata = get_cocsepdata_constptr(data), .h48data = get_h48data_constptr(data), .solutions_size = solutions_size, diff --git a/tools/300_solve_small/solve_small.c b/tools/300_solve_small/solve_small.c @@ -2,13 +2,13 @@ #define SOL_BUFFER_LEN 1000 -const char *solver = "h48h0k4"; +char *solver; int64_t size = 0; char *buf; char *scrambles[] = { - "R D' R2 D R U2 R' D' R U2 R D R'", /* 12 optimal */ - "RLUD RLUD RLUD", /* 12 optimal */ + //"R D' R2 D R U2 R' D' R U2 R D R'", /* 12 optimal */ + //"RLUD RLUD RLUD", /* 12 optimal */ "R' U' F D2 L2 F R2 U2 R2 B D2 L B2 D' B2 L' R' B D2 B U2 L U2 R' U' F", /* FMC2019 A1 - 16 optimal */ // "R' U' F D R F2 D L F D2 F2 L' U R' L2 D' R2 F2 R2 D L2 U2 R' U' F", /* FMC2024 A1 - 19 optimal */ NULL @@ -37,12 +37,20 @@ void run(void) { } } -int main(void) { +int main(int argc, char **argv) { char filename[255]; + if (argc < 2) { + printf("Error: not enough arguments. " + "A solver must be given.\n"); + return 1; + } + + solver = argv[1]; srand(time(NULL)); nissy_setlogger(log_stderr); + sprintf(filename, "tables/%s", solver); if (getdata(solver, &buf, filename) != 0) return 1;