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 e6ff0ce6926fa921a13055c9c35d8e60b691e776
parent dd6078288b5d7af4a4c0cdd1377a2976af569c9a
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Wed, 11 Sep 2024 17:01:49 +0200

Finished table refactor

Diffstat:
Msrc/nissy.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Msrc/nissy.h | 6++++++
Msrc/solvers/tables.h | 6+++---
Mtools/001_gendata_h48h0k4/gendata_h48h0k4.c | 22++++++----------------
Mtools/002_gendata_h48h0k2/gendata_h48h0k2.c | 21++++++---------------
Mtools/020_solve_small/solve_small.c | 16+++++++++-------
Mtools/run_tool.sh | 2+-
Mtools/tool.h | 10++++++++++
8 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/src/nissy.c b/src/nissy.c @@ -196,6 +196,53 @@ nissy_datasize( } int64_t +nissy_datainfo( + const void *table, + void (*write)(const char *, ...) +) +{ + uint8_t i; + tableinfo_t info; + + readtableinfo(table, &info); + + write("\n---------\n\n"); + write("Table information for '%s'\n", info.solver); + write("\n"); + write("Size: %" PRIu64 " bytes\n", info.fullsize); + write("Entries: %" PRIu64 " (%" PRIu8 " bits per entry)", + info.entries, info.bits); + write("\n"); + + switch (info.type) { + case TABLETYPE_PRUNING: + write("\n"); + if (info.base != 0) + write(" (base value = %" PRIu8 ")", info.base); + write(":\nValue\tPositions\n"); + for (i = 0; i <= info.maxvalue; i++) { + write("%" PRIu8 "\t%" PRIu64 "\n", + i, info.distribution[i]); + } + break; + case TABLETYPE_SPECIAL: + write("This is an ad-hoc table\n"); + break; + default: + LOG("datainfo: unknown table type\n"); + return 1; + } + + if (info.next != 0) { + return nissy_datainfo((char *)table + info.next, write); + } + + write("\n---------\n"); + + return 0; +} + +int64_t nissy_gendata( const char *solver, const char *options, diff --git a/src/nissy.h b/src/nissy.h @@ -86,6 +86,12 @@ int64_t nissy_gendata( void *generated_data ); +/* Print information on a data table via the provided callback writer */ +int64_t nissy_datainfo( + const void *table, + void (*write)(const char *, ...) +); + /* Returns the number of solutions found, or -1 in case of error */ int64_t nissy_solve( const char cube[static 22], diff --git a/src/solvers/tables.h b/src/solvers/tables.h @@ -4,6 +4,9 @@ #define INFO_SOLVER_STRLEN 100 #define INFO_DISTRIBUTION_LEN 21 +#define TABLETYPE_PRUNING 0 +#define TABLETYPE_SPECIAL 1 + #define INFO_OFFSET_SOLVER 0 #define INFO_OFFSET_TYPE INFO_SOLVER_STRLEN #define INFO_OFFSET_INFOSIZE (INFO_OFFSET_TYPE + sizeof(uint64_t)) @@ -17,9 +20,6 @@ #define INFO_OFFSET_NEXT (INFO_OFFSET_MAXVALUE + sizeof(uint8_t)) #define INFO_OFFSET_DISTRIBUTION (INFO_OFFSET_NEXT + sizeof(uint64_t)) -const uint64_t TABLETYPE_PRUNING = 0; -const uint64_t TABLETYPE_SPECIAL = 1; - typedef struct { char solver[INFO_SOLVER_STRLEN]; uint64_t type; diff --git a/tools/001_gendata_h48h0k4/gendata_h48h0k4.c b/tools/001_gendata_h48h0k4/gendata_h48h0k4.c @@ -27,8 +27,6 @@ uint32_t expected[21] = { char *buf; void run(void) { - uint32_t *h48info, x; - int i; int64_t s; s = nissy_gendata("h48", OPTIONS, buf); @@ -36,20 +34,12 @@ void run(void) { if (s == -1) { printf("Error generating table\n"); } else { - printf("Table is probably ok\n"); -/* -TODO: adapt to new tables - printf("Succesfully generated %" PRId64 " bytes. Table:\n", s); - h48info = (uint32_t *)buf + 1 + (ETABLESIZE(HVALUE) + COCSEPSIZE) / 4; - for (i = 0; i < MAXDEPTH+1 && h48info[i+1]; i++) { - x = h48info[i+1]; - printf("%d:\t%" PRIu32, i, x); - if (x != expected[i]) - printf(" <--- Error! Expected: %" PRIu32, - expected[i]); - printf("\n"); - } -*/ + nissy_datainfo(buf, write_stdout); + printf("\n"); + printf("Succesfully generated %" PRId64 " bytes. " + "See above for details on the tables.\n", s); + + /* TODO: check that the table is correct */ } } diff --git a/tools/002_gendata_h48h0k2/gendata_h48h0k2.c b/tools/002_gendata_h48h0k2/gendata_h48h0k2.c @@ -5,9 +5,6 @@ #define OPTIONS "0;2;20" #define LONGOPTIONS "h = 0, k = 2, max depth = 20" -#define COCSEPSIZE 1119792 -#define ETABLESIZE(h) (((3393 * 495 * 70) >> 2) << (size_t)(h)) - uint32_t expected[21] = { /* Base value is 8 */ [0] = 5473562, @@ -19,8 +16,6 @@ uint32_t expected[21] = { char *buf; void run(void) { - uint32_t *h48info, x; - int i; int64_t s; s = nissy_gendata("h48", OPTIONS, buf); @@ -28,16 +23,12 @@ void run(void) { if (s == -1) { printf("Error generating table\n"); } else { - printf("Succesfully generated %" PRId64 " bytes. Table:\n", s); - h48info = (uint32_t *)buf + 1 + (ETABLESIZE(HVALUE) + COCSEPSIZE) / 4; - for (i = 0; i < 4; i++) { - x = h48info[i+1]; - printf("%d:\t%" PRIu32, i, x); - if (x != expected[i]) - printf(" <--- Error! Expected: %" PRIu32, - expected[i]); - printf("\n"); - } + nissy_datainfo(buf, write_stdout); + printf("\n"); + printf("Succesfully generated %" PRId64 " bytes. " + "See above for details on the tables.\n", s); + + /* TODO: check that the table is correct */ } } diff --git a/tools/020_solve_small/solve_small.c b/tools/020_solve_small/solve_small.c @@ -20,20 +20,22 @@ void run(void) { printf("Solved the following scrambles:\n\n"); for (i = 0; scrambles[i] != NULL; i++) { - printf("%s\n", scrambles[i]); + printf("%d. %s\n", i+1, scrambles[i]); fprintf(stderr, "Solving scramble %s\n", scrambles[i]); if (nissy_frommoves(scrambles[i], cube) == -1) { - fprintf(stderr, "Invalid scramble, " - "continuing with next scramble\n"); + fprintf(stderr, "Invalid scramble\n"); + printf("Invalid\n"); continue; } n = nissy_solve( cube, "h48", options, "", 0, 20, 1, -1, buf, sol); - if (n == 0) - fprintf(stderr, "No solution found, " - "continuing with next scramble\n"); + if (n == 0) { + printf("No solution\n"); + fprintf(stderr, "No solution found\n"); + } else { + printf("Solutions:\n%s\n", sol); + } } - printf("\n"); } int main(void) { diff --git a/tools/run_tool.sh b/tools/run_tool.sh @@ -16,7 +16,7 @@ for t in tools/*; do fi toolname="$(basename "$t" .c)" $CC -o $BIN $t/*.c $CUBEOBJ || exit 1; - $BIN | tee "tools/results/$toolname-$d.txt" + $BIN | tee "tools/results/$toolname-$d.txt" "tools/results/last.out" break done diff --git a/tools/tool.h b/tools/tool.h @@ -18,6 +18,16 @@ log_stderr(const char *str, ...) va_end(args); } +static void +write_stdout(const char *str, ...) +{ + va_list args; + + va_start(args, str); + vfprintf(stdout, str, args); + va_end(args); +} + static double timerun(void (*run)(void), char *name) {