aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.txt21
-rw-r--r--old/_trans_move_arr.c389
-rw-r--r--old/gendata_bfs_attempt.c153
-rw-r--r--old/inverse_fast.c51
-rw-r--r--old/inverses.c71
-rwxr-xr-xold/moves_trans/genmovecode.sh19
-rwxr-xr-xold/moves_trans/gentranscode.sh42
-rw-r--r--old/moves_trans/moves_src.c264
-rwxr-xr-xold/moves_trans/v2/genmovecode.sh21
-rwxr-xr-xold/moves_trans/v2/gentranscode.sh24
-rw-r--r--src/cube.c2
-rw-r--r--src/cube_avx2.h53
-rw-r--r--src/cube_generic.h488
-rw-r--r--src/cube_portable.h22
-rw-r--r--src/io_cube.h359
-rw-r--r--src/io_move_trans.h87
16 files changed, 550 insertions, 1516 deletions
diff --git a/TODO.txt b/TODO.txt
index 86ffd22..ca867c6 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,18 +1,23 @@
1Refactoring: remove cube_fast_t and add b32 format 1Refactoring: remove cube_fast_t and add b32 format
2 - fix all public functions in cube.h 2 - cleanup cube.h
3 and their implementations in cube_generic 3 remove some documentation, move to new file
4 - cube i/o format 4 create src/cube_pulic.h for implementations of cube.h stuff
5 move all formats other than b32 to convert.{c,h} 5 - switch to b32 by default (part 1)
6 add tests for conversion 6 add tests for b32 (write at some by hand)
7 convert test files (?) 7 - fix utility code in utils/*.c
8 make b32 default 8 replace h48_to_lst with convert.c
9 replace utils/*.c with a generic convert utility 9 fix invert.c
10 fix utils/*.sh scripts to use the new convert
11 convert all utils/cubes/*.txt files in b32 format
12 - switch to b32 by default (part 2)
13 change all tests to use b32
10 - if all public functions work with strings, always use return value 14 - if all public functions work with strings, always use return value
11 as error code (solve already does this), and use string as buffer 15 as error code (solve already does this), and use string as buffer
12 to print error 16 to print error
13 17
14Transform with big table 18Transform with big table
15 - make static cube actually static (how?) 19 - make static cube actually static (how?)
20 - if not possible, cleanup in some way
16 21
17Solver 22Solver
18 - write a solver (how many tricks? some, but not all are needed) 23 - write a solver (how many tricks? some, but not all are needed)
diff --git a/old/_trans_move_arr.c b/old/_trans_move_arr.c
deleted file mode 100644
index a00105f..0000000
--- a/old/_trans_move_arr.c
+++ /dev/null
@@ -1,389 +0,0 @@
1static cube_t trans_move_cube[] = {
2 [UFr] = {
3 .c = {0, 1, 2, 3, 4, 5, 6, 7},
4 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
5 },
6 [ULr] = {
7 .c = {4, 5, 7, 6, 1, 0, 2, 3},
8 .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24}
9 },
10 [UBr] = {
11 .c = {1, 0, 3, 2, 5, 4, 7, 6},
12 .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9}
13 },
14 [URr] = {
15 .c = {5, 4, 6, 7, 0, 1, 3, 2},
16 .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26}
17 },
18 [DFr] = {
19 .c = {2, 3, 0, 1, 6, 7, 4, 5},
20 .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10}
21 },
22 [DLr] = {
23 .c = {7, 6, 4, 5, 2, 3, 1, 0},
24 .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27}
25 },
26 [DBr] = {
27 .c = {3, 2, 1, 0, 7, 6, 5, 4},
28 .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8}
29 },
30 [DRr] = {
31 .c = {6, 7, 5, 4, 3, 2, 0, 1},
32 .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25}
33 },
34 [RUr] = {
35 .c = {64, 67, 65, 66, 37, 38, 36, 39},
36 .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3}
37 },
38 [RFr] = {
39 .c = {38, 37, 36, 39, 64, 67, 66, 65},
40 .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18}
41 },
42 [RDr] = {
43 .c = {67, 64, 66, 65, 38, 37, 39, 36},
44 .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1}
45 },
46 [RBr] = {
47 .c = {37, 38, 39, 36, 67, 64, 65, 66},
48 .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16}
49 },
50 [LUr] = {
51 .c = {65, 66, 64, 67, 36, 39, 37, 38},
52 .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2}
53 },
54 [LFr] = {
55 .c = {36, 39, 38, 37, 66, 65, 64, 67},
56 .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17}
57 },
58 [LDr] = {
59 .c = {66, 65, 67, 64, 39, 36, 38, 37},
60 .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0}
61 },
62 [LBr] = {
63 .c = {39, 36, 37, 38, 65, 66, 67, 64},
64 .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19}
65 },
66 [FUr] = {
67 .c = {68, 70, 69, 71, 32, 34, 33, 35},
68 .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6}
69 },
70 [FRr] = {
71 .c = {32, 34, 35, 33, 70, 68, 69, 71},
72 .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21}
73 },
74 [FDr] = {
75 .c = {70, 68, 71, 69, 34, 32, 35, 33},
76 .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4}
77 },
78 [FLr] = {
79 .c = {34, 32, 33, 35, 68, 70, 71, 69},
80 .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23}
81 },
82 [BUr] = {
83 .c = {69, 71, 68, 70, 33, 35, 32, 34},
84 .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7}
85 },
86 [BRr] = {
87 .c = {35, 33, 32, 34, 69, 71, 70, 68},
88 .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22}
89 },
90 [BDr] = {
91 .c = {71, 69, 70, 68, 35, 33, 34, 32},
92 .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5}
93 },
94 [BLr] = {
95 .c = {33, 35, 34, 32, 71, 69, 68, 70},
96 .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20}
97 },
98 [UFm] = {
99 .c = {4, 5, 6, 7, 0, 1, 2, 3},
100 .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10}
101 },
102 [ULm] = {
103 .c = {0, 1, 3, 2, 5, 4, 6, 7},
104 .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25}
105 },
106 [UBm] = {
107 .c = {5, 4, 7, 6, 1, 0, 3, 2},
108 .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8}
109 },
110 [URm] = {
111 .c = {1, 0, 2, 3, 4, 5, 7, 6},
112 .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27}
113 },
114 [DFm] = {
115 .c = {6, 7, 4, 5, 2, 3, 0, 1},
116 .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11}
117 },
118 [DLm] = {
119 .c = {3, 2, 0, 1, 6, 7, 5, 4},
120 .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26}
121 },
122 [DBm] = {
123 .c = {7, 6, 5, 4, 3, 2, 1, 0},
124 .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9}
125 },
126 [DRm] = {
127 .c = {2, 3, 1, 0, 7, 6, 4, 5},
128 .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24}
129 },
130 [RUm] = {
131 .c = {68, 71, 69, 70, 33, 34, 32, 35},
132 .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3}
133 },
134 [RFm] = {
135 .c = {34, 33, 32, 35, 68, 71, 70, 69},
136 .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18}
137 },
138 [RDm] = {
139 .c = {71, 68, 70, 69, 34, 33, 35, 32},
140 .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1}
141 },
142 [RBm] = {
143 .c = {33, 34, 35, 32, 71, 68, 69, 70},
144 .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16}
145 },
146 [LUm] = {
147 .c = {69, 70, 68, 71, 32, 35, 33, 34},
148 .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2}
149 },
150 [LFm] = {
151 .c = {32, 35, 34, 33, 70, 69, 68, 71},
152 .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17}
153 },
154 [LDm] = {
155 .c = {70, 69, 71, 68, 35, 32, 34, 33},
156 .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0}
157 },
158 [LBm] = {
159 .c = {35, 32, 33, 34, 69, 70, 71, 68},
160 .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19}
161 },
162 [FUm] = {
163 .c = {64, 66, 65, 67, 36, 38, 37, 39},
164 .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7}
165 },
166 [FRm] = {
167 .c = {36, 38, 39, 37, 66, 64, 65, 67},
168 .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20}
169 },
170 [FDm] = {
171 .c = {66, 64, 67, 65, 38, 36, 39, 37},
172 .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5}
173 },
174 [FLm] = {
175 .c = {38, 36, 37, 39, 64, 66, 67, 65},
176 .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22}
177 },
178 [BUm] = {
179 .c = {65, 67, 64, 66, 37, 39, 36, 38},
180 .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6}
181 },
182 [BRm] = {
183 .c = {39, 37, 36, 38, 65, 67, 66, 64},
184 .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23}
185 },
186 [BDm] = {
187 .c = {67, 65, 66, 64, 39, 37, 38, 36},
188 .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4}
189 },
190 [BLm] = {
191 .c = {37, 39, 38, 36, 67, 65, 64, 66},
192 .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21}
193 },
194};
195
196static cube_t trans_move_cube_inverse[] = {
197 [UFr] = {
198 .c = {0, 1, 2, 3, 4, 5, 6, 7},
199 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
200 },
201 [ULr] = {
202 .c = {5, 4, 6, 7, 0, 1, 3, 2},
203 .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26}
204 },
205 [UBr] = {
206 .c = {1, 0, 3, 2, 5, 4, 7, 6},
207 .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9}
208 },
209 [URr] = {
210 .c = {4, 5, 7, 6, 1, 0, 2, 3},
211 .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24}
212 },
213 [DFr] = {
214 .c = {2, 3, 0, 1, 6, 7, 4, 5},
215 .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10}
216 },
217 [DLr] = {
218 .c = {7, 6, 4, 5, 2, 3, 1, 0},
219 .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27}
220 },
221 [DBr] = {
222 .c = {3, 2, 1, 0, 7, 6, 5, 4},
223 .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8}
224 },
225 [DRr] = {
226 .c = {6, 7, 5, 4, 3, 2, 0, 1},
227 .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25}
228 },
229 [RUr] = {
230 .c = {32, 34, 35, 33, 70, 68, 69, 71},
231 .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21}
232 },
233 [RFr] = {
234 .c = {36, 39, 38, 37, 66, 65, 64, 67},
235 .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17}
236 },
237 [RDr] = {
238 .c = {33, 35, 34, 32, 71, 69, 68, 70},
239 .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20}
240 },
241 [RBr] = {
242 .c = {37, 38, 39, 36, 67, 64, 65, 66},
243 .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16}
244 },
245 [LUr] = {
246 .c = {34, 32, 33, 35, 68, 70, 71, 69},
247 .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23}
248 },
249 [LFr] = {
250 .c = {38, 37, 36, 39, 64, 67, 66, 65},
251 .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18}
252 },
253 [LDr] = {
254 .c = {35, 33, 32, 34, 69, 71, 70, 68},
255 .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22}
256 },
257 [LBr] = {
258 .c = {39, 36, 37, 38, 65, 66, 67, 64},
259 .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19}
260 },
261 [FUr] = {
262 .c = {68, 70, 69, 71, 32, 34, 33, 35},
263 .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6}
264 },
265 [FRr] = {
266 .c = {64, 67, 65, 66, 37, 38, 36, 39},
267 .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3}
268 },
269 [FDr] = {
270 .c = {69, 71, 68, 70, 33, 35, 32, 34},
271 .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7}
272 },
273 [FLr] = {
274 .c = {65, 66, 64, 67, 36, 39, 37, 38},
275 .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2}
276 },
277 [BUr] = {
278 .c = {70, 68, 71, 69, 34, 32, 35, 33},
279 .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4}
280 },
281 [BRr] = {
282 .c = {66, 65, 67, 64, 39, 36, 38, 37},
283 .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0}
284 },
285 [BDr] = {
286 .c = {71, 69, 70, 68, 35, 33, 34, 32},
287 .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5}
288 },
289 [BLr] = {
290 .c = {67, 64, 66, 65, 38, 37, 39, 36},
291 .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1}
292 },
293 [UFm] = {
294 .c = {4, 5, 6, 7, 0, 1, 2, 3},
295 .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10}
296 },
297 [ULm] = {
298 .c = {0, 1, 3, 2, 5, 4, 6, 7},
299 .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25}
300 },
301 [UBm] = {
302 .c = {5, 4, 7, 6, 1, 0, 3, 2},
303 .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8}
304 },
305 [URm] = {
306 .c = {1, 0, 2, 3, 4, 5, 7, 6},
307 .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27}
308 },
309 [DFm] = {
310 .c = {6, 7, 4, 5, 2, 3, 0, 1},
311 .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11}
312 },
313 [DLm] = {
314 .c = {2, 3, 1, 0, 7, 6, 4, 5},
315 .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24}
316 },
317 [DBm] = {
318 .c = {7, 6, 5, 4, 3, 2, 1, 0},
319 .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9}
320 },
321 [DRm] = {
322 .c = {3, 2, 0, 1, 6, 7, 5, 4},
323 .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26}
324 },
325 [RUm] = {
326 .c = {70, 68, 69, 71, 32, 34, 35, 33},
327 .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22}
328 },
329 [RFm] = {
330 .c = {66, 65, 64, 67, 36, 39, 38, 37},
331 .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18}
332 },
333 [RDm] = {
334 .c = {71, 69, 68, 70, 33, 35, 34, 32},
335 .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23}
336 },
337 [RBm] = {
338 .c = {67, 64, 65, 66, 37, 38, 39, 36},
339 .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19}
340 },
341 [LUm] = {
342 .c = {68, 70, 71, 69, 34, 32, 33, 35},
343 .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20}
344 },
345 [LFm] = {
346 .c = {64, 67, 66, 65, 38, 37, 36, 39},
347 .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17}
348 },
349 [LDm] = {
350 .c = {69, 71, 70, 68, 35, 33, 32, 34},
351 .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21}
352 },
353 [LBm] = {
354 .c = {65, 66, 67, 64, 39, 36, 37, 38},
355 .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16}
356 },
357 [FUm] = {
358 .c = {32, 34, 33, 35, 68, 70, 69, 71},
359 .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7}
360 },
361 [FRm] = {
362 .c = {37, 38, 36, 39, 64, 67, 65, 66},
363 .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2}
364 },
365 [FDm] = {
366 .c = {33, 35, 32, 34, 69, 71, 68, 70},
367 .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6}
368 },
369 [FLm] = {
370 .c = {36, 39, 37, 38, 65, 66, 64, 67},
371 .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3}
372 },
373 [BUm] = {
374 .c = {34, 32, 35, 33, 70, 68, 71, 69},
375 .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5}
376 },
377 [BRm] = {
378 .c = {39, 36, 38, 37, 66, 65, 67, 64},
379 .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1}
380 },
381 [BDm] = {
382 .c = {35, 33, 34, 32, 71, 69, 70, 68},
383 .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4}
384 },
385 [BLm] = {
386 .c = {38, 37, 39, 36, 67, 64, 66, 65},
387 .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0}
388 },
389};
diff --git a/old/gendata_bfs_attempt.c b/old/gendata_bfs_attempt.c
deleted file mode 100644
index 4cd5ae9..0000000
--- a/old/gendata_bfs_attempt.c
+++ /dev/null
@@ -1,153 +0,0 @@
1_static size_t gendata_cocsep(void *);
2_static uint32_t dfs_cocsep(cube_fast_t, uint8_t, uint8_t, uint32_t *);
3
4/*
5Each element of the cocsep table is a uint32_t used as follows:
6 - Lowest 8-bit block: pruning value
7 - Second-lower 8-bit block: "ttrep" (transformation to representative)
8 - Top 16-bit block: symcoord value
9After the data as described above, more auxiliary information is appended:
10 - A uint32_t representing the number of symmetry classes
11 - A uint32_t representing the highest value of the pruning table
12 - One uint32_t for each "line" of the pruning table, representing the number
13 of positions having that pruning value.
14*/
15_static size_t
16gendata_cocsep(void *buf)
17{
18 uint32_t *buf32, cc;
19 uint64_t i64;
20 uint16_t n;
21 uint8_t i, j;
22 size_t tablesize;
23
24 tablesize = _3p7 << 7U;
25
26 buf32 = (uint32_t *)buf;
27 memset(buf32, 0xFFU, 4*tablesize);
28 memset(buf32 + tablesize, 0, 21*4);
29
30/* New impl BFS
31
32 uint32_t nold = 0, nnew = 0;
33 uint64_t coord;
34 uint8_t m, olddepth;
35 cube_fast_t c, d, oldlevel[100000], newlevel[100000];
36 newlevel[0] = cubetofast(solvedcube());
37 nnew = 1;
38 buf32[coord_fast_cocsep(newlevel[0])] = UFr << 8U;
39 n = 1;
40 DBG_LOG("gendata_cocsep: found 1 position at depth 0\n");
41 for (i = 1; i < 10; i++) {
42 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
43 memcpy(oldlevel, newlevel, nnew * sizeof(cube_fast_t));
44 nold = nnew;
45 nnew = 0;
46 for (j = 0; j < nold; j++) {
47 _foreach_move(m, oldlevel[j], newlevel[nnew],
48 coord = coord_fast_cocsep(newlevel[nnew]);
49 olddepth = buf32[coord] & 0xFFU;
50 buf32[coord] = i;
51 nnew += olddepth > i;
52 )
53 }
54 DBG_LOG("found %" PRIu32 "\n", nnew);
55 }
56
57End new impl BFS */
58
59 /* Pruning values */
60 buf32[tablesize+1] = 9U; /* Known max pruning value */
61 for (i = 0, cc = 0; i < 10; i++) {
62 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
63 cc = dfs_cocsep(cubetofast(solvedcube()), 0, i, buf32);
64 buf32[tablesize+i+2] = cc;
65 DBG_LOG("found %" PRIu32 "\n", cc);
66 }
67
68 /* Symmetries */
69 for (i64 = 0, n = 0; i64 < tablesize; i64++) {
70 }
71 buf32[tablesize] = (uint32_t)n;
72
73 DBG_LOG("cocsep data computed, %" PRIu32 " symmetry classes\n", n);
74 DBG_LOG("Maximum pruning value: %" PRIu32 "\n", buf32[tablesize+1]);
75 DBG_LOG("Pruning value distribution:\n");
76 for (j = 0; j < 10; j++)
77 DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+2]);
78
79 return 4*(tablesize + 11);
80}
81
82_static uint32_t
83dfs_cocsep(cube_fast_t c, uint8_t depth, uint8_t maxdepth, uint32_t *buf32)
84{
85 uint8_t m, olddepth;
86 uint32_t update, cc;
87 uint64_t i;
88 cube_fast_t d;
89
90 i = coord_fast_cocsep(c);
91 olddepth = (uint8_t)(buf32[i] & 0xFFU);
92 if (olddepth < depth)
93 return 0;
94
95 if (depth == maxdepth) {
96 update = (buf32[i] & 0xFFU) == 0xFFU;
97 buf32[i] = depth;
98 return update;
99 }
100
101 cc = 0;
102 _foreach_move(m, c, d,
103 cc += dfs_cocsep(d, depth+1, maxdepth, buf32);
104 )
105
106 return cc;
107}
108
109/*
110_static uint32_t
111dfs_cocsep(
112 cube_fast_t c,
113 uint8_t depth,
114 uint8_t maxdepth,
115 uint16_t *n,
116 uint32_t *buf32
117)
118{
119 uint8_t m, t, tinv, olddepth;
120 uint32_t cc, oldvalue;
121 uint64_t i;
122 cube_fast_t d;
123
124 oldvalue = buf32[coord_fast_cocsep(c)];
125 if (depth == maxdepth) {
126 if ((oldvalue & 0xFFU) != 0xFFU)
127 return 0;
128
129 for (t = 0, cc = 0; t < 48; t++) {
130 d = transform(c, t);
131 i = coord_fast_cocsep(d);
132 tinv = inverse_trans(t);
133 if ((buf32[i] & 0xFFU) == 0xFFU)
134 cc++;
135 buf32[i] = (*n << 16U) | (tinv << 8U) | depth;
136 }
137 (*n)++;
138
139 return cc;
140 }
141
142 olddepth = (uint8_t)(oldvalue & 0xFFU);
143 if (olddepth != depth)
144 return 0;
145
146 cc = 0;
147 _foreach_move(m, c, d,
148 cc += dfs_cocsep(d, depth+1, maxdepth, n, buf32);
149 )
150
151 return cc;
152}
153*/
diff --git a/old/inverse_fast.c b/old/inverse_fast.c
deleted file mode 100644
index 13ace58..0000000
--- a/old/inverse_fast.c
+++ /dev/null
@@ -1,51 +0,0 @@
1_static_inline cube_fast_t
2cleanaftershuffle(cube_fast_t c)
3{
4 __m256i b;
5
6 b = _mm256_set_epi8(
7 ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0
9 );
10
11 return _mm256_andnot_si256(b, c);
12}
13
14_static_inline cube_fast_t
15inverse_fast(cube_fast_t c)
16{
17 /* Method taken from Andrew Skalski's vcube[1]. The addition sequence
18 * was generated using [2].
19 * [1] https://github.com/Voltara/vcube
20 * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
21 */
22 cube_fast_t v3, vi, vo, vp, ret;
23
24 v3 = _mm256_shuffle_epi8(c, c);
25 v3 = _mm256_shuffle_epi8(v3, c);
26 vi = _mm256_shuffle_epi8(v3, v3);
27 vi = _mm256_shuffle_epi8(vi, vi);
28 vi = _mm256_shuffle_epi8(vi, vi);
29 vi = _mm256_shuffle_epi8(vi, v3);
30 vi = _mm256_shuffle_epi8(vi, vi);
31 vi = _mm256_shuffle_epi8(vi, vi);
32 vi = _mm256_shuffle_epi8(vi, vi);
33 vi = _mm256_shuffle_epi8(vi, vi);
34 vi = _mm256_shuffle_epi8(vi, c);
35 vi = _mm256_shuffle_epi8(vi, vi);
36 vi = _mm256_shuffle_epi8(vi, vi);
37 vi = _mm256_shuffle_epi8(vi, vi);
38 vi = _mm256_shuffle_epi8(vi, vi);
39 vi = _mm256_shuffle_epi8(vi, vi);
40 vi = _mm256_shuffle_epi8(vi, v3);
41 vi = _mm256_shuffle_epi8(vi, vi);
42 vi = _mm256_shuffle_epi8(vi, c);
43
44 vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2));
45 vo = _mm256_shuffle_epi8(vo, vi);
46 vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi);
47 ret = _mm256_or_si256(vp, vo);
48 ret = cleanaftershuffle(ret);
49
50 return invertco_fast(ret);
51}
diff --git a/old/inverses.c b/old/inverses.c
deleted file mode 100644
index eb8e80b..0000000
--- a/old/inverses.c
+++ /dev/null
@@ -1,71 +0,0 @@
1static move_t inverse_move_arr[] = {
2 [U] = U3,
3 [U2] = U2,
4 [U3] = U,
5 [D] = D3,
6 [D2] = D2,
7 [D3] = D,
8 [R] = R3,
9 [R2] = R2,
10 [R3] = R,
11 [L] = L3,
12 [L2] = L2,
13 [L3] = L,
14 [F] = F3,
15 [F2] = F2,
16 [F3] = F,
17 [B] = B3,
18 [B2] = B2,
19 [B3] = B,
20};
21
22static trans_t inverse_trans_arr[] = {
23 [UFr] = UFr,
24 [ULr] = URr,
25 [UBr] = UBr,
26 [URr] = URr,
27 [DFr] = DFr,
28 [DLr] = DLr,
29 [DRr] = DRr,
30 [DBr] = DBr,
31 [RUr] = FRr,
32 [RFr] = LFr,
33 [RDr] = BLr,
34 [RBr] = RBr,
35 [LUr] = FLr,
36 [LFr] = RFr,
37 [LDr] = BRr,
38 [LBr] = LBr,
39 [FUr] = FUr,
40 [FRr] = RUr,
41 [FDr] = BUr,
42 [FLr] = LUr,
43 [BUr] = FDr,
44 [BLr] = RDr,
45 [BDr] = BDr,
46 [BRr] = LDr,
47 [UFm] = UFm,
48 [ULm] = ULm,
49 [UBm] = UBm,
50 [URm] = ULm,
51 [DFm] = DFm,
52 [DLm] = DRm,
53 [DRm] = DLm,
54 [DBm] = DBm,
55 [RUm] = FLm,
56 [RFm] = RFm,
57 [RDm] = BRm,
58 [RBm] = LBm,
59 [LUm] = FRm,
60 [LFm] = LFm,
61 [LDm] = BLm,
62 [LBm] = RBm,
63 [FUm] = FUm,
64 [FRm] = LUm,
65 [FDm] = BUm,
66 [FLm] = RUm,
67 [BUm] = FDm,
68 [BLm] = LDm,
69 [BDm] = BDm,
70 [BRm] = RDm,
71};
diff --git a/old/moves_trans/genmovecode.sh b/old/moves_trans/genmovecode.sh
deleted file mode 100755
index 0857f31..0000000
--- a/old/moves_trans/genmovecode.sh
+++ /dev/null
@@ -1,19 +0,0 @@
1#!/bin/sh
2
3type="${1:-src}"
4
5gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
6
7genfuncs() {
8 for f in move_??_*.txt; do
9 move="$(echo $f | sed 's/.*_// ; s/\.txt//')"
10 printf 'static inline cube_fast_t\n_move_%s' "$move"
11 printf '(cube_fast_t c)\n{\n'
12 printf '\tcube_fast_t m = '
13 ./h48_to_"$type" <"$f" | sed '2,4s/^/\t/'
14 printf ';\n\n\treturn compose_fast(c, m);\n}\n\n'
15 done
16}
17
18genfuncs
19rm -f h48_to_"$type" invert
diff --git a/old/moves_trans/gentranscode.sh b/old/moves_trans/gentranscode.sh
deleted file mode 100755
index 198ac93..0000000
--- a/old/moves_trans/gentranscode.sh
+++ /dev/null
@@ -1,42 +0,0 @@
1#!/bin/sh
2
3type="${1:-src}"
4
5gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
6gcc -DDEBUG invert.c ../cube.c -o invert
7
8# Old version
9genarray() {
10 for f in transform_??_???.txt; do
11 trans="$(echo $f | sed 's/.*_// ; s/\.txt//')"
12 printf '[%s] = ' "$trans"
13 if [ "$1" = "-i" ]; then
14 ./invert <"$f" | ./h48_to_"$type"
15 else
16 ./h48_to_"$type" <"$f"
17 fi
18 printf ',\n'
19 done
20}
21
22genfuncs() {
23 for f in transform_??_???.txt; do
24 trans="$(echo $f | sed 's/.*_// ; s/\.txt//')"
25 printf 'static inline cube_fast_t\n_trans_%s' "$trans"
26 printf '(cube_fast_t c)\n{\n'
27 printf '\tcube_fast_t ret;\n\n'
28 printf '\tcube_fast_t tn = '
29 ./h48_to_"$type" <"$f" | sed '2,4s/^/\t/'
30 printf ';\n\tcube_fast_t ti = '
31 ./invert <"$f" | ./h48_to_"$type" | sed '2,4 s/^/\t/'
32 printf ';\n\n\tret = compose_fast(tn, c);\n'
33 printf '\tret = compose_fast(ret, ti);\n'
34 if [ -n "$(echo "$trans" | grep "m")" ]; then
35 printf '\tret = invertco_fast(ret);\n'
36 fi
37 printf '\n\treturn ret;\n}\n\n'
38 done
39}
40
41genfuncs
42rm -f h48_to_"$type" invert
diff --git a/old/moves_trans/moves_src.c b/old/moves_trans/moves_src.c
deleted file mode 100644
index faf4729..0000000
--- a/old/moves_trans/moves_src.c
+++ /dev/null
@@ -1,264 +0,0 @@
1#define PERM4(r, i, j, k, l) \
2 aux = r[i]; \
3 r[i] = r[l]; \
4 r[l] = r[k]; \
5 r[k] = r[j]; \
6 r[j] = aux;
7#define PERM22(r, i, j, k, l) \
8 aux = r[i]; \
9 r[i] = r[j]; \
10 r[j] = aux; \
11 aux = r[k]; \
12 r[k] = r[l]; \
13 r[l] = aux;
14#define CO(a, b) \
15 aux = (a & _cobits) + (b & _cobits); \
16 auy = (aux + _ctwist_cw) >> 2U; \
17 auz = (aux + auy) & _cobits2; \
18 a = (a & _pbits) | auz;
19#define CO4(r, i, j, k, l) \
20 CO(r[i], _ctwist_cw) \
21 CO(r[j], _ctwist_cw) \
22 CO(r[k], _ctwist_ccw) \
23 CO(r[l], _ctwist_ccw)
24#define EO4(r, i, j, k, l) \
25 r[i] ^= _eobit; \
26 r[j] ^= _eobit; \
27 r[k] ^= _eobit; \
28 r[l] ^= _eobit;
29
30_static_inline cube_fast_t
31_move_U(cube_fast_t c)
32{
33 uint8_t aux;
34 cube_fast_t ret = c;
35
36 PERM4(ret.edge, _e_uf, _e_ul, _e_ub, _e_ur)
37 PERM4(ret.corner, _c_ufr, _c_ufl, _c_ubl, _c_ubr)
38
39 return ret;
40}
41
42_static_inline cube_fast_t
43_move_U2(cube_fast_t c)
44{
45 uint8_t aux;
46 cube_fast_t ret = c;
47
48 PERM22(ret.edge, _e_uf, _e_ub, _e_ul, _e_ur)
49 PERM22(ret.corner, _c_ufr, _c_ubl, _c_ufl, _c_ubr)
50
51 return ret;
52}
53
54_static_inline cube_fast_t
55_move_U3(cube_fast_t c)
56{
57 uint8_t aux;
58 cube_fast_t ret = c;
59
60 PERM4(ret.edge, _e_uf, _e_ur, _e_ub, _e_ul)
61 PERM4(ret.corner, _c_ufr, _c_ubr, _c_ubl, _c_ufl)
62
63 return ret;
64}
65
66_static_inline cube_fast_t
67_move_D(cube_fast_t c)
68{
69 uint8_t aux;
70 cube_fast_t ret = c;
71
72 PERM4(ret.edge, _e_df, _e_dr, _e_db, _e_dl)
73 PERM4(ret.corner, _c_dfr, _c_dbr, _c_dbl, _c_dfl)
74
75 return ret;
76}
77
78_static_inline cube_fast_t
79_move_D2(cube_fast_t c)
80{
81 uint8_t aux;
82 cube_fast_t ret = c;
83
84 PERM22(ret.edge, _e_df, _e_db, _e_dr, _e_dl)
85 PERM22(ret.corner, _c_dfr, _c_dbl, _c_dbr, _c_dfl)
86
87 return ret;
88}
89
90_static_inline cube_fast_t
91_move_D3(cube_fast_t c)
92{
93 uint8_t aux;
94 cube_fast_t ret = c;
95
96 PERM4(ret.edge, _e_df, _e_dl, _e_db, _e_dr)
97 PERM4(ret.corner, _c_dfr, _c_dfl, _c_dbl, _c_dbr)
98
99 return ret;
100}
101
102_static_inline cube_fast_t
103_move_R(cube_fast_t c)
104{
105 uint8_t aux, auy, auz;
106 cube_fast_t ret = c;
107
108 PERM4(ret.edge, _e_ur, _e_br, _e_dr, _e_fr)
109 PERM4(ret.corner, _c_ufr, _c_ubr, _c_dbr, _c_dfr)
110
111 CO4(ret.corner, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
112
113 return ret;
114}
115
116_static_inline cube_fast_t
117_move_R2(cube_fast_t c)
118{
119 uint8_t aux;
120 cube_fast_t ret = c;
121
122 PERM22(ret.edge, _e_ur, _e_dr, _e_fr, _e_br)
123 PERM22(ret.corner, _c_ufr, _c_dbr, _c_ubr, _c_dfr)
124
125 return ret;
126}
127
128_static_inline cube_fast_t
129_move_R3(cube_fast_t c)
130{
131 uint8_t aux, auy, auz;
132 cube_fast_t ret = c;
133
134 PERM4(ret.edge, _e_ur, _e_fr, _e_dr, _e_br)
135 PERM4(ret.corner, _c_ufr, _c_dfr, _c_dbr, _c_ubr)
136
137 CO4(ret.corner, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
138
139 return ret;
140}
141
142_static_inline cube_fast_t
143_move_L(cube_fast_t c)
144{
145 uint8_t aux, auy, auz;
146 cube_fast_t ret = c;
147
148 PERM4(ret.edge, _e_ul, _e_fl, _e_dl, _e_bl)
149 PERM4(ret.corner, _c_ufl, _c_dfl, _c_dbl, _c_ubl)
150
151 CO4(ret.corner, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
152
153 return ret;
154}
155
156_static_inline cube_fast_t
157_move_L2(cube_fast_t c)
158{
159 uint8_t aux;
160 cube_fast_t ret = c;
161
162 PERM22(ret.edge, _e_ul, _e_dl, _e_fl, _e_bl)
163 PERM22(ret.corner, _c_ufl, _c_dbl, _c_ubl, _c_dfl)
164
165 return ret;
166}
167
168_static_inline cube_fast_t
169_move_L3(cube_fast_t c)
170{
171 uint8_t aux, auy, auz;
172 cube_fast_t ret = c;
173
174 PERM4(ret.edge, _e_ul, _e_bl, _e_dl, _e_fl)
175 PERM4(ret.corner, _c_ufl, _c_ubl, _c_dbl, _c_dfl)
176
177 CO4(ret.corner, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
178
179 return ret;
180}
181
182_static_inline cube_fast_t
183_move_F(cube_fast_t c)
184{
185 uint8_t aux, auy, auz;
186 cube_fast_t ret = c;
187
188 PERM4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl)
189 PERM4(ret.corner, _c_ufr, _c_dfr, _c_dfl, _c_ufl)
190
191 EO4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl)
192 CO4(ret.corner, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
193
194 return ret;
195}
196
197_static_inline cube_fast_t
198_move_F2(cube_fast_t c)
199{
200 uint8_t aux;
201 cube_fast_t ret = c;
202
203 PERM22(ret.edge, _e_uf, _e_df, _e_fr, _e_fl)
204 PERM22(ret.corner, _c_ufr, _c_dfl, _c_ufl, _c_dfr)
205
206 return ret;
207}
208
209_static_inline cube_fast_t
210_move_F3(cube_fast_t c)
211{
212 uint8_t aux, auy, auz;
213 cube_fast_t ret = c;
214
215 PERM4(ret.edge, _e_uf, _e_fl, _e_df, _e_fr)
216 PERM4(ret.corner, _c_ufr, _c_ufl, _c_dfl, _c_dfr)
217
218 EO4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl)
219 CO4(ret.corner, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
220
221 return ret;
222}
223
224_static_inline cube_fast_t
225_move_B(cube_fast_t c)
226{
227 uint8_t aux, auy, auz;
228 cube_fast_t ret = c;
229
230 PERM4(ret.edge, _e_ub, _e_bl, _e_db, _e_br)
231 PERM4(ret.corner, _c_ubr, _c_ubl, _c_dbl, _c_dbr)
232
233 EO4(ret.edge, _e_ub, _e_br, _e_db, _e_bl)
234 CO4(ret.corner, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
235
236 return ret;
237}
238
239_static_inline cube_fast_t
240_move_B2(cube_fast_t c)
241{
242 uint8_t aux;
243 cube_fast_t ret = c;
244
245 PERM22(ret.edge, _e_ub, _e_db, _e_br, _e_bl)
246 PERM22(ret.corner, _c_ubr, _c_dbl, _c_ubl, _c_dbr)
247
248 return ret;
249}
250
251_static_inline cube_fast_t
252_move_B3(cube_fast_t c)
253{
254 uint8_t aux, auy, auz;
255 cube_fast_t ret = c;
256
257 PERM4(ret.edge, _e_ub, _e_br, _e_db, _e_bl)
258 PERM4(ret.corner, _c_ubr, _c_dbr, _c_dbl, _c_ubl)
259
260 EO4(ret.edge, _e_ub, _e_br, _e_db, _e_bl)
261 CO4(ret.corner, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
262
263 return ret;
264}
diff --git a/old/moves_trans/v2/genmovecode.sh b/old/moves_trans/v2/genmovecode.sh
deleted file mode 100755
index 9d5fa7a..0000000
--- a/old/moves_trans/v2/genmovecode.sh
+++ /dev/null
@@ -1,21 +0,0 @@
1#!/bin/sh
2
3type="${1:-src}"
4
5gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
6
7lineavx() { printf '#define _move_cube_%s ' "$1"; }
8linesrc() { printf '_static cube_fast_t _move_cube_%s = ' "$1"; }
9sedavx() { sed '1,2s/$/ \\/ ; 3s/$/)/ ; 3q'; }
10sedsrc() { sed '3s/$/ };/ ; 3q'; }
11
12gen() {
13 for f in move_??_*.txt; do
14 move="$(echo $f | sed 's/.*_// ; s/\.txt//')"
15 line$type "$move"
16 ./h48_to_"$type" <"$f" | sed$type
17 done
18}
19
20gen
21rm -f h48_to_"$type" invert
diff --git a/old/moves_trans/v2/gentranscode.sh b/old/moves_trans/v2/gentranscode.sh
deleted file mode 100755
index b9d41b6..0000000
--- a/old/moves_trans/v2/gentranscode.sh
+++ /dev/null
@@ -1,24 +0,0 @@
1#!/bin/sh
2
3type="${1:-src}"
4
5gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
6gcc -DDEBUG invert.c ../cube.c -o invert
7
8lineavx() { printf '#define _trans_cube_%s ' "$1"; }
9linesrc() { printf '_static cube_fast_t _trans_cube_%s = ' "$1"; }
10sedavx() { sed '1,2s/$/ \\/ ; 3s/$/)/ ; 3q'; }
11sedsrc() { sed '3s/$/ };/ ; 3q'; }
12
13gen() {
14 for f in transform_??_???.txt; do
15 trans="$(echo $f | sed 's/.*_// ; s/\.txt//')"
16 line$type "$trans"
17 ./h48_to_"$type" <"$f" | sed$type
18 line$type "${trans}_inverse"
19 ./invert <"$f" | ./h48_to_"$type" | sed$type
20 done
21}
22
23gen
24rm -f h48_to_"$type" invert
diff --git a/src/cube.c b/src/cube.c
index 0083acc..fce0683 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -31,8 +31,10 @@
31#include "cube_portable.h" 31#include "cube_portable.h"
32#endif 32#endif
33 33
34#include "io_move_trans.h"
34#include "constant_cubes.h" 35#include "constant_cubes.h"
35#include "cube_generic.h" 36#include "cube_generic.h"
37#include "io_cube.h"
36 38
37/* TODO: work in progress */ 39/* TODO: work in progress */
38#if 0 40#if 0
diff --git a/src/cube_avx2.h b/src/cube_avx2.h
index 42ca9b5..b189023 100644
--- a/src/cube_avx2.h
+++ b/src/cube_avx2.h
@@ -25,6 +25,7 @@ _static_inline cube_t compose_epcpeo(cube_t, cube_t);
25_static_inline cube_t compose_edges(cube_t, cube_t); 25_static_inline cube_t compose_edges(cube_t, cube_t);
26_static_inline cube_t compose_corners(cube_t, cube_t); 26_static_inline cube_t compose_corners(cube_t, cube_t);
27_static_inline cube_t compose(cube_t, cube_t); 27_static_inline cube_t compose(cube_t, cube_t);
28_static_inline cube_t inverse(cube_t);
28 29
29_static_inline int64_t coord_co(cube_t); 30_static_inline int64_t coord_co(cube_t);
30_static_inline int64_t coord_csep(cube_t); 31_static_inline int64_t coord_csep(cube_t);
@@ -135,6 +136,58 @@ compose(cube_t c1, cube_t c2)
135 return s; 136 return s;
136} 137}
137 138
139_static_inline cube_t
140cleanaftershuffle(cube_t c)
141{
142 __m256i b;
143
144 b = _mm256_set_epi8(
145 ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
146 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0
147 );
148
149 return _mm256_andnot_si256(b, c);
150}
151
152_static_inline cube_t
153inverse(cube_t c)
154{
155 /* Method taken from Andrew Skalski's vcube[1]. The addition sequence
156 * was generated using [2].
157 * [1] https://github.com/Voltara/vcube
158 * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
159 */
160 cube_t v3, vi, vo, vp, ret;
161
162 v3 = _mm256_shuffle_epi8(c, c);
163 v3 = _mm256_shuffle_epi8(v3, c);
164 vi = _mm256_shuffle_epi8(v3, v3);
165 vi = _mm256_shuffle_epi8(vi, vi);
166 vi = _mm256_shuffle_epi8(vi, vi);
167 vi = _mm256_shuffle_epi8(vi, v3);
168 vi = _mm256_shuffle_epi8(vi, vi);
169 vi = _mm256_shuffle_epi8(vi, vi);
170 vi = _mm256_shuffle_epi8(vi, vi);
171 vi = _mm256_shuffle_epi8(vi, vi);
172 vi = _mm256_shuffle_epi8(vi, c);
173 vi = _mm256_shuffle_epi8(vi, vi);
174 vi = _mm256_shuffle_epi8(vi, vi);
175 vi = _mm256_shuffle_epi8(vi, vi);
176 vi = _mm256_shuffle_epi8(vi, vi);
177 vi = _mm256_shuffle_epi8(vi, vi);
178 vi = _mm256_shuffle_epi8(vi, v3);
179 vi = _mm256_shuffle_epi8(vi, vi);
180 vi = _mm256_shuffle_epi8(vi, c);
181
182 vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2));
183 vo = _mm256_shuffle_epi8(vo, vi);
184 vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi);
185 ret = _mm256_or_si256(vp, vo);
186 ret = cleanaftershuffle(ret);
187
188 return invertco(ret);
189}
190
138_static_inline int64_t 191_static_inline int64_t
139coord_co(cube_t c) 192coord_co(cube_t c)
140{ 193{
diff --git a/src/cube_generic.h b/src/cube_generic.h
index a90aa17..844b328 100644
--- a/src/cube_generic.h
+++ b/src/cube_generic.h
@@ -1,62 +1,27 @@
1#define _move(M, c) compose(c, _move_cube_ ## M) 1#define _move(M, c) compose(c, _move_cube_ ## M)
2#define _premove(M, c) compose(_move_cube_ ## M, c) 2#define _premove(M, c) compose(_move_cube_ ## M, c)
3 3
4_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); 4_static cube_t solvedcube();
5_static bool isconsistent(cube_t);
6_static bool issolvable(cube_t);
7_static bool issolved(cube_t);
8_static bool iserror(cube_t);
9_static cube_t applymoves(cube_t, const char *);
10_static cube_t applytrans(cube_t, const char *);
11
5_static int permsign(uint8_t *, int); 12_static int permsign(uint8_t *, int);
6_static uint8_t readco(const char *);
7_static uint8_t readcp(const char *);
8_static uint8_t readeo(const char *);
9_static uint8_t readep(const char *);
10_static cube_t readcube_B32(const char *);
11_static cube_t readcube_H48(const char *);
12_static uint8_t readpiece_LST(const char **);
13_static cube_t readcube_LST(const char *);
14_static int writepiece_LST(uint8_t, char *);
15_static void writecube_B32(cube_t, char *);
16_static void writecube_H48(cube_t, char *);
17_static void writecube_LST(cube_t, char *);
18_static uint8_t b32toedge(char);
19_static uint8_t b32tocorner(char);
20_static char edgetob32(uint8_t);
21_static char cornertob32(uint8_t);
22_static uint8_t readmove(char);
23_static uint8_t readmodifier(char);
24_static uint8_t readtrans(const char *);
25_static int writemoves(uint8_t *, int, char *);
26_static void writetrans(uint8_t, char *);
27_static cube_t move(cube_t, uint8_t); 13_static cube_t move(cube_t, uint8_t);
28_static cube_t transform_edges(cube_t, uint8_t); 14_static cube_t transform_edges(cube_t, uint8_t);
29_static cube_t transform_corners(cube_t, uint8_t); 15_static cube_t transform_corners(cube_t, uint8_t);
30_static cube_t transform(cube_t, uint8_t); 16_static cube_t transform(cube_t, uint8_t);
31 17
32_static struct { 18_static cube_t
33 const char *name; 19solvedcube()
34 cube_t (*read)(const char *);
35 void (*write)(cube_t, char *);
36} ioformat[] =
37{
38 { .name = "B32", .read = readcube_B32, .write = writecube_B32 },
39 { .name = "LST", .read = readcube_LST, .write = writecube_LST },
40 { .name = "H48", .read = readcube_H48, .write = writecube_H48 },
41 { .name = "NONE", .read = NULL, .write = NULL },
42};
43
44_static_inline cube_t
45cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
46{
47 return static_cube(
48 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
49 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
50 e[8], e[9], e[10], e[11]);
51}
52
53cube_t
54solvedcube(void)
55{ 20{
56 return solved; 21 return solved;
57} 22}
58 23
59bool 24_static bool
60isconsistent(cube_t cube) 25isconsistent(cube_t cube)
61{ 26{
62 uint8_t i, p, e, piece, corner[8], edge[12]; 27 uint8_t i, p, e, piece, corner[8], edge[12];
@@ -112,7 +77,7 @@ inconsistent_co:
112 return false; 77 return false;
113} 78}
114 79
115bool 80_static bool
116issolvable(cube_t cube) 81issolvable(cube_t cube)
117{ 82{
118 uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8]; 83 uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8];
@@ -170,32 +135,7 @@ iserror(cube_t cube)
170 return equal(cube, zero); 135 return equal(cube, zero);
171} 136}
172 137
173cube_t 138_static cube_t
174inverse(cube_t cube)
175{
176 uint8_t i, piece, orien, e[12], c[8], edge[12], corner[8];
177
178 DBG_ASSERT(isconsistent(cube), zero,
179 "inverse error: inconsistent cube\n");
180
181 pieces(&cube, corner, edge);
182
183 for (i = 0; i < 12; i++) {
184 piece = edge[i];
185 orien = piece & _eobit;
186 e[piece & _pbits] = i | orien;
187 }
188
189 for (i = 0; i < 8; i++) {
190 piece = corner[i];
191 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
192 c[piece & _pbits] = i | orien;
193 }
194
195 return cubefromarray(c, e);
196}
197
198cube_t
199applymoves(cube_t cube, const char *buf) 139applymoves(cube_t cube, const char *buf)
200{ 140{
201 uint8_t r, m; 141 uint8_t r, m;
@@ -224,7 +164,7 @@ applymoves_error:
224 return zero; 164 return zero;
225} 165}
226 166
227cube_t 167_static cube_t
228applytrans(cube_t cube, const char *buf) 168applytrans(cube_t cube, const char *buf)
229{ 169{
230 uint8_t t; 170 uint8_t t;
@@ -237,49 +177,6 @@ applytrans(cube_t cube, const char *buf)
237 return transform(cube, t); 177 return transform(cube, t);
238} 178}
239 179
240cube_t
241readcube(const char *format, const char *buf)
242{
243 int i;
244
245 for (i = 0; ioformat[i].read != NULL; i++)
246 if (!strcmp(format, ioformat[i].name))
247 return ioformat[i].read(buf);
248
249 DBG_LOG("Cannot read cube in the given format\n");
250 return zero;
251}
252
253void
254writecube(const char *format, cube_t cube, char *buf)
255{
256 char *errormsg;
257 size_t len;
258
259 if (!isconsistent(cube)) {
260 errormsg = "ERROR: cannot write inconsistent cube";
261 goto writecube_error;
262 }
263
264 int i;
265
266 for (i = 0; ioformat[i].write != NULL; i++) {
267 if (!strcmp(format, ioformat[i].name)) {
268 ioformat[i].write(cube, buf);
269 return;
270 }
271 }
272
273 errormsg = "ERROR: cannot write cube in the given format";
274
275writecube_error:
276 DBG_LOG("writecube error, see stdout for details\n");
277 len = strlen(errormsg);
278 memcpy(buf, errormsg, len);
279 buf[len] = '\n';
280 buf[len+1] = '\0';
281}
282
283_static int 180_static int
284permsign(uint8_t *a, int n) 181permsign(uint8_t *a, int n)
285{ 182{
@@ -293,363 +190,6 @@ permsign(uint8_t *a, int n)
293 return ret % 2; 190 return ret % 2;
294} 191}
295 192
296_static uint8_t
297readco(const char *str)
298{
299 if (*str == '0')
300 return 0;
301 if (*str == '1')
302 return _ctwist_cw;
303 if (*str == '2')
304 return _ctwist_ccw;
305
306 DBG_LOG("Error reading CO\n");
307 return _error;
308}
309
310_static uint8_t
311readcp(const char *str)
312{
313 uint8_t c;
314
315 for (c = 0; c < 8; c++)
316 if (!strncmp(str, cornerstr[c], 3) ||
317 !strncmp(str, cornerstralt[c], 3))
318 return c;
319
320 DBG_LOG("Error reading CP\n");
321 return _error;
322}
323
324_static uint8_t
325readeo(const char *str)
326{
327 if (*str == '0')
328 return 0;
329 if (*str == '1')
330 return _eflip;
331
332 DBG_LOG("Error reading EO\n");
333 return _error;
334}
335
336_static uint8_t
337readep(const char *str)
338{
339 uint8_t e;
340
341 for (e = 0; e < 12; e++)
342 if (!strncmp(str, edgestr[e], 2))
343 return e;
344
345 DBG_LOG("Error reading EP\n");
346 return _error;
347}
348
349_static cube_t
350readcube_B32(const char *buf)
351{
352 int i;
353 uint8_t c[8], e[12];
354
355 for (i = 0; i < 8; i++) {
356 c[i] = b32tocorner(buf[i]);
357 DBG_ASSERT(c[i] < 255, zero,
358 "Error reading B32 corner %d (char %d)\n", i, i);
359 }
360
361 for (i = 0; i < 12; i++) {
362 e[i] = b32toedge(buf[i+9]);
363 DBG_ASSERT(e[i] < 255, zero,
364 "Error reading B32 edge %d (char %d)\n", i, i+9);
365 }
366
367 return cubefromarray(c, e);
368}
369
370_static cube_t
371readcube_H48(const char *buf)
372{
373 int i;
374 uint8_t piece, orient, c[8], e[12];
375 const char *b;
376
377 b = buf;
378
379 for (i = 0; i < 12; i++) {
380 while (*b == ' ' || *b == '\t' || *b == '\n')
381 b++;
382 if ((piece = readep(b)) == _error)
383 return zero;
384 b += 2;
385 if ((orient = readeo(b)) == _error)
386 return zero;
387 b++;
388 e[i] = piece | orient;
389 }
390 for (i = 0; i < 8; i++) {
391 while (*b == ' ' || *b == '\t' || *b == '\n')
392 b++;
393 if ((piece = readcp(b)) == _error)
394 return zero;
395 b += 3;
396 if ((orient = readco(b)) == _error)
397 return zero;
398 b++;
399 c[i] = piece | orient;
400 }
401
402 return cubefromarray(c, e);
403}
404
405_static uint8_t
406readpiece_LST(const char **b)
407{
408 uint8_t ret;
409 bool read;
410
411 while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n')
412 (*b)++;
413
414 for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) {
415 read = true;
416 ret = ret * 10 + (**b) - '0';
417 }
418
419 return read ? ret : _error;
420}
421
422_static cube_t
423readcube_LST(const char *buf)
424{
425 int i;
426 uint8_t c[8], e[12];
427
428 for (i = 0; i < 8; i++)
429 c[i] = readpiece_LST(&buf);
430
431 for (i = 0; i < 12; i++)
432 e[i] = readpiece_LST(&buf);
433
434 return cubefromarray(c, e);
435}
436
437_static int
438writepiece_LST(uint8_t piece, char *buf)
439{
440 char digits[3];
441 int i, len;
442
443 len = 0;
444 while (piece != 0) {
445 digits[len++] = (piece % 10) + '0';
446 piece /= 10;
447 }
448
449 if (len == 0)
450 digits[len++] = '0';
451
452 for (i = 0; i < len; i++)
453 buf[i] = digits[len-i-1];
454
455 buf[len] = ',';
456 buf[len+1] = ' ';
457
458 return len+2;
459}
460
461_static void
462writecube_B32(cube_t cube, char *buf)
463{
464 int i;
465 uint8_t corner[8], edge[12];
466
467 pieces(&cube, corner, edge);
468
469 for (i = 0; i < 8; i++)
470 buf[i] = cornertob32(corner[i]);
471
472 buf[8] = '=';
473
474 for (i = 0; i < 12; i++)
475 buf[i+9] = edgetob32(edge[i]);
476
477 buf[21] = '\0';
478}
479
480_static void
481writecube_H48(cube_t cube, char *buf)
482{
483 uint8_t piece, perm, orient, corner[8], edge[12];
484 int i;
485
486 pieces(&cube, corner, edge);
487
488 for (i = 0; i < 12; i++) {
489 piece = edge[i];
490 perm = piece & _pbits;
491 orient = (piece & _eobit) >> _eoshift;
492 buf[4*i ] = edgestr[perm][0];
493 buf[4*i + 1] = edgestr[perm][1];
494 buf[4*i + 2] = orient + '0';
495 buf[4*i + 3] = ' ';
496 }
497 for (i = 0; i < 8; i++) {
498 piece = corner[i];
499 perm = piece & _pbits;
500 orient = (piece & _cobits) >> _coshift;
501 buf[48 + 5*i ] = cornerstr[perm][0];
502 buf[48 + 5*i + 1] = cornerstr[perm][1];
503 buf[48 + 5*i + 2] = cornerstr[perm][2];
504 buf[48 + 5*i + 3] = orient + '0';
505 buf[48 + 5*i + 4] = ' ';
506 }
507
508 buf[48+39] = '\0';
509}
510
511_static void
512writecube_LST(cube_t cube, char *buf)
513{
514 int i;
515 size_t ptr;
516 uint8_t piece, corner[8], edge[12];
517
518 ptr = 0;
519 pieces(&cube, corner, edge);
520
521 for (i = 0; i < 8; i++) {
522 piece = corner[i];
523 ptr += writepiece_LST(piece, buf + ptr);
524 }
525
526 for (i = 0; i < 12; i++) {
527 piece = edge[i];
528 ptr += writepiece_LST(piece, buf + ptr);
529 }
530
531 *(buf+ptr-2) = 0;
532}
533
534_static uint8_t
535b32toedge(char c)
536{
537 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
538 return 255;
539
540 return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a');
541}
542
543_static uint8_t
544b32tocorner(char c) {
545 uint8_t val;
546
547 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
548 return 255;
549
550 val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26;
551
552 return (val & 7) | ((val & 24) << 2);
553}
554
555_static char
556edgetob32(uint8_t edge)
557{
558 return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26);
559}
560
561_static char
562cornertob32(uint8_t corner)
563{
564 uint8_t val;
565
566 val = (corner & 7) | ((corner & 96) >> 2);
567
568 return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26);
569}
570
571_static uint8_t
572readmove(char c)
573{
574 switch (c) {
575 case 'U':
576 return _move_U;
577 case 'D':
578 return _move_D;
579 case 'R':
580 return _move_R;
581 case 'L':
582 return _move_L;
583 case 'F':
584 return _move_F;
585 case 'B':
586 return _move_B;
587 default:
588 return _error;
589 }
590}
591
592_static uint8_t
593readmodifier(char c)
594{
595 switch (c) {
596 case '1': /* Fallthrough */
597 case '2': /* Fallthrough */
598 case '3':
599 return c - '0' - 1;
600 case '\'':
601 return 2;
602 default:
603 return 0;
604 }
605}
606
607_static uint8_t
608readtrans(const char *buf)
609{
610 uint8_t t;
611
612 for (t = 0; t < 48; t++)
613 if (!strncmp(buf, transstr[t], 11))
614 return t;
615
616 DBG_LOG("readtrans error\n");
617 return _error;
618}
619
620_static int
621writemoves(uint8_t *m, int n, char *buf)
622{
623 int i;
624 size_t len;
625 const char *s;
626 char *b;
627
628 for (i = 0, b = buf; i < n; i++, b++) {
629 s = movestr[m[i]];
630 len = strlen(s);
631 memcpy(b, s, len);
632 b += len;
633 *b = ' ';
634 }
635
636 if (b != buf)
637 b--; /* Remove last space */
638 *b = '\0';
639
640 return b - buf;
641}
642
643_static void
644writetrans(uint8_t t, char *buf)
645{
646 if (t >= 48)
647 memcpy(buf, "error trans", 11);
648 else
649 memcpy(buf, transstr[t], 11);
650 buf[11] = '\0';
651}
652
653_static cube_t 193_static cube_t
654move(cube_t c, uint8_t m) 194move(cube_t c, uint8_t m)
655{ 195{
diff --git a/src/cube_portable.h b/src/cube_portable.h
index 71a7e41..77e803b 100644
--- a/src/cube_portable.h
+++ b/src/cube_portable.h
@@ -22,6 +22,7 @@ _static_inline void compose_corners_inplace(cube_t, cube_t, cube_t *);
22_static_inline cube_t compose_edges(cube_t, cube_t); 22_static_inline cube_t compose_edges(cube_t, cube_t);
23_static_inline cube_t compose_corners(cube_t, cube_t); 23_static_inline cube_t compose_corners(cube_t, cube_t);
24_static_inline cube_t compose(cube_t, cube_t); 24_static_inline cube_t compose(cube_t, cube_t);
25_static_inline cube_t inverse(cube_t);
25 26
26_static_inline int64_t coord_co(cube_t); 27_static_inline int64_t coord_co(cube_t);
27_static_inline int64_t coord_csep(cube_t); 28_static_inline int64_t coord_csep(cube_t);
@@ -133,6 +134,27 @@ compose(cube_t c1, cube_t c2)
133 return ret; 134 return ret;
134} 135}
135 136
137cube_t
138inverse(cube_t cube)
139{
140 uint8_t i, piece, orien;
141 cube_t ret;
142
143 for (i = 0; i < 12; i++) {
144 piece = cube.edge[i];
145 orien = piece & _eobit;
146 ret.edge[piece & _pbits] = i | orien;
147 }
148
149 for (i = 0; i < 8; i++) {
150 piece = cube.corner[i];
151 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
152 ret.corner[piece & _pbits] = i | orien;
153 }
154
155 return ret;
156}
157
136_static_inline int64_t 158_static_inline int64_t
137coord_co(cube_t c) 159coord_co(cube_t c)
138{ 160{
diff --git a/src/io_cube.h b/src/io_cube.h
new file mode 100644
index 0000000..63c9f53
--- /dev/null
+++ b/src/io_cube.h
@@ -0,0 +1,359 @@
1_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
2
3_static uint8_t readco(const char *);
4_static uint8_t readcp(const char *);
5_static uint8_t readeo(const char *);
6_static uint8_t readep(const char *);
7_static cube_t readcube_B32(const char *);
8_static cube_t readcube_H48(const char *);
9_static uint8_t readpiece_LST(const char **);
10_static cube_t readcube_LST(const char *);
11
12_static int writepiece_LST(uint8_t, char *);
13_static void writecube_B32(cube_t, char *);
14_static void writecube_H48(cube_t, char *);
15_static void writecube_LST(cube_t, char *);
16
17_static uint8_t b32toedge(char);
18_static uint8_t b32tocorner(char);
19_static char edgetob32(uint8_t);
20_static char cornertob32(uint8_t);
21
22_static struct {
23 const char *name;
24 cube_t (*read)(const char *);
25 void (*write)(cube_t, char *);
26} ioformat[] =
27{
28 { .name = "B32", .read = readcube_B32, .write = writecube_B32 },
29 { .name = "LST", .read = readcube_LST, .write = writecube_LST },
30 { .name = "H48", .read = readcube_H48, .write = writecube_H48 },
31 { .name = "NONE", .read = NULL, .write = NULL },
32};
33
34_static_inline cube_t
35cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
36{
37 return static_cube(
38 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
39 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
40 e[8], e[9], e[10], e[11]);
41}
42
43cube_t
44readcube(const char *format, const char *buf)
45{
46 int i;
47
48 for (i = 0; ioformat[i].read != NULL; i++)
49 if (!strcmp(format, ioformat[i].name))
50 return ioformat[i].read(buf);
51
52 DBG_LOG("Cannot read cube in the given format\n");
53 return zero;
54}
55
56void
57writecube(const char *format, cube_t cube, char *buf)
58{
59 char *errormsg;
60 size_t len;
61
62 if (!isconsistent(cube)) {
63 errormsg = "ERROR: cannot write inconsistent cube";
64 goto writecube_error;
65 }
66
67 int i;
68
69 for (i = 0; ioformat[i].write != NULL; i++) {
70 if (!strcmp(format, ioformat[i].name)) {
71 ioformat[i].write(cube, buf);
72 return;
73 }
74 }
75
76 errormsg = "ERROR: cannot write cube in the given format";
77
78writecube_error:
79 DBG_LOG("writecube error, see stdout for details\n");
80 len = strlen(errormsg);
81 memcpy(buf, errormsg, len);
82 buf[len] = '\n';
83 buf[len+1] = '\0';
84}
85
86_static uint8_t
87readco(const char *str)
88{
89 if (*str == '0')
90 return 0;
91 if (*str == '1')
92 return _ctwist_cw;
93 if (*str == '2')
94 return _ctwist_ccw;
95
96 DBG_LOG("Error reading CO\n");
97 return _error;
98}
99
100_static uint8_t
101readcp(const char *str)
102{
103 uint8_t c;
104
105 for (c = 0; c < 8; c++)
106 if (!strncmp(str, cornerstr[c], 3) ||
107 !strncmp(str, cornerstralt[c], 3))
108 return c;
109
110 DBG_LOG("Error reading CP\n");
111 return _error;
112}
113
114_static uint8_t
115readeo(const char *str)
116{
117 if (*str == '0')
118 return 0;
119 if (*str == '1')
120 return _eflip;
121
122 DBG_LOG("Error reading EO\n");
123 return _error;
124}
125
126_static uint8_t
127readep(const char *str)
128{
129 uint8_t e;
130
131 for (e = 0; e < 12; e++)
132 if (!strncmp(str, edgestr[e], 2))
133 return e;
134
135 DBG_LOG("Error reading EP\n");
136 return _error;
137}
138
139_static cube_t
140readcube_B32(const char *buf)
141{
142 int i;
143 uint8_t c[8], e[12];
144
145 for (i = 0; i < 8; i++) {
146 c[i] = b32tocorner(buf[i]);
147 DBG_ASSERT(c[i] < 255, zero,
148 "Error reading B32 corner %d (char %d)\n", i, i);
149 }
150
151 for (i = 0; i < 12; i++) {
152 e[i] = b32toedge(buf[i+9]);
153 DBG_ASSERT(e[i] < 255, zero,
154 "Error reading B32 edge %d (char %d)\n", i, i+9);
155 }
156
157 return cubefromarray(c, e);
158}
159
160_static cube_t
161readcube_H48(const char *buf)
162{
163 int i;
164 uint8_t piece, orient, c[8], e[12];
165 const char *b;
166
167 b = buf;
168
169 for (i = 0; i < 12; i++) {
170 while (*b == ' ' || *b == '\t' || *b == '\n')
171 b++;
172 if ((piece = readep(b)) == _error)
173 return zero;
174 b += 2;
175 if ((orient = readeo(b)) == _error)
176 return zero;
177 b++;
178 e[i] = piece | orient;
179 }
180 for (i = 0; i < 8; i++) {
181 while (*b == ' ' || *b == '\t' || *b == '\n')
182 b++;
183 if ((piece = readcp(b)) == _error)
184 return zero;
185 b += 3;
186 if ((orient = readco(b)) == _error)
187 return zero;
188 b++;
189 c[i] = piece | orient;
190 }
191
192 return cubefromarray(c, e);
193}
194
195_static uint8_t
196readpiece_LST(const char **b)
197{
198 uint8_t ret;
199 bool read;
200
201 while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n')
202 (*b)++;
203
204 for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) {
205 read = true;
206 ret = ret * 10 + (**b) - '0';
207 }
208
209 return read ? ret : _error;
210}
211
212_static cube_t
213readcube_LST(const char *buf)
214{
215 int i;
216 uint8_t c[8], e[12];
217
218 for (i = 0; i < 8; i++)
219 c[i] = readpiece_LST(&buf);
220
221 for (i = 0; i < 12; i++)
222 e[i] = readpiece_LST(&buf);
223
224 return cubefromarray(c, e);
225}
226
227_static int
228writepiece_LST(uint8_t piece, char *buf)
229{
230 char digits[3];
231 int i, len;
232
233 len = 0;
234 while (piece != 0) {
235 digits[len++] = (piece % 10) + '0';
236 piece /= 10;
237 }
238
239 if (len == 0)
240 digits[len++] = '0';
241
242 for (i = 0; i < len; i++)
243 buf[i] = digits[len-i-1];
244
245 buf[len] = ',';
246 buf[len+1] = ' ';
247
248 return len+2;
249}
250
251_static void
252writecube_B32(cube_t cube, char *buf)
253{
254 int i;
255 uint8_t corner[8], edge[12];
256
257 pieces(&cube, corner, edge);
258
259 for (i = 0; i < 8; i++)
260 buf[i] = cornertob32(corner[i]);
261
262 buf[8] = '=';
263
264 for (i = 0; i < 12; i++)
265 buf[i+9] = edgetob32(edge[i]);
266
267 buf[21] = '\0';
268}
269
270_static void
271writecube_H48(cube_t cube, char *buf)
272{
273 uint8_t piece, perm, orient, corner[8], edge[12];
274 int i;
275
276 pieces(&cube, corner, edge);
277
278 for (i = 0; i < 12; i++) {
279 piece = edge[i];
280 perm = piece & _pbits;
281 orient = (piece & _eobit) >> _eoshift;
282 buf[4*i ] = edgestr[perm][0];
283 buf[4*i + 1] = edgestr[perm][1];
284 buf[4*i + 2] = orient + '0';
285 buf[4*i + 3] = ' ';
286 }
287 for (i = 0; i < 8; i++) {
288 piece = corner[i];
289 perm = piece & _pbits;
290 orient = (piece & _cobits) >> _coshift;
291 buf[48 + 5*i ] = cornerstr[perm][0];
292 buf[48 + 5*i + 1] = cornerstr[perm][1];
293 buf[48 + 5*i + 2] = cornerstr[perm][2];
294 buf[48 + 5*i + 3] = orient + '0';
295 buf[48 + 5*i + 4] = ' ';
296 }
297
298 buf[48+39] = '\0';
299}
300
301_static void
302writecube_LST(cube_t cube, char *buf)
303{
304 int i;
305 size_t ptr;
306 uint8_t piece, corner[8], edge[12];
307
308 ptr = 0;
309 pieces(&cube, corner, edge);
310
311 for (i = 0; i < 8; i++) {
312 piece = corner[i];
313 ptr += writepiece_LST(piece, buf + ptr);
314 }
315
316 for (i = 0; i < 12; i++) {
317 piece = edge[i];
318 ptr += writepiece_LST(piece, buf + ptr);
319 }
320
321 *(buf+ptr-2) = 0;
322}
323
324_static uint8_t
325b32toedge(char c)
326{
327 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
328 return 255;
329
330 return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a');
331}
332
333_static uint8_t
334b32tocorner(char c) {
335 uint8_t val;
336
337 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
338 return 255;
339
340 val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26;
341
342 return (val & 7) | ((val & 24) << 2);
343}
344
345_static char
346edgetob32(uint8_t edge)
347{
348 return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26);
349}
350
351_static char
352cornertob32(uint8_t corner)
353{
354 uint8_t val;
355
356 val = (corner & 7) | ((corner & 96) >> 2);
357
358 return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26);
359}
diff --git a/src/io_move_trans.h b/src/io_move_trans.h
new file mode 100644
index 0000000..e36b8e5
--- /dev/null
+++ b/src/io_move_trans.h
@@ -0,0 +1,87 @@
1_static uint8_t readmove(char);
2_static uint8_t readmodifier(char);
3_static uint8_t readtrans(const char *);
4_static int writemoves(uint8_t *, int, char *);
5_static void writetrans(uint8_t, char *);
6
7_static uint8_t
8readmove(char c)
9{
10 switch (c) {
11 case 'U':
12 return _move_U;
13 case 'D':
14 return _move_D;
15 case 'R':
16 return _move_R;
17 case 'L':
18 return _move_L;
19 case 'F':
20 return _move_F;
21 case 'B':
22 return _move_B;
23 default:
24 return _error;
25 }
26}
27
28_static uint8_t
29readmodifier(char c)
30{
31 switch (c) {
32 case '1': /* Fallthrough */
33 case '2': /* Fallthrough */
34 case '3':
35 return c - '0' - 1;
36 case '\'':
37 return 2;
38 default:
39 return 0;
40 }
41}
42
43_static uint8_t
44readtrans(const char *buf)
45{
46 uint8_t t;
47
48 for (t = 0; t < 48; t++)
49 if (!strncmp(buf, transstr[t], 11))
50 return t;
51
52 DBG_LOG("readtrans error\n");
53 return _error;
54}
55
56_static int
57writemoves(uint8_t *m, int n, char *buf)
58{
59 int i;
60 size_t len;
61 const char *s;
62 char *b;
63
64 for (i = 0, b = buf; i < n; i++, b++) {
65 s = movestr[m[i]];
66 len = strlen(s);
67 memcpy(b, s, len);
68 b += len;
69 *b = ' ';
70 }
71
72 if (b != buf)
73 b--; /* Remove last space */
74 *b = '\0';
75
76 return b - buf;
77}
78
79_static void
80writetrans(uint8_t t, char *buf)
81{
82 if (t >= 48)
83 memcpy(buf, "error trans", 11);
84 else
85 memcpy(buf, transstr[t], 11);
86 buf[11] = '\0';
87}

Generated with cgit - Back to sebastiano.tronto.net