diff options
| -rw-r--r-- | TODO.txt | 29 | ||||
| -rw-r--r-- | src/cube.c | 6 | ||||
| -rw-r--r-- | src/cube_avx2.h | 25 | ||||
| -rw-r--r-- | src/cube_portable.h | 22 | ||||
| -rw-r--r-- | src/cube_routines.h | 41 | ||||
| -rw-r--r-- | test/001_pieces/01_solved.in (renamed from test/001_cube_conversion/00_solved.in) | 0 | ||||
| -rw-r--r-- | test/001_pieces/01_solved.out | 2 | ||||
| -rw-r--r-- | test/001_pieces/02_scrambled.in | 1 | ||||
| -rw-r--r-- | test/001_pieces/02_scrambled.out | 2 | ||||
| -rw-r--r-- | test/001_pieces/pieces_tests.c | 28 | ||||
| -rw-r--r-- | test/002_cube_conversion/00_solved.in (renamed from test/001_cube_conversion/00_solved.out) | 0 | ||||
| -rw-r--r-- | test/002_cube_conversion/00_solved.out | 1 | ||||
| -rw-r--r-- | test/002_cube_conversion/01_scrambled.in (renamed from test/001_cube_conversion/01_scrambled.in) | 0 | ||||
| -rw-r--r-- | test/002_cube_conversion/01_scrambled.out (renamed from test/001_cube_conversion/01_scrambled.out) | 0 | ||||
| -rw-r--r-- | test/002_cube_conversion/cube_conversion_tests.c (renamed from test/001_cube_conversion/cube_conversion_tests.c) | 0 |
15 files changed, 144 insertions, 13 deletions
| @@ -1,12 +1,30 @@ | |||
| 1 | Correctness | 1 | Refactoring: remove cube_fast_t and add b32 format |
| 2 | - check all bitwise operations specifically | 2 | x added b32 converter by piece (not tested, will be tested automatically) |
| 3 | - consider adding more warnings (-pedantic?) or using more static analyzers | 3 | x added piece functions (e.g. corner(cube, i)) |
| 4 | (would be more efficient to just convert the whole thing to arrays...) | ||
| 5 | - replace all usages of cube_t with cube_fast_t and piece functions | ||
| 6 | (this is mainly in cube_routines) | ||
| 7 | (fix tests in tandem with main code) | ||
| 8 | cubetofast fasttocube | ||
| 9 | zero and solved | ||
| 10 | solvedcube(void) | ||
| 11 | [cube.h] isconsistent, issolvable, issolved, equal, iserror | ||
| 12 | [cube.h] compose, inverse | ||
| 13 | [cube.h] applymoves, applytrans | ||
| 14 | [cube.h] readcube writecube | ||
| 15 | [cube.h] solve | ||
| 16 | - add b32 i/o format as default | ||
| 17 | - remove cube_t type | ||
| 18 | - rename cube_fast_t to cube_t | ||
| 19 | - if all public functions work with strings, always use return value | ||
| 20 | as error code (solve already does this), and use string as buffer | ||
| 21 | to print error | ||
| 4 | 22 | ||
| 5 | Solver | 23 | Solver |
| 6 | - write a solver (how many tricks? some, but not all are needed) | 24 | - write a solver (how many tricks? some, but not all are needed) |
| 7 | 25 | ||
| 8 | More utilities for tables (in cube.h) | 26 | More utilities for tables (in cube.h) |
| 9 | - a "dryrun" function that only tells you the size needed | 27 | - for tables, a "dryrun" function that only tells you the size needed |
| 10 | - check hash of generated data | 28 | - check hash of generated data |
| 11 | 29 | ||
| 12 | Goal: find out which k value is best | 30 | Goal: find out which k value is best |
| @@ -15,9 +33,6 @@ Goal: find out which k value is best | |||
| 15 | - benchmark for different sizes! | 33 | - benchmark for different sizes! |
| 16 | 34 | ||
| 17 | Refactoring | 35 | Refactoring |
| 18 | - remove cube type and some low-level utilities from interface, | ||
| 19 | rename cube_fast_t to cube_t | ||
| 20 | - add b64 i/o format, base64 encoded cube, one 6-bit word per piece | ||
| 21 | - transformations: remove switch to make shorter, but keep performance | 36 | - transformations: remove switch to make shorter, but keep performance |
| 22 | 37 | ||
| 23 | ## H48 optimal solver (some has already been implemented) | 38 | ## H48 optimal solver (some has already been implemented) |
| @@ -9,10 +9,8 @@ | |||
| 9 | #define DBG_LOG(...) fprintf(stderr, __VA_ARGS__) | 9 | #define DBG_LOG(...) fprintf(stderr, __VA_ARGS__) |
| 10 | #define DBG_WARN(condition, ...) if (!(condition)) DBG_LOG(__VA_ARGS__); | 10 | #define DBG_WARN(condition, ...) if (!(condition)) DBG_LOG(__VA_ARGS__); |
| 11 | #define DBG_ASSERT(condition, retval, ...) \ | 11 | #define DBG_ASSERT(condition, retval, ...) \ |
| 12 | if (!(condition)) { \ | 12 | if (!(condition)) { DBG_LOG(__VA_ARGS__); return retval; } |
| 13 | DBG_LOG(__VA_ARGS__); \ | 13 | |
| 14 | return retval; \ | ||
| 15 | } | ||
| 16 | #else | 14 | #else |
| 17 | #define _static static | 15 | #define _static static |
| 18 | #define _static_inline static inline | 16 | #define _static_inline static inline |
diff --git a/src/cube_avx2.h b/src/cube_avx2.h index 233afed..f3fe731 100644 --- a/src/cube_avx2.h +++ b/src/cube_avx2.h | |||
| @@ -14,6 +14,8 @@ _static_inline cube_fast_t fastcube( | |||
| 14 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, | 14 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, |
| 15 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t | 15 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t |
| 16 | ); | 16 | ); |
| 17 | _static uint8_t corner(cube_fast_t, int); | ||
| 18 | _static uint8_t edge(cube_fast_t, int); | ||
| 17 | _static cube_fast_t cubetofast(cube_t); | 19 | _static cube_fast_t cubetofast(cube_t); |
| 18 | _static cube_t fasttocube(cube_fast_t); | 20 | _static cube_t fasttocube(cube_fast_t); |
| 19 | _static_inline bool equal_fast(cube_fast_t, cube_fast_t); | 21 | _static_inline bool equal_fast(cube_fast_t, cube_fast_t); |
| @@ -68,6 +70,28 @@ fastcube( | |||
| 68 | ); | 70 | ); |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 73 | _static uint8_t | ||
| 74 | corner(cube_fast_t c, int i) | ||
| 75 | { | ||
| 76 | uint8_t aux[32]; | ||
| 77 | |||
| 78 | DBG_ASSERT(i >= 0 && i < 8, 255, "Corner must be between 0 and 7\n"); | ||
| 79 | _mm256_storeu_si256((__m256i_u *)aux, c); | ||
| 80 | |||
| 81 | return aux[i]; | ||
| 82 | } | ||
| 83 | |||
| 84 | _static uint8_t | ||
| 85 | edge(cube_fast_t c, int i) | ||
| 86 | { | ||
| 87 | uint8_t aux[32]; | ||
| 88 | |||
| 89 | DBG_ASSERT(i >= 0 && i < 12, 255, "Edge must be between 0 and 11\n"); | ||
| 90 | _mm256_storeu_si256((__m256i_u *)aux, c); | ||
| 91 | |||
| 92 | return aux[i+16]; | ||
| 93 | } | ||
| 94 | |||
| 71 | _static cube_fast_t | 95 | _static cube_fast_t |
| 72 | cubetofast(cube_t a) | 96 | cubetofast(cube_t a) |
| 73 | { | 97 | { |
| @@ -338,4 +362,3 @@ invcoord_fast_esep(int64_t esep) | |||
| 338 | 362 | ||
| 339 | return ret; | 363 | return ret; |
| 340 | } | 364 | } |
| 341 | |||
diff --git a/src/cube_portable.h b/src/cube_portable.h index 2999d8a..48885ff 100644 --- a/src/cube_portable.h +++ b/src/cube_portable.h | |||
| @@ -1,4 +1,7 @@ | |||
| 1 | typedef cube_t cube_fast_t; | 1 | typedef struct { |
| 2 | uint8_t corner[8]; | ||
| 3 | uint8_t edge[12]; | ||
| 4 | } cube_fast_t; | ||
| 2 | 5 | ||
| 3 | _static_inline cube_fast_t fastcube( | 6 | _static_inline cube_fast_t fastcube( |
| 4 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, | 7 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, |
| @@ -6,6 +9,8 @@ _static_inline cube_fast_t fastcube( | |||
| 6 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, | 9 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, |
| 7 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t | 10 | uint8_t, uint8_t, uint8_t, uint8_t, uint8_t |
| 8 | ); | 11 | ); |
| 12 | _static uint8_t corner(cube_fast_t, int); | ||
| 13 | _static uint8_t edge(cube_fast_t, int); | ||
| 9 | _static cube_fast_t cubetofast(cube_t); | 14 | _static cube_fast_t cubetofast(cube_t); |
| 10 | _static cube_t fasttocube(cube_fast_t); | 15 | _static cube_t fasttocube(cube_fast_t); |
| 11 | _static_inline bool equal_fast(cube_fast_t, cube_fast_t); | 16 | _static_inline bool equal_fast(cube_fast_t, cube_fast_t); |
| @@ -66,6 +71,21 @@ fastcube( | |||
| 66 | return cube; | 71 | return cube; |
| 67 | } | 72 | } |
| 68 | 73 | ||
| 74 | _static uint8_t | ||
| 75 | corner(cube_fast_t c, int i) | ||
| 76 | { | ||
| 77 | DBG_ASSERT(i >= 0 && i < 8, 255, "Corner must be between 0 and 7\n"); | ||
| 78 | |||
| 79 | return c.corner[i]; | ||
| 80 | } | ||
| 81 | _static uint8_t | ||
| 82 | edge(cube_fast_t c, int i) | ||
| 83 | { | ||
| 84 | DBG_ASSERT(i >= 0 && i < 12, 255, "Edge must be between 0 and 11\n"); | ||
| 85 | |||
| 86 | return c.edge[i]; | ||
| 87 | } | ||
| 88 | |||
| 69 | _static cube_fast_t | 89 | _static cube_fast_t |
| 70 | cubetofast(cube_t cube) | 90 | cubetofast(cube_t cube) |
| 71 | { | 91 | { |
diff --git a/src/cube_routines.h b/src/cube_routines.h index fb19355..3730e90 100644 --- a/src/cube_routines.h +++ b/src/cube_routines.h | |||
| @@ -12,6 +12,10 @@ _static cube_t readcube_LST(const char *); | |||
| 12 | _static int writepiece_LST(uint8_t, char *); | 12 | _static int writepiece_LST(uint8_t, char *); |
| 13 | _static void writecube_H48(cube_t, char *); | 13 | _static void writecube_H48(cube_t, char *); |
| 14 | _static void writecube_LST(cube_t, char *); | 14 | _static void writecube_LST(cube_t, char *); |
| 15 | _static uint8_t b32toedge(char); | ||
| 16 | _static uint8_t b32tocorner(char); | ||
| 17 | _static char edgetob32(uint8_t); | ||
| 18 | _static char cornertob32(uint8_t); | ||
| 15 | _static uint8_t readmove(char); | 19 | _static uint8_t readmove(char); |
| 16 | _static uint8_t readmodifier(char); | 20 | _static uint8_t readmodifier(char); |
| 17 | _static uint8_t readtrans(const char *); | 21 | _static uint8_t readtrans(const char *); |
| @@ -494,6 +498,43 @@ writecube_LST(cube_t cube, char *buf) | |||
| 494 | } | 498 | } |
| 495 | 499 | ||
| 496 | _static uint8_t | 500 | _static uint8_t |
| 501 | b32toedge(char c) | ||
| 502 | { | ||
| 503 | DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255, | ||
| 504 | "Error reading base32 piece"); | ||
| 505 | |||
| 506 | return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a'); | ||
| 507 | } | ||
| 508 | |||
| 509 | _static uint8_t | ||
| 510 | b32tocorner(char c) { | ||
| 511 | uint8_t val; | ||
| 512 | |||
| 513 | DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255, | ||
| 514 | "Error reading base32 piece"); | ||
| 515 | |||
| 516 | val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; | ||
| 517 | |||
| 518 | return (val & 7) | ((val & 24) << 2); | ||
| 519 | } | ||
| 520 | |||
| 521 | _static char | ||
| 522 | edgetob32(uint8_t edge) | ||
| 523 | { | ||
| 524 | return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26); | ||
| 525 | } | ||
| 526 | |||
| 527 | _static char | ||
| 528 | cornertob32(uint8_t corner) | ||
| 529 | { | ||
| 530 | uint8_t val; | ||
| 531 | |||
| 532 | val = (corner & 7) | ((corner & 96) >> 2); | ||
| 533 | |||
| 534 | return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26); | ||
| 535 | } | ||
| 536 | |||
| 537 | _static uint8_t | ||
| 497 | readmove(char c) | 538 | readmove(char c) |
| 498 | { | 539 | { |
| 499 | switch (c) { | 540 | switch (c) { |
diff --git a/test/001_cube_conversion/00_solved.in b/test/001_pieces/01_solved.in index dff224d..dff224d 100644 --- a/test/001_cube_conversion/00_solved.in +++ b/test/001_pieces/01_solved.in | |||
diff --git a/test/001_pieces/01_solved.out b/test/001_pieces/01_solved.out new file mode 100644 index 0000000..94eb955 --- /dev/null +++ b/test/001_pieces/01_solved.out | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 0 1 2 3 4 5 6 7 | ||
| 2 | 0 1 2 3 4 5 6 7 8 9 10 11 | ||
diff --git a/test/001_pieces/02_scrambled.in b/test/001_pieces/02_scrambled.in new file mode 100644 index 0000000..6a05bbc --- /dev/null +++ b/test/001_pieces/02_scrambled.in | |||
| @@ -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/001_pieces/02_scrambled.out b/test/001_pieces/02_scrambled.out new file mode 100644 index 0000000..136336a --- /dev/null +++ b/test/001_pieces/02_scrambled.out | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 38 32 37 68 67 2 71 1 | ||
| 2 | 9 2 17 8 4 3 0 27 21 26 6 7 | ||
diff --git a/test/001_pieces/pieces_tests.c b/test/001_pieces/pieces_tests.c new file mode 100644 index 0000000..f3d8d4e --- /dev/null +++ b/test/001_pieces/pieces_tests.c | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #include "../test.h" | ||
| 2 | |||
| 3 | uint8_t corner(cube_fast_t, int); | ||
| 4 | uint8_t edge(cube_fast_t, int); | ||
| 5 | |||
| 6 | int main(void) { | ||
| 7 | int i; | ||
| 8 | char str[STRLENMAX], *aux; | ||
| 9 | cube_t cube; | ||
| 10 | cube_fast_t fast; | ||
| 11 | |||
| 12 | aux = str; | ||
| 13 | while (fgets(aux, STRLENMAX, stdin) != NULL) | ||
| 14 | while (*aux != '\n') | ||
| 15 | aux++; | ||
| 16 | |||
| 17 | cube = readcube("H48", str); | ||
| 18 | fast = cubetofast(cube); | ||
| 19 | |||
| 20 | for (i = 0; i < 8; i++) | ||
| 21 | printf("%" PRIu8 " ", corner(fast, i)); | ||
| 22 | printf("\n"); | ||
| 23 | for (i = 0; i < 12; i++) | ||
| 24 | printf("%" PRIu8 " ", edge(fast, i)); | ||
| 25 | printf("\n"); | ||
| 26 | |||
| 27 | return 0; | ||
| 28 | } | ||
diff --git a/test/001_cube_conversion/00_solved.out b/test/002_cube_conversion/00_solved.in index dff224d..dff224d 100644 --- a/test/001_cube_conversion/00_solved.out +++ b/test/002_cube_conversion/00_solved.in | |||
diff --git a/test/002_cube_conversion/00_solved.out b/test/002_cube_conversion/00_solved.out new file mode 100644 index 0000000..dff224d --- /dev/null +++ b/test/002_cube_conversion/00_solved.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/001_cube_conversion/01_scrambled.in b/test/002_cube_conversion/01_scrambled.in index 453cc8a..453cc8a 100644 --- a/test/001_cube_conversion/01_scrambled.in +++ b/test/002_cube_conversion/01_scrambled.in | |||
diff --git a/test/001_cube_conversion/01_scrambled.out b/test/002_cube_conversion/01_scrambled.out index 453cc8a..453cc8a 100644 --- a/test/001_cube_conversion/01_scrambled.out +++ b/test/002_cube_conversion/01_scrambled.out | |||
diff --git a/test/001_cube_conversion/cube_conversion_tests.c b/test/002_cube_conversion/cube_conversion_tests.c index df03eb6..df03eb6 100644 --- a/test/001_cube_conversion/cube_conversion_tests.c +++ b/test/002_cube_conversion/cube_conversion_tests.c | |||
