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 0b1930307f41db3ea7552d6b2f4666b33c64d26a
parent b218c803ae1110b08b4896be0a59177e280c9091
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Sun,  9 Jun 2024 20:06:19 +0200

More cleanup

Diffstat:
MTODO.txt | 21+++++++++++++--------
Dold/_trans_move_arr.c | 389-------------------------------------------------------------------------------
Dold/gendata_bfs_attempt.c | 153-------------------------------------------------------------------------------
Dold/inverse_fast.c | 51---------------------------------------------------
Dold/inverses.c | 71-----------------------------------------------------------------------
Dold/moves_trans/genmovecode.sh | 19-------------------
Dold/moves_trans/gentranscode.sh | 42------------------------------------------
Dold/moves_trans/moves_src.c | 264-------------------------------------------------------------------------------
Dold/moves_trans/v2/genmovecode.sh | 21---------------------
Dold/moves_trans/v2/gentranscode.sh | 24------------------------
Msrc/cube.c | 2++
Msrc/cube_avx2.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/cube_generic.h | 488+++----------------------------------------------------------------------------
Msrc/cube_portable.h | 22++++++++++++++++++++++
Asrc/io_cube.h | 359+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/io_move_trans.h | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16 files changed, 550 insertions(+), 1516 deletions(-)

