commit c5c5017a335208881e27fc8f72c1d0145a04622a
parent 28ad019d62583b7e89b4e76922aa73857d5876eb
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Sun, 9 Jun 2024 12:43:49 +0200
Remvoed cube_fast_t and more. More cleaning up to do.
Diffstat:
32 files changed, 1663 insertions(+), 1677 deletions(-)
diff --git a/TODO.txt b/TODO.txt
@@ -1,25 +1,19 @@
Refactoring: remove cube_fast_t and add b32 format
- x added b32 converter by piece (not tested, will be tested automatically)
- x added piece functions (e.g. corner(cube, i))
- (would be more efficient to just convert the whole thing to arrays...)
- - replace all usages of cube_t with cube_fast_t and piece functions
- (this is mainly in cube_routines)
- (fix tests in tandem with main code)
- cubetofast fasttocube
- zero and solved
- solvedcube(void)
- [cube.h] isconsistent, issolvable, issolved, equal, iserror
- [cube.h] compose, inverse
- [cube.h] applymoves, applytrans
- [cube.h] readcube writecube
- [cube.h] solve
- - add b32 i/o format as default
- - remove cube_t type
- - rename cube_fast_t to cube_t
+ - 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
- 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?)
+
Solver
- write a solver (how many tricks? some, but not all are needed)
diff --git a/src/constant_cubes.h b/src/constant_cubes.h
@@ -0,0 +1,229 @@
+#define _move_cube_U static_cube( \
+ 5, 4, 2, 3, 0, 1, 6, 7, 4, 5, 2, 3, 1, 0, 6, 7, 8, 9, 10, 11)
+#define _move_cube_U2 static_cube( \
+ 1, 0, 2, 3, 5, 4, 6, 7, 1, 0, 2, 3, 5, 4, 6, 7, 8, 9, 10, 11)
+#define _move_cube_U3 static_cube( \
+ 4, 5, 2, 3, 1, 0, 6, 7, 5, 4, 2, 3, 0, 1, 6, 7, 8, 9, 10, 11)
+#define _move_cube_D static_cube( \
+ 0, 1, 7, 6, 4, 5, 2, 3, 0, 1, 7, 6, 4, 5, 2, 3, 8, 9, 10, 11)
+#define _move_cube_D2 static_cube( \
+ 0, 1, 3, 2, 4, 5, 7, 6, 0, 1, 3, 2, 4, 5, 7, 6, 8, 9, 10, 11)
+#define _move_cube_D3 static_cube( \
+ 0, 1, 6, 7, 4, 5, 3, 2, 0, 1, 6, 7, 4, 5, 3, 2, 8, 9, 10, 11)
+#define _move_cube_R static_cube( \
+ 70, 1, 2, 69, 4, 32, 35, 7, 0, 1, 2, 3, 8, 5, 6, 11, 7, 9, 10, 4)
+#define _move_cube_R2 static_cube( \
+ 3, 1, 2, 0, 4, 6, 5, 7, 0, 1, 2, 3, 7, 5, 6, 4, 11, 9, 10, 8)
+#define _move_cube_R3 static_cube( \
+ 69, 1, 2, 70, 4, 35, 32, 7, 0, 1, 2, 3, 11, 5, 6, 8, 4, 9, 10, 7)
+#define _move_cube_L static_cube( \
+ 0, 71, 68, 3, 33, 5, 6, 34, 0, 1, 2, 3, 4, 10, 9, 7, 8, 5, 6, 11)
+#define _move_cube_L2 static_cube( \
+ 0, 2, 1, 3, 7, 5, 6, 4, 0, 1, 2, 3, 4, 6, 5, 7, 8, 10, 9, 11)
+#define _move_cube_L3 static_cube( \
+ 0, 68, 71, 3, 34, 5, 6, 33, 0, 1, 2, 3, 4, 9, 10, 7, 8, 6, 5, 11)
+#define _move_cube_F static_cube( \
+ 36, 1, 38, 3, 66, 5, 64, 7, 25, 1, 2, 24, 4, 5, 6, 7, 16, 19, 10, 11)
+#define _move_cube_F2 static_cube( \
+ 2, 1, 0, 3, 6, 5, 4, 7, 3, 1, 2, 0, 4, 5, 6, 7, 9, 8, 10, 11)
+#define _move_cube_F3 static_cube( \
+ 38, 1, 36, 3, 64, 5, 66, 7, 24, 1, 2, 25, 4, 5, 6, 7, 19, 16, 10, 11)
+#define _move_cube_B static_cube( \
+ 0, 37, 2, 39, 4, 67, 6, 65, 0, 27, 26, 3, 4, 5, 6, 7, 8, 9, 17, 18)
+#define _move_cube_B2 static_cube( \
+ 0, 3, 2, 1, 4, 7, 6, 5, 0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 11, 10)
+#define _move_cube_B3 static_cube( \
+ 0, 39, 2, 37, 4, 65, 6, 67, 0, 26, 27, 3, 4, 5, 6, 7, 8, 9, 18, 17)
+
+#define _trans_cube_UFr static_cube( \
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
+#define _trans_cube_UFr_inverse static_cube( \
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
+#define _trans_cube_ULr static_cube( \
+ 4, 5, 7, 6, 1, 0, 2, 3, 5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24)
+#define _trans_cube_ULr_inverse static_cube( \
+ 5, 4, 6, 7, 0, 1, 3, 2, 4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26)
+#define _trans_cube_UBr static_cube( \
+ 1, 0, 3, 2, 5, 4, 7, 6, 1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9)
+#define _trans_cube_UBr_inverse static_cube( \
+ 1, 0, 3, 2, 5, 4, 7, 6, 1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9)
+#define _trans_cube_URr static_cube( \
+ 5, 4, 6, 7, 0, 1, 3, 2, 4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26)
+#define _trans_cube_URr_inverse static_cube( \
+ 4, 5, 7, 6, 1, 0, 2, 3, 5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24)
+#define _trans_cube_DFr static_cube( \
+ 2, 3, 0, 1, 6, 7, 4, 5, 3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10)
+#define _trans_cube_DFr_inverse static_cube( \
+ 2, 3, 0, 1, 6, 7, 4, 5, 3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10)
+#define _trans_cube_DLr static_cube( \
+ 7, 6, 4, 5, 2, 3, 1, 0, 6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27)
+#define _trans_cube_DLr_inverse static_cube( \
+ 7, 6, 4, 5, 2, 3, 1, 0, 6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27)
+#define _trans_cube_DBr static_cube( \
+ 3, 2, 1, 0, 7, 6, 5, 4, 2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8)
+#define _trans_cube_DBr_inverse static_cube( \
+ 3, 2, 1, 0, 7, 6, 5, 4, 2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8)
+#define _trans_cube_DRr static_cube( \
+ 6, 7, 5, 4, 3, 2, 0, 1, 7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25)
+#define _trans_cube_DRr_inverse static_cube( \
+ 6, 7, 5, 4, 3, 2, 0, 1, 7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25)
+#define _trans_cube_RUr static_cube( \
+ 64, 67, 65, 66, 37, 38, 36, 39, 20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3)
+#define _trans_cube_RUr_inverse static_cube( \
+ 32, 34, 35, 33, 70, 68, 69, 71, 8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21)
+#define _trans_cube_RFr static_cube( \
+ 38, 37, 36, 39, 64, 67, 66, 65, 24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18)
+#define _trans_cube_RFr_inverse static_cube( \
+ 36, 39, 38, 37, 66, 65, 64, 67, 25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17)
+#define _trans_cube_RDr static_cube( \
+ 67, 64, 66, 65, 38, 37, 39, 36, 23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1)
+#define _trans_cube_RDr_inverse static_cube( \
+ 33, 35, 34, 32, 71, 69, 68, 70, 10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20)
+#define _trans_cube_RBr static_cube( \
+ 37, 38, 39, 36, 67, 64, 65, 66, 27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16)
+#define _trans_cube_RBr_inverse static_cube( \
+ 37, 38, 39, 36, 67, 64, 65, 66, 27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16)
+#define _trans_cube_LUr static_cube( \
+ 65, 66, 64, 67, 36, 39, 37, 38, 21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2)
+#define _trans_cube_LUr_inverse static_cube( \
+ 34, 32, 33, 35, 68, 70, 71, 69, 9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23)
+#define _trans_cube_LFr static_cube( \
+ 36, 39, 38, 37, 66, 65, 64, 67, 25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17)
+#define _trans_cube_LFr_inverse static_cube( \
+ 38, 37, 36, 39, 64, 67, 66, 65, 24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18)
+#define _trans_cube_LDr static_cube( \
+ 66, 65, 67, 64, 39, 36, 38, 37, 22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0)
+#define _trans_cube_LDr_inverse static_cube( \
+ 35, 33, 32, 34, 69, 71, 70, 68, 11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22)
+#define _trans_cube_LBr static_cube( \
+ 39, 36, 37, 38, 65, 66, 67, 64, 26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19)
+#define _trans_cube_LBr_inverse static_cube( \
+ 39, 36, 37, 38, 65, 66, 67, 64, 26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19)
+#define _trans_cube_FUr static_cube( \
+ 68, 70, 69, 71, 32, 34, 33, 35, 16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6)
+#define _trans_cube_FUr_inverse static_cube( \
+ 68, 70, 69, 71, 32, 34, 33, 35, 16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6)
+#define _trans_cube_FRr static_cube( \
+ 32, 34, 35, 33, 70, 68, 69, 71, 8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21)
+#define _trans_cube_FRr_inverse static_cube( \
+ 64, 67, 65, 66, 37, 38, 36, 39, 20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3)
+#define _trans_cube_FDr static_cube( \
+ 70, 68, 71, 69, 34, 32, 35, 33, 19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4)
+#define _trans_cube_FDr_inverse static_cube( \
+ 69, 71, 68, 70, 33, 35, 32, 34, 17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7)
+#define _trans_cube_FLr static_cube( \
+ 34, 32, 33, 35, 68, 70, 71, 69, 9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23)
+#define _trans_cube_FLr_inverse static_cube( \
+ 65, 66, 64, 67, 36, 39, 37, 38, 21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2)
+#define _trans_cube_BUr static_cube( \
+ 69, 71, 68, 70, 33, 35, 32, 34, 17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7)
+#define _trans_cube_BUr_inverse static_cube( \
+ 70, 68, 71, 69, 34, 32, 35, 33, 19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4)
+#define _trans_cube_BRr static_cube( \
+ 35, 33, 32, 34, 69, 71, 70, 68, 11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22)
+#define _trans_cube_BRr_inverse static_cube( \
+ 66, 65, 67, 64, 39, 36, 38, 37, 22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0)
+#define _trans_cube_BDr static_cube( \
+ 71, 69, 70, 68, 35, 33, 34, 32, 18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5)
+#define _trans_cube_BDr_inverse static_cube( \
+ 71, 69, 70, 68, 35, 33, 34, 32, 18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5)
+#define _trans_cube_BLr static_cube( \
+ 33, 35, 34, 32, 71, 69, 68, 70, 10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20)
+#define _trans_cube_BLr_inverse static_cube( \
+ 67, 64, 66, 65, 38, 37, 39, 36, 23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1)
+#define _trans_cube_UFm static_cube( \
+ 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10)
+#define _trans_cube_UFm_inverse static_cube( \
+ 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10)
+#define _trans_cube_ULm static_cube( \
+ 0, 1, 3, 2, 5, 4, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25)
+#define _trans_cube_ULm_inverse static_cube( \
+ 0, 1, 3, 2, 5, 4, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25)
+#define _trans_cube_UBm static_cube( \
+ 5, 4, 7, 6, 1, 0, 3, 2, 1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8)
+#define _trans_cube_UBm_inverse static_cube( \
+ 5, 4, 7, 6, 1, 0, 3, 2, 1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8)
+#define _trans_cube_URm static_cube( \
+ 1, 0, 2, 3, 4, 5, 7, 6, 5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27)
+#define _trans_cube_URm_inverse static_cube( \
+ 1, 0, 2, 3, 4, 5, 7, 6, 5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27)
+#define _trans_cube_DFm static_cube( \
+ 6, 7, 4, 5, 2, 3, 0, 1, 3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11)
+#define _trans_cube_DFm_inverse static_cube( \
+ 6, 7, 4, 5, 2, 3, 0, 1, 3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11)
+#define _trans_cube_DLm static_cube( \
+ 3, 2, 0, 1, 6, 7, 5, 4, 7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26)
+#define _trans_cube_DLm_inverse static_cube( \
+ 2, 3, 1, 0, 7, 6, 4, 5, 6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24)
+#define _trans_cube_DBm static_cube( \
+ 7, 6, 5, 4, 3, 2, 1, 0, 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9)
+#define _trans_cube_DBm_inverse static_cube( \
+ 7, 6, 5, 4, 3, 2, 1, 0, 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9)
+#define _trans_cube_DRm static_cube( \
+ 2, 3, 1, 0, 7, 6, 4, 5, 6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24)
+#define _trans_cube_DRm_inverse static_cube( \
+ 3, 2, 0, 1, 6, 7, 5, 4, 7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26)
+#define _trans_cube_RUm static_cube( \
+ 68, 71, 69, 70, 33, 34, 32, 35, 21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3)
+#define _trans_cube_RUm_inverse static_cube( \
+ 70, 68, 69, 71, 32, 34, 35, 33, 8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22)
+#define _trans_cube_RFm static_cube( \
+ 34, 33, 32, 35, 68, 71, 70, 69, 25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18)
+#define _trans_cube_RFm_inverse static_cube( \
+ 66, 65, 64, 67, 36, 39, 38, 37, 25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18)
+#define _trans_cube_RDm static_cube( \
+ 71, 68, 70, 69, 34, 33, 35, 32, 22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1)
+#define _trans_cube_RDm_inverse static_cube( \
+ 71, 69, 68, 70, 33, 35, 34, 32, 10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23)
+#define _trans_cube_RBm static_cube( \
+ 33, 34, 35, 32, 71, 68, 69, 70, 26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16)
+#define _trans_cube_RBm_inverse static_cube( \
+ 67, 64, 65, 66, 37, 38, 39, 36, 27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19)
+#define _trans_cube_LUm static_cube( \
+ 69, 70, 68, 71, 32, 35, 33, 34, 20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2)
+#define _trans_cube_LUm_inverse static_cube( \
+ 68, 70, 71, 69, 34, 32, 33, 35, 9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20)
+#define _trans_cube_LFm static_cube( \
+ 32, 35, 34, 33, 70, 69, 68, 71, 24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17)
+#define _trans_cube_LFm_inverse static_cube( \
+ 64, 67, 66, 65, 38, 37, 36, 39, 24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17)
+#define _trans_cube_LDm static_cube( \
+ 70, 69, 71, 68, 35, 32, 34, 33, 23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0)
+#define _trans_cube_LDm_inverse static_cube( \
+ 69, 71, 70, 68, 35, 33, 32, 34, 11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21)
+#define _trans_cube_LBm static_cube( \
+ 35, 32, 33, 34, 69, 70, 71, 68, 27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19)
+#define _trans_cube_LBm_inverse static_cube( \
+ 65, 66, 67, 64, 39, 36, 37, 38, 26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16)
+#define _trans_cube_FUm static_cube( \
+ 64, 66, 65, 67, 36, 38, 37, 39, 16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7)
+#define _trans_cube_FUm_inverse static_cube( \
+ 32, 34, 33, 35, 68, 70, 69, 71, 16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7)
+#define _trans_cube_FRm static_cube( \
+ 36, 38, 39, 37, 66, 64, 65, 67, 9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20)
+#define _trans_cube_FRm_inverse static_cube( \
+ 37, 38, 36, 39, 64, 67, 65, 66, 20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2)
+#define _trans_cube_FDm static_cube( \
+ 66, 64, 67, 65, 38, 36, 39, 37, 19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5)
+#define _trans_cube_FDm_inverse static_cube( \
+ 33, 35, 32, 34, 69, 71, 68, 70, 17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6)
+#define _trans_cube_FLm static_cube( \
+ 38, 36, 37, 39, 64, 66, 67, 65, 8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22)
+#define _trans_cube_FLm_inverse static_cube( \
+ 36, 39, 37, 38, 65, 66, 64, 67, 21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3)
+#define _trans_cube_BUm static_cube( \
+ 65, 67, 64, 66, 37, 39, 36, 38, 17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6)
+#define _trans_cube_BUm_inverse static_cube( \
+ 34, 32, 35, 33, 70, 68, 71, 69, 19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5)
+#define _trans_cube_BRm static_cube( \
+ 39, 37, 36, 38, 65, 67, 66, 64, 10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23)
+#define _trans_cube_BRm_inverse static_cube( \
+ 39, 36, 38, 37, 66, 65, 67, 64, 22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1)
+#define _trans_cube_BDm static_cube( \
+ 67, 65, 66, 64, 39, 37, 38, 36, 18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4)
+#define _trans_cube_BDm_inverse static_cube( \
+ 35, 33, 34, 32, 71, 69, 70, 68, 18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4)
+#define _trans_cube_BLm static_cube( \
+ 37, 39, 38, 36, 67, 65, 64, 66, 11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21)
+#define _trans_cube_BLm_inverse static_cube( \
+ 38, 37, 39, 36, 67, 64, 66, 65, 23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0)
diff --git a/src/constants.h b/src/constants.h
@@ -130,247 +130,6 @@ _static int64_t binomial[12][12] = {
#define _eflip UINT8_C(0x10)
#define _error UINT8_C(0xFF)
-_static cube_t zero = { .corner = {0}, .edge = {0} };
-_static cube_t solved = {
- .corner = {0, 1, 2, 3, 4, 5, 6, 7},
- .edge = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
-};
-
-#define zero_fast fastcube( \
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-#define solved_fast fastcube( \
- 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
-
-#define _move_cube_U fastcube( \
- 5, 4, 2, 3, 0, 1, 6, 7, 4, 5, 2, 3, 1, 0, 6, 7, 8, 9, 10, 11)
-#define _move_cube_U2 fastcube( \
- 1, 0, 2, 3, 5, 4, 6, 7, 1, 0, 2, 3, 5, 4, 6, 7, 8, 9, 10, 11)
-#define _move_cube_U3 fastcube( \
- 4, 5, 2, 3, 1, 0, 6, 7, 5, 4, 2, 3, 0, 1, 6, 7, 8, 9, 10, 11)
-#define _move_cube_D fastcube( \
- 0, 1, 7, 6, 4, 5, 2, 3, 0, 1, 7, 6, 4, 5, 2, 3, 8, 9, 10, 11)
-#define _move_cube_D2 fastcube( \
- 0, 1, 3, 2, 4, 5, 7, 6, 0, 1, 3, 2, 4, 5, 7, 6, 8, 9, 10, 11)
-#define _move_cube_D3 fastcube( \
- 0, 1, 6, 7, 4, 5, 3, 2, 0, 1, 6, 7, 4, 5, 3, 2, 8, 9, 10, 11)
-#define _move_cube_R fastcube( \
- 70, 1, 2, 69, 4, 32, 35, 7, 0, 1, 2, 3, 8, 5, 6, 11, 7, 9, 10, 4)
-#define _move_cube_R2 fastcube( \
- 3, 1, 2, 0, 4, 6, 5, 7, 0, 1, 2, 3, 7, 5, 6, 4, 11, 9, 10, 8)
-#define _move_cube_R3 fastcube( \
- 69, 1, 2, 70, 4, 35, 32, 7, 0, 1, 2, 3, 11, 5, 6, 8, 4, 9, 10, 7)
-#define _move_cube_L fastcube( \
- 0, 71, 68, 3, 33, 5, 6, 34, 0, 1, 2, 3, 4, 10, 9, 7, 8, 5, 6, 11)
-#define _move_cube_L2 fastcube( \
- 0, 2, 1, 3, 7, 5, 6, 4, 0, 1, 2, 3, 4, 6, 5, 7, 8, 10, 9, 11)
-#define _move_cube_L3 fastcube( \
- 0, 68, 71, 3, 34, 5, 6, 33, 0, 1, 2, 3, 4, 9, 10, 7, 8, 6, 5, 11)
-#define _move_cube_F fastcube( \
- 36, 1, 38, 3, 66, 5, 64, 7, 25, 1, 2, 24, 4, 5, 6, 7, 16, 19, 10, 11)
-#define _move_cube_F2 fastcube( \
- 2, 1, 0, 3, 6, 5, 4, 7, 3, 1, 2, 0, 4, 5, 6, 7, 9, 8, 10, 11)
-#define _move_cube_F3 fastcube( \
- 38, 1, 36, 3, 64, 5, 66, 7, 24, 1, 2, 25, 4, 5, 6, 7, 19, 16, 10, 11)
-#define _move_cube_B fastcube( \
- 0, 37, 2, 39, 4, 67, 6, 65, 0, 27, 26, 3, 4, 5, 6, 7, 8, 9, 17, 18)
-#define _move_cube_B2 fastcube( \
- 0, 3, 2, 1, 4, 7, 6, 5, 0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 11, 10)
-#define _move_cube_B3 fastcube( \
- 0, 39, 2, 37, 4, 65, 6, 67, 0, 26, 27, 3, 4, 5, 6, 7, 8, 9, 18, 17)
-
-#define _trans_cube_UFr fastcube( \
- 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
-#define _trans_cube_UFr_inverse fastcube( \
- 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
-#define _trans_cube_ULr fastcube( \
- 4, 5, 7, 6, 1, 0, 2, 3, 5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24)
-#define _trans_cube_ULr_inverse fastcube( \
- 5, 4, 6, 7, 0, 1, 3, 2, 4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26)
-#define _trans_cube_UBr fastcube( \
- 1, 0, 3, 2, 5, 4, 7, 6, 1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9)
-#define _trans_cube_UBr_inverse fastcube( \
- 1, 0, 3, 2, 5, 4, 7, 6, 1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9)
-#define _trans_cube_URr fastcube( \
- 5, 4, 6, 7, 0, 1, 3, 2, 4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26)
-#define _trans_cube_URr_inverse fastcube( \
- 4, 5, 7, 6, 1, 0, 2, 3, 5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24)
-#define _trans_cube_DFr fastcube( \
- 2, 3, 0, 1, 6, 7, 4, 5, 3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10)
-#define _trans_cube_DFr_inverse fastcube( \
- 2, 3, 0, 1, 6, 7, 4, 5, 3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10)
-#define _trans_cube_DLr fastcube( \
- 7, 6, 4, 5, 2, 3, 1, 0, 6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27)
-#define _trans_cube_DLr_inverse fastcube( \
- 7, 6, 4, 5, 2, 3, 1, 0, 6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27)
-#define _trans_cube_DBr fastcube( \
- 3, 2, 1, 0, 7, 6, 5, 4, 2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8)
-#define _trans_cube_DBr_inverse fastcube( \
- 3, 2, 1, 0, 7, 6, 5, 4, 2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8)
-#define _trans_cube_DRr fastcube( \
- 6, 7, 5, 4, 3, 2, 0, 1, 7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25)
-#define _trans_cube_DRr_inverse fastcube( \
- 6, 7, 5, 4, 3, 2, 0, 1, 7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25)
-#define _trans_cube_RUr fastcube( \
- 64, 67, 65, 66, 37, 38, 36, 39, 20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3)
-#define _trans_cube_RUr_inverse fastcube( \
- 32, 34, 35, 33, 70, 68, 69, 71, 8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21)
-#define _trans_cube_RFr fastcube( \
- 38, 37, 36, 39, 64, 67, 66, 65, 24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18)
-#define _trans_cube_RFr_inverse fastcube( \
- 36, 39, 38, 37, 66, 65, 64, 67, 25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17)
-#define _trans_cube_RDr fastcube( \
- 67, 64, 66, 65, 38, 37, 39, 36, 23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1)
-#define _trans_cube_RDr_inverse fastcube( \
- 33, 35, 34, 32, 71, 69, 68, 70, 10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20)
-#define _trans_cube_RBr fastcube( \
- 37, 38, 39, 36, 67, 64, 65, 66, 27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16)
-#define _trans_cube_RBr_inverse fastcube( \
- 37, 38, 39, 36, 67, 64, 65, 66, 27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16)
-#define _trans_cube_LUr fastcube( \
- 65, 66, 64, 67, 36, 39, 37, 38, 21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2)
-#define _trans_cube_LUr_inverse fastcube( \
- 34, 32, 33, 35, 68, 70, 71, 69, 9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23)
-#define _trans_cube_LFr fastcube( \
- 36, 39, 38, 37, 66, 65, 64, 67, 25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17)
-#define _trans_cube_LFr_inverse fastcube( \
- 38, 37, 36, 39, 64, 67, 66, 65, 24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18)
-#define _trans_cube_LDr fastcube( \
- 66, 65, 67, 64, 39, 36, 38, 37, 22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0)
-#define _trans_cube_LDr_inverse fastcube( \
- 35, 33, 32, 34, 69, 71, 70, 68, 11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22)
-#define _trans_cube_LBr fastcube( \
- 39, 36, 37, 38, 65, 66, 67, 64, 26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19)
-#define _trans_cube_LBr_inverse fastcube( \
- 39, 36, 37, 38, 65, 66, 67, 64, 26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19)
-#define _trans_cube_FUr fastcube( \
- 68, 70, 69, 71, 32, 34, 33, 35, 16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6)
-#define _trans_cube_FUr_inverse fastcube( \
- 68, 70, 69, 71, 32, 34, 33, 35, 16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6)
-#define _trans_cube_FRr fastcube( \
- 32, 34, 35, 33, 70, 68, 69, 71, 8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21)
-#define _trans_cube_FRr_inverse fastcube( \
- 64, 67, 65, 66, 37, 38, 36, 39, 20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3)
-#define _trans_cube_FDr fastcube( \
- 70, 68, 71, 69, 34, 32, 35, 33, 19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4)
-#define _trans_cube_FDr_inverse fastcube( \
- 69, 71, 68, 70, 33, 35, 32, 34, 17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7)
-#define _trans_cube_FLr fastcube( \
- 34, 32, 33, 35, 68, 70, 71, 69, 9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23)
-#define _trans_cube_FLr_inverse fastcube( \
- 65, 66, 64, 67, 36, 39, 37, 38, 21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2)
-#define _trans_cube_BUr fastcube( \
- 69, 71, 68, 70, 33, 35, 32, 34, 17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7)
-#define _trans_cube_BUr_inverse fastcube( \
- 70, 68, 71, 69, 34, 32, 35, 33, 19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4)
-#define _trans_cube_BRr fastcube( \
- 35, 33, 32, 34, 69, 71, 70, 68, 11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22)
-#define _trans_cube_BRr_inverse fastcube( \
- 66, 65, 67, 64, 39, 36, 38, 37, 22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0)
-#define _trans_cube_BDr fastcube( \
- 71, 69, 70, 68, 35, 33, 34, 32, 18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5)
-#define _trans_cube_BDr_inverse fastcube( \
- 71, 69, 70, 68, 35, 33, 34, 32, 18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5)
-#define _trans_cube_BLr fastcube( \
- 33, 35, 34, 32, 71, 69, 68, 70, 10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20)
-#define _trans_cube_BLr_inverse fastcube( \
- 67, 64, 66, 65, 38, 37, 39, 36, 23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1)
-#define _trans_cube_UFm fastcube( \
- 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10)
-#define _trans_cube_UFm_inverse fastcube( \
- 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10)
-#define _trans_cube_ULm fastcube( \
- 0, 1, 3, 2, 5, 4, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25)
-#define _trans_cube_ULm_inverse fastcube( \
- 0, 1, 3, 2, 5, 4, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25)
-#define _trans_cube_UBm fastcube( \
- 5, 4, 7, 6, 1, 0, 3, 2, 1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8)
-#define _trans_cube_UBm_inverse fastcube( \
- 5, 4, 7, 6, 1, 0, 3, 2, 1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8)
-#define _trans_cube_URm fastcube( \
- 1, 0, 2, 3, 4, 5, 7, 6, 5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27)
-#define _trans_cube_URm_inverse fastcube( \
- 1, 0, 2, 3, 4, 5, 7, 6, 5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27)
-#define _trans_cube_DFm fastcube( \
- 6, 7, 4, 5, 2, 3, 0, 1, 3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11)
-#define _trans_cube_DFm_inverse fastcube( \
- 6, 7, 4, 5, 2, 3, 0, 1, 3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11)
-#define _trans_cube_DLm fastcube( \
- 3, 2, 0, 1, 6, 7, 5, 4, 7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26)
-#define _trans_cube_DLm_inverse fastcube( \
- 2, 3, 1, 0, 7, 6, 4, 5, 6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24)
-#define _trans_cube_DBm fastcube( \
- 7, 6, 5, 4, 3, 2, 1, 0, 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9)
-#define _trans_cube_DBm_inverse fastcube( \
- 7, 6, 5, 4, 3, 2, 1, 0, 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9)
-#define _trans_cube_DRm fastcube( \
- 2, 3, 1, 0, 7, 6, 4, 5, 6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24)
-#define _trans_cube_DRm_inverse fastcube( \
- 3, 2, 0, 1, 6, 7, 5, 4, 7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26)
-#define _trans_cube_RUm fastcube( \
- 68, 71, 69, 70, 33, 34, 32, 35, 21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3)
-#define _trans_cube_RUm_inverse fastcube( \
- 70, 68, 69, 71, 32, 34, 35, 33, 8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22)
-#define _trans_cube_RFm fastcube( \
- 34, 33, 32, 35, 68, 71, 70, 69, 25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18)
-#define _trans_cube_RFm_inverse fastcube( \
- 66, 65, 64, 67, 36, 39, 38, 37, 25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18)
-#define _trans_cube_RDm fastcube( \
- 71, 68, 70, 69, 34, 33, 35, 32, 22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1)
-#define _trans_cube_RDm_inverse fastcube( \
- 71, 69, 68, 70, 33, 35, 34, 32, 10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23)
-#define _trans_cube_RBm fastcube( \
- 33, 34, 35, 32, 71, 68, 69, 70, 26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16)
-#define _trans_cube_RBm_inverse fastcube( \
- 67, 64, 65, 66, 37, 38, 39, 36, 27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19)
-#define _trans_cube_LUm fastcube( \
- 69, 70, 68, 71, 32, 35, 33, 34, 20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2)
-#define _trans_cube_LUm_inverse fastcube( \
- 68, 70, 71, 69, 34, 32, 33, 35, 9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20)
-#define _trans_cube_LFm fastcube( \
- 32, 35, 34, 33, 70, 69, 68, 71, 24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17)
-#define _trans_cube_LFm_inverse fastcube( \
- 64, 67, 66, 65, 38, 37, 36, 39, 24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17)
-#define _trans_cube_LDm fastcube( \
- 70, 69, 71, 68, 35, 32, 34, 33, 23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0)
-#define _trans_cube_LDm_inverse fastcube( \
- 69, 71, 70, 68, 35, 33, 32, 34, 11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21)
-#define _trans_cube_LBm fastcube( \
- 35, 32, 33, 34, 69, 70, 71, 68, 27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19)
-#define _trans_cube_LBm_inverse fastcube( \
- 65, 66, 67, 64, 39, 36, 37, 38, 26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16)
-#define _trans_cube_FUm fastcube( \
- 64, 66, 65, 67, 36, 38, 37, 39, 16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7)
-#define _trans_cube_FUm_inverse fastcube( \
- 32, 34, 33, 35, 68, 70, 69, 71, 16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7)
-#define _trans_cube_FRm fastcube( \
- 36, 38, 39, 37, 66, 64, 65, 67, 9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20)
-#define _trans_cube_FRm_inverse fastcube( \
- 37, 38, 36, 39, 64, 67, 65, 66, 20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2)
-#define _trans_cube_FDm fastcube( \
- 66, 64, 67, 65, 38, 36, 39, 37, 19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5)
-#define _trans_cube_FDm_inverse fastcube( \
- 33, 35, 32, 34, 69, 71, 68, 70, 17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6)
-#define _trans_cube_FLm fastcube( \
- 38, 36, 37, 39, 64, 66, 67, 65, 8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22)
-#define _trans_cube_FLm_inverse fastcube( \
- 36, 39, 37, 38, 65, 66, 64, 67, 21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3)
-#define _trans_cube_BUm fastcube( \
- 65, 67, 64, 66, 37, 39, 36, 38, 17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6)
-#define _trans_cube_BUm_inverse fastcube( \
- 34, 32, 35, 33, 70, 68, 71, 69, 19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5)
-#define _trans_cube_BRm fastcube( \
- 39, 37, 36, 38, 65, 67, 66, 64, 10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23)
-#define _trans_cube_BRm_inverse fastcube( \
- 39, 36, 38, 37, 66, 65, 67, 64, 22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1)
-#define _trans_cube_BDm fastcube( \
- 67, 65, 66, 64, 39, 37, 38, 36, 18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4)
-#define _trans_cube_BDm_inverse fastcube( \
- 35, 33, 34, 32, 71, 69, 70, 68, 18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4)
-#define _trans_cube_BLm fastcube( \
- 37, 39, 38, 36, 67, 65, 64, 66, 11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21)
-#define _trans_cube_BLm_inverse fastcube( \
- 38, 37, 39, 36, 67, 64, 66, 65, 23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0)
-
_static const char *cornerstr[] = {
[_c_ufr] = "UFR",
[_c_ubl] = "UBL",
diff --git a/src/cube.c b/src/cube.c
@@ -19,7 +19,6 @@
#define DBG_ASSERT(condition, retval, ...)
#endif
-#include "cube.h"
#include "constants.h"
#if defined(CUBE_AVX2)
@@ -32,8 +31,17 @@
#include "cube_portable.h"
#endif
-#include "cube_routines.h"
-#include "cube_transform.h" /* TODO: merge with cube_routines? */
+#include "constant_cubes.h"
+#include "cube_generic.h"
+
+/* TODO: work in progress */
+#if 0
+#include "constant_cubes_transform.h"
+#include "cube_transform.h"
+#else
+#include "cube_transform_with_switch.h"
+#endif
+
#include "moves.h"
#include "solve_h48.h"
#include "solve_generic.h"
diff --git a/src/cube.h b/src/cube.h
@@ -25,23 +25,6 @@ you operate on the cube only via the functions provided below, you don't
need to worry about this.
******************************************************************************/
-typedef struct {
- uint8_t corner[8];
- uint8_t edge[12];
-} cube_t;
-
-/* Returns a copy of the solved cube */
-cube_t solvedcube(void);
-
-/* Basic checks on the cube */
-bool isconsistent(cube_t);
-bool issolvable(cube_t);
-bool issolved(cube_t);
-bool equal(cube_t, cube_t);
-
-/* All functions can return an error value, use iserror() to check this */
-bool iserror(cube_t);
-
/* Apply the second cube on the first as a move sequence */
cube_t compose(cube_t, cube_t);
diff --git a/src/cube_avx2.h b/src/cube_avx2.h
@@ -1,4 +1,4 @@
-typedef __m256i cube_fast_t;
+typedef __m256i cube_t;
#define _co2_avx2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x6060606060606060))
#define _cocw_avx2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x2020202020202020))
@@ -8,117 +8,47 @@ typedef __m256i cube_fast_t;
#define _eo_avx2 \
_mm256_set_epi64x(INT64_C(0x10101010), INT64_C(0x1010101010101010), 0, 0)
-_static_inline cube_fast_t fastcube(
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
-);
-_static uint8_t corner(cube_fast_t, int);
-_static uint8_t edge(cube_fast_t, int);
-_static cube_fast_t cubetofast(cube_t);
-_static cube_t fasttocube(cube_fast_t);
-_static_inline bool equal_fast(cube_fast_t, cube_fast_t);
-_static_inline bool issolved_fast(cube_fast_t);
-_static_inline cube_fast_t invertco_fast(cube_fast_t);
-_static_inline cube_fast_t compose_epcpeo(cube_fast_t, cube_fast_t);
-_static_inline cube_fast_t compose_fast_edges(cube_fast_t, cube_fast_t);
-_static_inline cube_fast_t compose_fast_corners(cube_fast_t, cube_fast_t);
-_static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
-
-_static_inline int64_t coord_fast_co(cube_fast_t);
-_static_inline int64_t coord_fast_csep(cube_fast_t);
-_static_inline int64_t coord_fast_cocsep(cube_fast_t);
-_static_inline int64_t coord_fast_eo(cube_fast_t);
-_static_inline int64_t coord_fast_esep(cube_fast_t);
-
-_static_inline void copy_corners_fast(cube_fast_t *, cube_fast_t);
-_static_inline void copy_edges_fast(cube_fast_t *, cube_fast_t);
-_static_inline void set_eo_fast(cube_fast_t *, int64_t);
-_static_inline cube_fast_t invcoord_fast_esep(int64_t);
-
-_static_inline cube_fast_t
-fastcube(
- uint8_t c_ufr,
- uint8_t c_ubl,
- uint8_t c_dfl,
- uint8_t c_dbr,
- uint8_t c_ufl,
- uint8_t c_ubr,
- uint8_t c_dfr,
- uint8_t c_dbl,
-
- uint8_t e_uf,
- uint8_t e_ub,
- uint8_t e_db,
- uint8_t e_df,
- uint8_t e_ur,
- uint8_t e_ul,
- uint8_t e_dl,
- uint8_t e_dr,
- uint8_t e_fr,
- uint8_t e_fl,
- uint8_t e_bl,
- uint8_t e_br
-)
-{
- return _mm256_set_epi8(
- 0, 0, 0, 0, e_br, e_bl, e_fl, e_fr,
- e_dr, e_dl, e_ul, e_ur, e_df, e_db, e_ub, e_uf,
- 0, 0, 0, 0, 0, 0, 0, 0,
- c_dbl, c_dfr, c_ubr, c_ufl, c_dbr, c_dfl, c_ubl, c_ufr
- );
-}
-
-_static uint8_t
-corner(cube_fast_t c, int i)
-{
- uint8_t aux[32];
-
- DBG_ASSERT(i >= 0 && i < 8, 255, "Corner must be between 0 and 7\n");
- _mm256_storeu_si256((__m256i_u *)aux, c);
-
- return aux[i];
-}
-
-_static uint8_t
-edge(cube_fast_t c, int i)
+#define static_cube(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \
+ e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \
+ _mm256_set_epi8(0, 0, 0, 0, e_br, e_bl, e_fl, e_fr, \
+ e_dr, e_dl, e_ul, e_ur, e_df, e_db, e_ub, e_uf, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ c_dbl, c_dfr, c_ubr, c_ufl, c_dbr, c_dfl, c_ubl, c_ufr)
+#define zero _mm256_set_epi64x(0, 0, 0, 0)
+#define solved static_cube( \
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
+
+_static void pieces(cube_t *, uint8_t [static 8], uint8_t [static 12]);
+_static_inline bool equal(cube_t, cube_t);
+_static_inline cube_t invertco(cube_t);
+_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 int64_t coord_co(cube_t);
+_static_inline int64_t coord_csep(cube_t);
+_static_inline int64_t coord_cocsep(cube_t);
+_static_inline int64_t coord_eo(cube_t);
+_static_inline int64_t coord_esep(cube_t);
+
+_static_inline void copy_corners(cube_t *, cube_t);
+_static_inline void copy_edges(cube_t *, cube_t);
+_static_inline void set_eo(cube_t *, int64_t);
+_static_inline cube_t invcoord_esep(int64_t);
+
+_static void
+pieces(cube_t *cube, uint8_t c[static 8], uint8_t e[static 12])
{
uint8_t aux[32];
- DBG_ASSERT(i >= 0 && i < 12, 255, "Edge must be between 0 and 11\n");
- _mm256_storeu_si256((__m256i_u *)aux, c);
-
- return aux[i+16];
-}
-
-_static cube_fast_t
-cubetofast(cube_t a)
-{
- uint8_t aux[32];
-
- memset(aux, 0, 32);
- memcpy(aux, &a.corner, 8);
- memcpy(aux + 16, &a.edge, 12);
-
- return _mm256_loadu_si256((__m256i_u *)&aux);
-}
-
-_static cube_t
-fasttocube(cube_fast_t c)
-{
- cube_t a;
- uint8_t aux[32];
-
- _mm256_storeu_si256((__m256i_u *)aux, c);
- memcpy(&a.corner, aux, 8);
- memcpy(&a.edge, aux + 16, 12);
-
- return a;
+ _mm256_storeu_si256((__m256i_u *)aux, *cube);
+ memcpy(c, aux, 8);
+ memcpy(e, aux+16, 12);
}
_static_inline bool
-equal_fast(cube_fast_t c1, cube_fast_t c2)
+equal(cube_t c1, cube_t c2)
{
int32_t mask;
__m256i cmp;
@@ -129,16 +59,10 @@ equal_fast(cube_fast_t c1, cube_fast_t c2)
return mask == ~0;
}
-_static_inline bool
-issolved_fast(cube_fast_t cube)
-{
- return equal_fast(cube, solved_fast);
-}
-
-_static_inline cube_fast_t
-invertco_fast(cube_fast_t c)
+_static_inline cube_t
+invertco(cube_t c)
{
- cube_fast_t co, shleft, shright, summed, newco, cleanco, ret;
+ cube_t co, shleft, shright, summed, newco, cleanco, ret;
co = _mm256_and_si256(c, _co2_avx2);
shleft = _mm256_slli_epi32(co, 1);
@@ -151,10 +75,10 @@ invertco_fast(cube_fast_t c)
return ret;
}
-_static_inline cube_fast_t
-compose_epcpeo(cube_fast_t c1, cube_fast_t c2)
+_static_inline cube_t
+compose_epcpeo(cube_t c1, cube_t c2)
{
- cube_fast_t b, s, eo2;
+ cube_t b, s, eo2;
/* Permute and clean unused bits */
s = _mm256_shuffle_epi8(c1, c2);
@@ -171,27 +95,27 @@ compose_epcpeo(cube_fast_t c1, cube_fast_t c2)
return s;
}
-_static_inline cube_fast_t
-compose_fast_edges(cube_fast_t c1, cube_fast_t c2)
+_static_inline cube_t
+compose_edges(cube_t c1, cube_t c2)
{
return compose_epcpeo(c1, c2);
}
-_static_inline cube_fast_t
-compose_fast_corners(cube_fast_t c1, cube_fast_t c2)
+_static_inline cube_t
+compose_corners(cube_t c1, cube_t c2)
{
/*
* We do a full compose. Minor optimizations are possible, like
* saving one instruction by not doing EO, but it should not
* be significant.
*/
- return compose_fast(c1, c2);
+ return compose(c1, c2);
}
-_static_inline cube_fast_t
-compose_fast(cube_fast_t c1, cube_fast_t c2)
+_static_inline cube_t
+compose(cube_t c1, cube_t c2)
{
- cube_fast_t s, co1, co2, aux, auy1, auy2, auz1, auz2;
+ cube_t s, co1, co2, aux, auy1, auy2, auz1, auz2;
s = compose_epcpeo(c1, c2);
@@ -212,9 +136,9 @@ compose_fast(cube_fast_t c1, cube_fast_t c2)
}
_static_inline int64_t
-coord_fast_co(cube_fast_t c)
+coord_co(cube_t c)
{
- cube_fast_t co;
+ cube_t co;
int64_t mem[4], ret, i, p;
co = _mm256_and_si256(c, _co2_avx2);
@@ -228,9 +152,9 @@ coord_fast_co(cube_fast_t c)
}
_static_inline int64_t
-coord_fast_csep(cube_fast_t c)
+coord_csep(cube_t c)
{
- cube_fast_t cp, shifted;
+ cube_t cp, shifted;
int64_t mask;
cp = _mm256_and_si256(c, _cp_avx2);
@@ -241,15 +165,15 @@ coord_fast_csep(cube_fast_t c)
}
_static_inline int64_t
-coord_fast_cocsep(cube_fast_t c)
+coord_cocsep(cube_t c)
{
- return (coord_fast_co(c) << 7) + coord_fast_csep(c);
+ return (coord_co(c) << 7) + coord_csep(c);
}
_static_inline int64_t
-coord_fast_eo(cube_fast_t c)
+coord_eo(cube_t c)
{
- cube_fast_t eo, shifted;
+ cube_t eo, shifted;
int64_t mask;
eo = _mm256_and_si256(c, _eo_avx2);
@@ -260,9 +184,9 @@ coord_fast_eo(cube_fast_t c)
}
_static_inline int64_t
-coord_fast_esep(cube_fast_t c)
+coord_esep(cube_t c)
{
- cube_fast_t ep;
+ cube_t ep;
int64_t e, mem[4], i, j, jj, k, l, ret1, ret2, bit1, bit2, is1;
ep = _mm256_and_si256(c, _ep_avx2);
@@ -291,19 +215,19 @@ coord_fast_esep(cube_fast_t c)
}
_static_inline void
-copy_corners_fast(cube_fast_t *dest, cube_fast_t src)
+copy_corners(cube_t *dest, cube_t src)
{
*dest = _mm256_blend_epi32(*dest, src, 0x0F);
}
_static_inline void
-copy_edges_fast(cube_fast_t *dest, cube_fast_t src)
+copy_edges(cube_t *dest, cube_t src)
{
*dest = _mm256_blend_epi32(*dest, src, 0xF0);
}
_static_inline void
-set_eo_fast(cube_fast_t *cube, int64_t eo)
+set_eo(cube_t *cube, int64_t eo)
{
int64_t eo12, eotop, eobot;
__m256i veo;
@@ -327,10 +251,10 @@ set_eo_fast(cube_fast_t *cube, int64_t eo)
*cube = _mm256_or_si256(*cube, veo);
}
-_static_inline cube_fast_t
-invcoord_fast_esep(int64_t esep)
+_static_inline cube_t
+invcoord_esep(int64_t esep)
{
- cube_fast_t eee, ret;
+ cube_t eee, ret;
int64_t bit1, bit2, i, j, jj, k, l, s, v, w, is1, set1, set2;
uint8_t mem[32];
uint8_t slice[3] = {0};
@@ -356,9 +280,9 @@ invcoord_fast_esep(int64_t esep)
mem[i+16] = (slice[s]++) | (uint8_t)(s << 2);
}
- ret = cubetofast(solved);
+ ret = solved;
eee = _mm256_loadu_si256((__m256i_u *)&mem);
- copy_edges_fast(&ret, eee);
+ copy_edges(&ret, eee);
return ret;
}
diff --git a/src/cube_generic.h b/src/cube_generic.h
@@ -0,0 +1,702 @@
+#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 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)
+{
+ return solved;
+}
+
+bool
+isconsistent(cube_t cube)
+{
+ uint8_t i, p, e, piece, corner[8], edge[12];
+ bool found[12];
+
+ pieces(&cube, corner, edge);
+
+ for (i = 0; i < 12; i++)
+ found[i] = false;
+ for (i = 0; i < 12; i++) {
+ piece = edge[i];
+ p = piece & _pbits;
+ e = piece & _eobit;
+ if (p >= 12)
+ goto inconsistent_ep;
+ if (e != 0 && e != _eobit)
+ goto inconsistent_eo;
+ found[p] = true;
+ }
+ for (i = 0; i < 12; i++)
+ if (!found[i])
+ goto inconsistent_ep;
+
+ for (i = 0; i < 8; i++)
+ found[i] = false;
+ for (i = 0; i < 8; i++) {
+ piece = corner[i];
+ p = piece & _pbits;
+ e = piece & _cobits;
+ if (p >= 8)
+ goto inconsistent_cp;
+ if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw)
+ goto inconsistent_co;
+ found[p] = true;
+ }
+ for (i = 0; i < 8; i++)
+ if (!found[i])
+ goto inconsistent_co;
+
+ return true;
+
+inconsistent_ep:
+ DBG_LOG("Inconsistent EP\n");
+ return false;
+inconsistent_cp:
+ DBG_LOG("Inconsistent CP\n");
+ return false;
+inconsistent_eo:
+ DBG_LOG("Inconsistent EO\n");
+ return false;
+inconsistent_co:
+ DBG_LOG("Inconsistent CO\n");
+ return false;
+}
+
+bool
+issolvable(cube_t cube)
+{
+ uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8];
+
+ DBG_ASSERT(isconsistent(cube), false,
+ "issolvable: cube is inconsistent\n");
+
+ pieces(&cube, corner, edge);
+ for (i = 0; i < 12; i++)
+ ep[i] = edge[i] & _pbits;
+ for (i = 0; i < 8; i++)
+ cp[i] = corner[i] & _pbits;
+
+ if (permsign(ep, 12) != permsign(cp, 8))
+ goto issolvable_parity;
+
+ eo = 0;
+ for (i = 0; i < 12; i++) {
+ piece = edge[i];
+ eo += (piece & _eobit) >> _eoshift;
+ }
+ if (eo % 2 != 0)
+ goto issolvable_eo;
+
+ co = 0;
+ for (i = 0; i < 8; i++) {
+ piece = corner[i];
+ co += (piece & _cobits) >> _coshift;
+ }
+ if (co % 3 != 0)
+ goto issolvable_co;
+
+ return true;
+
+issolvable_parity:
+ DBG_LOG("EP and CP parities are different\n");
+ return false;
+issolvable_eo:
+ DBG_LOG("Odd number of flipped edges\n");
+ return false;
+issolvable_co:
+ DBG_LOG("Sum of corner orientation is not multiple of 3\n");
+ return false;
+}
+
+bool
+issolved(cube_t cube)
+{
+ return equal(cube, solved);
+}
+
+bool
+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
+applymoves(cube_t cube, const char *buf)
+{
+ uint8_t r, m;
+ const char *b;
+
+ DBG_ASSERT(isconsistent(cube), zero,
+ "move error: inconsistent cube\n");
+
+ for (b = buf; *b != '\0'; b++) {
+ while (*b == ' ' || *b == '\t' || *b == '\n')
+ b++;
+ if (*b == '\0')
+ goto applymoves_finish;
+ if ((r = readmove(*b)) == _error)
+ goto applymoves_error;
+ if ((m = readmodifier(*(b+1))) != 0)
+ b++;
+ cube = move(cube, r + m);
+ }
+
+applymoves_finish:
+ return cube;
+
+applymoves_error:
+ DBG_LOG("applymoves error\n");
+ return zero;
+}
+
+cube_t
+applytrans(cube_t cube, const char *buf)
+{
+ uint8_t t;
+
+ DBG_ASSERT(isconsistent(cube), zero,
+ "transformation error: inconsistent cube\n");
+
+ t = readtrans(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)
+{
+ int i, j;
+ uint8_t ret = 0;
+
+ for (i = 0; i < n; i++)
+ for (j = i+1; j < n; j++)
+ ret += a[i] > a[j] ? 1 : 0;
+
+ 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)
+{
+ switch (m) {
+ case _move_U:
+ return _move(U, c);
+ case _move_U2:
+ return _move(U2, c);
+ case _move_U3:
+ return _move(U3, c);
+ case _move_D:
+ return _move(D, c);
+ case _move_D2:
+ return _move(D2, c);
+ case _move_D3:
+ return _move(D3, c);
+ case _move_R:
+ return _move(R, c);
+ case _move_R2:
+ return _move(R2, c);
+ case _move_R3:
+ return _move(R3, c);
+ case _move_L:
+ return _move(L, c);
+ case _move_L2:
+ return _move(L2, c);
+ case _move_L3:
+ return _move(L3, c);
+ case _move_F:
+ return _move(F, c);
+ case _move_F2:
+ return _move(F2, c);
+ case _move_F3:
+ return _move(F3, c);
+ case _move_B:
+ return _move(B, c);
+ case _move_B2:
+ return _move(B2, c);
+ case _move_B3:
+ return _move(B3, c);
+ default:
+ DBG_LOG("move error, unknown move\n");
+ return zero;
+ }
+}
+
+/*
+TODO transform is now relegated to a separated file because it is too long.
+It would be nice to make it shorter without loosing performance.
+*/
diff --git a/src/cube_neon.h b/src/cube_neon.h
@@ -3,4 +3,4 @@
typedef struct {
uint8x16_t corner;
uint8x16_t edge;
-} cube_fast_t;
+} cube_t;
diff --git a/src/cube_portable.h b/src/cube_portable.h
@@ -1,109 +1,48 @@
typedef struct {
uint8_t corner[8];
uint8_t edge[12];
-} cube_fast_t;
-
-_static_inline cube_fast_t fastcube(
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
- uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
-);
-_static uint8_t corner(cube_fast_t, int);
-_static uint8_t edge(cube_fast_t, int);
-_static cube_fast_t cubetofast(cube_t);
-_static cube_t fasttocube(cube_fast_t);
-_static_inline bool equal_fast(cube_fast_t, cube_fast_t);
-_static_inline bool issolved_fast(cube_fast_t);
-_static_inline cube_fast_t invertco_fast(cube_fast_t);
-_static_inline void compose_edges_inplace(cube_fast_t, cube_fast_t, cube_fast_t *);
-_static_inline void compose_corners_inplace(cube_fast_t, cube_fast_t, cube_fast_t *);
-_static_inline cube_fast_t compose_fast_edges(cube_fast_t, cube_fast_t);
-_static_inline cube_fast_t compose_fast_corners(cube_fast_t, cube_fast_t);
-_static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
-
-_static_inline int64_t coord_fast_co(cube_fast_t);
-_static_inline int64_t coord_fast_csep(cube_fast_t);
-_static_inline int64_t coord_fast_cocsep(cube_fast_t);
-_static_inline int64_t coord_fast_eo(cube_fast_t);
-_static_inline int64_t coord_fast_esep(cube_fast_t);
-
-_static_inline void copy_corners_fast(cube_fast_t *, cube_fast_t);
-_static_inline void copy_edges_fast(cube_fast_t *, cube_fast_t);
-_static_inline void set_eo_fast(cube_fast_t *, int64_t);
-_static_inline cube_fast_t invcoord_fast_esep(int64_t);
-
-_static_inline cube_fast_t
-fastcube(
- uint8_t c_ufr,
- uint8_t c_ubl,
- uint8_t c_dfl,
- uint8_t c_dbr,
- uint8_t c_ufl,
- uint8_t c_ubr,
- uint8_t c_dfr,
- uint8_t c_dbl,
-
- uint8_t e_uf,
- uint8_t e_ub,
- uint8_t e_db,
- uint8_t e_df,
- uint8_t e_ur,
- uint8_t e_ul,
- uint8_t e_dl,
- uint8_t e_dr,
- uint8_t e_fr,
- uint8_t e_fl,
- uint8_t e_bl,
- uint8_t e_br
-)
+} cube_t;
+
+#define static_cube(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \
+ e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \
+ ((cube_t) { \
+ .corner = { c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl }, \
+ .edge = { e_uf, e_ub, e_db, e_df, e_ur, e_ul, \
+ e_dl, e_dr, e_fr, e_fl, e_bl, e_br } })
+#define zero static_cube( \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+#define solved static_cube( \
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
+
+_static void pieces(cube_t *, uint8_t [static 8], uint8_t [static 12]);
+_static_inline bool equal(cube_t, cube_t);
+_static_inline cube_t invertco(cube_t);
+_static_inline void compose_edges_inplace(cube_t, cube_t, cube_t *);
+_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 int64_t coord_co(cube_t);
+_static_inline int64_t coord_csep(cube_t);
+_static_inline int64_t coord_cocsep(cube_t);
+_static_inline int64_t coord_eo(cube_t);
+_static_inline int64_t coord_esep(cube_t);
+
+_static_inline void copy_corners(cube_t *, cube_t);
+_static_inline void copy_edges(cube_t *, cube_t);
+_static_inline void set_eo(cube_t *, int64_t);
+_static_inline cube_t invcoord_esep(int64_t);
+
+_static void
+pieces(cube_t *cube, uint8_t c[static 8], uint8_t e[static 12])
{
- cube_fast_t cube = {
- .corner = {
- c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl
- },
- .edge = {
- e_uf, e_ub, e_db, e_df, e_ur, e_ul,
- e_dl, e_dr, e_fr, e_fl, e_bl, e_br
- }
- };
-
- return cube;
-}
-
-_static uint8_t
-corner(cube_fast_t c, int i)
-{
- DBG_ASSERT(i >= 0 && i < 8, 255, "Corner must be between 0 and 7\n");
-
- return c.corner[i];
-}
-_static uint8_t
-edge(cube_fast_t c, int i)
-{
- DBG_ASSERT(i >= 0 && i < 12, 255, "Edge must be between 0 and 11\n");
-
- return c.edge[i];
-}
-
-_static cube_fast_t
-cubetofast(cube_t cube)
-{
- cube_fast_t fast;
- memcpy(&fast, &cube, sizeof(cube_fast_t));
- return fast;
-}
-
-_static cube_t
-fasttocube(cube_fast_t fast)
-{
- cube_t cube;
- memcpy(&cube, &fast, sizeof(cube_fast_t));
- return cube;
+ memcpy(c, cube->corner, 8);
+ memcpy(e, cube->edge, 12);
}
_static_inline bool
-equal_fast(cube_fast_t c1, cube_fast_t c2)
+equal(cube_t c1, cube_t c2)
{
uint8_t i;
bool ret;
@@ -117,17 +56,11 @@ equal_fast(cube_fast_t c1, cube_fast_t c2)
return ret;
}
-_static_inline bool
-issolved_fast(cube_fast_t cube)
-{
- return equal_fast(cube, solved_fast);
-}
-
-_static_inline cube_fast_t
-invertco_fast(cube_fast_t c)
+_static_inline cube_t
+invertco(cube_t c)
{
uint8_t i, piece, orien;
- cube_fast_t ret;
+ cube_t ret;
ret = c;
for (i = 0; i < 8; i++) {
@@ -140,7 +73,7 @@ invertco_fast(cube_fast_t c)
}
_static_inline void
-compose_edges_inplace(cube_fast_t c1, cube_fast_t c2, cube_fast_t *ret)
+compose_edges_inplace(cube_t c1, cube_t c2, cube_t *ret)
{
uint8_t i, piece1, piece2, p, orien;
@@ -154,7 +87,7 @@ compose_edges_inplace(cube_fast_t c1, cube_fast_t c2, cube_fast_t *ret)
}
_static_inline void
-compose_corners_inplace(cube_fast_t c1, cube_fast_t c2, cube_fast_t *ret)
+compose_corners_inplace(cube_t c1, cube_t c2, cube_t *ret)
{
uint8_t i, piece1, piece2, p, orien, aux, auy;
@@ -169,30 +102,30 @@ compose_corners_inplace(cube_fast_t c1, cube_fast_t c2, cube_fast_t *ret)
}
}
-_static_inline cube_fast_t
-compose_fast_edges(cube_fast_t c1, cube_fast_t c2)
+_static_inline cube_t
+compose_edges(cube_t c1, cube_t c2)
{
- cube_fast_t ret = zero_fast;
+ cube_t ret = zero;
compose_edges_inplace(c1, c2, &ret);
return ret;
}
-_static_inline cube_fast_t
-compose_fast_corners(cube_fast_t c1, cube_fast_t c2)
+_static_inline cube_t
+compose_corners(cube_t c1, cube_t c2)
{
- cube_fast_t ret = zero_fast;
+ cube_t ret = zero;
compose_corners_inplace(c1, c2, &ret);
return ret;
}
-_static_inline cube_fast_t
-compose_fast(cube_fast_t c1, cube_fast_t c2)
+_static_inline cube_t
+compose(cube_t c1, cube_t c2)
{
- cube_fast_t ret = zero_fast;
+ cube_t ret = zero;
compose_edges_inplace(c1, c2, &ret);
compose_corners_inplace(c1, c2, &ret);
@@ -201,7 +134,7 @@ compose_fast(cube_fast_t c1, cube_fast_t c2)
}
_static_inline int64_t
-coord_fast_co(cube_fast_t c)
+coord_co(cube_t c)
{
int i, p;
int64_t ret;
@@ -220,7 +153,7 @@ possible. Encoding this as a number from 0 to C(8,4) would save about 40%
of space, but we are not going to use this coordinate in large tables.
*/
_static_inline int64_t
-coord_fast_csep(cube_fast_t c)
+coord_csep(cube_t c)
{
int i, p;
int64_t ret;
@@ -232,13 +165,13 @@ coord_fast_csep(cube_fast_t c)
}
_static_inline int64_t
-coord_fast_cocsep(cube_fast_t c)
+coord_cocsep(cube_t c)
{
- return (coord_fast_co(c) << 7) + coord_fast_csep(c);
+ return (coord_co(c) << 7) + coord_csep(c);
}
_static_inline int64_t
-coord_fast_eo(cube_fast_t c)
+coord_eo(cube_t c)
{
int i, p;
int64_t ret;
@@ -254,7 +187,7 @@ We encode the edge separation as a number from 0 to C(12,4)*C(8,4).
It can be seen as the composition of two "subset index" coordinates.
*/
_static_inline int64_t
-coord_fast_esep(cube_fast_t c)
+coord_esep(cube_t c)
{
int64_t i, j, jj, k, l, ret1, ret2, bit1, bit2, is1;
@@ -286,19 +219,19 @@ coord_fast_esep(cube_fast_t c)
}
_static_inline void
-copy_corners_fast(cube_fast_t *dest, cube_fast_t src)
+copy_corners(cube_t *dest, cube_t src)
{
memcpy(&dest->corner, src.corner, sizeof(src.corner));
}
_static_inline void
-copy_edges_fast(cube_fast_t *dest, cube_fast_t src)
+copy_edges(cube_t *dest, cube_t src)
{
memcpy(&dest->edge, src.edge, sizeof(src.edge));
}
_static_inline void
-set_eo_fast(cube_fast_t *cube, int64_t eo)
+set_eo(cube_t *cube, int64_t eo)
{
uint8_t i, sum, flip;
@@ -310,14 +243,14 @@ set_eo_fast(cube_fast_t *cube, int64_t eo)
cube->edge[0] = (cube->edge[0] & ~_eobit) | (_eobit * (sum % 2));
}
-_static_inline cube_fast_t
-invcoord_fast_esep(int64_t esep)
+_static_inline cube_t
+invcoord_esep(int64_t esep)
{
- cube_fast_t ret;
+ cube_t ret;
int64_t bit1, bit2, i, j, jj, k, l, s, v, w, is1, set1, set2;
uint8_t slice[3] = {0};
- ret = cubetofast(solved);
+ ret = solved;
set1 = esep % 70;
set2 = esep / 70;
diff --git a/src/cube_routines.h b/src/cube_routines.h
@@ -1,668 +0,0 @@
-#define _move(M, c) compose_fast(c, _move_cube_ ## M)
-#define _premove(M, c) compose_fast(_move_cube_ ## M, c)
-
-_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_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_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_fast_t move(cube_fast_t, uint8_t);
-_static cube_fast_t transform_edges(cube_fast_t, uint8_t);
-_static cube_fast_t transform_corners(cube_fast_t, uint8_t);
-_static cube_fast_t transform(cube_fast_t, uint8_t);
-
-cube_t
-solvedcube(void)
-{
- return solved;
-}
-
-bool
-isconsistent(cube_t cube)
-{
- uint8_t i, p, e, piece;
- bool found[12];
-
- for (i = 0; i < 12; i++)
- found[i] = false;
- for (i = 0; i < 12; i++) {
- piece = cube.edge[i];
- p = piece & _pbits;
- e = piece & _eobit;
- if (p >= 12)
- goto inconsistent_ep;
- if (e != 0 && e != _eobit)
- goto inconsistent_eo;
- found[p] = true;
- }
- for (i = 0; i < 12; i++)
- if (!found[i])
- goto inconsistent_ep;
-
- for (i = 0; i < 8; i++)
- found[i] = false;
- for (i = 0; i < 8; i++) {
- piece = cube.corner[i];
- p = piece & _pbits;
- e = piece & _cobits;
- if (p >= 8)
- goto inconsistent_cp;
- if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw)
- goto inconsistent_co;
- found[p] = true;
- }
- for (i = 0; i < 8; i++)
- if (!found[i])
- goto inconsistent_co;
-
- return true;
-
-inconsistent_ep:
- DBG_LOG("Inconsistent EP\n");
- return false;
-inconsistent_cp:
- DBG_LOG("Inconsistent CP\n");
- return false;
-inconsistent_eo:
- DBG_LOG("Inconsistent EO\n");
- return false;
-inconsistent_co:
- DBG_LOG("Inconsistent CO\n");
- return false;
-}
-
-bool
-issolvable(cube_t cube)
-{
- uint8_t i, eo, co, piece, edges[12], corners[8];
-
- DBG_ASSERT(isconsistent(cube), false,
- "issolvable: cube is inconsistent\n");
-
- for (i = 0; i < 12; i++)
- edges[i] = cube.edge[i] & _pbits;
- for (i = 0; i < 8; i++)
- corners[i] = cube.corner[i] & _pbits;
-
- if (permsign(edges, 12) != permsign(corners, 8))
- goto issolvable_parity;
-
- eo = 0;
- for (i = 0; i < 12; i++) {
- piece = cube.edge[i];
- eo += (piece & _eobit) >> _eoshift;
- }
- if (eo % 2 != 0)
- goto issolvable_eo;
-
- co = 0;
- for (i = 0; i < 8; i++) {
- piece = cube.corner[i];
- co += (piece & _cobits) >> _coshift;
- }
- if (co % 3 != 0)
- goto issolvable_co;
-
- return true;
-
-issolvable_parity:
- DBG_LOG("EP and CP parities are different\n");
- return false;
-issolvable_eo:
- DBG_LOG("Odd number of flipped edges\n");
- return false;
-issolvable_co:
- DBG_LOG("Sum of corner orientation is not multiple of 3\n");
- return false;
-}
-
-bool
-issolved(cube_t cube)
-{
- return equal(cube, solved);
-}
-
-bool
-equal(cube_t c1, cube_t c2)
-{
- int i;
- bool ret;
-
- ret = true;
- for (i = 0; i < 8; i++)
- ret = ret && c1.corner[i] == c2.corner[i];
- for (i = 0; i < 12; i++)
- ret = ret && c1.edge[i] == c2.edge[i];
-
- return ret;
-}
-
-bool
-iserror(cube_t cube)
-{
- return equal(cube, zero);
-}
-
-cube_t
-compose(cube_t c1, cube_t c2)
-{
- DBG_ASSERT(isconsistent(c1) && isconsistent(c2),
- zero, "compose error: inconsistent cube\n")
-
- return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2)));
-}
-
-cube_t
-inverse(cube_t cube)
-{
- cube_t ret;
- uint8_t i, piece, orien;
-
- DBG_ASSERT(isconsistent(cube), zero,
- "inverse error: inconsistent cube\n");
-
- ret = zero;
-
- 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;
-}
-
-cube_t
-applymoves(cube_t cube, const char *buf)
-{
- cube_fast_t fast;
- uint8_t r, m;
- const char *b;
-
- DBG_ASSERT(isconsistent(cube), zero,
- "move error: inconsistent cube\n");
-
- fast = cubetofast(cube);
-
- for (b = buf; *b != '\0'; b++) {
- while (*b == ' ' || *b == '\t' || *b == '\n')
- b++;
- if (*b == '\0')
- goto applymoves_finish;
- if ((r = readmove(*b)) == _error)
- goto applymoves_error;
- if ((m = readmodifier(*(b+1))) != 0)
- b++;
- fast = move(fast, r + m);
- }
-
-applymoves_finish:
- return fasttocube(fast);
-
-applymoves_error:
- DBG_LOG("applymoves error\n");
- return zero;
-}
-
-cube_t
-applytrans(cube_t cube, const char *buf)
-{
- cube_fast_t fast;
- uint8_t t;
-
- DBG_ASSERT(isconsistent(cube), zero,
- "transformation error: inconsistent cube\n");
-
- t = readtrans(buf);
- fast = cubetofast(cube);
- fast = transform(fast, t);
-
- return fasttocube(fast);
-}
-
-cube_t
-readcube(const char *format, const char *buf)
-{
- cube_t cube;
-
- 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;
- }
-
- return cube;
-}
-
-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;
- }
-
- if (!strcmp(format, "H48")) {
- writecube_H48(cube, buf);
- } else if (!strcmp(format, "LST")) {
- writecube_LST(cube, buf);
- } else {
- errormsg = "ERROR: cannot write cube in the given format";
- goto writecube_error;
- }
-
- return;
-
-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)
-{
- int i, j;
- uint8_t ret = 0;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += a[i] > a[j] ? 1 : 0;
-
- 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_H48(const char *buf)
-{
- int i;
- uint8_t piece, orient;
- cube_t ret = {0};
- 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++;
- ret.edge[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++;
- ret.corner[i] = piece | orient;
- }
-
- return ret;
-}
-
-_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;
- 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_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_H48(cube_t cube, char *buf)
-{
- uint8_t piece, perm, orient;
- int i;
-
- for (i = 0; i < 12; i++) {
- piece = cube.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 = cube.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;
-
- ptr = 0;
-
- for (i = 0; i < 8; i++) {
- piece = cube.corner[i];
- ptr += writepiece_LST(piece, buf + ptr);
- }
-
- for (i = 0; i < 12; i++) {
- piece = cube.edge[i];
- ptr += writepiece_LST(piece, buf + ptr);
- }
-
- *(buf+ptr-2) = 0;
-}
-
-_static uint8_t
-b32toedge(char c)
-{
- DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255,
- "Error reading base32 piece");
-
- return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a');
-}
-
-_static uint8_t
-b32tocorner(char c) {
- uint8_t val;
-
- DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255,
- "Error reading base32 piece");
-
- 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_fast_t
-move(cube_fast_t c, uint8_t m)
-{
- switch (m) {
- case _move_U:
- return _move(U, c);
- case _move_U2:
- return _move(U2, c);
- case _move_U3:
- return _move(U3, c);
- case _move_D:
- return _move(D, c);
- case _move_D2:
- return _move(D2, c);
- case _move_D3:
- return _move(D3, c);
- case _move_R:
- return _move(R, c);
- case _move_R2:
- return _move(R2, c);
- case _move_R3:
- return _move(R3, c);
- case _move_L:
- return _move(L, c);
- case _move_L2:
- return _move(L2, c);
- case _move_L3:
- return _move(L3, c);
- case _move_F:
- return _move(F, c);
- case _move_F2:
- return _move(F2, c);
- case _move_F3:
- return _move(F3, c);
- case _move_B:
- return _move(B, c);
- case _move_B2:
- return _move(B2, c);
- case _move_B3:
- return _move(B3, c);
- default:
- DBG_LOG("move error, unknown move\n");
- return zero_fast;
- }
-}
-
-/*
-TODO transform is now relegated to a separated file because it is too long.
-It would be nice to make it shorter without loosing performance.
-*/
diff --git a/src/cube_transform.h b/src/cube_transform.h
@@ -1,336 +1,176 @@
+/* TODO: remove these macros, if the below works */
+
#define _trans_edges_rotation(T, c) \
- compose_fast_edges(compose_fast_edges(_trans_cube_ ## T, c), \
+ compose_edges(compose_edges(_trans_cube_ ## T, c), \
_trans_cube_ ## T ## _inverse)
#define _trans_edges_mirrored(T, c) _trans_edges_rotation(T, c)
#define _trans_corners_rotation(T, c) \
- compose_fast_corners(compose_fast_corners(_trans_cube_ ## T, c), \
+ compose_corners(compose_corners(_trans_cube_ ## T, c), \
_trans_cube_ ## T ## _inverse)
#define _trans_corners_mirrored(T, c) \
- invertco_fast(compose_fast_corners( \
- compose_fast_corners(_trans_cube_ ## T, c), _trans_cube_ ## T ## _inverse))
+ invertco(compose_corners( \
+ compose_corners(_trans_cube_ ## T, c), _trans_cube_ ## T ## _inverse))
#define _trans_rotation(T, c) \
- compose_fast(compose_fast(_trans_cube_ ## T, c), \
+ compose(compose(_trans_cube_ ## T, c), \
_trans_cube_ ## T ## _inverse)
#define _trans_mirrored(T, c) \
- invertco_fast(compose_fast(compose_fast(_trans_cube_ ## T, c), \
+ invertco(compose(compose(_trans_cube_ ## T, c), \
_trans_cube_ ## T ## _inverse))
-_static cube_fast_t
-transform_edges(cube_fast_t c, uint8_t t)
+static cube_t cube_trans_table[48] = {
+ [_trans_UFr] = _trans_cube_UFr,
+ [_trans_UFm] = _trans_cube_UFm,
+ [_trans_ULr] = _trans_cube_URr,
+ [_trans_ULm] = _trans_cube_ULm,
+ [_trans_UBr] = _trans_cube_UBr,
+ [_trans_UBm] = _trans_cube_UBm,
+ [_trans_URr] = _trans_cube_ULr,
+ [_trans_URm] = _trans_cube_URm,
+ [_trans_DFr] = _trans_cube_DFr,
+ [_trans_DFm] = _trans_cube_DFm,
+ [_trans_DLr] = _trans_cube_DLr,
+ [_trans_DLm] = _trans_cube_DRm,
+ [_trans_DBr] = _trans_cube_DBr,
+ [_trans_DBm] = _trans_cube_DBm,
+ [_trans_DRr] = _trans_cube_DRr,
+ [_trans_DRm] = _trans_cube_DLm,
+ [_trans_RUr] = _trans_cube_FRr,
+ [_trans_RUm] = _trans_cube_FLm,
+ [_trans_RFr] = _trans_cube_LFr,
+ [_trans_RFm] = _trans_cube_RFm,
+ [_trans_RDr] = _trans_cube_BLr,
+ [_trans_RDm] = _trans_cube_BRm,
+ [_trans_RBr] = _trans_cube_RBr,
+ [_trans_RBm] = _trans_cube_LBm,
+ [_trans_LUr] = _trans_cube_FLr,
+ [_trans_LUm] = _trans_cube_FRm,
+ [_trans_LFr] = _trans_cube_RFr,
+ [_trans_LFm] = _trans_cube_LFm,
+ [_trans_LDr] = _trans_cube_BRr,
+ [_trans_LDm] = _trans_cube_BLm,
+ [_trans_LBr] = _trans_cube_LBr,
+ [_trans_LBm] = _trans_cube_RBm,
+ [_trans_FUr] = _trans_cube_FUr,
+ [_trans_FUm] = _trans_cube_FUm,
+ [_trans_FRr] = _trans_cube_RUr,
+ [_trans_FRm] = _trans_cube_LUm,
+ [_trans_FDr] = _trans_cube_BUr,
+ [_trans_FDm] = _trans_cube_BUm,
+ [_trans_FLr] = _trans_cube_LUr,
+ [_trans_FLm] = _trans_cube_RUm,
+ [_trans_BUr] = _trans_cube_FDr,
+ [_trans_BUm] = _trans_cube_FDm,
+ [_trans_BRr] = _trans_cube_LDr,
+ [_trans_BRm] = _trans_cube_RDm,
+ [_trans_BDr] = _trans_cube_BDr,
+ [_trans_BDm] = _trans_cube_BDm,
+ [_trans_BLr] = _trans_cube_RDr,
+ [_trans_BLm] = _trans_cube_LDm,
+};
+
+static cube_t cube_trans_table_inverse[48] = {
+ [_trans_UFr] = _trans_cube_UFr_inverse,
+ [_trans_UFm] = _trans_cube_UFm_inverse,
+ [_trans_ULr] = _trans_cube_URr_inverse,
+ [_trans_ULm] = _trans_cube_ULm_inverse,
+ [_trans_UBr] = _trans_cube_UBr_inverse,
+ [_trans_UBm] = _trans_cube_UBm_inverse,
+ [_trans_URr] = _trans_cube_ULr_inverse,
+ [_trans_URm] = _trans_cube_URm_inverse,
+ [_trans_DFr] = _trans_cube_DFr_inverse,
+ [_trans_DFm] = _trans_cube_DFm_inverse,
+ [_trans_DLr] = _trans_cube_DLr_inverse,
+ [_trans_DLm] = _trans_cube_DRm_inverse,
+ [_trans_DBr] = _trans_cube_DBr_inverse,
+ [_trans_DBm] = _trans_cube_DBm_inverse,
+ [_trans_DRr] = _trans_cube_DRr_inverse,
+ [_trans_DRm] = _trans_cube_DLm_inverse,
+ [_trans_RUr] = _trans_cube_FRr_inverse,
+ [_trans_RUm] = _trans_cube_FLm_inverse,
+ [_trans_RFr] = _trans_cube_LFr_inverse,
+ [_trans_RFm] = _trans_cube_RFm_inverse,
+ [_trans_RDr] = _trans_cube_BLr_inverse,
+ [_trans_RDm] = _trans_cube_BRm_inverse,
+ [_trans_RBr] = _trans_cube_RBr_inverse,
+ [_trans_RBm] = _trans_cube_LBm_inverse,
+ [_trans_LUr] = _trans_cube_FLr_inverse,
+ [_trans_LUm] = _trans_cube_FRm_inverse,
+ [_trans_LFr] = _trans_cube_RFr_inverse,
+ [_trans_LFm] = _trans_cube_LFm_inverse,
+ [_trans_LDr] = _trans_cube_BRr_inverse,
+ [_trans_LDm] = _trans_cube_BLm_inverse,
+ [_trans_LBr] = _trans_cube_LBr_inverse,
+ [_trans_LBm] = _trans_cube_RBm_inverse,
+ [_trans_FUr] = _trans_cube_FUr_inverse,
+ [_trans_FUm] = _trans_cube_FUm_inverse,
+ [_trans_FRr] = _trans_cube_RUr_inverse,
+ [_trans_FRm] = _trans_cube_LUm_inverse,
+ [_trans_FDr] = _trans_cube_BUr_inverse,
+ [_trans_FDm] = _trans_cube_BUm_inverse,
+ [_trans_FLr] = _trans_cube_LUr_inverse,
+ [_trans_FLm] = _trans_cube_RUm_inverse,
+ [_trans_BUr] = _trans_cube_FDr_inverse,
+ [_trans_BUm] = _trans_cube_FDm_inverse,
+ [_trans_BRr] = _trans_cube_LDr_inverse,
+ [_trans_BRm] = _trans_cube_RDm_inverse,
+ [_trans_BDr] = _trans_cube_BDr_inverse,
+ [_trans_BDm] = _trans_cube_BDm_inverse,
+ [_trans_BLr] = _trans_cube_RDr_inverse,
+ [_trans_BLm] = _trans_cube_LDm_inverse,
+};
+
+_static cube_t
+transform_edges(cube_t c, uint8_t t)
{
- switch (t) {
- case _trans_UFr:
- return _trans_edges_rotation(UFr, c);
- case _trans_ULr:
- return _trans_edges_rotation(ULr, c);
- case _trans_UBr:
- return _trans_edges_rotation(UBr, c);
- case _trans_URr:
- return _trans_edges_rotation(URr, c);
- case _trans_DFr:
- return _trans_edges_rotation(DFr, c);
- case _trans_DLr:
- return _trans_edges_rotation(DLr, c);
- case _trans_DBr:
- return _trans_edges_rotation(DBr, c);
- case _trans_DRr:
- return _trans_edges_rotation(DRr, c);
- case _trans_RUr:
- return _trans_edges_rotation(RUr, c);
- case _trans_RFr:
- return _trans_edges_rotation(RFr, c);
- case _trans_RDr:
- return _trans_edges_rotation(RDr, c);
- case _trans_RBr:
- return _trans_edges_rotation(RBr, c);
- case _trans_LUr:
- return _trans_edges_rotation(LUr, c);
- case _trans_LFr:
- return _trans_edges_rotation(LFr, c);
- case _trans_LDr:
- return _trans_edges_rotation(LDr, c);
- case _trans_LBr:
- return _trans_edges_rotation(LBr, c);
- case _trans_FUr:
- return _trans_edges_rotation(FUr, c);
- case _trans_FRr:
- return _trans_edges_rotation(FRr, c);
- case _trans_FDr:
- return _trans_edges_rotation(FDr, c);
- case _trans_FLr:
- return _trans_edges_rotation(FLr, c);
- case _trans_BUr:
- return _trans_edges_rotation(BUr, c);
- case _trans_BRr:
- return _trans_edges_rotation(BRr, c);
- case _trans_BDr:
- return _trans_edges_rotation(BDr, c);
- case _trans_BLr:
- return _trans_edges_rotation(BLr, c);
- case _trans_UFm:
- return _trans_edges_mirrored(UFm, c);
- case _trans_ULm:
- return _trans_edges_mirrored(ULm, c);
- case _trans_UBm:
- return _trans_edges_mirrored(UBm, c);
- case _trans_URm:
- return _trans_edges_mirrored(URm, c);
- case _trans_DFm:
- return _trans_edges_mirrored(DFm, c);
- case _trans_DLm:
- return _trans_edges_mirrored(DLm, c);
- case _trans_DBm:
- return _trans_edges_mirrored(DBm, c);
- case _trans_DRm:
- return _trans_edges_mirrored(DRm, c);
- case _trans_RUm:
- return _trans_edges_mirrored(RUm, c);
- case _trans_RFm:
- return _trans_edges_mirrored(RFm, c);
- case _trans_RDm:
- return _trans_edges_mirrored(RDm, c);
- case _trans_RBm:
- return _trans_edges_mirrored(RBm, c);
- case _trans_LUm:
- return _trans_edges_mirrored(LUm, c);
- case _trans_LFm:
- return _trans_edges_mirrored(LFm, c);
- case _trans_LDm:
- return _trans_edges_mirrored(LDm, c);
- case _trans_LBm:
- return _trans_edges_mirrored(LBm, c);
- case _trans_FUm:
- return _trans_edges_mirrored(FUm, c);
- case _trans_FRm:
- return _trans_edges_mirrored(FRm, c);
- case _trans_FDm:
- return _trans_edges_mirrored(FDm, c);
- case _trans_FLm:
- return _trans_edges_mirrored(FLm, c);
- case _trans_BUm:
- return _trans_edges_mirrored(BUm, c);
- case _trans_BRm:
- return _trans_edges_mirrored(BRm, c);
- case _trans_BDm:
- return _trans_edges_mirrored(BDm, c);
- case _trans_BLm:
- return _trans_edges_mirrored(BLm, c);
- default:
- DBG_LOG("transform error, unknown transformation\n");
- return zero_fast;
- }
+ cube_t ret, trans_cube, trans_inv;
+
+ DBG_ASSERT(t < 48, zero,
+ "transform: invalid transformation %" PRIu8
+ ", must be between 0 and 47\n", t);
+
+ trans_cube = cube_trans_table[t];
+ trans_inv = cube_trans_table_inverse[t];
+
+ ret = compose_edges(trans_cube, c);
+ ret = compose_edges(ret, trans_inv);
+
+ return ret;
}
-_static cube_fast_t
-transform_corners(cube_fast_t c, uint8_t t)
+_static cube_t
+transform_corners(cube_t c, uint8_t t)
{
- switch (t) {
- case _trans_UFr:
- return _trans_corners_rotation(UFr, c);
- case _trans_ULr:
- return _trans_corners_rotation(ULr, c);
- case _trans_UBr:
- return _trans_corners_rotation(UBr, c);
- case _trans_URr:
- return _trans_corners_rotation(URr, c);
- case _trans_DFr:
- return _trans_corners_rotation(DFr, c);
- case _trans_DLr:
- return _trans_corners_rotation(DLr, c);
- case _trans_DBr:
- return _trans_corners_rotation(DBr, c);
- case _trans_DRr:
- return _trans_corners_rotation(DRr, c);
- case _trans_RUr:
- return _trans_corners_rotation(RUr, c);
- case _trans_RFr:
- return _trans_corners_rotation(RFr, c);
- case _trans_RDr:
- return _trans_corners_rotation(RDr, c);
- case _trans_RBr:
- return _trans_corners_rotation(RBr, c);
- case _trans_LUr:
- return _trans_corners_rotation(LUr, c);
- case _trans_LFr:
- return _trans_corners_rotation(LFr, c);
- case _trans_LDr:
- return _trans_corners_rotation(LDr, c);
- case _trans_LBr:
- return _trans_corners_rotation(LBr, c);
- case _trans_FUr:
- return _trans_corners_rotation(FUr, c);
- case _trans_FRr:
- return _trans_corners_rotation(FRr, c);
- case _trans_FDr:
- return _trans_corners_rotation(FDr, c);
- case _trans_FLr:
- return _trans_corners_rotation(FLr, c);
- case _trans_BUr:
- return _trans_corners_rotation(BUr, c);
- case _trans_BRr:
- return _trans_corners_rotation(BRr, c);
- case _trans_BDr:
- return _trans_corners_rotation(BDr, c);
- case _trans_BLr:
- return _trans_corners_rotation(BLr, c);
- case _trans_UFm:
- return _trans_corners_mirrored(UFm, c);
- case _trans_ULm:
- return _trans_corners_mirrored(ULm, c);
- case _trans_UBm:
- return _trans_corners_mirrored(UBm, c);
- case _trans_URm:
- return _trans_corners_mirrored(URm, c);
- case _trans_DFm:
- return _trans_corners_mirrored(DFm, c);
- case _trans_DLm:
- return _trans_corners_mirrored(DLm, c);
- case _trans_DBm:
- return _trans_corners_mirrored(DBm, c);
- case _trans_DRm:
- return _trans_corners_mirrored(DRm, c);
- case _trans_RUm:
- return _trans_corners_mirrored(RUm, c);
- case _trans_RFm:
- return _trans_corners_mirrored(RFm, c);
- case _trans_RDm:
- return _trans_corners_mirrored(RDm, c);
- case _trans_RBm:
- return _trans_corners_mirrored(RBm, c);
- case _trans_LUm:
- return _trans_corners_mirrored(LUm, c);
- case _trans_LFm:
- return _trans_corners_mirrored(LFm, c);
- case _trans_LDm:
- return _trans_corners_mirrored(LDm, c);
- case _trans_LBm:
- return _trans_corners_mirrored(LBm, c);
- case _trans_FUm:
- return _trans_corners_mirrored(FUm, c);
- case _trans_FRm:
- return _trans_corners_mirrored(FRm, c);
- case _trans_FDm:
- return _trans_corners_mirrored(FDm, c);
- case _trans_FLm:
- return _trans_corners_mirrored(FLm, c);
- case _trans_BUm:
- return _trans_corners_mirrored(BUm, c);
- case _trans_BRm:
- return _trans_corners_mirrored(BRm, c);
- case _trans_BDm:
- return _trans_corners_mirrored(BDm, c);
- case _trans_BLm:
- return _trans_corners_mirrored(BLm, c);
- default:
- DBG_LOG("transform error, unknown transformation\n");
- return zero_fast;
- }
+ cube_t ret, trans_cube, trans_inv;
+
+ DBG_ASSERT(t < 48, zero,
+ "transform: invalid transformation %" PRIu8
+ ", must be between 0 and 47\n", t);
+
+ trans_cube = cube_trans_table[t];
+ trans_inv = cube_trans_table_inverse[t];
+
+ ret = compose_corners(trans_cube, c);
+ ret = compose_corners(ret, trans_inv);
+
+ return t < 24 ? ret : invertco(ret);
}
-_static cube_fast_t
-transform(cube_fast_t c, uint8_t t)
+_static cube_t
+transform(cube_t c, uint8_t t)
{
- switch (t) {
- case _trans_UFr:
- return _trans_rotation(UFr, c);
- case _trans_ULr:
- return _trans_rotation(ULr, c);
- case _trans_UBr:
- return _trans_rotation(UBr, c);
- case _trans_URr:
- return _trans_rotation(URr, c);
- case _trans_DFr:
- return _trans_rotation(DFr, c);
- case _trans_DLr:
- return _trans_rotation(DLr, c);
- case _trans_DBr:
- return _trans_rotation(DBr, c);
- case _trans_DRr:
- return _trans_rotation(DRr, c);
- case _trans_RUr:
- return _trans_rotation(RUr, c);
- case _trans_RFr:
- return _trans_rotation(RFr, c);
- case _trans_RDr:
- return _trans_rotation(RDr, c);
- case _trans_RBr:
- return _trans_rotation(RBr, c);
- case _trans_LUr:
- return _trans_rotation(LUr, c);
- case _trans_LFr:
- return _trans_rotation(LFr, c);
- case _trans_LDr:
- return _trans_rotation(LDr, c);
- case _trans_LBr:
- return _trans_rotation(LBr, c);
- case _trans_FUr:
- return _trans_rotation(FUr, c);
- case _trans_FRr:
- return _trans_rotation(FRr, c);
- case _trans_FDr:
- return _trans_rotation(FDr, c);
- case _trans_FLr:
- return _trans_rotation(FLr, c);
- case _trans_BUr:
- return _trans_rotation(BUr, c);
- case _trans_BRr:
- return _trans_rotation(BRr, c);
- case _trans_BDr:
- return _trans_rotation(BDr, c);
- case _trans_BLr:
- return _trans_rotation(BLr, c);
- case _trans_UFm:
- return _trans_mirrored(UFm, c);
- case _trans_ULm:
- return _trans_mirrored(ULm, c);
- case _trans_UBm:
- return _trans_mirrored(UBm, c);
- case _trans_URm:
- return _trans_mirrored(URm, c);
- case _trans_DFm:
- return _trans_mirrored(DFm, c);
- case _trans_DLm:
- return _trans_mirrored(DLm, c);
- case _trans_DBm:
- return _trans_mirrored(DBm, c);
- case _trans_DRm:
- return _trans_mirrored(DRm, c);
- case _trans_RUm:
- return _trans_mirrored(RUm, c);
- case _trans_RFm:
- return _trans_mirrored(RFm, c);
- case _trans_RDm:
- return _trans_mirrored(RDm, c);
- case _trans_RBm:
- return _trans_mirrored(RBm, c);
- case _trans_LUm:
- return _trans_mirrored(LUm, c);
- case _trans_LFm:
- return _trans_mirrored(LFm, c);
- case _trans_LDm:
- return _trans_mirrored(LDm, c);
- case _trans_LBm:
- return _trans_mirrored(LBm, c);
- case _trans_FUm:
- return _trans_mirrored(FUm, c);
- case _trans_FRm:
- return _trans_mirrored(FRm, c);
- case _trans_FDm:
- return _trans_mirrored(FDm, c);
- case _trans_FLm:
- return _trans_mirrored(FLm, c);
- case _trans_BUm:
- return _trans_mirrored(BUm, c);
- case _trans_BRm:
- return _trans_mirrored(BRm, c);
- case _trans_BDm:
- return _trans_mirrored(BDm, c);
- case _trans_BLm:
- return _trans_mirrored(BLm, c);
- default:
- DBG_LOG("transform error, unknown transformation\n");
- return zero_fast;
- }
+ cube_t ret, trans_cube, trans_inv;
+
+ DBG_ASSERT(t < 48, zero,
+ "transform: invalid transformation %" PRIu8
+ ", must be between 0 and 47\n", t);
+
+ trans_cube = cube_trans_table[t];
+ trans_inv = cube_trans_table_inverse[t];
+
+ ret = compose(trans_cube, c);
+ ret = compose(ret, trans_inv);
+
+ return t < 24 ? ret : invertco(ret);
}
diff --git a/src/cube_transform_with_switch.h b/src/cube_transform_with_switch.h
@@ -0,0 +1,336 @@
+#define _trans_edges_rotation(T, c) \
+ compose_edges(compose_edges(_trans_cube_ ## T, c), \
+ _trans_cube_ ## T ## _inverse)
+#define _trans_edges_mirrored(T, c) _trans_edges_rotation(T, c)
+
+#define _trans_corners_rotation(T, c) \
+ compose_corners(compose_corners(_trans_cube_ ## T, c), \
+ _trans_cube_ ## T ## _inverse)
+#define _trans_corners_mirrored(T, c) \
+ invertco(compose_corners( \
+ compose_corners(_trans_cube_ ## T, c), _trans_cube_ ## T ## _inverse))
+
+#define _trans_rotation(T, c) \
+ compose(compose(_trans_cube_ ## T, c), \
+ _trans_cube_ ## T ## _inverse)
+#define _trans_mirrored(T, c) \
+ invertco(compose(compose(_trans_cube_ ## T, c), \
+ _trans_cube_ ## T ## _inverse))
+
+_static cube_t
+transform_edges(cube_t c, uint8_t t)
+{
+ switch (t) {
+ case _trans_UFr:
+ return _trans_edges_rotation(UFr, c);
+ case _trans_ULr:
+ return _trans_edges_rotation(ULr, c);
+ case _trans_UBr:
+ return _trans_edges_rotation(UBr, c);
+ case _trans_URr:
+ return _trans_edges_rotation(URr, c);
+ case _trans_DFr:
+ return _trans_edges_rotation(DFr, c);
+ case _trans_DLr:
+ return _trans_edges_rotation(DLr, c);
+ case _trans_DBr:
+ return _trans_edges_rotation(DBr, c);
+ case _trans_DRr:
+ return _trans_edges_rotation(DRr, c);
+ case _trans_RUr:
+ return _trans_edges_rotation(RUr, c);
+ case _trans_RFr:
+ return _trans_edges_rotation(RFr, c);
+ case _trans_RDr:
+ return _trans_edges_rotation(RDr, c);
+ case _trans_RBr:
+ return _trans_edges_rotation(RBr, c);
+ case _trans_LUr:
+ return _trans_edges_rotation(LUr, c);
+ case _trans_LFr:
+ return _trans_edges_rotation(LFr, c);
+ case _trans_LDr:
+ return _trans_edges_rotation(LDr, c);
+ case _trans_LBr:
+ return _trans_edges_rotation(LBr, c);
+ case _trans_FUr:
+ return _trans_edges_rotation(FUr, c);
+ case _trans_FRr:
+ return _trans_edges_rotation(FRr, c);
+ case _trans_FDr:
+ return _trans_edges_rotation(FDr, c);
+ case _trans_FLr:
+ return _trans_edges_rotation(FLr, c);
+ case _trans_BUr:
+ return _trans_edges_rotation(BUr, c);
+ case _trans_BRr:
+ return _trans_edges_rotation(BRr, c);
+ case _trans_BDr:
+ return _trans_edges_rotation(BDr, c);
+ case _trans_BLr:
+ return _trans_edges_rotation(BLr, c);
+ case _trans_UFm:
+ return _trans_edges_mirrored(UFm, c);
+ case _trans_ULm:
+ return _trans_edges_mirrored(ULm, c);
+ case _trans_UBm:
+ return _trans_edges_mirrored(UBm, c);
+ case _trans_URm:
+ return _trans_edges_mirrored(URm, c);
+ case _trans_DFm:
+ return _trans_edges_mirrored(DFm, c);
+ case _trans_DLm:
+ return _trans_edges_mirrored(DLm, c);
+ case _trans_DBm:
+ return _trans_edges_mirrored(DBm, c);
+ case _trans_DRm:
+ return _trans_edges_mirrored(DRm, c);
+ case _trans_RUm:
+ return _trans_edges_mirrored(RUm, c);
+ case _trans_RFm:
+ return _trans_edges_mirrored(RFm, c);
+ case _trans_RDm:
+ return _trans_edges_mirrored(RDm, c);
+ case _trans_RBm:
+ return _trans_edges_mirrored(RBm, c);
+ case _trans_LUm:
+ return _trans_edges_mirrored(LUm, c);
+ case _trans_LFm:
+ return _trans_edges_mirrored(LFm, c);
+ case _trans_LDm:
+ return _trans_edges_mirrored(LDm, c);
+ case _trans_LBm:
+ return _trans_edges_mirrored(LBm, c);
+ case _trans_FUm:
+ return _trans_edges_mirrored(FUm, c);
+ case _trans_FRm:
+ return _trans_edges_mirrored(FRm, c);
+ case _trans_FDm:
+ return _trans_edges_mirrored(FDm, c);
+ case _trans_FLm:
+ return _trans_edges_mirrored(FLm, c);
+ case _trans_BUm:
+ return _trans_edges_mirrored(BUm, c);
+ case _trans_BRm:
+ return _trans_edges_mirrored(BRm, c);
+ case _trans_BDm:
+ return _trans_edges_mirrored(BDm, c);
+ case _trans_BLm:
+ return _trans_edges_mirrored(BLm, c);
+ default:
+ DBG_LOG("transform error, unknown transformation\n");
+ return zero;
+ }
+}
+
+_static cube_t
+transform_corners(cube_t c, uint8_t t)
+{
+ switch (t) {
+ case _trans_UFr:
+ return _trans_corners_rotation(UFr, c);
+ case _trans_ULr:
+ return _trans_corners_rotation(ULr, c);
+ case _trans_UBr:
+ return _trans_corners_rotation(UBr, c);
+ case _trans_URr:
+ return _trans_corners_rotation(URr, c);
+ case _trans_DFr:
+ return _trans_corners_rotation(DFr, c);
+ case _trans_DLr:
+ return _trans_corners_rotation(DLr, c);
+ case _trans_DBr:
+ return _trans_corners_rotation(DBr, c);
+ case _trans_DRr:
+ return _trans_corners_rotation(DRr, c);
+ case _trans_RUr:
+ return _trans_corners_rotation(RUr, c);
+ case _trans_RFr:
+ return _trans_corners_rotation(RFr, c);
+ case _trans_RDr:
+ return _trans_corners_rotation(RDr, c);
+ case _trans_RBr:
+ return _trans_corners_rotation(RBr, c);
+ case _trans_LUr:
+ return _trans_corners_rotation(LUr, c);
+ case _trans_LFr:
+ return _trans_corners_rotation(LFr, c);
+ case _trans_LDr:
+ return _trans_corners_rotation(LDr, c);
+ case _trans_LBr:
+ return _trans_corners_rotation(LBr, c);
+ case _trans_FUr:
+ return _trans_corners_rotation(FUr, c);
+ case _trans_FRr:
+ return _trans_corners_rotation(FRr, c);
+ case _trans_FDr:
+ return _trans_corners_rotation(FDr, c);
+ case _trans_FLr:
+ return _trans_corners_rotation(FLr, c);
+ case _trans_BUr:
+ return _trans_corners_rotation(BUr, c);
+ case _trans_BRr:
+ return _trans_corners_rotation(BRr, c);
+ case _trans_BDr:
+ return _trans_corners_rotation(BDr, c);
+ case _trans_BLr:
+ return _trans_corners_rotation(BLr, c);
+ case _trans_UFm:
+ return _trans_corners_mirrored(UFm, c);
+ case _trans_ULm:
+ return _trans_corners_mirrored(ULm, c);
+ case _trans_UBm:
+ return _trans_corners_mirrored(UBm, c);
+ case _trans_URm:
+ return _trans_corners_mirrored(URm, c);
+ case _trans_DFm:
+ return _trans_corners_mirrored(DFm, c);
+ case _trans_DLm:
+ return _trans_corners_mirrored(DLm, c);
+ case _trans_DBm:
+ return _trans_corners_mirrored(DBm, c);
+ case _trans_DRm:
+ return _trans_corners_mirrored(DRm, c);
+ case _trans_RUm:
+ return _trans_corners_mirrored(RUm, c);
+ case _trans_RFm:
+ return _trans_corners_mirrored(RFm, c);
+ case _trans_RDm:
+ return _trans_corners_mirrored(RDm, c);
+ case _trans_RBm:
+ return _trans_corners_mirrored(RBm, c);
+ case _trans_LUm:
+ return _trans_corners_mirrored(LUm, c);
+ case _trans_LFm:
+ return _trans_corners_mirrored(LFm, c);
+ case _trans_LDm:
+ return _trans_corners_mirrored(LDm, c);
+ case _trans_LBm:
+ return _trans_corners_mirrored(LBm, c);
+ case _trans_FUm:
+ return _trans_corners_mirrored(FUm, c);
+ case _trans_FRm:
+ return _trans_corners_mirrored(FRm, c);
+ case _trans_FDm:
+ return _trans_corners_mirrored(FDm, c);
+ case _trans_FLm:
+ return _trans_corners_mirrored(FLm, c);
+ case _trans_BUm:
+ return _trans_corners_mirrored(BUm, c);
+ case _trans_BRm:
+ return _trans_corners_mirrored(BRm, c);
+ case _trans_BDm:
+ return _trans_corners_mirrored(BDm, c);
+ case _trans_BLm:
+ return _trans_corners_mirrored(BLm, c);
+ default:
+ DBG_LOG("transform error, unknown transformation\n");
+ return zero;
+ }
+}
+
+_static cube_t
+transform(cube_t c, uint8_t t)
+{
+ switch (t) {
+ case _trans_UFr:
+ return _trans_rotation(UFr, c);
+ case _trans_ULr:
+ return _trans_rotation(ULr, c);
+ case _trans_UBr:
+ return _trans_rotation(UBr, c);
+ case _trans_URr:
+ return _trans_rotation(URr, c);
+ case _trans_DFr:
+ return _trans_rotation(DFr, c);
+ case _trans_DLr:
+ return _trans_rotation(DLr, c);
+ case _trans_DBr:
+ return _trans_rotation(DBr, c);
+ case _trans_DRr:
+ return _trans_rotation(DRr, c);
+ case _trans_RUr:
+ return _trans_rotation(RUr, c);
+ case _trans_RFr:
+ return _trans_rotation(RFr, c);
+ case _trans_RDr:
+ return _trans_rotation(RDr, c);
+ case _trans_RBr:
+ return _trans_rotation(RBr, c);
+ case _trans_LUr:
+ return _trans_rotation(LUr, c);
+ case _trans_LFr:
+ return _trans_rotation(LFr, c);
+ case _trans_LDr:
+ return _trans_rotation(LDr, c);
+ case _trans_LBr:
+ return _trans_rotation(LBr, c);
+ case _trans_FUr:
+ return _trans_rotation(FUr, c);
+ case _trans_FRr:
+ return _trans_rotation(FRr, c);
+ case _trans_FDr:
+ return _trans_rotation(FDr, c);
+ case _trans_FLr:
+ return _trans_rotation(FLr, c);
+ case _trans_BUr:
+ return _trans_rotation(BUr, c);
+ case _trans_BRr:
+ return _trans_rotation(BRr, c);
+ case _trans_BDr:
+ return _trans_rotation(BDr, c);
+ case _trans_BLr:
+ return _trans_rotation(BLr, c);
+ case _trans_UFm:
+ return _trans_mirrored(UFm, c);
+ case _trans_ULm:
+ return _trans_mirrored(ULm, c);
+ case _trans_UBm:
+ return _trans_mirrored(UBm, c);
+ case _trans_URm:
+ return _trans_mirrored(URm, c);
+ case _trans_DFm:
+ return _trans_mirrored(DFm, c);
+ case _trans_DLm:
+ return _trans_mirrored(DLm, c);
+ case _trans_DBm:
+ return _trans_mirrored(DBm, c);
+ case _trans_DRm:
+ return _trans_mirrored(DRm, c);
+ case _trans_RUm:
+ return _trans_mirrored(RUm, c);
+ case _trans_RFm:
+ return _trans_mirrored(RFm, c);
+ case _trans_RDm:
+ return _trans_mirrored(RDm, c);
+ case _trans_RBm:
+ return _trans_mirrored(RBm, c);
+ case _trans_LUm:
+ return _trans_mirrored(LUm, c);
+ case _trans_LFm:
+ return _trans_mirrored(LFm, c);
+ case _trans_LDm:
+ return _trans_mirrored(LDm, c);
+ case _trans_LBm:
+ return _trans_mirrored(LBm, c);
+ case _trans_FUm:
+ return _trans_mirrored(FUm, c);
+ case _trans_FRm:
+ return _trans_mirrored(FRm, c);
+ case _trans_FDm:
+ return _trans_mirrored(FDm, c);
+ case _trans_FLm:
+ return _trans_mirrored(FLm, c);
+ case _trans_BUm:
+ return _trans_mirrored(BUm, c);
+ case _trans_BRm:
+ return _trans_mirrored(BRm, c);
+ case _trans_BDm:
+ return _trans_mirrored(BDm, c);
+ case _trans_BLm:
+ return _trans_mirrored(BLm, c);
+ default:
+ DBG_LOG("transform error, unknown transformation\n");
+ return zero;
+ }
+}
diff --git a/src/solve_generic.h b/src/solve_generic.h
@@ -1,19 +1,19 @@
typedef struct {
- cube_fast_t cube;
+ cube_t cube;
uint8_t depth;
int64_t maxsols;
char **nextsol;
int64_t *nsols;
uint8_t nmoves;
uint8_t moves[20];
- uint8_t (*estimate)(cube_fast_t);
+ uint8_t (*estimate)(cube_t);
} dfsarg_generic_t;
_static void solve_generic_appendsolution(dfsarg_generic_t *);
_static int solve_generic_dfs(dfsarg_generic_t *);
_static int64_t solve_generic(cube_t, const char *, int8_t, int8_t, int64_t,
- int8_t, char *, uint8_t (*)(cube_fast_t));
-_static uint8_t estimate_simple(cube_fast_t);
+ int8_t, char *, uint8_t (*)(cube_t));
+_static uint8_t estimate_simple(cube_t);
_static int64_t solve_simple(cube_t, int8_t, int8_t, int64_t, int8_t, char *);
int64_t
@@ -135,7 +135,7 @@ solve_generic(
int64_t maxsols,
int8_t optimal,
char *sols,
- uint8_t (*estimate)(cube_fast_t)
+ uint8_t (*estimate)(cube_t)
/* TODO: add validator */
/* TODO: maybe add data for estimate */
/* TODO: add moveset (and allowednext?) */
@@ -190,7 +190,7 @@ solve_generic(
}
arg = (dfsarg_generic_t) {
- .cube = cubetofast(cube),
+ .cube = cube,
.maxsols = maxsols,
.nextsol = &sols,
.nsols = &ret,
@@ -223,9 +223,9 @@ solve_generic(
}
_static uint8_t
-estimate_simple(cube_fast_t cube)
+estimate_simple(cube_t cube)
{
- return issolved_fast(cube) ? 0 : 1;
+ return issolved(cube) ? 0 : 1;
}
_static int64_t
diff --git a/src/solve_h48.h b/src/solve_h48.h
@@ -20,14 +20,14 @@
#define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8)))
typedef struct {
- cube_fast_t cube;
+ cube_t cube;
uint8_t depth;
uint8_t maxdepth;
uint16_t *n;
uint32_t *buf32;
uint8_t *visited;
uint64_t *selfsim;
- cube_fast_t *rep;
+ cube_t *rep;
} dfsarg_cocsep_t;
typedef struct {
@@ -36,14 +36,14 @@ typedef struct {
uint32_t *cocsepdata;
uint32_t *buf32;
uint64_t *selfsim;
- cube_fast_t *crep;
+ cube_t *crep;
} bfsarg_esep_t;
-_static_inline int64_t coord_h48(cube_fast_t, const uint32_t *, uint8_t);
-_static_inline int64_t coord_h48_edges(cube_fast_t, int64_t, uint8_t, uint8_t);
-_static_inline cube_fast_t invcoord_h48(int64_t, const cube_fast_t *, uint8_t);
+_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t);
+_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t);
+_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t);
-_static size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *);
+_static size_t gendata_cocsep(void *, uint64_t *, cube_t *);
_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *);
_static size_t gendata_h48(void *, uint8_t, uint8_t);
_static uint64_t gendata_esep_bfs(bfsarg_esep_t *);
@@ -54,7 +54,7 @@ _static_inline uint8_t get_esep_pval(const uint32_t *, int64_t);
_static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t);
_static_inline int64_t
-coord_h48(cube_fast_t c, const uint32_t *cocsepdata, uint8_t h)
+coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h)
{
int64_t cocsep, coclass;
uint32_t data;
@@ -62,7 +62,7 @@ coord_h48(cube_fast_t c, const uint32_t *cocsepdata, uint8_t h)
DBG_ASSERT(h <= 11, -1, "coord_h48: h must be between 0 and 11\n");
- cocsep = coord_fast_cocsep(c);
+ cocsep = coord_cocsep(c);
data = cocsepdata[cocsep];
coclass = (int64_t)COCLASS(data);
ttrep = (int64_t)TTREP(data);
@@ -71,14 +71,14 @@ coord_h48(cube_fast_t c, const uint32_t *cocsepdata, uint8_t h)
}
_static_inline int64_t
-coord_h48_edges(cube_fast_t c, int64_t coclass, uint8_t t, uint8_t h)
+coord_h48_edges(cube_t c, int64_t coclass, uint8_t t, uint8_t h)
{
- cube_fast_t d;
+ cube_t d;
int64_t esep, eo, edges;
d = transform_edges(c, t);
- esep = coord_fast_esep(d);
- eo = coord_fast_eo(d);
+ esep = coord_esep(d);
+ eo = coord_eo(d);
edges = (esep << (int64_t)h) + (eo >> (11 - (int64_t)h));
return coclass * H48_ESIZE(h) + edges;
@@ -89,12 +89,12 @@ This function does not necessarily return a cube whose coordinate is
the given value, because it works up to symmetry. This means that the
returned cube is a transformed cube of one that gives the correct value.
*/
-_static_inline cube_fast_t
-invcoord_h48(int64_t i, const cube_fast_t *crep, uint8_t h) {
- cube_fast_t ret;
+_static_inline cube_t
+invcoord_h48(int64_t i, const cube_t *crep, uint8_t h) {
+ cube_t ret;
int64_t hh, coclass, ee, esep, eo;
- DBG_ASSERT(h <= 11, cubetofast(zero),
+ DBG_ASSERT(h <= 11, zero,
"invcoord_h48: h must be between 0 and 11\n");
hh = (int64_t)h;
@@ -103,9 +103,9 @@ invcoord_h48(int64_t i, const cube_fast_t *crep, uint8_t h) {
esep = ee >> hh;
eo = (ee & ((1 << hh) - 1)) << (11 - hh);
- ret = invcoord_fast_esep(esep);
- copy_corners_fast(&ret, crep[coclass]);
- set_eo_fast(&ret, eo);
+ ret = invcoord_esep(esep);
+ copy_corners(&ret, crep[coclass]);
+ set_eo(&ret, eo);
return ret;
}
@@ -122,7 +122,7 @@ After the data as described above, more auxiliary information is appended:
of positions having that pruning value.
*/
_static size_t
-gendata_cocsep(void *buf, uint64_t *selfsim, cube_fast_t *rep)
+gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep)
{
uint32_t *buf32, *info, cc;
uint16_t n;
@@ -135,7 +135,7 @@ gendata_cocsep(void *buf, uint64_t *selfsim, cube_fast_t *rep)
memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES);
arg = (dfsarg_cocsep_t) {
- .cube = cubetofast(solvedcube()),
+ .cube = solved,
.n = &n,
.buf32 = buf32,
.visited = visited,
@@ -175,10 +175,10 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
uint32_t cc, class, ttrep, depth, olddepth;
uint64_t t, is;
int64_t i, j;
- cube_fast_t d;
+ cube_t d;
dfsarg_cocsep_t nextarg;
- i = coord_fast_cocsep(arg->cube);
+ i = coord_cocsep(arg->cube);
olddepth = (uint8_t)(arg->buf32[i] & 0xFF);
if (olddepth < arg->depth || get_visited(arg->visited, i))
return 0;
@@ -190,7 +190,7 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
for (t = 0, cc = 0; t < 48; t++) {
d = transform_corners(arg->cube, t);
- j = coord_fast_cocsep(d);
+ j = coord_cocsep(d);
is = (i == j);
arg->selfsim[*arg->n] |= is << t;
set_visited(arg->visited, j);
@@ -231,7 +231,7 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
bfsarg_esep_t arg;
int64_t sc, cc, tot, esep_max;
uint64_t selfsim[COCSEP_CLASSES];
- cube_fast_t crep[COCSEP_CLASSES];
+ cube_t crep[COCSEP_CLASSES];
size_t cocsepsize, infosize;
esep_max = (int64_t)ESEP_MAX(h);
@@ -241,7 +241,7 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
info = buf32 + (ESEP_TABLESIZE(h, k) / sizeof(uint32_t));
memset(buf32, 0xFF, ESEP_TABLESIZE(h, k));
- sc = coord_h48(cubetofast(solved), cocsepdata, h);
+ sc = coord_h48(solved, cocsepdata, h);
set_esep_pval(buf32, sc, 0);
info[1] = 1;
arg = (bfsarg_esep_t) {
@@ -281,7 +281,7 @@ gendata_esep_bfs(bfsarg_esep_t *arg)
uint8_t c, m, x;
uint32_t cc;
int64_t i, j, k, t, cocsep_coord, sim, esep_max;
- cube_fast_t cube, moved, transd;
+ cube_t cube, moved, transd;
esep_max = (uint64_t)ESEP_MAX(arg->h);
diff --git a/test/001_pieces/pieces_tests.c b/test/001_pieces/pieces_tests.c
@@ -1,13 +1,12 @@
#include "../test.h"
-uint8_t corner(cube_fast_t, int);
-uint8_t edge(cube_fast_t, int);
+void pieces(cube_t *, uint8_t [static 8], uint8_t [static 12]);
int main(void) {
int i;
+ uint8_t corner[8], edge[12];
char str[STRLENMAX], *aux;
cube_t cube;
- cube_fast_t fast;
aux = str;
while (fgets(aux, STRLENMAX, stdin) != NULL)
@@ -15,13 +14,13 @@ int main(void) {
aux++;
cube = readcube("H48", str);
- fast = cubetofast(cube);
+ pieces(&cube, corner, edge);
for (i = 0; i < 8; i++)
- printf("%" PRIu8 " ", corner(fast, i));
+ printf("%" PRIu8 " ", corner[i]);
printf("\n");
for (i = 0; i < 12; i++)
- printf("%" PRIu8 " ", edge(fast, i));
+ printf("%" PRIu8 " ", edge[i]);
printf("\n");
return 0;
diff --git a/test/002_cube_conversion/00_solved.in b/test/002_cube_conversion/00_solved.in
@@ -1 +0,0 @@
-UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0
diff --git a/test/002_cube_conversion/00_solved.out b/test/002_cube_conversion/00_solved.out
@@ -1 +0,0 @@
-UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0
diff --git a/test/002_cube_conversion/01_scrambled.in b/test/002_cube_conversion/01_scrambled.in
@@ -1 +0,0 @@
-BL1 DB0 UL1 DF0 BR1 UF1 DL0 FL1 UB0 DR1 FR1 UR1 UBR2 UBL1 DFR2 DBL2 DBR0 DFL0 UFR0 UFL2
diff --git a/test/002_cube_conversion/01_scrambled.out b/test/002_cube_conversion/01_scrambled.out
@@ -1 +0,0 @@
-BL1 DB0 UL1 DF0 BR1 UF1 DL0 FL1 UB0 DR1 FR1 UR1 UBR2 UBL1 DFR2 DBL2 DBR0 DFL0 UFR0 UFL2
diff --git a/test/002_cube_conversion/cube_conversion_tests.c b/test/002_cube_conversion/cube_conversion_tests.c
@@ -1,25 +0,0 @@
-#include "../test.h"
-
-bool equal(cube_t, cube_t);
-
-int main(void) {
- char cubestr[STRLENMAX];
- cube_t cube, cube2;
- cube_fast_t fast;
-
- fgets(cubestr, STRLENMAX, stdin);
- cube = readcube("H48", cubestr);
- fast = cubetofast(cube);
- cube2 = fasttocube(fast);
-
- if (iserror(cube)) {
- printf("Error reading cube\n");
- } else if (iserror(cube2)) {
- printf("Error converting cube\n");
- } else {
- writecube("H48", cube2, cubestr);
- printf("%s\n", cubestr);
- }
-
- return 0;
-}
diff --git a/test/071_coord_eo/coord_eo_tests.c b/test/071_coord_eo/coord_eo_tests.c
@@ -1,18 +1,16 @@
#include "../test.h"
-int64_t coord_fast_eo(cube_fast_t);
+int64_t coord_eo(cube_t);
int main(void) {
char str[STRLENMAX];
cube_t cube;
- cube_fast_t fast;
int64_t result;
fgets(str, STRLENMAX, stdin);
cube = readcube("H48", str);
- fast = cubetofast(cube);
- result = coord_fast_eo(fast);
+ result = coord_eo(cube);
printf("%" PRId64 "\n", result);
diff --git a/test/072_coord_co/coord_co_tests.c b/test/072_coord_co/coord_co_tests.c
@@ -1,18 +1,16 @@
#include "../test.h"
-int64_t coord_fast_co(cube_fast_t);
+int64_t coord_co(cube_t);
int main(void) {
char str[STRLENMAX];
cube_t cube;
- cube_fast_t fast;
int64_t result;
fgets(str, STRLENMAX, stdin);
cube = readcube("H48", str);
- fast = cubetofast(cube);
- result = coord_fast_co(fast);
+ result = coord_co(cube);
printf("%" PRId64 "\n", result);
diff --git a/test/073_coord_csep/coord_csep_tests.c b/test/073_coord_csep/coord_csep_tests.c
@@ -1,18 +1,16 @@
#include "../test.h"
-int64_t coord_fast_csep(cube_fast_t);
+int64_t coord_csep(cube_t);
int main(void) {
char str[STRLENMAX];
cube_t cube;
- cube_fast_t fast;
int64_t result;
fgets(str, STRLENMAX, stdin);
cube = readcube("H48", str);
- fast = cubetofast(cube);
- result = coord_fast_csep(fast);
+ result = coord_csep(cube);
printf("%" PRId64 "\n", result);
diff --git a/test/074_coord_esep/coord_esep_tests.c b/test/074_coord_esep/coord_esep_tests.c
@@ -1,18 +1,16 @@
#include "../test.h"
-int64_t coord_fast_esep(cube_fast_t);
+int64_t coord_esep(cube_t);
int main(void) {
char str[STRLENMAX];
cube_t cube;
- cube_fast_t fast;
int64_t result;
fgets(str, STRLENMAX, stdin);
cube = readcube("H48", str);
- fast = cubetofast(cube);
- result = coord_fast_esep(fast);
+ result = coord_esep(cube);
printf("%" PRId64 "\n", result);
diff --git a/test/075_set_eo/set_eo_tests.c b/test/075_set_eo/set_eo_tests.c
@@ -1,32 +1,32 @@
#include "../test.h"
-int64_t coord_fast_eo(cube_fast_t);
-void set_eo_fast(cube_fast_t *, int64_t);
+int64_t coord_eo(cube_t);
+void set_eo(cube_t *, int64_t);
+void pieces(cube_t *, uint8_t [static 8], uint8_t [static 12]);
int main(void) {
char str[STRLENMAX];
cube_t cube;
- cube_fast_t fast;
+ uint8_t edge[12], corner[8];
int64_t eo;
fgets(str, STRLENMAX, stdin);
cube = readcube("H48", str);
- fast = cubetofast(cube);
fgets(str, STRLENMAX, stdin);
eo = atoi(str);
- set_eo_fast(&fast, eo);
+ set_eo(&cube, eo);
- cube = fasttocube(fast);
if (iserror(cube)) {
printf("Error setting EO\n");
} else if (!isconsistent(cube)) {
+ pieces(&cube, corner, edge);
fprintf(stderr, "edges: ");
for (int i = 0; i < 12; i++)
- fprintf(stderr, "%d ", cube.edge[i]);
+ fprintf(stderr, "%d ", edge[i]);
fprintf(stderr, "\n");
for (int i = 0; i < 8; i++)
- fprintf(stderr, "%d ", cube.corner[i]);
+ fprintf(stderr, "%d ", corner[i]);
fprintf(stderr, "\n");
printf("Setting EO resulted in inconsistent cube\n");
} else {
diff --git a/test/076_copy_corners/copy_corners_tests.c b/test/076_copy_corners/copy_corners_tests.c
@@ -1,23 +1,19 @@
#include "../test.h"
-void copy_corners_fast(cube_fast_t *, cube_fast_t);
+void copy_corners(cube_t *, cube_t);
int main(void) {
char str[STRLENMAX];
cube_t c1, c2;
- cube_fast_t f1, f2;
fgets(str, STRLENMAX, stdin);
c1 = readcube("H48", str);
- f1 = cubetofast(c1);
fgets(str, STRLENMAX, stdin);
c2 = readcube("H48", str);
- f2 = cubetofast(c2);
- copy_corners_fast(&f1, f2);
+ copy_corners(&c1, c2);
- c1 = fasttocube(f1);
if (iserror(c1)) {
printf("Error setting EO\n");
} else if (!isconsistent(c1)) {
diff --git a/test/077_copy_edges/copy_edges_tests.c b/test/077_copy_edges/copy_edges_tests.c
@@ -1,23 +1,19 @@
#include "../test.h"
-void copy_edges_fast(cube_fast_t *, cube_fast_t);
+void copy_edges(cube_t *, cube_t);
int main(void) {
char str[STRLENMAX];
cube_t c1, c2;
- cube_fast_t f1, f2;
fgets(str, STRLENMAX, stdin);
c1 = readcube("H48", str);
- f1 = cubetofast(c1);
fgets(str, STRLENMAX, stdin);
c2 = readcube("H48", str);
- f2 = cubetofast(c2);
- copy_edges_fast(&f1, f2);
+ copy_edges(&c1, c2);
- c1 = fasttocube(f1);
if (iserror(c1)) {
printf("Error setting EO\n");
} else if (!isconsistent(c1)) {
diff --git a/test/078_invcoord_esep/invcoord_esep_tests.c b/test/078_invcoord_esep/invcoord_esep_tests.c
@@ -1,21 +1,19 @@
#include "../test.h"
-int64_t coord_fast_esep(cube_fast_t);
-cube_fast_t invcoord_fast_esep(int64_t);
+int64_t coord_esep(cube_t);
+cube_t invcoord_esep(int64_t);
int main(void) {
char str[STRLENMAX];
cube_t cube;
- cube_fast_t fast;
int64_t i;
fgets(str, STRLENMAX, stdin);
cube = readcube("H48", str);
- fast = cubetofast(cube);
- i = coord_fast_esep(fast);
- fast = invcoord_fast_esep(i);
- i = coord_fast_esep(fast);
+ i = coord_esep(cube);
+ cube = invcoord_esep(i);
+ i = coord_esep(cube);
printf("%" PRId64 "\n", i);
diff --git a/test/100_gendata_cocsep/gendata_cocsep_tests.c b/test/100_gendata_cocsep/gendata_cocsep_tests.c
@@ -2,12 +2,12 @@
#define COCSEP_CLASSES 3393
-size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *);
+size_t gendata_cocsep(void *, uint64_t *, cube_t *);
int main(void) {
uint32_t buf[300000], i;
uint64_t selfsim[COCSEP_CLASSES];
- cube_fast_t rep[COCSEP_CLASSES];
+ cube_t rep[COCSEP_CLASSES];
size_t result;
result = gendata_cocsep(buf, selfsim, rep);
diff --git a/test/101_cocsep_selfsim/cocsep_selfsim_tests.c b/test/101_cocsep_selfsim/cocsep_selfsim_tests.c
@@ -9,23 +9,23 @@
#define COCSEP_CLASSES 3393
-size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *);
-int64_t coord_fast_cocsep(cube_fast_t);
+size_t gendata_cocsep(void *, uint64_t *, cube_t *);
+int64_t coord_cocsep(cube_t);
int main(void) {
char str[STRLENMAX];
uint32_t buf[300000], data;
int64_t coord, coclass;
uint64_t selfsim[COCSEP_CLASSES], sim, t;
- cube_fast_t fast, rep[COCSEP_CLASSES];
+ cube_t cube, rep[COCSEP_CLASSES];
gendata_cocsep(buf, selfsim, rep);
/* All cases in the same test so we do not generate data many times */
while (fgets(str, STRLENMAX, stdin) != NULL) {
- fast = cubetofast(readcube("H48", str));
- coord = coord_fast_cocsep(fast);
+ cube = readcube("H48", str);
+ coord = coord_cocsep(cube);
data = buf[coord];
coclass = (data & (0xFFFU << 16)) >> 16;
sim = selfsim[coclass];
diff --git a/test/102_coord_invcoord_h48/coord_invcoord_h48_tests.c b/test/102_coord_invcoord_h48/coord_invcoord_h48_tests.c
@@ -2,10 +2,10 @@
#define COCSEP_CLASSES 3393
-size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *);
-int64_t coord_h48(cube_fast_t, const uint32_t *, uint8_t);
-cube_fast_t invcoord_h48(int64_t, const cube_fast_t *, uint8_t);
-cube_fast_t transform(cube_fast_t, uint8_t);
+size_t gendata_cocsep(void *, uint64_t *, cube_t *);
+int64_t coord_h48(cube_t, const uint32_t *, uint8_t);
+cube_t invcoord_h48(int64_t, const cube_t *, uint8_t);
+cube_t transform(cube_t, uint8_t);
int main(void) {
char str[STRLENMAX];
@@ -15,8 +15,7 @@ int main(void) {
uint32_t cocsepdata[300000];
uint64_t selfsim[COCSEP_CLASSES];
int64_t c, cc;
- cube_t cube;
- cube_fast_t fast, invc, rep[COCSEP_CLASSES];
+ cube_t cube, invc, rep[COCSEP_CLASSES];
gendata_cocsep(cocsepdata, selfsim, rep);
@@ -24,12 +23,11 @@ int main(void) {
h = 11;
while (fgets(str, STRLENMAX, stdin) != NULL) {
cube = readcube("H48", str);
- fast = cubetofast(cube);
- c = coord_h48(fast, cocsepdata, h);
+ c = coord_h48(cube, cocsepdata, h);
invc = invcoord_h48(c, rep, h);
for (t = 0, found = false; t < 48; t++) {
- fast = transform(invc, t);
- cc = coord_h48(fast, cocsepdata, h);
+ cube = transform(invc, t);
+ cc = coord_h48(cube, cocsepdata, h);
found = found || cc == c;
}
printf("%d %s\n", i, found ? "ok" : "ERROR");
diff --git a/test/test.h b/test/test.h
@@ -6,16 +6,14 @@
#define STRLENMAX 10000
+#ifdef CUBE_AVX2
+#include <immintrin.h>
+typedef __m256i cube_t;
+#else
typedef struct {
uint8_t corner[8];
uint8_t edge[12];
} cube_t;
-
-#ifdef CUBE_AVX2
-#include <immintrin.h>
-typedef __m256i cube_fast_t;
-#else
-typedef cube_t cube_fast_t;
#endif
/* Basic functions used in most tests */
@@ -26,5 +24,3 @@ bool issolvable(cube_t);
bool issolved(cube_t);
cube_t readcube(char *, char *);
void writecube(char *, cube_t, char *);
-cube_t fasttocube(cube_fast_t);
-cube_fast_t cubetofast(cube_t);