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 66c1c11ec13d362ddfb1b5f6abe8127969c0ad29
parent 5fb58d73581256c64d47250c5544d1cbf22f79c3
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Fri,  5 Jul 2024 22:16:44 +0200

Finished getcube

Diffstat:
MTODO.txt | 15---------------
Mshell.c | 4++--
Msrc/cube_generic.h | 37++++++++++++++++++++++++-------------
Msrc/utils.h | 6++++--
Atest/081_getcube/00_solved_0.in | 4++++
Atest/081_getcube/00_solved_0.out | 1+
Atest/081_getcube/02_scrambled.in | 4++++
Atest/081_getcube/02_scrambled.out | 1+
Atest/081_getcube/getcube_tests.c | 29+++++++++++++++++++++++++++++
9 files changed, 69 insertions(+), 32 deletions(-)

diff --git a/TODO.txt b/TODO.txt @@ -1,19 +1,4 @@ Check stats for all tables using H48stats solver - - implement getcube - x implement stuff in utils.h - x implement functions - x unit tests for permtoindex and indextoperm - x implement digit array to sumzero and inverse - x unit tests for digit arra to sumzero - x move cubefromarray from cube_io to where needed (cube_generic) - - implement in cube_generic - x getcube_fix - - getcube - x permutation - - orientation - - unit tests - x fix in cube_public - - test shell - optional: dr states (includes "fix" option) - implement tool for stats - output to file, only write cocsep to stdout diff --git a/shell.c b/shell.c @@ -241,7 +241,7 @@ randomcube_exec(args_t *args) eo = rand64(); cp = rand64(); co = rand64(); - ret = nissy_getcube(ep, eo, cp, co, args->str_options, result); + ret = nissy_getcube(ep, eo, cp, co, "fix", result); print_str_result(ret, result); return ret; @@ -305,7 +305,7 @@ gendata_exec(args_t *args) } if (ret != size) { fprintf(stderr, "Unknown error: unexpected data size " - "got %" PRId64 ", expected %" PRId64)\n", ret, size); + "got %" PRId64 ", expected %" PRId64 ")\n", ret, size); fclose(file); free(buf); return -5; diff --git a/src/cube_generic.h b/src/cube_generic.h @@ -185,34 +185,45 @@ frommoves(const char *buf) _static void getcube_fix(int64_t *ep, int64_t *eo, int64_t *cp, int64_t *co) { - uint8_t e[12], c[8], aux; + uint8_t e[12], c[8], coarr[8]; - *ep %= _12f; - *eo %= _2p11; - *cp %= _8f; - *cp %= _3p7; + *ep = (*ep % _12f + _12f) % _12f; + *eo = (*eo % _2p11 + _2p11) % _2p11; + *cp = (*cp % _8f + _8f) % _8f; + *co = (*cp % _3p7 + _3p7) % _3p7; indextoperm(*ep, 12, e); indextoperm(*cp, 8, c); if (permsign(e, 12) != permsign(c, 8)) { - aux = c[0]; - c[0] = c[1]; - c[1] = aux; + _swap(c[0], c[1]); *cp = permtoindex(c, 8); + + sumzerotodigits(*co, 8, 3, coarr); + _swap(coarr[0], coarr[1]); + *co = digitstosumzero(coarr, 8, 3); } } _static cube_t getcube(int64_t ep, int64_t eo, int64_t cp, int64_t co) { - uint8_t e[12], c[8]; + uint8_t i, earr[12], carr[8], eoarr[12], coarr[8]; - indextoperm(ep, 12, e); - indextoperm(cp, 8, c); + sumzerotodigits(eo, 12, 2, eoarr); + DBG_ASSERT(eoarr[0] != _error, zero, "Error making EO"); + indextoperm(ep, 12, earr); + DBG_ASSERT(earr[0] != _error, zero, "Error making EP"); + for (i = 0; i < 12; i++) + earr[i] |= eoarr[i] << _eoshift; - /* TODO: orientation */ + sumzerotodigits(co, 8, 3, coarr); + DBG_ASSERT(coarr[0] != _error, zero, "Error making CO"); + indextoperm(cp, 8, carr); + DBG_ASSERT(carr[0] != _error, zero, "Error making CP"); + for (i = 0; i < 8; i++) + carr[i] |= coarr[i] << _coshift; - return cubefromarray(c, e); + return cubefromarray(carr, earr); } _static cube_t diff --git a/src/utils.h b/src/utils.h @@ -1,3 +1,5 @@ +#define _swap(x, y) do { x ^= y; y ^= x; x ^= y; } while (0) + _static int64_t factorial(int64_t); _static bool isperm(uint8_t *, int64_t); _static int64_t permtoindex(uint8_t *, int64_t); @@ -138,7 +140,7 @@ digitstosumzero(uint8_t *a, uint8_t n, uint8_t b) return -1; } - for (i = 1, ret = 0, p = 1; i < n; i++, p *= (int64_t)b) { + for (i = 1, ret = 0, p = 1, sum = 0; i < n; i++, p *= (int64_t)b) { if (a[i] >= b) { LOG("Error: digit %" PRIu8 " larger than maximum" " (b=%" PRIu8 "\n", a[i], b); @@ -168,7 +170,7 @@ sumzerotodigits(int64_t d, uint8_t n, uint8_t b, uint8_t *a) goto digitstosumzero_error; } - for (i = 1; i < n; i++, d /= (int64_t)b) { + for (i = 1, sum = 0; i < n; i++, d /= (int64_t)b) { a[i] = (uint8_t)(d % (int64_t)b); sum += a[i]; } diff --git a/test/081_getcube/00_solved_0.in b/test/081_getcube/00_solved_0.in @@ -0,0 +1,4 @@ +0 +0 +0 +0 diff --git a/test/081_getcube/00_solved_0.out b/test/081_getcube/00_solved_0.out @@ -0,0 +1 @@ +UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 diff --git a/test/081_getcube/02_scrambled.in b/test/081_getcube/02_scrambled.in @@ -0,0 +1,4 @@ +367124500 +450 +30807 +562 diff --git a/test/081_getcube/02_scrambled.out b/test/081_getcube/02_scrambled.out @@ -0,0 +1 @@ +FL0 DB0 UB1 FR0 UR0 DF0 UF0 BR1 UL1 BL1 DL0 DR0 DFR1 UFR1 UBR1 UFL2 DBR2 DFL0 DBL2 UBL0 diff --git a/test/081_getcube/getcube_tests.c b/test/081_getcube/getcube_tests.c @@ -0,0 +1,29 @@ +#include "../test.h" + +cube_t getcube(int64_t, int64_t, int64_t, int64_t); + +void run(void) { + char str[STRLENMAX]; + cube_t cube; + int64_t ep, eo, cp, co; + + fgets(str, STRLENMAX, stdin); + ep = atoll(str); + fgets(str, STRLENMAX, stdin); + eo = atoll(str); + fgets(str, STRLENMAX, stdin); + cp = atoll(str); + fgets(str, STRLENMAX, stdin); + co = atoll(str); + + cube = getcube(ep, eo, cp, co); + + if (iserror(cube)) { + printf("Error cube\n"); + } else if (!isconsistent(cube)) { + printf("Inconsistent cube\n"); + } else { + writecube("H48", cube, str); + printf("%s\n", str); + } +}