diff --git a/TODO.txt b/TODO.txt @@ -1,18 +1,23 @@ Refactoring: remove cube_fast_t and add b32 format - - fix all public functions in cube.h - and their implementations in cube_generic - - cube i/o format - move all formats other than b32 to convert.{c,h} - add tests for conversion - convert test files (?) - make b32 default - replace utils/*.c with a generic convert utility + - cleanup cube.h + remove some documentation, move to new file + create src/cube_pulic.h for implementations of cube.h stuff + - switch to b32 by default (part 1) + add tests for b32 (write at some by hand) + - fix utility code in utils/*.c + replace h48_to_lst with convert.c + fix invert.c + fix utils/*.sh scripts to use the new convert + convert all utils/cubes/*.txt files in b32 format + - switch to b32 by default (part 2) + change all tests to use b32 - if all public functions work with strings, always use return value as error code (solve already does this), and use string as buffer to print error Transform with big table - make static cube actually static (how?) + - if not possible, cleanup in some way Solver - write a solver (how many tricks? some, but not all are needed) diff --git a/old/_trans_move_arr.c b/old/_trans_move_arr.c @@ -1,389 +0,0 @@ -static cube_t trans_move_cube[] = { - [UFr] = { - .c = {0, 1, 2, 3, 4, 5, 6, 7}, - .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} - }, - [ULr] = { - .c = {4, 5, 7, 6, 1, 0, 2, 3}, - .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24} - }, - [UBr] = { - .c = {1, 0, 3, 2, 5, 4, 7, 6}, - .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9} - }, - [URr] = { - .c = {5, 4, 6, 7, 0, 1, 3, 2}, - .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26} - }, - [DFr] = { - .c = {2, 3, 0, 1, 6, 7, 4, 5}, - .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10} - }, - [DLr] = { - .c = {7, 6, 4, 5, 2, 3, 1, 0}, - .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27} - }, - [DBr] = { - .c = {3, 2, 1, 0, 7, 6, 5, 4}, - .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8} - }, - [DRr] = { - .c = {6, 7, 5, 4, 3, 2, 0, 1}, - .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25} - }, - [RUr] = { - .c = {64, 67, 65, 66, 37, 38, 36, 39}, - .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3} - }, - [RFr] = { - .c = {38, 37, 36, 39, 64, 67, 66, 65}, - .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18} - }, - [RDr] = { - .c = {67, 64, 66, 65, 38, 37, 39, 36}, - .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1} - }, - [RBr] = { - .c = {37, 38, 39, 36, 67, 64, 65, 66}, - .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16} - }, - [LUr] = { - .c = {65, 66, 64, 67, 36, 39, 37, 38}, - .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2} - }, - [LFr] = { - .c = {36, 39, 38, 37, 66, 65, 64, 67}, - .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17} - }, - [LDr] = { - .c = {66, 65, 67, 64, 39, 36, 38, 37}, - .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0} - }, - [LBr] = { - .c = {39, 36, 37, 38, 65, 66, 67, 64}, - .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19} - }, - [FUr] = { - .c = {68, 70, 69, 71, 32, 34, 33, 35}, - .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6} - }, - [FRr] = { - .c = {32, 34, 35, 33, 70, 68, 69, 71}, - .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21} - }, - [FDr] = { - .c = {70, 68, 71, 69, 34, 32, 35, 33}, - .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4} - }, - [FLr] = { - .c = {34, 32, 33, 35, 68, 70, 71, 69}, - .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23} - }, - [BUr] = { - .c = {69, 71, 68, 70, 33, 35, 32, 34}, - .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7} - }, - [BRr] = { - .c = {35, 33, 32, 34, 69, 71, 70, 68}, - .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22} - }, - [BDr] = { - .c = {71, 69, 70, 68, 35, 33, 34, 32}, - .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5} - }, - [BLr] = { - .c = {33, 35, 34, 32, 71, 69, 68, 70}, - .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20} - }, - [UFm] = { - .c = {4, 5, 6, 7, 0, 1, 2, 3}, - .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10} - }, - [ULm] = { - .c = {0, 1, 3, 2, 5, 4, 6, 7}, - .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25} - }, - [UBm] = { - .c = {5, 4, 7, 6, 1, 0, 3, 2}, - .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8} - }, - [URm] = { - .c = {1, 0, 2, 3, 4, 5, 7, 6}, - .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27} - }, - [DFm] = { - .c = {6, 7, 4, 5, 2, 3, 0, 1}, - .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11} - }, - [DLm] = { - .c = {3, 2, 0, 1, 6, 7, 5, 4}, - .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26} - }, - [DBm] = { - .c = {7, 6, 5, 4, 3, 2, 1, 0}, - .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9} - }, - [DRm] = { - .c = {2, 3, 1, 0, 7, 6, 4, 5}, - .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24} - }, - [RUm] = { - .c = {68, 71, 69, 70, 33, 34, 32, 35}, - .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3} - }, - [RFm] = { - .c = {34, 33, 32, 35, 68, 71, 70, 69}, - .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18} - }, - [RDm] = { - .c = {71, 68, 70, 69, 34, 33, 35, 32}, - .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1} - }, - [RBm] = { - .c = {33, 34, 35, 32, 71, 68, 69, 70}, - .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16} - }, - [LUm] = { - .c = {69, 70, 68, 71, 32, 35, 33, 34}, - .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2} - }, - [LFm] = { - .c = {32, 35, 34, 33, 70, 69, 68, 71}, - .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17} - }, - [LDm] = { - .c = {70, 69, 71, 68, 35, 32, 34, 33}, - .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0} - }, - [LBm] = { - .c = {35, 32, 33, 34, 69, 70, 71, 68}, - .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19} - }, - [FUm] = { - .c = {64, 66, 65, 67, 36, 38, 37, 39}, - .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7} - }, - [FRm] = { - .c = {36, 38, 39, 37, 66, 64, 65, 67}, - .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20} - }, - [FDm] = { - .c = {66, 64, 67, 65, 38, 36, 39, 37}, - .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5} - }, - [FLm] = { - .c = {38, 36, 37, 39, 64, 66, 67, 65}, - .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22} - }, - [BUm] = { - .c = {65, 67, 64, 66, 37, 39, 36, 38}, - .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6} - }, - [BRm] = { - .c = {39, 37, 36, 38, 65, 67, 66, 64}, - .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23} - }, - [BDm] = { - .c = {67, 65, 66, 64, 39, 37, 38, 36}, - .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4} - }, - [BLm] = { - .c = {37, 39, 38, 36, 67, 65, 64, 66}, - .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21} - }, -}; - -static cube_t trans_move_cube_inverse[] = { - [UFr] = { - .c = {0, 1, 2, 3, 4, 5, 6, 7}, - .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} - }, - [ULr] = { - .c = {5, 4, 6, 7, 0, 1, 3, 2}, - .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26} - }, - [UBr] = { - .c = {1, 0, 3, 2, 5, 4, 7, 6}, - .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9} - }, - [URr] = { - .c = {4, 5, 7, 6, 1, 0, 2, 3}, - .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24} - }, - [DFr] = { - .c = {2, 3, 0, 1, 6, 7, 4, 5}, - .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10} - }, - [DLr] = { - .c = {7, 6, 4, 5, 2, 3, 1, 0}, - .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27} - }, - [DBr] = { - .c = {3, 2, 1, 0, 7, 6, 5, 4}, - .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8} - }, - [DRr] = { - .c = {6, 7, 5, 4, 3, 2, 0, 1}, - .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25} - }, - [RUr] = { - .c = {32, 34, 35, 33, 70, 68, 69, 71}, - .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21} - }, - [RFr] = { - .c = {36, 39, 38, 37, 66, 65, 64, 67}, - .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17} - }, - [RDr] = { - .c = {33, 35, 34, 32, 71, 69, 68, 70}, - .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20} - }, - [RBr] = { - .c = {37, 38, 39, 36, 67, 64, 65, 66}, - .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16} - }, - [LUr] = { - .c = {34, 32, 33, 35, 68, 70, 71, 69}, - .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23} - }, - [LFr] = { - .c = {38, 37, 36, 39, 64, 67, 66, 65}, - .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18} - }, - [LDr] = { - .c = {35, 33, 32, 34, 69, 71, 70, 68}, - .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22} - }, - [LBr] = { - .c = {39, 36, 37, 38, 65, 66, 67, 64}, - .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19} - }, - [FUr] = { - .c = {68, 70, 69, 71, 32, 34, 33, 35}, - .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6} - }, - [FRr] = { - .c = {64, 67, 65, 66, 37, 38, 36, 39}, - .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3} - }, - [FDr] = { - .c = {69, 71, 68, 70, 33, 35, 32, 34}, - .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7} - }, - [FLr] = { - .c = {65, 66, 64, 67, 36, 39, 37, 38}, - .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2} - }, - [BUr] = { - .c = {70, 68, 71, 69, 34, 32, 35, 33}, - .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4} - }, - [BRr] = { - .c = {66, 65, 67, 64, 39, 36, 38, 37}, - .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0} - }, - [BDr] = { - .c = {71, 69, 70, 68, 35, 33, 34, 32}, - .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5} - }, - [BLr] = { - .c = {67, 64, 66, 65, 38, 37, 39, 36}, - .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1} - }, - [UFm] = { - .c = {4, 5, 6, 7, 0, 1, 2, 3}, - .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10} - }, - [ULm] = { - .c = {0, 1, 3, 2, 5, 4, 6, 7}, - .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25} - }, - [UBm] = { - .c = {5, 4, 7, 6, 1, 0, 3, 2}, - .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8} - }, - [URm] = { - .c = {1, 0, 2, 3, 4, 5, 7, 6}, - .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27} - }, - [DFm] = { - .c = {6, 7, 4, 5, 2, 3, 0, 1}, - .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11} - }, - [DLm] = { - .c = {2, 3, 1, 0, 7, 6, 4, 5}, - .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24} - }, - [DBm] = { - .c = {7, 6, 5, 4, 3, 2, 1, 0}, - .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9} - }, - [DRm] = { - .c = {3, 2, 0, 1, 6, 7, 5, 4}, - .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26} - }, - [RUm] = { - .c = {70, 68, 69, 71, 32, 34, 35, 33}, - .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22} - }, - [RFm] = { - .c = {66, 65, 64, 67, 36, 39, 38, 37}, - .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18} - }, - [RDm] = { - .c = {71, 69, 68, 70, 33, 35, 34, 32}, - .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23} - }, - [RBm] = { - .c = {67, 64, 65, 66, 37, 38, 39, 36}, - .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19} - }, - [LUm] = { - .c = {68, 70, 71, 69, 34, 32, 33, 35}, - .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20} - }, - [LFm] = { - .c = {64, 67, 66, 65, 38, 37, 36, 39}, - .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17} - }, - [LDm] = { - .c = {69, 71, 70, 68, 35, 33, 32, 34}, - .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21} - }, - [LBm] = { - .c = {65, 66, 67, 64, 39, 36, 37, 38}, - .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16} - }, - [FUm] = { - .c = {32, 34, 33, 35, 68, 70, 69, 71}, - .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7} - }, - [FRm] = { - .c = {37, 38, 36, 39, 64, 67, 65, 66}, - .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2} - }, - [FDm] = { - .c = {33, 35, 32, 34, 69, 71, 68, 70}, - .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6} - }, - [FLm] = { - .c = {36, 39, 37, 38, 65, 66, 64, 67}, - .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3} - }, - [BUm] = { - .c = {34, 32, 35, 33, 70, 68, 71, 69}, - .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5} - }, - [BRm] = { - .c = {39, 36, 38, 37, 66, 65, 67, 64}, - .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1} - }, - [BDm] = { - .c = {35, 33, 34, 32, 71, 69, 70, 68}, - .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4} - }, - [BLm] = { - .c = {38, 37, 39, 36, 67, 64, 66, 65}, - .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0} - }, -}; diff --git a/old/gendata_bfs_attempt.c b/old/gendata_bfs_attempt.c @@ -1,153 +0,0 @@ -_static size_t gendata_cocsep(void *); -_static uint32_t dfs_cocsep(cube_fast_t, uint8_t, uint8_t, uint32_t *); - -/* -Each element of the cocsep table is a uint32_t used as follows: - - Lowest 8-bit block: pruning value - - Second-lower 8-bit block: "ttrep" (transformation to representative) - - Top 16-bit block: symcoord value -After the data as described above, more auxiliary information is appended: - - A uint32_t representing the number of symmetry classes - - A uint32_t representing the highest value of the pruning table - - One uint32_t for each "line" of the pruning table, representing the number - of positions having that pruning value. -*/ -_static size_t -gendata_cocsep(void *buf) -{ - uint32_t *buf32, cc; - uint64_t i64; - uint16_t n; - uint8_t i, j; - size_t tablesize; - - tablesize = _3p7 << 7U; - - buf32 = (uint32_t *)buf; - memset(buf32, 0xFFU, 4*tablesize); - memset(buf32 + tablesize, 0, 21*4); - -/* New impl BFS - - uint32_t nold = 0, nnew = 0; - uint64_t coord; - uint8_t m, olddepth; - cube_fast_t c, d, oldlevel[100000], newlevel[100000]; - newlevel[0] = cubetofast(solvedcube()); - nnew = 1; - buf32[coord_fast_cocsep(newlevel[0])] = UFr << 8U; - n = 1; - DBG_LOG("gendata_cocsep: found 1 position at depth 0\n"); - for (i = 1; i < 10; i++) { - DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i); - memcpy(oldlevel, newlevel, nnew * sizeof(cube_fast_t)); - nold = nnew; - nnew = 0; - for (j = 0; j < nold; j++) { - _foreach_move(m, oldlevel[j], newlevel[nnew], - coord = coord_fast_cocsep(newlevel[nnew]); - olddepth = buf32[coord] & 0xFFU; - buf32[coord] = i; - nnew += olddepth > i; - ) - } - DBG_LOG("found %" PRIu32 "\n", nnew); - } - -End new impl BFS */ - - /* Pruning values */ - buf32[tablesize+1] = 9U; /* Known max pruning value */ - for (i = 0, cc = 0; i < 10; i++) { - DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i); - cc = dfs_cocsep(cubetofast(solvedcube()), 0, i, buf32); - buf32[tablesize+i+2] = cc; - DBG_LOG("found %" PRIu32 "\n", cc); - } - - /* Symmetries */ - for (i64 = 0, n = 0; i64 < tablesize; i64++) { - } - buf32[tablesize] = (uint32_t)n; - - DBG_LOG("cocsep data computed, %" PRIu32 " symmetry classes\n", n); - DBG_LOG("Maximum pruning value: %" PRIu32 "\n", buf32[tablesize+1]); - DBG_LOG("Pruning value distribution:\n"); - for (j = 0; j < 10; j++) - DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+2]); - - return 4*(tablesize + 11); -} - -_static uint32_t -dfs_cocsep(cube_fast_t c, uint8_t depth, uint8_t maxdepth, uint32_t *buf32) -{ - uint8_t m, olddepth; - uint32_t update, cc; - uint64_t i; - cube_fast_t d; - - i = coord_fast_cocsep(c); - olddepth = (uint8_t)(buf32[i] & 0xFFU); - if (olddepth < depth) - return 0; - - if (depth == maxdepth) { - update = (buf32[i] & 0xFFU) == 0xFFU; - buf32[i] = depth; - return update; - } - - cc = 0; - _foreach_move(m, c, d, - cc += dfs_cocsep(d, depth+1, maxdepth, buf32); - ) - - return cc; -} - -/* -_static uint32_t -dfs_cocsep( - cube_fast_t c, - uint8_t depth, - uint8_t maxdepth, - uint16_t *n, - uint32_t *buf32 -) -{ - uint8_t m, t, tinv, olddepth; - uint32_t cc, oldvalue; - uint64_t i; - cube_fast_t d; - - oldvalue = buf32[coord_fast_cocsep(c)]; - if (depth == maxdepth) { - if ((oldvalue & 0xFFU) != 0xFFU) - return 0; - - for (t = 0, cc = 0; t < 48; t++) { - d = transform(c, t); - i = coord_fast_cocsep(d); - tinv = inverse_trans(t); - if ((buf32[i] & 0xFFU) == 0xFFU) - cc++; - buf32[i] = (*n << 16U) | (tinv << 8U) | depth; - } - (*n)++; - - return cc; - } - - olddepth = (uint8_t)(oldvalue & 0xFFU); - if (olddepth != depth) - return 0; - - cc = 0; - _foreach_move(m, c, d, - cc += dfs_cocsep(d, depth+1, maxdepth, n, buf32); - ) - - return cc; -} -*/ diff --git a/old/inverse_fast.c b/old/inverse_fast.c @@ -1,51 +0,0 @@ -_static_inline cube_fast_t -cleanaftershuffle(cube_fast_t c) -{ - __m256i b; - - b = _mm256_set_epi8( - ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0 - ); - - return _mm256_andnot_si256(b, c); -} - -_static_inline cube_fast_t -inverse_fast(cube_fast_t c) -{ - /* Method taken from Andrew Skalski's vcube[1]. The addition sequence - * was generated using [2]. - * [1] https://github.com/Voltara/vcube - * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html - */ - cube_fast_t v3, vi, vo, vp, ret; - - v3 = _mm256_shuffle_epi8(c, c); - v3 = _mm256_shuffle_epi8(v3, c); - vi = _mm256_shuffle_epi8(v3, v3); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, v3); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, c); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, v3); - vi = _mm256_shuffle_epi8(vi, vi); - vi = _mm256_shuffle_epi8(vi, c); - - vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2)); - vo = _mm256_shuffle_epi8(vo, vi); - vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi); - ret = _mm256_or_si256(vp, vo); - ret = cleanaftershuffle(ret); - - return invertco_fast(ret); -} diff --git a/old/inverses.c b/old/inverses.c @@ -1,71 +0,0 @@ -static move_t inverse_move_arr[] = { - [U] = U3, - [U2] = U2, - [U3] = U, - [D] = D3, - [D2] = D2, - [D3] = D, - [R] = R3, - [R2] = R2, - [R3] = R, - [L] = L3, - [L2] = L2, - [L3] = L, - [F] = F3, - [F2] = F2, - [F3] = F, - [B] = B3, - [B2] = B2, - [B3] = B, -}; - -static trans_t inverse_trans_arr[] = { - [UFr] = UFr, - [ULr] = URr, - [UBr] = UBr, - [URr] = URr, - [DFr] = DFr, - [DLr] = DLr, - [DRr] = DRr, - [DBr] = DBr, - [RUr] = FRr, - [RFr] = LFr, - [RDr] = BLr, - [RBr] = RBr, - [LUr] = FLr, - [LFr] = RFr, - [LDr] = BRr, - [LBr] = LBr, - [FUr] = FUr, - [FRr] = RUr, - [FDr] = BUr, - [FLr] = LUr, - [BUr] = FDr, - [BLr] = RDr, - [BDr] = BDr, - [BRr] = LDr, - [UFm] = UFm, - [ULm] = ULm, - [UBm] = UBm, - [URm] = ULm, - [DFm] = DFm, - [DLm] = DRm, - [DRm] = DLm, - [DBm] = DBm, - [RUm] = FLm, - [RFm] = RFm, - [RDm] = BRm, - [RBm] = LBm, - [LUm] = FRm, - [LFm] = LFm, - [LDm] = BLm, - [LBm] = RBm, - [FUm] = FUm, - [FRm] = LUm, - [FDm] = BUm, - [FLm] = RUm, - [BUm] = FDm, - [BLm] = LDm, - [BDm] = BDm, - [BRm] = RDm, -}; diff --git a/old/moves_trans/genmovecode.sh b/old/moves_trans/genmovecode.sh @@ -1,19 +0,0 @@ -#!/bin/sh - -type="${1:-src}" - -gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type" - -genfuncs() { - for f in move_??_*.txt; do - move="$(echo $f | sed 's/.*_// ; s/\.txt//')" - printf 'static inline cube_fast_t\n_move_%s' "$move" - printf '(cube_fast_t c)\n{\n' - printf '\tcube_fast_t m = ' - ./h48_to_"$type" <"$f" | sed '2,4s/^/\t/' - printf ';\n\n\treturn compose_fast(c, m);\n}\n\n' - done -} - -genfuncs -rm -f h48_to_"$type" invert diff --git a/old/moves_trans/gentranscode.sh b/old/moves_trans/gentranscode.sh @@ -1,42 +0,0 @@ -#!/bin/sh - -type="${1:-src}" - -gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type" -gcc -DDEBUG invert.c ../cube.c -o invert - -# Old version -genarray() { - for f in transform_??_???.txt; do - trans="$(echo $f | sed 's/.*_// ; s/\.txt//')" - printf '[%s] = ' "$trans" - if [ "$1" = "-i" ]; then - ./invert <"$f" | ./h48_to_"$type" - else - ./h48_to_"$type" <"$f" - fi - printf ',\n' - done -} - -genfuncs() { - for f in transform_??_???.txt; do - trans="$(echo $f | sed 's/.*_// ; s/\.txt//')" - printf 'static inline cube_fast_t\n_trans_%s' "$trans" - printf '(cube_fast_t c)\n{\n' - printf '\tcube_fast_t ret;\n\n' - printf '\tcube_fast_t tn = ' - ./h48_to_"$type" <"$f" | sed '2,4s/^/\t/' - printf ';\n\tcube_fast_t ti = ' - ./invert <"$f" | ./h48_to_"$type" | sed '2,4 s/^/\t/' - printf ';\n\n\tret = compose_fast(tn, c);\n' - printf '\tret = compose_fast(ret, ti);\n' - if [ -n "$(echo "$trans" | grep "m")" ]; then - printf '\tret = invertco_fast(ret);\n' - fi - printf '\n\treturn ret;\n}\n\n' - done -} - -genfuncs -rm -f h48_to_"$type" invert diff --git a/old/moves_trans/moves_src.c b/old/moves_trans/moves_src.c @@ -1,264 +0,0 @@ -#define PERM4(r, i, j, k, l) \ - aux = r[i]; \ - r[i] = r[l]; \ - r[l] = r[k]; \ - r[k] = r[j]; \ - r[j] = aux; -#define PERM22(r, i, j, k, l) \ - aux = r[i]; \ - r[i] = r[j]; \ - r[j] = aux; \ - aux = r[k]; \ - r[k] = r[l]; \ - r[l] = aux; -#define CO(a, b) \ - aux = (a & _cobits) + (b & _cobits); \ - auy = (aux + _ctwist_cw) >> 2U; \ - auz = (aux + auy) & _cobits2; \ - a = (a & _pbits) | auz; -#define CO4(r, i, j, k, l) \ - CO(r[i], _ctwist_cw) \ - CO(r[j], _ctwist_cw) \ - CO(r[k], _ctwist_ccw) \ - CO(r[l], _ctwist_ccw) -#define EO4(r, i, j, k, l) \ - r[i] ^= _eobit; \ - r[j] ^= _eobit; \ - r[k] ^= _eobit; \ - r[l] ^= _eobit; - -_static_inline cube_fast_t -_move_U(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_uf, _e_ul, _e_ub, _e_ur) - PERM4(ret.corner, _c_ufr, _c_ufl, _c_ubl, _c_ubr) - - return ret; -} - -_static_inline cube_fast_t -_move_U2(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM22(ret.edge, _e_uf, _e_ub, _e_ul, _e_ur) - PERM22(ret.corner, _c_ufr, _c_ubl, _c_ufl, _c_ubr) - - return ret; -} - -_static_inline cube_fast_t -_move_U3(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_uf, _e_ur, _e_ub, _e_ul) - PERM4(ret.corner, _c_ufr, _c_ubr, _c_ubl, _c_ufl) - - return ret; -} - -_static_inline cube_fast_t -_move_D(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_df, _e_dr, _e_db, _e_dl) - PERM4(ret.corner, _c_dfr, _c_dbr, _c_dbl, _c_dfl) - - return ret; -} - -_static_inline cube_fast_t -_move_D2(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM22(ret.edge, _e_df, _e_db, _e_dr, _e_dl) - PERM22(ret.corner, _c_dfr, _c_dbl, _c_dbr, _c_dfl) - - return ret; -} - -_static_inline cube_fast_t -_move_D3(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_df, _e_dl, _e_db, _e_dr) - PERM4(ret.corner, _c_dfr, _c_dfl, _c_dbl, _c_dbr) - - return ret; -} - -_static_inline cube_fast_t -_move_R(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_ur, _e_br, _e_dr, _e_fr) - PERM4(ret.corner, _c_ufr, _c_ubr, _c_dbr, _c_dfr) - - CO4(ret.corner, _c_ubr, _c_dfr, _c_ufr, _c_dbr) - - return ret; -} - -_static_inline cube_fast_t -_move_R2(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM22(ret.edge, _e_ur, _e_dr, _e_fr, _e_br) - PERM22(ret.corner, _c_ufr, _c_dbr, _c_ubr, _c_dfr) - - return ret; -} - -_static_inline cube_fast_t -_move_R3(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_ur, _e_fr, _e_dr, _e_br) - PERM4(ret.corner, _c_ufr, _c_dfr, _c_dbr, _c_ubr) - - CO4(ret.corner, _c_ubr, _c_dfr, _c_ufr, _c_dbr) - - return ret; -} - -_static_inline cube_fast_t -_move_L(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_ul, _e_fl, _e_dl, _e_bl) - PERM4(ret.corner, _c_ufl, _c_dfl, _c_dbl, _c_ubl) - - CO4(ret.corner, _c_ufl, _c_dbl, _c_dfl, _c_ubl) - - return ret; -} - -_static_inline cube_fast_t -_move_L2(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM22(ret.edge, _e_ul, _e_dl, _e_fl, _e_bl) - PERM22(ret.corner, _c_ufl, _c_dbl, _c_ubl, _c_dfl) - - return ret; -} - -_static_inline cube_fast_t -_move_L3(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_ul, _e_bl, _e_dl, _e_fl) - PERM4(ret.corner, _c_ufl, _c_ubl, _c_dbl, _c_dfl) - - CO4(ret.corner, _c_ufl, _c_dbl, _c_dfl, _c_ubl) - - return ret; -} - -_static_inline cube_fast_t -_move_F(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl) - PERM4(ret.corner, _c_ufr, _c_dfr, _c_dfl, _c_ufl) - - EO4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl) - CO4(ret.corner, _c_ufr, _c_dfl, _c_dfr, _c_ufl) - - return ret; -} - -_static_inline cube_fast_t -_move_F2(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM22(ret.edge, _e_uf, _e_df, _e_fr, _e_fl) - PERM22(ret.corner, _c_ufr, _c_dfl, _c_ufl, _c_dfr) - - return ret; -} - -_static_inline cube_fast_t -_move_F3(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_uf, _e_fl, _e_df, _e_fr) - PERM4(ret.corner, _c_ufr, _c_ufl, _c_dfl, _c_dfr) - - EO4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl) - CO4(ret.corner, _c_ufr, _c_dfl, _c_dfr, _c_ufl) - - return ret; -} - -_static_inline cube_fast_t -_move_B(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_ub, _e_bl, _e_db, _e_br) - PERM4(ret.corner, _c_ubr, _c_ubl, _c_dbl, _c_dbr) - - EO4(ret.edge, _e_ub, _e_br, _e_db, _e_bl) - CO4(ret.corner, _c_ubl, _c_dbr, _c_dbl, _c_ubr) - - return ret; -} - -_static_inline cube_fast_t -_move_B2(cube_fast_t c) -{ - uint8_t aux; - cube_fast_t ret = c; - - PERM22(ret.edge, _e_ub, _e_db, _e_br, _e_bl) - PERM22(ret.corner, _c_ubr, _c_dbl, _c_ubl, _c_dbr) - - return ret; -} - -_static_inline cube_fast_t -_move_B3(cube_fast_t c) -{ - uint8_t aux, auy, auz; - cube_fast_t ret = c; - - PERM4(ret.edge, _e_ub, _e_br, _e_db, _e_bl) - PERM4(ret.corner, _c_ubr, _c_dbr, _c_dbl, _c_ubl) - - EO4(ret.edge, _e_ub, _e_br, _e_db, _e_bl) - CO4(ret.corner, _c_ubl, _c_dbr, _c_dbl, _c_ubr) - - return ret; -} diff --git a/old/moves_trans/v2/genmovecode.sh b/old/moves_trans/v2/genmovecode.sh @@ -1,21 +0,0 @@ -#!/bin/sh - -type="${1:-src}" - -gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type" - -lineavx() { printf '#define _move_cube_%s ' "$1"; } -linesrc() { printf '_static cube_fast_t _move_cube_%s = ' "$1"; } -sedavx() { sed '1,2s/$/ \\/ ; 3s/$/)/ ; 3q'; } -sedsrc() { sed '3s/$/ };/ ; 3q'; } - -gen() { - for f in move_??_*.txt; do - move="$(echo $f | sed 's/.*_// ; s/\.txt//')" - line$type "$move" - ./h48_to_"$type" <"$f" | sed$type - done -} - -gen -rm -f h48_to_"$type" invert diff --git a/old/moves_trans/v2/gentranscode.sh b/old/moves_trans/v2/gentranscode.sh @@ -1,24 +0,0 @@ -#!/bin/sh - -type="${1:-src}" - -gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type" -gcc -DDEBUG invert.c ../cube.c -o invert - -lineavx() { printf '#define _trans_cube_%s ' "$1"; } -linesrc() { printf '_static cube_fast_t _trans_cube_%s = ' "$1"; } -sedavx() { sed '1,2s/$/ \\/ ; 3s/$/)/ ; 3q'; } -sedsrc() { sed '3s/$/ };/ ; 3q'; } - -gen() { - for f in transform_??_???.txt; do - trans="$(echo $f | sed 's/.*_// ; s/\.txt//')" - line$type "$trans" - ./h48_to_"$type" <"$f" | sed$type - line$type "${trans}_inverse" - ./invert <"$f" | ./h48_to_"$type" | sed$type - done -} - -gen -rm -f h48_to_"$type" invert diff --git a/src/cube.c b/src/cube.c @@ -31,8 +31,10 @@ #include "cube_portable.h" #endif +#include "io_move_trans.h" #include "constant_cubes.h" #include "cube_generic.h" +#include "io_cube.h" /* TODO: work in progress */ #if 0 diff --git a/src/cube_avx2.h b/src/cube_avx2.h @@ -25,6 +25,7 @@ _static_inline cube_t compose_epcpeo(cube_t, cube_t); _static_inline cube_t compose_edges(cube_t, cube_t); _static_inline cube_t compose_corners(cube_t, cube_t); _static_inline cube_t compose(cube_t, cube_t); +_static_inline cube_t inverse(cube_t); _static_inline int64_t coord_co(cube_t); _static_inline int64_t coord_csep(cube_t); @@ -135,6 +136,58 @@ compose(cube_t c1, cube_t c2) return s; } +_static_inline cube_t +cleanaftershuffle(cube_t c) +{ + __m256i b; + + b = _mm256_set_epi8( + ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0 + ); + + return _mm256_andnot_si256(b, c); +} + +_static_inline cube_t +inverse(cube_t c) +{ + /* Method taken from Andrew Skalski's vcube[1]. The addition sequence + * was generated using [2]. + * [1] https://github.com/Voltara/vcube + * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html + */ + cube_t v3, vi, vo, vp, ret; + + v3 = _mm256_shuffle_epi8(c, c); + v3 = _mm256_shuffle_epi8(v3, c); + vi = _mm256_shuffle_epi8(v3, v3); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, v3); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, c); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, v3); + vi = _mm256_shuffle_epi8(vi, vi); + vi = _mm256_shuffle_epi8(vi, c); + + vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2)); + vo = _mm256_shuffle_epi8(vo, vi); + vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi); + ret = _mm256_or_si256(vp, vo); + ret = cleanaftershuffle(ret); + + return invertco(ret); +} + _static_inline int64_t coord_co(cube_t c) { diff --git a/src/cube_generic.h b/src/cube_generic.h @@ -1,62 +1,27 @@ #define _move(M, c) compose(c, _move_cube_ ## M) #define _premove(M, c) compose(_move_cube_ ## M, c) -_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); +_static cube_t solvedcube(); +_static bool isconsistent(cube_t); +_static bool issolvable(cube_t); +_static bool issolved(cube_t); +_static bool iserror(cube_t); +_static cube_t applymoves(cube_t, const char *); +_static cube_t applytrans(cube_t, const char *); + _static int permsign(uint8_t *, int); -_static uint8_t readco(const char *); -_static uint8_t readcp(const char *); -_static uint8_t readeo(const char *); -_static uint8_t readep(const char *); -_static cube_t readcube_B32(const char *); -_static cube_t readcube_H48(const char *); -_static uint8_t readpiece_LST(const char **); -_static cube_t readcube_LST(const char *); -_static int writepiece_LST(uint8_t, char *); -_static void writecube_B32(cube_t, char *); -_static void writecube_H48(cube_t, char *); -_static void writecube_LST(cube_t, char *); -_static uint8_t b32toedge(char); -_static uint8_t b32tocorner(char); -_static char edgetob32(uint8_t); -_static char cornertob32(uint8_t); -_static uint8_t readmove(char); -_static uint8_t readmodifier(char); -_static uint8_t readtrans(const char *); -_static int writemoves(uint8_t *, int, char *); -_static void writetrans(uint8_t, char *); _static cube_t move(cube_t, uint8_t); _static cube_t transform_edges(cube_t, uint8_t); _static cube_t transform_corners(cube_t, uint8_t); _static cube_t transform(cube_t, uint8_t); -_static struct { - const char *name; - cube_t (*read)(const char *); - void (*write)(cube_t, char *); -} ioformat[] = -{ - { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, - { .name = "LST", .read = readcube_LST, .write = writecube_LST }, - { .name = "H48", .read = readcube_H48, .write = writecube_H48 }, - { .name = "NONE", .read = NULL, .write = NULL }, -}; - -_static_inline cube_t -cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) -{ - return static_cube( - c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], - e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], - e[8], e[9], e[10], e[11]); -} - -cube_t -solvedcube(void) +_static cube_t +solvedcube() { return solved; } -bool +_static bool isconsistent(cube_t cube) { uint8_t i, p, e, piece, corner[8], edge[12]; @@ -112,7 +77,7 @@ inconsistent_co: return false; } -bool +_static bool issolvable(cube_t cube) { uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8]; @@ -170,32 +135,7 @@ iserror(cube_t cube) return equal(cube, zero); } -cube_t -inverse(cube_t cube) -{ - uint8_t i, piece, orien, e[12], c[8], edge[12], corner[8]; - - DBG_ASSERT(isconsistent(cube), zero, - "inverse error: inconsistent cube\n"); - - pieces(&cube, corner, edge); - - for (i = 0; i < 12; i++) { - piece = edge[i]; - orien = piece & _eobit; - e[piece & _pbits] = i | orien; - } - - for (i = 0; i < 8; i++) { - piece = corner[i]; - orien = ((piece << 1) | (piece >> 1)) & _cobits2; - c[piece & _pbits] = i | orien; - } - - return cubefromarray(c, e); -} - -cube_t +_static cube_t applymoves(cube_t cube, const char *buf) { uint8_t r, m; @@ -224,7 +164,7 @@ applymoves_error: return zero; } -cube_t +_static cube_t applytrans(cube_t cube, const char *buf) { uint8_t t; @@ -237,49 +177,6 @@ applytrans(cube_t cube, const char *buf) return transform(cube, t); } -cube_t -readcube(const char *format, const char *buf) -{ - int i; - - for (i = 0; ioformat[i].read != NULL; i++) - if (!strcmp(format, ioformat[i].name)) - return ioformat[i].read(buf); - - DBG_LOG("Cannot read cube in the given format\n"); - return zero; -} - -void -writecube(const char *format, cube_t cube, char *buf) -{ - char *errormsg; - size_t len; - - if (!isconsistent(cube)) { - errormsg = "ERROR: cannot write inconsistent cube"; - goto writecube_error; - } - - int i; - - for (i = 0; ioformat[i].write != NULL; i++) { - if (!strcmp(format, ioformat[i].name)) { - ioformat[i].write(cube, buf); - return; - } - } - - errormsg = "ERROR: cannot write cube in the given format"; - -writecube_error: - DBG_LOG("writecube error, see stdout for details\n"); - len = strlen(errormsg); - memcpy(buf, errormsg, len); - buf[len] = '\n'; - buf[len+1] = '\0'; -} - _static int permsign(uint8_t *a, int n) { @@ -293,363 +190,6 @@ permsign(uint8_t *a, int n) return ret % 2; } -_static uint8_t -readco(const char *str) -{ - if (*str == '0') - return 0; - if (*str == '1') - return _ctwist_cw; - if (*str == '2') - return _ctwist_ccw; - - DBG_LOG("Error reading CO\n"); - return _error; -} - -_static uint8_t -readcp(const char *str) -{ - uint8_t c; - - for (c = 0; c < 8; c++) - if (!strncmp(str, cornerstr[c], 3) || - !strncmp(str, cornerstralt[c], 3)) - return c; - - DBG_LOG("Error reading CP\n"); - return _error; -} - -_static uint8_t -readeo(const char *str) -{ - if (*str == '0') - return 0; - if (*str == '1') - return _eflip; - - DBG_LOG("Error reading EO\n"); - return _error; -} - -_static uint8_t -readep(const char *str) -{ - uint8_t e; - - for (e = 0; e < 12; e++) - if (!strncmp(str, edgestr[e], 2)) - return e; - - DBG_LOG("Error reading EP\n"); - return _error; -} - -_static cube_t -readcube_B32(const char *buf) -{ - int i; - uint8_t c[8], e[12]; - - for (i = 0; i < 8; i++) { - c[i] = b32tocorner(buf[i]); - DBG_ASSERT(c[i] < 255, zero, - "Error reading B32 corner %d (char %d)\n", i, i); - } - - for (i = 0; i < 12; i++) { - e[i] = b32toedge(buf[i+9]); - DBG_ASSERT(e[i] < 255, zero, - "Error reading B32 edge %d (char %d)\n", i, i+9); - } - - return cubefromarray(c, e); -} - -_static cube_t -readcube_H48(const char *buf) -{ - int i; - uint8_t piece, orient, c[8], e[12]; - const char *b; - - b = buf; - - for (i = 0; i < 12; i++) { - while (*b == ' ' || *b == '\t' || *b == '\n') - b++; - if ((piece = readep(b)) == _error) - return zero; - b += 2; - if ((orient = readeo(b)) == _error) - return zero; - b++; - e[i] = piece | orient; - } - for (i = 0; i < 8; i++) { - while (*b == ' ' || *b == '\t' || *b == '\n') - b++; - if ((piece = readcp(b)) == _error) - return zero; - b += 3; - if ((orient = readco(b)) == _error) - return zero; - b++; - c[i] = piece | orient; - } - - return cubefromarray(c, e); -} - -_static uint8_t -readpiece_LST(const 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(const char *buf) -{ - int i; - uint8_t c[8], e[12]; - - for (i = 0; i < 8; i++) - c[i] = readpiece_LST(&buf); - - for (i = 0; i < 12; i++) - e[i] = readpiece_LST(&buf); - - return cubefromarray(c, e); -} - -_static int -writepiece_LST(uint8_t piece, char *buf) -{ - char digits[3]; - int i, len; - - len = 0; - while (piece != 0) { - digits[len++] = (piece % 10) + '0'; - piece /= 10; - } - - if (len == 0) - digits[len++] = '0'; - - for (i = 0; i < len; i++) - buf[i] = digits[len-i-1]; - - buf[len] = ','; - buf[len+1] = ' '; - - return len+2; -} - -_static void -writecube_B32(cube_t cube, char *buf) -{ - int i; - uint8_t corner[8], edge[12]; - - pieces(&cube, corner, edge); - - for (i = 0; i < 8; i++) - buf[i] = cornertob32(corner[i]); - - buf[8] = '='; - - for (i = 0; i < 12; i++) - buf[i+9] = edgetob32(edge[i]); - - buf[21] = '\0'; -} - -_static void -writecube_H48(cube_t cube, char *buf) -{ - uint8_t piece, perm, orient, corner[8], edge[12]; - int i; - - pieces(&cube, corner, edge); - - for (i = 0; i < 12; i++) { - piece = edge[i]; - perm = piece & _pbits; - orient = (piece & _eobit) >> _eoshift; - buf[4*i ] = edgestr[perm][0]; - buf[4*i + 1] = edgestr[perm][1]; - buf[4*i + 2] = orient + '0'; - buf[4*i + 3] = ' '; - } - for (i = 0; i < 8; i++) { - piece = corner[i]; - perm = piece & _pbits; - orient = (piece & _cobits) >> _coshift; - buf[48 + 5*i ] = cornerstr[perm][0]; - buf[48 + 5*i + 1] = cornerstr[perm][1]; - buf[48 + 5*i + 2] = cornerstr[perm][2]; - buf[48 + 5*i + 3] = orient + '0'; - buf[48 + 5*i + 4] = ' '; - } - - buf[48+39] = '\0'; -} - -_static void -writecube_LST(cube_t cube, char *buf) -{ - int i; - size_t ptr; - uint8_t piece, corner[8], edge[12]; - - ptr = 0; - pieces(&cube, corner, edge); - - for (i = 0; i < 8; i++) { - piece = corner[i]; - ptr += writepiece_LST(piece, buf + ptr); - } - - for (i = 0; i < 12; i++) { - piece = edge[i]; - ptr += writepiece_LST(piece, buf + ptr); - } - - *(buf+ptr-2) = 0; -} - -_static uint8_t -b32toedge(char c) -{ - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g')) - return 255; - - return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a'); -} - -_static uint8_t -b32tocorner(char c) { - uint8_t val; - - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g')) - return 255; - - val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; - - return (val & 7) | ((val & 24) << 2); -} - -_static char -edgetob32(uint8_t edge) -{ - return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26); -} - -_static char -cornertob32(uint8_t corner) -{ - uint8_t val; - - val = (corner & 7) | ((corner & 96) >> 2); - - return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26); -} - -_static uint8_t -readmove(char c) -{ - switch (c) { - case 'U': - return _move_U; - case 'D': - return _move_D; - case 'R': - return _move_R; - case 'L': - return _move_L; - case 'F': - return _move_F; - case 'B': - return _move_B; - default: - return _error; - } -} - -_static uint8_t -readmodifier(char c) -{ - switch (c) { - case '1': /* Fallthrough */ - case '2': /* Fallthrough */ - case '3': - return c - '0' - 1; - case '\'': - return 2; - default: - return 0; - } -} - -_static uint8_t -readtrans(const char *buf) -{ - uint8_t t; - - for (t = 0; t < 48; t++) - if (!strncmp(buf, transstr[t], 11)) - return t; - - DBG_LOG("readtrans error\n"); - return _error; -} - -_static int -writemoves(uint8_t *m, int n, char *buf) -{ - int i; - size_t len; - const char *s; - char *b; - - for (i = 0, b = buf; i < n; i++, b++) { - s = movestr[m[i]]; - len = strlen(s); - memcpy(b, s, len); - b += len; - *b = ' '; - } - - if (b != buf) - b--; /* Remove last space */ - *b = '\0'; - - return b - buf; -} - -_static void -writetrans(uint8_t t, char *buf) -{ - if (t >= 48) - memcpy(buf, "error trans", 11); - else - memcpy(buf, transstr[t], 11); - buf[11] = '\0'; -} - _static cube_t move(cube_t c, uint8_t m) { diff --git a/src/cube_portable.h b/src/cube_portable.h @@ -22,6 +22,7 @@ _static_inline void compose_corners_inplace(cube_t, cube_t, cube_t *); _static_inline cube_t compose_edges(cube_t, cube_t); _static_inline cube_t compose_corners(cube_t, cube_t); _static_inline cube_t compose(cube_t, cube_t); +_static_inline cube_t inverse(cube_t); _static_inline int64_t coord_co(cube_t); _static_inline int64_t coord_csep(cube_t); @@ -133,6 +134,27 @@ compose(cube_t c1, cube_t c2) return ret; } +cube_t +inverse(cube_t cube) +{ + uint8_t i, piece, orien; + cube_t ret; + + for (i = 0; i < 12; i++) { + piece = cube.edge[i]; + orien = piece & _eobit; + ret.edge[piece & _pbits] = i | orien; + } + + for (i = 0; i < 8; i++) { + piece = cube.corner[i]; + orien = ((piece << 1) | (piece >> 1)) & _cobits2; + ret.corner[piece & _pbits] = i | orien; + } + + return ret; +} + _static_inline int64_t coord_co(cube_t c) { diff --git a/src/io_cube.h b/src/io_cube.h @@ -0,0 +1,359 @@ +_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); + +_static uint8_t readco(const char *); +_static uint8_t readcp(const char *); +_static uint8_t readeo(const char *); +_static uint8_t readep(const char *); +_static cube_t readcube_B32(const char *); +_static cube_t readcube_H48(const char *); +_static uint8_t readpiece_LST(const char **); +_static cube_t readcube_LST(const char *); + +_static int writepiece_LST(uint8_t, char *); +_static void writecube_B32(cube_t, char *); +_static void writecube_H48(cube_t, char *); +_static void writecube_LST(cube_t, char *); + +_static uint8_t b32toedge(char); +_static uint8_t b32tocorner(char); +_static char edgetob32(uint8_t); +_static char cornertob32(uint8_t); + +_static struct { + const char *name; + cube_t (*read)(const char *); + void (*write)(cube_t, char *); +} ioformat[] = +{ + { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, + { .name = "LST", .read = readcube_LST, .write = writecube_LST }, + { .name = "H48", .read = readcube_H48, .write = writecube_H48 }, + { .name = "NONE", .read = NULL, .write = NULL }, +}; + +_static_inline cube_t +cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) +{ + return static_cube( + c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], + e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], + e[8], e[9], e[10], e[11]); +} + +cube_t +readcube(const char *format, const char *buf) +{ + int i; + + for (i = 0; ioformat[i].read != NULL; i++) + if (!strcmp(format, ioformat[i].name)) + return ioformat[i].read(buf); + + DBG_LOG("Cannot read cube in the given format\n"); + return zero; +} + +void +writecube(const char *format, cube_t cube, char *buf) +{ + char *errormsg; + size_t len; + + if (!isconsistent(cube)) { + errormsg = "ERROR: cannot write inconsistent cube"; + goto writecube_error; + } + + int i; + + for (i = 0; ioformat[i].write != NULL; i++) { + if (!strcmp(format, ioformat[i].name)) { + ioformat[i].write(cube, buf); + return; + } + } + + errormsg = "ERROR: cannot write cube in the given format"; + +writecube_error: + DBG_LOG("writecube error, see stdout for details\n"); + len = strlen(errormsg); + memcpy(buf, errormsg, len); + buf[len] = '\n'; + buf[len+1] = '\0'; +} + +_static uint8_t +readco(const char *str) +{ + if (*str == '0') + return 0; + if (*str == '1') + return _ctwist_cw; + if (*str == '2') + return _ctwist_ccw; + + DBG_LOG("Error reading CO\n"); + return _error; +} + +_static uint8_t +readcp(const char *str) +{ + uint8_t c; + + for (c = 0; c < 8; c++) + if (!strncmp(str, cornerstr[c], 3) || + !strncmp(str, cornerstralt[c], 3)) + return c; + + DBG_LOG("Error reading CP\n"); + return _error; +} + +_static uint8_t +readeo(const char *str) +{ + if (*str == '0') + return 0; + if (*str == '1') + return _eflip; + + DBG_LOG("Error reading EO\n"); + return _error; +} + +_static uint8_t +readep(const char *str) +{ + uint8_t e; + + for (e = 0; e < 12; e++) + if (!strncmp(str, edgestr[e], 2)) + return e; + + DBG_LOG("Error reading EP\n"); + return _error; +} + +_static cube_t +readcube_B32(const char *buf) +{ + int i; + uint8_t c[8], e[12]; + + for (i = 0; i < 8; i++) { + c[i] = b32tocorner(buf[i]); + DBG_ASSERT(c[i] < 255, zero, + "Error reading B32 corner %d (char %d)\n", i, i); + } + + for (i = 0; i < 12; i++) { + e[i] = b32toedge(buf[i+9]); + DBG_ASSERT(e[i] < 255, zero, + "Error reading B32 edge %d (char %d)\n", i, i+9); + } + + return cubefromarray(c, e); +} + +_static cube_t +readcube_H48(const char *buf) +{ + int i; + uint8_t piece, orient, c[8], e[12]; + const char *b; + + b = buf; + + for (i = 0; i < 12; i++) { + while (*b == ' ' || *b == '\t' || *b == '\n') + b++; + if ((piece = readep(b)) == _error) + return zero; + b += 2; + if ((orient = readeo(b)) == _error) + return zero; + b++; + e[i] = piece | orient; + } + for (i = 0; i < 8; i++) { + while (*b == ' ' || *b == '\t' || *b == '\n') + b++; + if ((piece = readcp(b)) == _error) + return zero; + b += 3; + if ((orient = readco(b)) == _error) + return zero; + b++; + c[i] = piece | orient; + } + + return cubefromarray(c, e); +} + +_static uint8_t +readpiece_LST(const 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(const char *buf) +{ + int i; + uint8_t c[8], e[12]; + + for (i = 0; i < 8; i++) + c[i] = readpiece_LST(&buf); + + for (i = 0; i < 12; i++) + e[i] = readpiece_LST(&buf); + + return cubefromarray(c, e); +} + +_static int +writepiece_LST(uint8_t piece, char *buf) +{ + char digits[3]; + int i, len; + + len = 0; + while (piece != 0) { + digits[len++] = (piece % 10) + '0'; + piece /= 10; + } + + if (len == 0) + digits[len++] = '0'; + + for (i = 0; i < len; i++) + buf[i] = digits[len-i-1]; + + buf[len] = ','; + buf[len+1] = ' '; + + return len+2; +} + +_static void +writecube_B32(cube_t cube, char *buf) +{ + int i; + uint8_t corner[8], edge[12]; + + pieces(&cube, corner, edge); + + for (i = 0; i < 8; i++) + buf[i] = cornertob32(corner[i]); + + buf[8] = '='; + + for (i = 0; i < 12; i++) + buf[i+9] = edgetob32(edge[i]); + + buf[21] = '\0'; +} + +_static void +writecube_H48(cube_t cube, char *buf) +{ + uint8_t piece, perm, orient, corner[8], edge[12]; + int i; + + pieces(&cube, corner, edge); + + for (i = 0; i < 12; i++) { + piece = edge[i]; + perm = piece & _pbits; + orient = (piece & _eobit) >> _eoshift; + buf[4*i ] = edgestr[perm][0]; + buf[4*i + 1] = edgestr[perm][1]; + buf[4*i + 2] = orient + '0'; + buf[4*i + 3] = ' '; + } + for (i = 0; i < 8; i++) { + piece = corner[i]; + perm = piece & _pbits; + orient = (piece & _cobits) >> _coshift; + buf[48 + 5*i ] = cornerstr[perm][0]; + buf[48 + 5*i + 1] = cornerstr[perm][1]; + buf[48 + 5*i + 2] = cornerstr[perm][2]; + buf[48 + 5*i + 3] = orient + '0'; + buf[48 + 5*i + 4] = ' '; + } + + buf[48+39] = '\0'; +} + +_static void +writecube_LST(cube_t cube, char *buf) +{ + int i; + size_t ptr; + uint8_t piece, corner[8], edge[12]; + + ptr = 0; + pieces(&cube, corner, edge); + + for (i = 0; i < 8; i++) { + piece = corner[i]; + ptr += writepiece_LST(piece, buf + ptr); + } + + for (i = 0; i < 12; i++) { + piece = edge[i]; + ptr += writepiece_LST(piece, buf + ptr); + } + + *(buf+ptr-2) = 0; +} + +_static uint8_t +b32toedge(char c) +{ + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g')) + return 255; + + return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a'); +} + +_static uint8_t +b32tocorner(char c) { + uint8_t val; + + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g')) + return 255; + + val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; + + return (val & 7) | ((val & 24) << 2); +} + +_static char +edgetob32(uint8_t edge) +{ + return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26); +} + +_static char +cornertob32(uint8_t corner) +{ + uint8_t val; + + val = (corner & 7) | ((corner & 96) >> 2); + + return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26); +} diff --git a/src/io_move_trans.h b/src/io_move_trans.h @@ -0,0 +1,87 @@ +_static uint8_t readmove(char); +_static uint8_t readmodifier(char); +_static uint8_t readtrans(const char *); +_static int writemoves(uint8_t *, int, char *); +_static void writetrans(uint8_t, char *); + +_static uint8_t +readmove(char c) +{ + switch (c) { + case 'U': + return _move_U; + case 'D': + return _move_D; + case 'R': + return _move_R; + case 'L': + return _move_L; + case 'F': + return _move_F; + case 'B': + return _move_B; + default: + return _error; + } +} + +_static uint8_t +readmodifier(char c) +{ + switch (c) { + case '1': /* Fallthrough */ + case '2': /* Fallthrough */ + case '3': + return c - '0' - 1; + case '\'': + return 2; + default: + return 0; + } +} + +_static uint8_t +readtrans(const char *buf) +{ + uint8_t t; + + for (t = 0; t < 48; t++) + if (!strncmp(buf, transstr[t], 11)) + return t; + + DBG_LOG("readtrans error\n"); + return _error; +} + +_static int +writemoves(uint8_t *m, int n, char *buf) +{ + int i; + size_t len; + const char *s; + char *b; + + for (i = 0, b = buf; i < n; i++, b++) { + s = movestr[m[i]]; + len = strlen(s); + memcpy(b, s, len); + b += len; + *b = ' '; + } + + if (b != buf) + b--; /* Remove last space */ + *b = '\0'; + + return b - buf; +} + +_static void +writetrans(uint8_t t, char *buf) +{ + if (t >= 48) + memcpy(buf, "error trans", 11); + else + memcpy(buf, transstr[t], 11); + buf[11] = '\0'; +}