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 2c8ad86805516211103df1ef7552d882f54748c3
parent bb5abea645a31832e9d6a94cea09714a9b1632e3
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Sun, 19 Nov 2023 22:03:17 +0100

Removed src cube type, kept only H48 and LST (for now)

Diffstat:
MTODO.txt | 6++++++
Mcube.c | 72++++++++++++++++++++++++++++++++++++++++--------------------------------
Mcube.h | 14+++-----------
Dtest/021_io_SRC_write/01_solved.out | 4----
Dtest/021_io_SRC_write/02_scrambled.out | 4----
Dtest/021_io_SRC_write/io_SRC_tests.c | 24------------------------
Mtest/023_io_LST_write/io_LST_tests.c | 7-------
Atest/024_io_LST_read/01_solved.in | 1+
Rtest/021_io_SRC_write/01_solved.in -> test/024_io_LST_read/01_solved.out | 0
Atest/024_io_LST_read/02_scrambled.in | 1+
Rtest/021_io_SRC_write/02_scrambled.in -> test/024_io_LST_read/02_scrambled.out | 0
Atest/024_io_LST_read/io_LST_tests.c | 24++++++++++++++++++++++++
12 files changed, 75 insertions(+), 82 deletions(-)

diff --git a/TODO.txt b/TODO.txt @@ -39,6 +39,12 @@ switch. Here NISS may be useful. * improve light solver with no table; consider using a small, hard-coded table, e.g. H48 corner table? +## ARM NEON intrinsics and other architectures + +* For ARM: use two uint8x16_t (or uint8x16x2_t) and vqtbl* instructions; + see https://developer.arm.com/architectures/instruction-sets/intrinsics +* Implement also SSE? Why not... + ## Optimizations ### General things diff --git a/cube.c b/cube.c @@ -849,9 +849,10 @@ _static uint8_t readcp(char *); _static uint8_t readeo(char *); _static uint8_t readep(char *); _static cube_t readcube_H48(char *); -_static int writepiece_SRC(uint8_t, char *); +_static uint8_t readpiece_LST(char **); +_static cube_t readcube_LST(char *); +_static int writepiece_LST(uint8_t, char *); _static void writecube_H48(cube_t, char *); -_static void writecube_SRC(cube_t, char *); _static void writecube_LST(cube_t, char *); _static uint8_t readmove(char); _static uint8_t readmodifier(char); @@ -1083,6 +1084,8 @@ readcube(char *format, char *buf) if (!strcmp(format, "H48")) { cube = readcube_H48(buf); + } else if (!strcmp(format, "LST")) { + cube = readcube_LST(buf); } else { DBG_LOG("Cannot read cube in the given format\n"); cube = zero; @@ -1104,8 +1107,6 @@ writecube(char *format, cube_t cube, char *buf) if (!strcmp(format, "H48")) { writecube_H48(cube, buf); - } else if (!strcmp(format, "SRC")) { - writecube_SRC(cube, buf); } else if (!strcmp(format, "LST")) { writecube_LST(cube, buf); } else { @@ -1225,8 +1226,40 @@ readcube_H48(char *buf) return ret; } +_static uint8_t +readpiece_LST(char **b) +{ + uint8_t ret; + bool read; + + while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n') + (*b)++; + + for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) { + read = true; + ret = ret * 10 + (**b) - '0'; + } + + return read ? ret : _error; +} + +_static cube_t +readcube_LST(char *buf) +{ + int i; + cube_t ret = {0}; + + for (i = 0; i < 8; i++) + ret.corner[i] = readpiece_LST(&buf); + + for (i = 0; i < 12; i++) + ret.edge[i] = readpiece_LST(&buf); + + return ret; +} + _static int -writepiece_SRC(uint8_t piece, char *buf) +writepiece_LST(uint8_t piece, char *buf) { char digits[3]; int i, len = 0; @@ -1278,31 +1311,6 @@ writecube_H48(cube_t cube, char *buf) } _static void -writecube_SRC(cube_t cube, char *buf) -{ - int i, ptr; - uint8_t piece; - - memcpy(buf, "{\n\t.corner = {", 14); - ptr = 14; - - for (i = 0; i < 8; i++) { - piece = cube.corner[i]; - ptr += writepiece_SRC(piece, buf + ptr); - } - - memcpy(buf+ptr-2, "},\n\t.edge = {", 13); - ptr += 11; - - for (i = 0; i < 12; i++) { - piece = cube.edge[i]; - ptr += writepiece_SRC(piece, buf + ptr); - } - - memcpy(buf+ptr-2, "}\n}\0", 4); -} - -_static void writecube_LST(cube_t cube, char *buf) { int i, ptr; @@ -1312,12 +1320,12 @@ writecube_LST(cube_t cube, char *buf) for (i = 0; i < 8; i++) { piece = cube.corner[i]; - ptr += writepiece_SRC(piece, buf + ptr); + ptr += writepiece_LST(piece, buf + ptr); } for (i = 0; i < 12; i++) { piece = cube.edge[i]; - ptr += writepiece_SRC(piece, buf + ptr); + ptr += writepiece_LST(piece, buf + ptr); } *(buf+ptr-2) = 0; diff --git a/cube.h b/cube.h @@ -86,20 +86,12 @@ Multiple representations of the cube as text are supported: If OUT is the output in SRC format, one can use `cube_t cube = OUT` to declare a new cube object. -- LST: similar to SRC, but only a list of comma-separated numbers is printed. - -Not all formats are supported for both reading and writing. More formats -may be supported in the future. +- LST: a format for internal use and generating code. + The cube is printed as a comma-separated list of 20 integers, as they appear + in cube_t. Corners come first, followed by edge (unlike H48). ******************************************************************************/ -/* Reads a cube from buf in the specified format, and return it. - * Supported formats: "H48". - */ cube_t readcube(char *format, char *buf); - -/* Write the given cube to buf in the specified format. - * Supported formats: "H48", "SRC", "LST". - */ void writecube(char *format, cube_t cube, char *buf); /****************************************************************************** diff --git a/test/021_io_SRC_write/01_solved.out b/test/021_io_SRC_write/01_solved.out @@ -1,4 +0,0 @@ -{ - .corner = {0, 1, 2, 3, 4, 5, 6, 7}, - .edge = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} -} diff --git a/test/021_io_SRC_write/02_scrambled.out b/test/021_io_SRC_write/02_scrambled.out @@ -1,4 +0,0 @@ -{ - .corner = {38, 32, 37, 68, 67, 2, 71, 1}, - .edge = {9, 2, 17, 8, 4, 3, 0, 27, 21, 26, 6, 7} -} diff --git a/test/021_io_SRC_write/io_SRC_tests.c b/test/021_io_SRC_write/io_SRC_tests.c @@ -1,24 +0,0 @@ -#include "../test.h" - -int main(void) { - char str[STRLENMAX], *aux; - cube_t cube; - - aux = str; - while (fgets(aux, STRLENMAX, stdin) != NULL) - while (*aux != '\n') - aux++; - - cube = readcube("H48", str); - - if (iserror(cube)) { - printf("Error reading cube\n"); - } else if (!issolvable(cube)) { - printf("Cube is not solvable\n"); - } else { - writecube("SRC", cube, str); - printf("%s\n", str); - } - - return 0; -} diff --git a/test/023_io_LST_write/io_LST_tests.c b/test/023_io_LST_write/io_LST_tests.c @@ -1,12 +1,5 @@ #include "../test.h" -#define STRLENMAX 10000 - -bool iserror(cube_t); -bool issolvable(cube_t); -cube_t readcube(char *, char *); -void writecube(char *, cube_t, char *); - int main(void) { char str[STRLENMAX], *aux; cube_t cube; diff --git a/test/024_io_LST_read/01_solved.in b/test/024_io_LST_read/01_solved.in @@ -0,0 +1 @@ +0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 diff --git a/test/021_io_SRC_write/01_solved.in b/test/024_io_LST_read/01_solved.out diff --git a/test/024_io_LST_read/02_scrambled.in b/test/024_io_LST_read/02_scrambled.in @@ -0,0 +1 @@ +38, 32, 37, 68, 67, 2, 71, 1, 9, 2, 17, 8, 4, 3, 0, 27, 21, 26, 6, 7 diff --git a/test/021_io_SRC_write/02_scrambled.in b/test/024_io_LST_read/02_scrambled.out diff --git a/test/024_io_LST_read/io_LST_tests.c b/test/024_io_LST_read/io_LST_tests.c @@ -0,0 +1,24 @@ +#include "../test.h" + +int main(void) { + char str[STRLENMAX], *aux; + cube_t cube; + + aux = str; + while (fgets(aux, STRLENMAX, stdin) != NULL) + while (*aux != '\n') + aux++; + + cube = readcube("LST", str); + + if (iserror(cube)) { + printf("Error reading cube\n"); + } else if (!issolvable(cube)) { + printf("Cube is not solvable\n"); + } else { + writecube("H48", cube, str); + printf("%s\n", str); + } + + return 0; +}