aboutsummaryrefslogtreecommitdiff
path: root/cube.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-11-05 16:29:14 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2023-11-05 16:37:39 +0100
commit1964938ca6abef6e5c81d9dccdf42c55abacb5e9 (patch)
tree9908417751ddf22e45ea68da0f209083249ac08e /cube.c
parent9c1659d91a331735f88c127aa236a59153e23dfc (diff)
downloadnissy-core-1964938ca6abef6e5c81d9dccdf42c55abacb5e9.tar.gz
nissy-core-1964938ca6abef6e5c81d9dccdf42c55abacb5e9.zip
Refactoring
Diffstat (limited to '')
-rw-r--r--cube.c3698
1 files changed, 3698 insertions, 0 deletions
diff --git a/cube.c b/cube.c
new file mode 100644
index 0000000..e98bc40
--- /dev/null
+++ b/cube.c
@@ -0,0 +1,3698 @@
1#include <inttypes.h>
2#include <stdbool.h>
3#include <string.h>
4
5#ifdef DEBUG
6#include <stdio.h>
7#endif
8
9#include "cube.h"
10
11/******************************************************************************
12Section: constants and strings
13******************************************************************************/
14
15#define U 0U
16#define U2 1U
17#define U3 2U
18#define D 3U
19#define D2 4U
20#define D3 5U
21#define R 6U
22#define R2 7U
23#define R3 8U
24#define L 9U
25#define L2 10U
26#define L3 11U
27#define F 12U
28#define F2 13U
29#define F3 14U
30#define B 15U
31#define B2 16U
32#define B3 17U
33
34#define UFr 0
35#define ULr 1
36#define UBr 2
37#define URr 3
38#define DFr 4
39#define DLr 5
40#define DBr 6
41#define DRr 7
42#define RUr 8
43#define RFr 9
44#define RDr 10
45#define RBr 11
46#define LUr 12
47#define LFr 13
48#define LDr 14
49#define LBr 15
50#define FUr 16
51#define FRr 17
52#define FDr 18
53#define FLr 19
54#define BUr 20
55#define BRr 21
56#define BDr 22
57#define BLr 23
58
59#define UFm 24
60#define ULm 25
61#define UBm 26
62#define URm 27
63#define DFm 28
64#define DLm 29
65#define DBm 30
66#define DRm 31
67#define RUm 32
68#define RFm 33
69#define RDm 34
70#define RBm 35
71#define LUm 36
72#define LFm 37
73#define LDm 38
74#define LBm 39
75#define FUm 40
76#define FRm 41
77#define FDm 42
78#define FLm 43
79#define BUm 44
80#define BRm 45
81#define BDm 46
82#define BLm 47
83
84#define errormove 99U
85#define errortrans 99U
86
87#define _c_ufr 0U
88#define _c_ubl 1U
89#define _c_dfl 2U
90#define _c_dbr 3U
91#define _c_ufl 4U
92#define _c_ubr 5U
93#define _c_dfr 6U
94#define _c_dbl 7U
95
96#define _e_uf 0U
97#define _e_ub 1U
98#define _e_db 2U
99#define _e_df 3U
100#define _e_ur 4U
101#define _e_ul 5U
102#define _e_dl 6U
103#define _e_dr 7U
104#define _e_fr 8U
105#define _e_fl 9U
106#define _e_bl 10U
107#define _e_br 11U
108
109#define _eoshift 4U
110#define _coshift 5U
111
112#define _pbits 0xFU
113#define _eobit 0x10U
114#define _cobits 0xF0U
115#define _cobits2 0x60U
116#define _ctwist_cw 0x20U
117#define _ctwist_ccw 0x40U
118#define _eflip 0x10U
119#define _error 0xFFU
120
121static char *cornerstr[] = {
122 [_c_ufr] = "UFR",
123 [_c_ubl] = "UBL",
124 [_c_dfl] = "DFL",
125 [_c_dbr] = "DBR",
126 [_c_ufl] = "UFL",
127 [_c_ubr] = "UBR",
128 [_c_dfr] = "DFR",
129 [_c_dbl] = "DBL"
130};
131
132static char *cornerstralt[] = {
133 [_c_ufr] = "URF",
134 [_c_ubl] = "ULB",
135 [_c_dfl] = "DLF",
136 [_c_dbr] = "DRB",
137 [_c_ufl] = "ULF",
138 [_c_ubr] = "URB",
139 [_c_dfr] = "DRF",
140 [_c_dbl] = "DLB"
141};
142
143static char *edgestr[] = {
144 [_e_uf] = "UF",
145 [_e_ub] = "UB",
146 [_e_db] = "DB",
147 [_e_df] = "DF",
148 [_e_ur] = "UR",
149 [_e_ul] = "UL",
150 [_e_dl] = "DL",
151 [_e_dr] = "DR",
152 [_e_fr] = "FR",
153 [_e_fl] = "FL",
154 [_e_bl] = "BL",
155 [_e_br] = "BR"
156};
157
158static char *movestr[] = {
159 [U] = "U",
160 [U2] = "U2",
161 [U3] = "U'",
162 [D] = "D",
163 [D2] = "D2",
164 [D3] = "D'",
165 [R] = "R",
166 [R2] = "R2",
167 [R3] = "R'",
168 [L] = "L",
169 [L2] = "L2",
170 [L3] = "L'",
171 [F] = "F",
172 [F2] = "F2",
173 [F3] = "F'",
174 [B] = "B",
175 [B2] = "B2",
176 [B3] = "B'",
177};
178
179static char *transstr[] = {
180 [UFr] = "rotation UF",
181 [UFm] = "mirrored UF",
182 [ULr] = "rotation UL",
183 [ULm] = "mirrored UL",
184 [UBr] = "rotation UB",
185 [UBm] = "mirrored UB",
186 [URr] = "rotation UR",
187 [URm] = "mirrored UR",
188 [DFr] = "rotation DF",
189 [DFm] = "mirrored DF",
190 [DLr] = "rotation DL",
191 [DLm] = "mirrored DL",
192 [DBr] = "rotation DB",
193 [DBm] = "mirrored DB",
194 [DRr] = "rotation DR",
195 [DRm] = "mirrored DR",
196 [RUr] = "rotation RU",
197 [RUm] = "mirrored RU",
198 [RFr] = "rotation RF",
199 [RFm] = "mirrored RF",
200 [RDr] = "rotation RD",
201 [RDm] = "mirrored RD",
202 [RBr] = "rotation RB",
203 [RBm] = "mirrored RB",
204 [LUr] = "rotation LU",
205 [LUm] = "mirrored LU",
206 [LFr] = "rotation LF",
207 [LFm] = "mirrored LF",
208 [LDr] = "rotation LD",
209 [LDm] = "mirrored LD",
210 [LBr] = "rotation LB",
211 [LBm] = "mirrored LB",
212 [FUr] = "rotation FU",
213 [FUm] = "mirrored FU",
214 [FRr] = "rotation FR",
215 [FRm] = "mirrored FR",
216 [FDr] = "rotation FD",
217 [FDm] = "mirrored FD",
218 [FLr] = "rotation FL",
219 [FLm] = "mirrored FL",
220 [BUr] = "rotation BU",
221 [BUm] = "mirrored BU",
222 [BRr] = "rotation BR",
223 [BRm] = "mirrored BR",
224 [BDr] = "rotation BD",
225 [BDm] = "mirrored BD",
226 [BLr] = "rotation BL",
227 [BLm] = "mirrored BL",
228};
229
230/******************************************************************************
231Section: cube_array
232
233This section contains non-optimized functions that operate on the cube in
234array format. These utilities are not used in performance-critical parts;
235for example, all I/O related stuff is here, as well as some checks on the
236state of the cube that are used in debugging.
237******************************************************************************/
238
239typedef struct {
240 uint8_t c[16];
241 uint8_t e[16];
242} cube_array_t;
243
244#define get_edge(cube, i) (cube).e[(i)]
245#define get_corner(cube, i) (cube).c[(i)]
246#define set_edge(cube, i, p) (cube).e[(i)] = (p)
247#define set_corner(cube, i, p) (cube).c[(i)] = (p)
248
249static void setzero_array(cube_array_t *);
250static bool equal_array(cube_array_t, cube_array_t);
251static bool iserror_array(cube_array_t);
252static bool isconsistent_array(cube_array_t);
253static bool issolvable_array(cube_array_t);
254static uint8_t readco(char *);
255static uint8_t readcp(char *);
256static uint8_t readeo(char *);
257static uint8_t readep(char *);
258static cube_array_t readcube_array(format_t, char *);
259static int permsign(uint8_t *, int);
260static cube_array_t readcube_array_H48(char *);
261static void writecube_array_AVX(cube_array_t, char *);
262static void writecube_array_H48(cube_array_t, char *);
263static int writepiece_SRC(uint8_t, char *);
264static void writecube_array_SRC(cube_array_t, char *);
265static uint8_t readmove(char);
266static uint8_t readmodifier(char);
267
268cube_array_t solvedcube_array = {
269 .c = {0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0},
270 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0}
271};
272cube_array_t zerocube_array = { .e = {0}, .c = {0} };
273
274static void
275setzero_array(cube_array_t *arr)
276{
277 memset(arr, 0, 32);
278}
279
280static bool
281equal_array(cube_array_t c1, cube_array_t c2)
282{
283 int i;
284 bool ret;
285
286 ret = true;
287 for (i = 0; i < 8; i++)
288 ret = ret && c1.c[i] == c2.c[i];
289 for (i = 0; i < 12; i++)
290 ret = ret && c1.e[i] == c2.e[i];
291
292 return ret;
293}
294
295static bool
296iserror_array(cube_array_t arr)
297{
298 return equal_array(arr, zerocube_array);
299}
300
301static uint8_t
302readco(char *str)
303{
304 if (*str == '0')
305 return 0;
306 if (*str == '1')
307 return _ctwist_cw;
308 if (*str == '2')
309 return _ctwist_ccw;
310
311#ifdef DEBUG
312 fprintf(stderr, "Error reading CO\n");
313#endif
314 return _error;
315}
316
317static uint8_t
318readcp(char *str)
319{
320 uint8_t c;
321
322 for (c = 0; c < 8; c++)
323 if (!strncmp(str, cornerstr[c], 3) ||
324 !strncmp(str, cornerstralt[c], 3))
325 return c;
326
327#ifdef DEBUG
328 fprintf(stderr, "Error reading CP\n");
329#endif
330 return _error;
331}
332
333static uint8_t
334readeo(char *str)
335{
336 if (*str == '0')
337 return 0;
338 if (*str == '1')
339 return _eflip;
340
341#ifdef DEBUG
342 fprintf(stderr, "Error reading EO\n");
343#endif
344 return _error;
345}
346
347static uint8_t
348readep(char *str)
349{
350 uint8_t e;
351
352 for (e = 0; e < 12; e++)
353 if (!strncmp(str, edgestr[e], 2))
354 return e;
355
356#ifdef DEBUG
357 fprintf(stderr, "Error reading EP\n");
358#endif
359 return _error;
360}
361
362static cube_array_t
363readcube_array_H48(char *buf)
364{
365 int i;
366 uint8_t piece, orient;
367 cube_array_t ret = {0};
368 char *b;
369
370 b = buf;
371
372 for (i = 0; i < 12; i++) {
373 while (*b == ' ' || *b == '\t' || *b == '\n')
374 b++;
375 if ((piece = readep(b)) == _error)
376 return zerocube_array;
377 b += 2;
378 if ((orient = readeo(b)) == _error)
379 return zerocube_array;
380 b++;
381 set_edge(ret, i, piece | orient);
382 }
383 for (i = 0; i < 8; i++) {
384 while (*b == ' ' || *b == '\t' || *b == '\n')
385 b++;
386 if ((piece = readcp(b)) == _error)
387 return zerocube_array;
388 b += 3;
389 if ((orient = readco(b)) == _error)
390 return zerocube_array;
391 b++;
392 set_corner(ret, i, piece | orient);
393 }
394
395 return ret;
396}
397
398cube_array_t
399readcube_array(format_t format, char *buf)
400{
401 cube_array_t arr;
402
403 switch (format) {
404 case H48:
405 arr = readcube_array_H48(buf);
406 break;
407 default:
408#ifdef DEBUG
409 fprintf(stderr, "Cannot read cube in the given format\n");
410#endif
411 setzero_array(&arr);
412 }
413
414#ifdef DEBUG
415 if (iserror_array(arr))
416 fprintf(stderr, "readcube error\n");
417#endif
418 return arr;
419}
420
421
422static int
423writepiece_SRC(uint8_t piece, char *buf)
424{
425 char digits[3];
426 int i, len = 0;
427
428 while (piece != 0) {
429 digits[len++] = (piece % 10) + '0';
430 piece /= 10;
431 }
432
433 if (len == 0)
434 digits[len++] = '0';
435
436 for (i = 0; i < len; i++)
437 buf[i] = digits[len-i-1];
438
439 buf[len] = ',';
440 buf[len+1] = ' ';
441
442 return len+2;
443}
444
445static void
446writecube_array_AVX(cube_array_t cube, char *buf)
447{
448 int i, ptr;
449 uint8_t piece;
450
451 memcpy(buf, "_mm256_set_epi8(\n\t0, 0, 0, 0, ", 30);
452 ptr = 30;
453
454 for (i = 11; i >= 0; i--) {
455 piece = get_edge(cube, i);
456 ptr += writepiece_SRC(piece, buf + ptr);
457 }
458
459 memcpy(buf+ptr-2, ",\n\t0, 0, 0, 0, 0, 0, 0, 0, ", 27);
460 ptr += 25;
461
462 for (i = 7; i >= 0; i--) {
463 piece = get_corner(cube, i);
464 ptr += writepiece_SRC(piece, buf + ptr);
465 }
466
467 memcpy(buf+ptr-2, "\n)\0", 3);
468}
469
470static void
471writecube_array_H48(cube_array_t cube, char *buf)
472{
473 uint8_t piece, perm, orient;
474 int i;
475
476 for (i = 0; i < 12; i++) {
477 piece = get_edge(cube, i);
478 perm = piece & _pbits;
479 orient = (piece & _eobit) >> _eoshift;
480 buf[4*i ] = edgestr[perm][0];
481 buf[4*i + 1] = edgestr[perm][1];
482 buf[4*i + 2] = orient + '0';
483 buf[4*i + 3] = ' ';
484 }
485 for (i = 0; i < 8; i++) {
486 piece = get_corner(cube, i);
487 perm = piece & _pbits;
488 orient = (piece & _cobits) >> _coshift;
489 buf[48 + 5*i ] = cornerstr[perm][0];
490 buf[48 + 5*i + 1] = cornerstr[perm][1];
491 buf[48 + 5*i + 2] = cornerstr[perm][2];
492 buf[48 + 5*i + 3] = orient + '0';
493 buf[48 + 5*i + 4] = ' ';
494 }
495
496 buf[48+39] = '\0';
497}
498
499static void
500writecube_array_SRC(cube_array_t cube, char *buf)
501{
502 int i, ptr;
503 uint8_t piece;
504
505 memcpy(buf, "{\n\t.c = {", 9);
506 ptr = 9;
507
508 for (i = 0; i < 8; i++) {
509 piece = get_corner(cube, i);
510 ptr += writepiece_SRC(piece, buf + ptr);
511 }
512
513 memcpy(buf+ptr-2, "},\n\t.e = {", 10);
514 ptr += 8;
515
516 for (i = 0; i < 12; i++) {
517 piece = get_edge(cube, i);
518 ptr += writepiece_SRC(piece, buf + ptr);
519 }
520
521 memcpy(buf+ptr-2, "}\n}\0", 4);
522}
523
524void
525writecube_array(format_t format, cube_array_t a, char *buf)
526{
527 char *errormsg;
528 size_t len;
529
530 if (!isconsistent_array(a)) {
531 errormsg = "ERROR: cannot write inconsistent cube";
532 goto writecube_error;
533 }
534
535 switch (format) {
536 case AVX:
537 writecube_array_AVX(a, buf);
538 break;
539 case H48:
540 writecube_array_H48(a, buf);
541 break;
542 case SRC:
543 writecube_array_SRC(a, buf);
544 break;
545 default:
546 errormsg = "ERROR: cannot write cube in the given format";
547 goto writecube_error;
548 }
549
550 return;
551
552writecube_error:
553#ifdef DEBUG
554 fprintf(stderr, "writecube error, see stdout for details\n");
555#endif
556 len = strlen(errormsg);
557 memcpy(buf, errormsg, len);
558 buf[len] = '\n';
559 buf[len+1] = '\0';
560}
561
562static uint8_t
563readmove(char c)
564{
565 switch (c) {
566 case 'U':
567 return U;
568 case 'D':
569 return D;
570 case 'R':
571 return R;
572 case 'L':
573 return L;
574 case 'F':
575 return F;
576 case 'B':
577 return B;
578 default:
579 return _error;
580 }
581}
582
583static uint8_t
584readmodifier(char c)
585{
586 switch (c) {
587 case '1': /* Fallthrough */
588 case '2': /* Fallthrough */
589 case '3':
590 return c - '0' - 1;
591 case '\'':
592 return 2;
593 default:
594 return 0;
595 }
596}
597
598int
599readmoves(char *buf, move_t *m)
600{
601 int n;
602 uint64_t r;
603 char *b;
604
605 for (b = buf, n = 0; *b != '\0'; b++) {
606 while (*b == ' ' || *b == '\t' || *b == '\n')
607 b++;
608 if (*b == '\0')
609 return n;
610 if ((r = readmove(*b)) == _error)
611 goto readmoves_error;
612 m[n] = (move_t)r;
613 if ((r = readmodifier(*(b+1))) != 0) {
614 b++;
615 m[n] += r;
616 }
617 n++;
618 }
619
620 return n;
621
622readmoves_error:
623#ifdef DEBUG
624 fprintf(stderr, "readmoves error\n");
625#endif
626 return -1;
627}
628
629trans_t
630readtrans(char *buf)
631{
632 uint8_t t;
633
634 for (t = 0; t < 48; t++)
635 if (!strncmp(buf, transstr[t], 11))
636 return t;
637
638#ifdef DEBUG
639 fprintf(stderr, "readtrans error\n");
640#endif
641 return errortrans;
642}
643
644void
645writemoves(move_t *m, int n, char *buf)
646{
647 int i;
648 size_t len;
649 char *b, *s;
650
651 for (i = 0, b = buf; i < n; i++, b++) {
652 s = movestr[m[i]];
653 len = strlen(s);
654 memcpy(b, s, len);
655 b += len;
656 *b = ' ';
657 }
658 *b = '\0';
659}
660
661void
662writetrans(trans_t t, char *buf)
663{
664 if (t >= 48)
665 memcpy(buf, "error trans", 11);
666 else
667 memcpy(buf, transstr[t], 11);
668 buf[11] = '\0';
669}
670
671static int
672permsign(uint8_t *a, int n)
673{
674 int i, j;
675 uint8_t ret = 0;
676
677 for (i = 0; i < n; i++)
678 for (j = i+1; j < n; j++)
679 ret += a[i] > a[j] ? 1 : 0;
680
681 return ret % 2;
682}
683
684static bool
685isconsistent_array(cube_array_t c)
686{
687 uint8_t i, p, e, piece;
688 bool found[12];
689
690 for (i = 0; i < 12; i++)
691 found[i] = false;
692 for (i = 0; i < 12; i++) {
693 piece = get_edge(c, i);
694 p = piece & _pbits;
695 e = piece & _eobit;
696 if (p >= 12)
697 goto inconsistent_ep;
698 if (e != 0 && e != _eobit)
699 goto inconsistent_eo;
700 found[p] = true;
701 }
702 for (i = 0; i < 12; i++)
703 if (!found[i])
704 goto inconsistent_ep;
705
706 for (i = 0; i < 8; i++)
707 found[i] = false;
708 for (i = 0; i < 8; i++) {
709 piece = get_corner(c, i);
710 p = piece & _pbits;
711 e = piece & _cobits;
712 if (p >= 8)
713 goto inconsistent_cp;
714 if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw)
715 goto inconsistent_co;
716 found[p] = true;
717 }
718 for (i = 0; i < 8; i++)
719 if (!found[i])
720 goto inconsistent_co;
721
722 return true;
723
724inconsistent_ep:
725#ifdef DEBUG
726 fprintf(stderr, "Inconsistent EP\n");
727#endif
728 return false;
729inconsistent_cp:
730#ifdef DEBUG
731 fprintf(stderr, "Inconsistent CP\n");
732#endif
733 return false;
734inconsistent_eo:
735#ifdef DEBUG
736 fprintf(stderr, "Inconsistent EO\n");
737#endif
738 return false;
739inconsistent_co:
740#ifdef DEBUG
741 fprintf(stderr, "Inconsistent CO\n");
742#endif
743 return false;
744}
745
746bool
747issolvable_array(cube_array_t c)
748{
749 uint8_t i, eo, co, piece, edges[12], corners[8];
750
751#ifdef DEBUG
752 if (!isconsistent_array(c)) {
753 fprintf(stderr, "issolvable: cube is inconsistent\n");
754 return false;
755 }
756#endif
757
758 for (i = 0; i < 12; i++)
759 edges[i] = get_edge(c, i) & _pbits;
760 for (i = 0; i < 8; i++)
761 corners[i] = get_corner(c, i) & _pbits;
762
763 if (permsign(edges, 12) != permsign(corners, 8))
764 goto issolvable_parity;
765
766 eo = 0;
767 for (i = 0; i < 12; i++) {
768 piece = get_edge(c, i);
769 eo += (piece & _eobit) >> _eoshift;
770 }
771 if (eo % 2 != 0)
772 goto issolvable_eo;
773
774 co = 0;
775 for (i = 0; i < 8; i++) {
776 piece = get_corner(c, i);
777 co += (piece & _cobits) >> _coshift;
778 }
779 if (co % 3 != 0)
780 goto issolvable_co;
781
782 return true;
783
784issolvable_parity:
785#ifdef DEBUG
786 fprintf(stderr, "EP and CP parities are different\n");
787#endif
788 return false;
789issolvable_eo:
790#ifdef DEBUG
791 fprintf(stderr, "Odd number of flipped edges\n");
792#endif
793 return false;
794issolvable_co:
795#ifdef DEBUG
796 fprintf(stderr, "Sum of corner orientation is not multiple of 3\n");
797#endif
798 return false;
799}
800
801/******************************************************************************
802Section: AVX2 fast methods
803
804This section contains performance-critical methods that rely on AVX2
805intructions such as routines for moving or transforming the cube.
806
807Note: the #ifdef below is closed in the next section.
808******************************************************************************/
809
810#ifdef CUBE_AVX2
811
812#define _co_avx2 _mm256_set_epi64x(0, 0, 0, 0xF0F0F0F0F0F0F0F0)
813#define _co2_avx2 _mm256_set_epi64x(0, 0, 0, 0x6060606060606060)
814#define _cocw_avx2 _mm256_set_epi64x(0, 0, 0, 0x2020202020202020)
815#define _eo_avx2 _mm256_set_epi64x(0x10101010, 0x1010101010101010, 0, 0)
816
817static cube_t _arraytocube(cube_array_t);
818static void _cubetoarray(cube_t, cube_array_t *);
819static inline bool _equal(cube_t, cube_t);
820static inline cube_t _invertco(cube_t);
821static inline cube_t _inverse(cube_t);
822static inline cube_t _compose(cube_t, cube_t);
823
824static inline cube_t
825_move_U(cube_t c)
826{
827 cube_t m = _mm256_set_epi8(
828 0, 0, 0, 0, 11, 10, 9, 8, 7, 6, 0, 1, 3, 2, 5, 4,
829 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 1, 0, 3, 2, 4, 5
830 );
831
832 return _mm256_shuffle_epi8(c, m);
833}
834
835static inline cube_t
836_move_U2(cube_t c)
837{
838 cube_t m = _mm256_set_epi8(
839 0, 0, 0, 0, 11, 10, 9, 8, 7, 6, 4, 5, 3, 2, 0, 1,
840 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 4, 5, 3, 2, 0, 1
841 );
842
843 return _mm256_shuffle_epi8(c, m);
844}
845
846static inline cube_t
847_move_U3(cube_t c)
848{
849 cube_t m = _mm256_set_epi8(
850 0, 0, 0, 0, 11, 10, 9, 8, 7, 6, 1, 0, 3, 2, 4, 5,
851 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 0, 1, 3, 2, 5, 4
852 );
853
854 return _mm256_shuffle_epi8(c, m);
855}
856
857static inline cube_t
858_move_D(cube_t c)
859{
860 cube_t m = _mm256_set_epi8(
861 0, 0, 0, 0, 11, 10, 9, 8, 3, 2, 5, 4, 6, 7, 1, 0,
862 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 5, 4, 6, 7, 1, 0
863 );
864
865 return _mm256_shuffle_epi8(c, m);
866}
867
868static inline cube_t
869_move_D2(cube_t c)
870{
871 cube_t m = _mm256_set_epi8(
872 0, 0, 0, 0, 11, 10, 9, 8, 6, 7, 5, 4, 2, 3, 1, 0,
873 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 5, 4, 2, 3, 1, 0
874 );
875
876 return _mm256_shuffle_epi8(c, m);
877}
878
879static inline cube_t
880_move_D3(cube_t c)
881{
882 cube_t m = _mm256_set_epi8(
883 0, 0, 0, 0, 11, 10, 9, 8, 2, 3, 5, 4, 7, 6, 1, 0,
884 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 4, 7, 6, 1, 0
885 );
886
887 return _mm256_shuffle_epi8(c, m);
888}
889
890static inline cube_t
891_move_R(cube_t c)
892{
893 cube_t m = _mm256_set_epi8(
894 0, 0, 0, 0, 4, 10, 9, 7, 11, 6, 5, 8, 3, 2, 1, 0,
895 0, 0, 0, 0, 0, 0, 0, 0, 7, 35, 32, 4, 69, 2, 1, 70
896 );
897
898 return _compose(c, m);
899}
900
901static inline cube_t
902_move_R2(cube_t c)
903{
904 cube_t m = _mm256_set_epi8(
905 0, 0, 0, 0, 8, 10, 9, 11, 4, 6, 5, 7, 3, 2, 1, 0,
906 0, 0, 0, 0, 0, 0, 0, 0, 7, 5, 6, 4, 0, 2, 1, 3
907 );
908
909 return _mm256_shuffle_epi8(c, m);
910}
911
912static inline cube_t
913_move_R3(cube_t c)
914{
915 cube_t m = _mm256_set_epi8(
916 0, 0, 0, 0, 7, 10, 9, 4, 8, 6, 5, 11, 3, 2, 1, 0,
917 0, 0, 0, 0, 0, 0, 0, 0, 7, 32, 35, 4, 70, 2, 1, 69
918 );
919
920 return _compose(c, m);
921}
922
923static inline cube_t
924_move_L(cube_t c)
925{
926 cube_t m = _mm256_set_epi8(
927 0, 0, 0, 0, 11, 6, 5, 8, 7, 9, 10, 4, 3, 2, 1, 0,
928 0, 0, 0, 0, 0, 0, 0, 0, 34, 6, 5, 33, 3, 68, 71, 0
929 );
930
931 return _compose(c, m);
932}
933
934static inline cube_t
935_move_L2(cube_t c)
936{
937 cube_t m = _mm256_set_epi8(
938 0, 0, 0, 0, 11, 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0,
939 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 5, 7, 3, 1, 2, 0
940 );
941
942 return _mm256_shuffle_epi8(c, m);
943}
944
945static inline cube_t
946_move_L3(cube_t c)
947{
948 cube_t m = _mm256_set_epi8(
949 0, 0, 0, 0, 11, 5, 6, 8, 7, 10, 9, 4, 3, 2, 1, 0,
950 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 5, 34, 3, 71, 68, 0
951 );
952
953 return _compose(c, m);
954}
955
956static inline cube_t
957_move_F(cube_t c)
958{
959 cube_t m = _mm256_set_epi8(
960 0, 0, 0, 0, 11, 10, 19, 16, 7, 6, 5, 4, 24, 2, 1, 25,
961 0, 0, 0, 0, 0, 0, 0, 0, 7, 64, 5, 66, 3, 38, 1, 36
962 );
963
964 return _compose(c, m);
965}
966
967static inline cube_t
968_move_F2(cube_t c)
969{
970 cube_t m = _mm256_set_epi8(
971 0, 0, 0, 0, 11, 10, 8, 9, 7, 6, 5, 4, 0, 2, 1, 3,
972 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 5, 6, 3, 0, 1, 2
973 );
974
975 return _mm256_shuffle_epi8(c, m);
976}
977
978static inline cube_t
979_move_F3(cube_t c)
980{
981 cube_t m = _mm256_set_epi8(
982 0, 0, 0, 0, 11, 10, 16, 19, 7, 6, 5, 4, 25, 2, 1, 24,
983 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 5, 64, 3, 36, 1, 38
984 );
985
986 return _compose(c, m);
987}
988
989static inline cube_t
990_move_B(cube_t c)
991{
992 cube_t m = _mm256_set_epi8(
993 0, 0, 0, 0, 18, 17, 9, 8, 7, 6, 5, 4, 3, 26, 27, 0,
994 0, 0, 0, 0, 0, 0, 0, 0, 65, 6, 67, 4, 39, 2, 37, 0
995 );
996
997 return _compose(c, m);
998}
999
1000static inline cube_t
1001_move_B2(cube_t c)
1002{
1003 cube_t m = _mm256_set_epi8(
1004 0, 0, 0, 0, 10, 11, 9, 8, 7, 6, 5, 4, 3, 1, 2, 0,
1005 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 4, 1, 2, 3, 0
1006 );
1007
1008 return _mm256_shuffle_epi8(c, m);
1009}
1010
1011static inline cube_t
1012_move_B3(cube_t c)
1013{
1014 cube_t m = _mm256_set_epi8(
1015 0, 0, 0, 0, 17, 18, 9, 8, 7, 6, 5, 4, 3, 27, 26, 0,
1016 0, 0, 0, 0, 0, 0, 0, 0, 67, 6, 65, 4, 37, 2, 39, 0
1017 );
1018
1019 return _compose(c, m);
1020}
1021
1022static inline cube_t
1023_trans_UFr(cube_t c)
1024{
1025 cube_t ret;
1026
1027 cube_t tn = _mm256_set_epi8(
1028 0, 0, 0, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
1029 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0
1030 );
1031 cube_t ti = _mm256_set_epi8(
1032 0, 0, 0, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
1033 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0
1034 );
1035
1036 ret = compose(tn, c);
1037 ret = compose(ret, ti);
1038
1039 return ret;
1040}
1041
1042static inline cube_t
1043_trans_ULr(cube_t c)
1044{
1045 cube_t ret;
1046
1047 cube_t tn = _mm256_set_epi8(
1048 0, 0, 0, 0, 24, 27, 26, 25, 3, 2, 1, 0, 6, 7, 4, 5,
1049 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 1, 6, 7, 5, 4
1050 );
1051 cube_t ti = _mm256_set_epi8(
1052 0, 0, 0, 0, 26, 25, 24, 27, 2, 3, 0, 1, 7, 6, 5, 4,
1053 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 1, 0, 7, 6, 4, 5
1054 );
1055
1056 ret = compose(tn, c);
1057 ret = compose(ret, ti);
1058
1059 return ret;
1060}
1061
1062static inline cube_t
1063_trans_UBr(cube_t c)
1064{
1065 cube_t ret;
1066
1067 cube_t tn = _mm256_set_epi8(
1068 0, 0, 0, 0, 9, 8, 11, 10, 6, 7, 4, 5, 2, 3, 0, 1,
1069 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 4, 5, 2, 3, 0, 1
1070 );
1071 cube_t ti = _mm256_set_epi8(
1072 0, 0, 0, 0, 9, 8, 11, 10, 6, 7, 4, 5, 2, 3, 0, 1,
1073 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 4, 5, 2, 3, 0, 1
1074 );
1075
1076 ret = compose(tn, c);
1077 ret = compose(ret, ti);
1078
1079 return ret;
1080}
1081
1082static inline cube_t
1083_trans_URr(cube_t c)
1084{
1085 cube_t ret;
1086
1087 cube_t tn = _mm256_set_epi8(
1088 0, 0, 0, 0, 26, 25, 24, 27, 2, 3, 0, 1, 7, 6, 5, 4,
1089 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 1, 0, 7, 6, 4, 5
1090 );
1091 cube_t ti = _mm256_set_epi8(
1092 0, 0, 0, 0, 24, 27, 26, 25, 3, 2, 1, 0, 6, 7, 4, 5,
1093 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 1, 6, 7, 5, 4
1094 );
1095
1096 ret = compose(tn, c);
1097 ret = compose(ret, ti);
1098
1099 return ret;
1100}
1101
1102static inline cube_t
1103_trans_DFr(cube_t c)
1104{
1105 cube_t ret;
1106
1107 cube_t tn = _mm256_set_epi8(
1108 0, 0, 0, 0, 10, 11, 8, 9, 5, 4, 7, 6, 0, 1, 2, 3,
1109 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 7, 6, 1, 0, 3, 2
1110 );
1111 cube_t ti = _mm256_set_epi8(
1112 0, 0, 0, 0, 10, 11, 8, 9, 5, 4, 7, 6, 0, 1, 2, 3,
1113 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 7, 6, 1, 0, 3, 2
1114 );
1115
1116 ret = compose(tn, c);
1117 ret = compose(ret, ti);
1118
1119 return ret;
1120}
1121
1122static inline cube_t
1123_trans_DLr(cube_t c)
1124{
1125 cube_t ret;
1126
1127 cube_t tn = _mm256_set_epi8(
1128 0, 0, 0, 0, 27, 24, 25, 26, 1, 0, 3, 2, 5, 4, 7, 6,
1129 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 5, 4, 6, 7
1130 );
1131 cube_t ti = _mm256_set_epi8(
1132 0, 0, 0, 0, 27, 24, 25, 26, 1, 0, 3, 2, 5, 4, 7, 6,
1133 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 5, 4, 6, 7
1134 );
1135
1136 ret = compose(tn, c);
1137 ret = compose(ret, ti);
1138
1139 return ret;
1140}
1141
1142static inline cube_t
1143_trans_DBr(cube_t c)
1144{
1145 cube_t ret;
1146
1147 cube_t tn = _mm256_set_epi8(
1148 0, 0, 0, 0, 8, 9, 10, 11, 4, 5, 6, 7, 1, 0, 3, 2,
1149 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3
1150 );
1151 cube_t ti = _mm256_set_epi8(
1152 0, 0, 0, 0, 8, 9, 10, 11, 4, 5, 6, 7, 1, 0, 3, 2,
1153 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3
1154 );
1155
1156 ret = compose(tn, c);
1157 ret = compose(ret, ti);
1158
1159 return ret;
1160}
1161
1162static inline cube_t
1163_trans_DRr(cube_t c)
1164{
1165 cube_t ret;
1166
1167 cube_t tn = _mm256_set_epi8(
1168 0, 0, 0, 0, 25, 26, 27, 24, 0, 1, 2, 3, 4, 5, 6, 7,
1169 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 4, 5, 7, 6
1170 );
1171 cube_t ti = _mm256_set_epi8(
1172 0, 0, 0, 0, 25, 26, 27, 24, 0, 1, 2, 3, 4, 5, 6, 7,
1173 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 4, 5, 7, 6
1174 );
1175
1176 ret = compose(tn, c);
1177 ret = compose(ret, ti);
1178
1179 return ret;
1180}
1181
1182static inline cube_t
1183_trans_RUr(cube_t c)
1184{
1185 cube_t ret;
1186
1187 cube_t tn = _mm256_set_epi8(
1188 0, 0, 0, 0, 3, 2, 1, 0, 25, 26, 27, 24, 21, 22, 23, 20,
1189 0, 0, 0, 0, 0, 0, 0, 0, 39, 36, 38, 37, 66, 65, 67, 64
1190 );
1191 cube_t ti = _mm256_set_epi8(
1192 0, 0, 0, 0, 21, 22, 23, 20, 17, 18, 19, 16, 11, 10, 9, 8,
1193 0, 0, 0, 0, 0, 0, 0, 0, 71, 69, 68, 70, 33, 35, 34, 32
1194 );
1195
1196 ret = compose(tn, c);
1197 ret = compose(ret, ti);
1198
1199 return ret;
1200}
1201
1202static inline cube_t
1203_trans_RFr(cube_t c)
1204{
1205 cube_t ret;
1206
1207 cube_t tn = _mm256_set_epi8(
1208 0, 0, 0, 0, 18, 17, 16, 19, 22, 21, 20, 23, 25, 26, 27, 24,
1209 0, 0, 0, 0, 0, 0, 0, 0, 65, 66, 67, 64, 39, 36, 37, 38
1210 );
1211 cube_t ti = _mm256_set_epi8(
1212 0, 0, 0, 0, 17, 18, 19, 16, 20, 23, 22, 21, 24, 27, 26, 25,
1213 0, 0, 0, 0, 0, 0, 0, 0, 67, 64, 65, 66, 37, 38, 39, 36
1214 );
1215
1216 ret = compose(tn, c);
1217 ret = compose(ret, ti);
1218
1219 return ret;
1220}
1221
1222static inline cube_t
1223_trans_RDr(cube_t c)
1224{
1225 cube_t ret;
1226
1227 cube_t tn = _mm256_set_epi8(
1228 0, 0, 0, 0, 1, 0, 3, 2, 26, 25, 24, 27, 22, 21, 20, 23,
1229 0, 0, 0, 0, 0, 0, 0, 0, 36, 39, 37, 38, 65, 66, 64, 67
1230 );
1231 cube_t ti = _mm256_set_epi8(
1232 0, 0, 0, 0, 20, 23, 22, 21, 16, 19, 18, 17, 9, 8, 11, 10,
1233 0, 0, 0, 0, 0, 0, 0, 0, 70, 68, 69, 71, 32, 34, 35, 33
1234 );
1235
1236 ret = compose(tn, c);
1237 ret = compose(ret, ti);
1238
1239 return ret;
1240}
1241
1242static inline cube_t
1243_trans_RBr(cube_t c)
1244{
1245 cube_t ret;
1246
1247 cube_t tn = _mm256_set_epi8(
1248 0, 0, 0, 0, 16, 19, 18, 17, 21, 22, 23, 20, 26, 25, 24, 27,
1249 0, 0, 0, 0, 0, 0, 0, 0, 66, 65, 64, 67, 36, 39, 38, 37
1250 );
1251 cube_t ti = _mm256_set_epi8(
1252 0, 0, 0, 0, 16, 19, 18, 17, 21, 22, 23, 20, 26, 25, 24, 27,
1253 0, 0, 0, 0, 0, 0, 0, 0, 66, 65, 64, 67, 36, 39, 38, 37
1254 );
1255
1256 ret = compose(tn, c);
1257 ret = compose(ret, ti);
1258
1259 return ret;
1260}
1261
1262static inline cube_t
1263_trans_LUr(cube_t c)
1264{
1265 cube_t ret;
1266
1267 cube_t tn = _mm256_set_epi8(
1268 0, 0, 0, 0, 2, 3, 0, 1, 27, 24, 25, 26, 20, 23, 22, 21,
1269 0, 0, 0, 0, 0, 0, 0, 0, 38, 37, 39, 36, 67, 64, 66, 65
1270 );
1271 cube_t ti = _mm256_set_epi8(
1272 0, 0, 0, 0, 23, 20, 21, 22, 18, 17, 16, 19, 10, 11, 8, 9,
1273 0, 0, 0, 0, 0, 0, 0, 0, 69, 71, 70, 68, 35, 33, 32, 34
1274 );
1275
1276 ret = compose(tn, c);
1277 ret = compose(ret, ti);
1278
1279 return ret;
1280}
1281
1282static inline cube_t
1283_trans_LFr(cube_t c)
1284{
1285 cube_t ret;
1286
1287 cube_t tn = _mm256_set_epi8(
1288 0, 0, 0, 0, 17, 18, 19, 16, 20, 23, 22, 21, 24, 27, 26, 25,
1289 0, 0, 0, 0, 0, 0, 0, 0, 67, 64, 65, 66, 37, 38, 39, 36
1290 );
1291 cube_t ti = _mm256_set_epi8(
1292 0, 0, 0, 0, 18, 17, 16, 19, 22, 21, 20, 23, 25, 26, 27, 24,
1293 0, 0, 0, 0, 0, 0, 0, 0, 65, 66, 67, 64, 39, 36, 37, 38
1294 );
1295
1296 ret = compose(tn, c);
1297 ret = compose(ret, ti);
1298
1299 return ret;
1300}
1301
1302static inline cube_t
1303_trans_LDr(cube_t c)
1304{
1305 cube_t ret;
1306
1307 cube_t tn = _mm256_set_epi8(
1308 0, 0, 0, 0, 0, 1, 2, 3, 24, 27, 26, 25, 23, 20, 21, 22,
1309 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 36, 39, 64, 67, 65, 66
1310 );
1311 cube_t ti = _mm256_set_epi8(
1312 0, 0, 0, 0, 22, 21, 20, 23, 19, 16, 17, 18, 8, 9, 10, 11,
1313 0, 0, 0, 0, 0, 0, 0, 0, 68, 70, 71, 69, 34, 32, 33, 35
1314 );
1315
1316 ret = compose(tn, c);
1317 ret = compose(ret, ti);
1318
1319 return ret;
1320}
1321
1322static inline cube_t
1323_trans_LBr(cube_t c)
1324{
1325 cube_t ret;
1326
1327 cube_t tn = _mm256_set_epi8(
1328 0, 0, 0, 0, 19, 16, 17, 18, 23, 20, 21, 22, 27, 24, 25, 26,
1329 0, 0, 0, 0, 0, 0, 0, 0, 64, 67, 66, 65, 38, 37, 36, 39
1330 );
1331 cube_t ti = _mm256_set_epi8(
1332 0, 0, 0, 0, 19, 16, 17, 18, 23, 20, 21, 22, 27, 24, 25, 26,
1333 0, 0, 0, 0, 0, 0, 0, 0, 64, 67, 66, 65, 38, 37, 36, 39
1334 );
1335
1336 ret = compose(tn, c);
1337 ret = compose(ret, ti);
1338
1339 return ret;
1340}
1341
1342static inline cube_t
1343_trans_FUr(cube_t c)
1344{
1345 cube_t ret;
1346
1347 cube_t tn = _mm256_set_epi8(
1348 0, 0, 0, 0, 6, 7, 4, 5, 10, 11, 8, 9, 17, 18, 19, 16,
1349 0, 0, 0, 0, 0, 0, 0, 0, 35, 33, 34, 32, 71, 69, 70, 68
1350 );
1351 cube_t ti = _mm256_set_epi8(
1352 0, 0, 0, 0, 6, 7, 4, 5, 10, 11, 8, 9, 17, 18, 19, 16,
1353 0, 0, 0, 0, 0, 0, 0, 0, 35, 33, 34, 32, 71, 69, 70, 68
1354 );
1355
1356 ret = compose(tn, c);
1357 ret = compose(ret, ti);
1358
1359 return ret;
1360}
1361
1362static inline cube_t
1363_trans_FRr(cube_t c)
1364{
1365 cube_t ret;
1366
1367 cube_t tn = _mm256_set_epi8(
1368 0, 0, 0, 0, 21, 22, 23, 20, 17, 18, 19, 16, 11, 10, 9, 8,
1369 0, 0, 0, 0, 0, 0, 0, 0, 71, 69, 68, 70, 33, 35, 34, 32
1370 );
1371 cube_t ti = _mm256_set_epi8(
1372 0, 0, 0, 0, 3, 2, 1, 0, 25, 26, 27, 24, 21, 22, 23, 20,
1373 0, 0, 0, 0, 0, 0, 0, 0, 39, 36, 38, 37, 66, 65, 67, 64
1374 );
1375
1376 ret = compose(tn, c);
1377 ret = compose(ret, ti);
1378
1379 return ret;
1380}
1381
1382static inline cube_t
1383_trans_FDr(cube_t c)
1384{
1385 cube_t ret;
1386
1387 cube_t tn = _mm256_set_epi8(
1388 0, 0, 0, 0, 4, 5, 6, 7, 11, 10, 9, 8, 18, 17, 16, 19,
1389 0, 0, 0, 0, 0, 0, 0, 0, 33, 35, 32, 34, 69, 71, 68, 70
1390 );
1391 cube_t ti = _mm256_set_epi8(
1392 0, 0, 0, 0, 7, 6, 5, 4, 8, 9, 10, 11, 16, 19, 18, 17,
1393 0, 0, 0, 0, 0, 0, 0, 0, 34, 32, 35, 33, 70, 68, 71, 69
1394 );
1395
1396 ret = compose(tn, c);
1397 ret = compose(ret, ti);
1398
1399 return ret;
1400}
1401
1402static inline cube_t
1403_trans_FLr(cube_t c)
1404{
1405 cube_t ret;
1406
1407 cube_t tn = _mm256_set_epi8(
1408 0, 0, 0, 0, 23, 20, 21, 22, 18, 17, 16, 19, 10, 11, 8, 9,
1409 0, 0, 0, 0, 0, 0, 0, 0, 69, 71, 70, 68, 35, 33, 32, 34
1410 );
1411 cube_t ti = _mm256_set_epi8(
1412 0, 0, 0, 0, 2, 3, 0, 1, 27, 24, 25, 26, 20, 23, 22, 21,
1413 0, 0, 0, 0, 0, 0, 0, 0, 38, 37, 39, 36, 67, 64, 66, 65
1414 );
1415
1416 ret = compose(tn, c);
1417 ret = compose(ret, ti);
1418
1419 return ret;
1420}
1421
1422static inline cube_t
1423_trans_BUr(cube_t c)
1424{
1425 cube_t ret;
1426
1427 cube_t tn = _mm256_set_epi8(
1428 0, 0, 0, 0, 7, 6, 5, 4, 8, 9, 10, 11, 16, 19, 18, 17,
1429 0, 0, 0, 0, 0, 0, 0, 0, 34, 32, 35, 33, 70, 68, 71, 69
1430 );
1431 cube_t ti = _mm256_set_epi8(
1432 0, 0, 0, 0, 4, 5, 6, 7, 11, 10, 9, 8, 18, 17, 16, 19,
1433 0, 0, 0, 0, 0, 0, 0, 0, 33, 35, 32, 34, 69, 71, 68, 70
1434 );
1435
1436 ret = compose(tn, c);
1437 ret = compose(ret, ti);
1438
1439 return ret;
1440}
1441
1442static inline cube_t
1443_trans_BRr(cube_t c)
1444{
1445 cube_t ret;
1446
1447 cube_t tn = _mm256_set_epi8(
1448 0, 0, 0, 0, 22, 21, 20, 23, 19, 16, 17, 18, 8, 9, 10, 11,
1449 0, 0, 0, 0, 0, 0, 0, 0, 68, 70, 71, 69, 34, 32, 33, 35
1450 );
1451 cube_t ti = _mm256_set_epi8(
1452 0, 0, 0, 0, 0, 1, 2, 3, 24, 27, 26, 25, 23, 20, 21, 22,
1453 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 36, 39, 64, 67, 65, 66
1454 );
1455
1456 ret = compose(tn, c);
1457 ret = compose(ret, ti);
1458
1459 return ret;
1460}
1461
1462static inline cube_t
1463_trans_BDr(cube_t c)
1464{
1465 cube_t ret;
1466
1467 cube_t tn = _mm256_set_epi8(
1468 0, 0, 0, 0, 5, 4, 7, 6, 9, 8, 11, 10, 19, 16, 17, 18,
1469 0, 0, 0, 0, 0, 0, 0, 0, 32, 34, 33, 35, 68, 70, 69, 71
1470 );
1471 cube_t ti = _mm256_set_epi8(
1472 0, 0, 0, 0, 5, 4, 7, 6, 9, 8, 11, 10, 19, 16, 17, 18,
1473 0, 0, 0, 0, 0, 0, 0, 0, 32, 34, 33, 35, 68, 70, 69, 71
1474 );
1475
1476 ret = compose(tn, c);
1477 ret = compose(ret, ti);
1478
1479 return ret;
1480}
1481
1482static inline cube_t
1483_trans_BLr(cube_t c)
1484{
1485 cube_t ret;
1486
1487 cube_t tn = _mm256_set_epi8(
1488 0, 0, 0, 0, 20, 23, 22, 21, 16, 19, 18, 17, 9, 8, 11, 10,
1489 0, 0, 0, 0, 0, 0, 0, 0, 70, 68, 69, 71, 32, 34, 35, 33
1490 );
1491 cube_t ti = _mm256_set_epi8(
1492 0, 0, 0, 0, 1, 0, 3, 2, 26, 25, 24, 27, 22, 21, 20, 23,
1493 0, 0, 0, 0, 0, 0, 0, 0, 36, 39, 37, 38, 65, 66, 64, 67
1494 );
1495
1496 ret = compose(tn, c);
1497 ret = compose(ret, ti);
1498
1499 return ret;
1500}
1501
1502static inline cube_t
1503_trans_UFm(cube_t c)
1504{
1505 cube_t ret;
1506
1507 cube_t tn = _mm256_set_epi8(
1508 0, 0, 0, 0, 10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1, 0,
1509 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 1, 0, 7, 6, 5, 4
1510 );
1511 cube_t ti = _mm256_set_epi8(
1512 0, 0, 0, 0, 10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1, 0,
1513 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 1, 0, 7, 6, 5, 4
1514 );
1515
1516 ret = compose(tn, c);
1517 ret = compose(ret, ti);
1518 ret = _invertco(ret);
1519
1520 return ret;
1521}
1522
1523static inline cube_t
1524_trans_ULm(cube_t c)
1525{
1526 cube_t ret;
1527
1528 cube_t tn = _mm256_set_epi8(
1529 0, 0, 0, 0, 25, 26, 27, 24, 3, 2, 1, 0, 7, 6, 5, 4,
1530 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 4, 5, 2, 3, 1, 0
1531 );
1532 cube_t ti = _mm256_set_epi8(
1533 0, 0, 0, 0, 25, 26, 27, 24, 3, 2, 1, 0, 7, 6, 5, 4,
1534 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 4, 5, 2, 3, 1, 0
1535 );
1536
1537 ret = compose(tn, c);
1538 ret = compose(ret, ti);
1539 ret = _invertco(ret);
1540
1541 return ret;
1542}
1543
1544static inline cube_t
1545_trans_UBm(cube_t c)
1546{
1547 cube_t ret;
1548
1549 cube_t tn = _mm256_set_epi8(
1550 0, 0, 0, 0, 8, 9, 10, 11, 7, 6, 5, 4, 2, 3, 0, 1,
1551 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 1, 6, 7, 4, 5
1552 );
1553 cube_t ti = _mm256_set_epi8(
1554 0, 0, 0, 0, 8, 9, 10, 11, 7, 6, 5, 4, 2, 3, 0, 1,
1555 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 1, 6, 7, 4, 5
1556 );
1557
1558 ret = compose(tn, c);
1559 ret = compose(ret, ti);
1560 ret = _invertco(ret);
1561
1562 return ret;
1563}
1564
1565static inline cube_t
1566_trans_URm(cube_t c)
1567{
1568 cube_t ret;
1569
1570 cube_t tn = _mm256_set_epi8(
1571 0, 0, 0, 0, 27, 24, 25, 26, 2, 3, 0, 1, 6, 7, 4, 5,
1572 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 5, 4, 3, 2, 0, 1
1573 );
1574 cube_t ti = _mm256_set_epi8(
1575 0, 0, 0, 0, 27, 24, 25, 26, 2, 3, 0, 1, 6, 7, 4, 5,
1576 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 5, 4, 3, 2, 0, 1
1577 );
1578
1579 ret = compose(tn, c);
1580 ret = compose(ret, ti);
1581 ret = _invertco(ret);
1582
1583 return ret;
1584}
1585
1586static inline cube_t
1587_trans_DFm(cube_t c)
1588{
1589 cube_t ret;
1590
1591 cube_t tn = _mm256_set_epi8(
1592 0, 0, 0, 0, 11, 10, 9, 8, 4, 5, 6, 7, 0, 1, 2, 3,
1593 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 2, 5, 4, 7, 6
1594 );
1595 cube_t ti = _mm256_set_epi8(
1596 0, 0, 0, 0, 11, 10, 9, 8, 4, 5, 6, 7, 0, 1, 2, 3,
1597 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 2, 5, 4, 7, 6
1598 );
1599
1600 ret = compose(tn, c);
1601 ret = compose(ret, ti);
1602 ret = _invertco(ret);
1603
1604 return ret;
1605}
1606
1607static inline cube_t
1608_trans_DLm(cube_t c)
1609{
1610 cube_t ret;
1611
1612 cube_t tn = _mm256_set_epi8(
1613 0, 0, 0, 0, 26, 25, 24, 27, 1, 0, 3, 2, 4, 5, 6, 7,
1614 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 7, 6, 1, 0, 2, 3
1615 );
1616 cube_t ti = _mm256_set_epi8(
1617 0, 0, 0, 0, 24, 27, 26, 25, 0, 1, 2, 3, 5, 4, 7, 6,
1618 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 6, 7, 0, 1, 3, 2
1619 );
1620
1621 ret = compose(tn, c);
1622 ret = compose(ret, ti);
1623 ret = _invertco(ret);
1624
1625 return ret;
1626}
1627
1628static inline cube_t
1629_trans_DBm(cube_t c)
1630{
1631 cube_t ret;
1632
1633 cube_t tn = _mm256_set_epi8(
1634 0, 0, 0, 0, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2,
1635 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7
1636 );
1637 cube_t ti = _mm256_set_epi8(
1638 0, 0, 0, 0, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2,
1639 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7
1640 );
1641
1642 ret = compose(tn, c);
1643 ret = compose(ret, ti);
1644 ret = _invertco(ret);
1645
1646 return ret;
1647}
1648
1649static inline cube_t
1650_trans_DRm(cube_t c)
1651{
1652 cube_t ret;
1653
1654 cube_t tn = _mm256_set_epi8(
1655 0, 0, 0, 0, 24, 27, 26, 25, 0, 1, 2, 3, 5, 4, 7, 6,
1656 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 6, 7, 0, 1, 3, 2
1657 );
1658 cube_t ti = _mm256_set_epi8(
1659 0, 0, 0, 0, 26, 25, 24, 27, 1, 0, 3, 2, 4, 5, 6, 7,
1660 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 7, 6, 1, 0, 2, 3
1661 );
1662
1663 ret = compose(tn, c);
1664 ret = compose(ret, ti);
1665 ret = _invertco(ret);
1666
1667 return ret;
1668}
1669
1670static inline cube_t
1671_trans_RUm(cube_t c)
1672{
1673 cube_t ret;
1674
1675 cube_t tn = _mm256_set_epi8(
1676 0, 0, 0, 0, 3, 2, 1, 0, 24, 27, 26, 25, 20, 23, 22, 21,
1677 0, 0, 0, 0, 0, 0, 0, 0, 35, 32, 34, 33, 70, 69, 71, 68
1678 );
1679 cube_t ti = _mm256_set_epi8(
1680 0, 0, 0, 0, 22, 21, 20, 23, 18, 17, 16, 19, 11, 10, 9, 8,
1681 0, 0, 0, 0, 0, 0, 0, 0, 33, 35, 34, 32, 71, 69, 68, 70
1682 );
1683
1684 ret = compose(tn, c);
1685 ret = compose(ret, ti);
1686 ret = _invertco(ret);
1687
1688 return ret;
1689}
1690
1691static inline cube_t
1692_trans_RFm(cube_t c)
1693{
1694 cube_t ret;
1695
1696 cube_t tn = _mm256_set_epi8(
1697 0, 0, 0, 0, 18, 17, 16, 19, 23, 20, 21, 22, 24, 27, 26, 25,
1698 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 71, 68, 35, 32, 33, 34
1699 );
1700 cube_t ti = _mm256_set_epi8(
1701 0, 0, 0, 0, 18, 17, 16, 19, 23, 20, 21, 22, 24, 27, 26, 25,
1702 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 39, 36, 67, 64, 65, 66
1703 );
1704
1705 ret = compose(tn, c);
1706 ret = compose(ret, ti);
1707 ret = _invertco(ret);
1708
1709 return ret;
1710}
1711
1712static inline cube_t
1713_trans_RDm(cube_t c)
1714{
1715 cube_t ret;
1716
1717 cube_t tn = _mm256_set_epi8(
1718 0, 0, 0, 0, 1, 0, 3, 2, 27, 24, 25, 26, 23, 20, 21, 22,
1719 0, 0, 0, 0, 0, 0, 0, 0, 32, 35, 33, 34, 69, 70, 68, 71
1720 );
1721 cube_t ti = _mm256_set_epi8(
1722 0, 0, 0, 0, 23, 20, 21, 22, 19, 16, 17, 18, 9, 8, 11, 10,
1723 0, 0, 0, 0, 0, 0, 0, 0, 32, 34, 35, 33, 70, 68, 69, 71
1724 );
1725
1726 ret = compose(tn, c);
1727 ret = compose(ret, ti);
1728 ret = _invertco(ret);
1729
1730 return ret;
1731}
1732
1733static inline cube_t
1734_trans_RBm(cube_t c)
1735{
1736 cube_t ret;
1737
1738 cube_t tn = _mm256_set_epi8(
1739 0, 0, 0, 0, 16, 19, 18, 17, 20, 23, 22, 21, 27, 24, 25, 26,
1740 0, 0, 0, 0, 0, 0, 0, 0, 70, 69, 68, 71, 32, 35, 34, 33
1741 );
1742 cube_t ti = _mm256_set_epi8(
1743 0, 0, 0, 0, 19, 16, 17, 18, 22, 21, 20, 23, 26, 25, 24, 27,
1744 0, 0, 0, 0, 0, 0, 0, 0, 36, 39, 38, 37, 66, 65, 64, 67
1745 );
1746
1747 ret = compose(tn, c);
1748 ret = compose(ret, ti);
1749 ret = _invertco(ret);
1750
1751 return ret;
1752}
1753
1754static inline cube_t
1755_trans_LUm(cube_t c)
1756{
1757 cube_t ret;
1758
1759 cube_t tn = _mm256_set_epi8(
1760 0, 0, 0, 0, 2, 3, 0, 1, 26, 25, 24, 27, 21, 22, 23, 20,
1761 0, 0, 0, 0, 0, 0, 0, 0, 34, 33, 35, 32, 71, 68, 70, 69
1762 );
1763 cube_t ti = _mm256_set_epi8(
1764 0, 0, 0, 0, 20, 23, 22, 21, 17, 18, 19, 16, 10, 11, 8, 9,
1765 0, 0, 0, 0, 0, 0, 0, 0, 35, 33, 32, 34, 69, 71, 70, 68
1766 );
1767
1768 ret = compose(tn, c);
1769 ret = compose(ret, ti);
1770 ret = _invertco(ret);
1771
1772 return ret;
1773}
1774
1775static inline cube_t
1776_trans_LFm(cube_t c)
1777{
1778 cube_t ret;
1779
1780 cube_t tn = _mm256_set_epi8(
1781 0, 0, 0, 0, 17, 18, 19, 16, 21, 22, 23, 20, 25, 26, 27, 24,
1782 0, 0, 0, 0, 0, 0, 0, 0, 71, 68, 69, 70, 33, 34, 35, 32
1783 );
1784 cube_t ti = _mm256_set_epi8(
1785 0, 0, 0, 0, 17, 18, 19, 16, 21, 22, 23, 20, 25, 26, 27, 24,
1786 0, 0, 0, 0, 0, 0, 0, 0, 39, 36, 37, 38, 65, 66, 67, 64
1787 );
1788
1789 ret = compose(tn, c);
1790 ret = compose(ret, ti);
1791 ret = _invertco(ret);
1792
1793 return ret;
1794}
1795
1796static inline cube_t
1797_trans_LDm(cube_t c)
1798{
1799 cube_t ret;
1800
1801 cube_t tn = _mm256_set_epi8(
1802 0, 0, 0, 0, 0, 1, 2, 3, 25, 26, 27, 24, 22, 21, 20, 23,
1803 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, 32, 35, 68, 71, 69, 70
1804 );
1805 cube_t ti = _mm256_set_epi8(
1806 0, 0, 0, 0, 21, 22, 23, 20, 16, 19, 18, 17, 8, 9, 10, 11,
1807 0, 0, 0, 0, 0, 0, 0, 0, 34, 32, 33, 35, 68, 70, 71, 69
1808 );
1809
1810 ret = compose(tn, c);
1811 ret = compose(ret, ti);
1812 ret = _invertco(ret);
1813
1814 return ret;
1815}
1816
1817static inline cube_t
1818_trans_LBm(cube_t c)
1819{
1820 cube_t ret;
1821
1822 cube_t tn = _mm256_set_epi8(
1823 0, 0, 0, 0, 19, 16, 17, 18, 22, 21, 20, 23, 26, 25, 24, 27,
1824 0, 0, 0, 0, 0, 0, 0, 0, 68, 71, 70, 69, 34, 33, 32, 35
1825 );
1826 cube_t ti = _mm256_set_epi8(
1827 0, 0, 0, 0, 16, 19, 18, 17, 20, 23, 22, 21, 27, 24, 25, 26,
1828 0, 0, 0, 0, 0, 0, 0, 0, 38, 37, 36, 39, 64, 67, 66, 65
1829 );
1830
1831 ret = compose(tn, c);
1832 ret = compose(ret, ti);
1833 ret = _invertco(ret);
1834
1835 return ret;
1836}
1837
1838static inline cube_t
1839_trans_FUm(cube_t c)
1840{
1841 cube_t ret;
1842
1843 cube_t tn = _mm256_set_epi8(
1844 0, 0, 0, 0, 7, 6, 5, 4, 11, 10, 9, 8, 17, 18, 19, 16,
1845 0, 0, 0, 0, 0, 0, 0, 0, 39, 37, 38, 36, 67, 65, 66, 64
1846 );
1847 cube_t ti = _mm256_set_epi8(
1848 0, 0, 0, 0, 7, 6, 5, 4, 11, 10, 9, 8, 17, 18, 19, 16,
1849 0, 0, 0, 0, 0, 0, 0, 0, 71, 69, 70, 68, 35, 33, 34, 32
1850 );
1851
1852 ret = compose(tn, c);
1853 ret = compose(ret, ti);
1854 ret = _invertco(ret);
1855
1856 return ret;
1857}
1858
1859static inline cube_t
1860_trans_FRm(cube_t c)
1861{
1862 cube_t ret;
1863
1864 cube_t tn = _mm256_set_epi8(
1865 0, 0, 0, 0, 20, 23, 22, 21, 17, 18, 19, 16, 10, 11, 8, 9,
1866 0, 0, 0, 0, 0, 0, 0, 0, 67, 65, 64, 66, 37, 39, 38, 36
1867 );
1868 cube_t ti = _mm256_set_epi8(
1869 0, 0, 0, 0, 2, 3, 0, 1, 26, 25, 24, 27, 21, 22, 23, 20,
1870 0, 0, 0, 0, 0, 0, 0, 0, 66, 65, 67, 64, 39, 36, 38, 37
1871 );
1872
1873 ret = compose(tn, c);
1874 ret = compose(ret, ti);
1875 ret = _invertco(ret);
1876
1877 return ret;
1878}
1879
1880static inline cube_t
1881_trans_FDm(cube_t c)
1882{
1883 cube_t ret;
1884
1885 cube_t tn = _mm256_set_epi8(
1886 0, 0, 0, 0, 5, 4, 7, 6, 10, 11, 8, 9, 18, 17, 16, 19,
1887 0, 0, 0, 0, 0, 0, 0, 0, 37, 39, 36, 38, 65, 67, 64, 66
1888 );
1889 cube_t ti = _mm256_set_epi8(
1890 0, 0, 0, 0, 6, 7, 4, 5, 9, 8, 11, 10, 16, 19, 18, 17,
1891 0, 0, 0, 0, 0, 0, 0, 0, 70, 68, 71, 69, 34, 32, 35, 33
1892 );
1893
1894 ret = compose(tn, c);
1895 ret = compose(ret, ti);
1896 ret = _invertco(ret);
1897
1898 return ret;
1899}
1900
1901static inline cube_t
1902_trans_FLm(cube_t c)
1903{
1904 cube_t ret;
1905
1906 cube_t tn = _mm256_set_epi8(
1907 0, 0, 0, 0, 22, 21, 20, 23, 18, 17, 16, 19, 11, 10, 9, 8,
1908 0, 0, 0, 0, 0, 0, 0, 0, 65, 67, 66, 64, 39, 37, 36, 38
1909 );
1910 cube_t ti = _mm256_set_epi8(
1911 0, 0, 0, 0, 3, 2, 1, 0, 24, 27, 26, 25, 20, 23, 22, 21,
1912 0, 0, 0, 0, 0, 0, 0, 0, 67, 64, 66, 65, 38, 37, 39, 36
1913 );
1914
1915 ret = compose(tn, c);
1916 ret = compose(ret, ti);
1917 ret = _invertco(ret);
1918
1919 return ret;
1920}
1921
1922static inline cube_t
1923_trans_BUm(cube_t c)
1924{
1925 cube_t ret;
1926
1927 cube_t tn = _mm256_set_epi8(
1928 0, 0, 0, 0, 6, 7, 4, 5, 9, 8, 11, 10, 16, 19, 18, 17,
1929 0, 0, 0, 0, 0, 0, 0, 0, 38, 36, 39, 37, 66, 64, 67, 65
1930 );
1931 cube_t ti = _mm256_set_epi8(
1932 0, 0, 0, 0, 5, 4, 7, 6, 10, 11, 8, 9, 18, 17, 16, 19,
1933 0, 0, 0, 0, 0, 0, 0, 0, 69, 71, 68, 70, 33, 35, 32, 34
1934 );
1935
1936 ret = compose(tn, c);
1937 ret = compose(ret, ti);
1938 ret = _invertco(ret);
1939
1940 return ret;
1941}
1942
1943static inline cube_t
1944_trans_BRm(cube_t c)
1945{
1946 cube_t ret;
1947
1948 cube_t tn = _mm256_set_epi8(
1949 0, 0, 0, 0, 23, 20, 21, 22, 19, 16, 17, 18, 9, 8, 11, 10,
1950 0, 0, 0, 0, 0, 0, 0, 0, 64, 66, 67, 65, 38, 36, 37, 39
1951 );
1952 cube_t ti = _mm256_set_epi8(
1953 0, 0, 0, 0, 1, 0, 3, 2, 27, 24, 25, 26, 23, 20, 21, 22,
1954 0, 0, 0, 0, 0, 0, 0, 0, 64, 67, 65, 66, 37, 38, 36, 39
1955 );
1956
1957 ret = compose(tn, c);
1958 ret = compose(ret, ti);
1959 ret = _invertco(ret);
1960
1961 return ret;
1962}
1963
1964static inline cube_t
1965_trans_BDm(cube_t c)
1966{
1967 cube_t ret;
1968
1969 cube_t tn = _mm256_set_epi8(
1970 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 19, 16, 17, 18,
1971 0, 0, 0, 0, 0, 0, 0, 0, 36, 38, 37, 39, 64, 66, 65, 67
1972 );
1973 cube_t ti = _mm256_set_epi8(
1974 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 19, 16, 17, 18,
1975 0, 0, 0, 0, 0, 0, 0, 0, 68, 70, 69, 71, 32, 34, 33, 35
1976 );
1977
1978 ret = compose(tn, c);
1979 ret = compose(ret, ti);
1980 ret = _invertco(ret);
1981
1982 return ret;
1983}
1984
1985static inline cube_t
1986_trans_BLm(cube_t c)
1987{
1988 cube_t ret;
1989
1990 cube_t tn = _mm256_set_epi8(
1991 0, 0, 0, 0, 21, 22, 23, 20, 16, 19, 18, 17, 8, 9, 10, 11,
1992 0, 0, 0, 0, 0, 0, 0, 0, 66, 64, 65, 67, 36, 38, 39, 37
1993 );
1994 cube_t ti = _mm256_set_epi8(
1995 0, 0, 0, 0, 0, 1, 2, 3, 25, 26, 27, 24, 22, 21, 20, 23,
1996 0, 0, 0, 0, 0, 0, 0, 0, 65, 66, 64, 67, 36, 39, 37, 38
1997 );
1998
1999 ret = compose(tn, c);
2000 ret = compose(ret, ti);
2001 ret = _invertco(ret);
2002
2003 return ret;
2004}
2005
2006static cube_t
2007_arraytocube(cube_array_t a)
2008{
2009 return _mm256_loadu_si256((__m256i_u *)&a);
2010}
2011
2012static void
2013_cubetoarray(cube_t c, cube_array_t *a)
2014{
2015 _mm256_storeu_si256((__m256i_u *)a, c);
2016}
2017
2018static inline bool
2019_equal(cube_t c1, cube_t c2)
2020{
2021 uint32_t mask;
2022 __m256i cmp;
2023
2024 cmp = _mm256_cmpeq_epi8(c1, c2);
2025 mask = _mm256_movemask_epi8(cmp);
2026
2027 return mask == 0xffffffffU;
2028}
2029
2030static inline cube_t
2031_invertco(cube_t c)
2032{
2033 cube_t co, shleft, shright, summed, newco, cleanco, ret;
2034
2035 co = _mm256_and_si256(c, _co2_avx2);
2036 shleft = _mm256_slli_epi32(co, 1);
2037 shright = _mm256_srli_epi32(co, 1);
2038 summed = _mm256_or_si256(shleft, shright);
2039 newco = _mm256_and_si256(summed, _co2_avx2);
2040 cleanco = _mm256_xor_si256(c, co);
2041 ret = _mm256_or_si256(cleanco, newco);
2042
2043 return ret;
2044}
2045
2046static inline cube_t
2047_inverse(cube_t c)
2048{
2049 /* Method taken from Andrew Skalski's vcube[1]. The addition sequence
2050 * was generated using [2].
2051 * [1] https://github.com/Voltara/vcube
2052 * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
2053 */
2054 cube_t v3, vi, vo, vp, ret;
2055
2056 v3 = _mm256_shuffle_epi8(c, c);
2057 v3 = _mm256_shuffle_epi8(v3, c);
2058 vi = _mm256_shuffle_epi8(v3, v3);
2059 vi = _mm256_shuffle_epi8(vi, vi);
2060 vi = _mm256_shuffle_epi8(vi, vi);
2061 vi = _mm256_shuffle_epi8(vi, v3);
2062 vi = _mm256_shuffle_epi8(vi, vi);
2063 vi = _mm256_shuffle_epi8(vi, vi);
2064 vi = _mm256_shuffle_epi8(vi, vi);
2065 vi = _mm256_shuffle_epi8(vi, vi);
2066 vi = _mm256_shuffle_epi8(vi, c);
2067 vi = _mm256_shuffle_epi8(vi, vi);
2068 vi = _mm256_shuffle_epi8(vi, vi);
2069 vi = _mm256_shuffle_epi8(vi, vi);
2070 vi = _mm256_shuffle_epi8(vi, vi);
2071 vi = _mm256_shuffle_epi8(vi, vi);
2072 vi = _mm256_shuffle_epi8(vi, v3);
2073 vi = _mm256_shuffle_epi8(vi, vi);
2074 vi = _mm256_shuffle_epi8(vi, c);
2075
2076 vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2));
2077 vo = _mm256_shuffle_epi8(vo, vi);
2078 vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi);
2079 ret = _mm256_or_si256(vp, vo);
2080
2081 return _invertco(ret);
2082}
2083
2084static inline cube_t
2085_compose(cube_t c1, cube_t c2)
2086{
2087 cube_t ret;
2088
2089 cube_t s, eo2, ed, co1, co2, aux, auy1, auy2, auz1, auz2, coclean;
2090
2091 eo2 = _mm256_and_si256(c2, _eo_avx2);
2092 s = _mm256_shuffle_epi8(c1, c2);
2093 ed = _mm256_xor_si256(s, eo2);
2094 co1 = _mm256_and_si256(s, _co2_avx2);
2095 co2 = _mm256_and_si256(c2, _co2_avx2);
2096 aux = _mm256_add_epi8(co1, co2);
2097 auy1 = _mm256_add_epi8(aux, _cocw_avx2);
2098 auy2 = _mm256_srli_epi32(auy1, 2);
2099 auz1 = _mm256_add_epi8(aux, auy2);
2100 auz2 = _mm256_and_si256(auz1, _co2_avx2);
2101 coclean = _mm256_andnot_si256(_co2_avx2, ed);
2102 ret = _mm256_or_si256(coclean, auz2);
2103
2104 return ret;
2105}
2106
2107
2108/******************************************************************************
2109Section: portable fast methods
2110
2111This section contains performance-critical methods that do not use
2112advanced CPU instructions. They are used as an alternative to the ones
2113in the previous section(s) for unsupported architectures.
2114******************************************************************************/
2115
2116#else
2117
2118#define PERM4(r, i, j, k, l) \
2119 aux = r[i]; \
2120 r[i] = r[l]; \
2121 r[l] = r[k]; \
2122 r[k] = r[j]; \
2123 r[j] = aux;
2124#define PERM22(r, i, j, k, l) \
2125 aux = r[i]; \
2126 r[i] = r[j]; \
2127 r[j] = aux; \
2128 aux = r[k]; \
2129 r[k] = r[l]; \
2130 r[l] = aux;
2131#define CO(a, b) \
2132 aux = (a & _cobits) + (b & _cobits); \
2133 auy = (aux + _ctwist_cw) >> 2U; \
2134 auz = (aux + auy) & _cobits2; \
2135 a = (a & _pbits) | auz;
2136#define CO4(r, i, j, k, l) \
2137 CO(r[i], _ctwist_cw) \
2138 CO(r[j], _ctwist_cw) \
2139 CO(r[k], _ctwist_ccw) \
2140 CO(r[l], _ctwist_ccw)
2141#define EO4(r, i, j, k, l) \
2142 r[i] ^= _eobit; \
2143 r[j] ^= _eobit; \
2144 r[k] ^= _eobit; \
2145 r[l] ^= _eobit;
2146
2147static cube_t _arraytocube(cube_array_t);
2148static void _cubetoarray(cube_t, cube_array_t *);
2149static inline bool _equal(cube_t, cube_t);
2150static inline cube_t _invertco(cube_t);
2151static inline cube_t _inverse(cube_t);
2152static inline cube_t _compose(cube_t, cube_t);
2153
2154static inline cube_t
2155_move_U(cube_t c)
2156{
2157 uint8_t aux;
2158 cube_t ret = c;
2159
2160 PERM4(ret.e, _e_uf, _e_ul, _e_ub, _e_ur)
2161 PERM4(ret.c, _c_ufr, _c_ufl, _c_ubl, _c_ubr)
2162
2163 return ret;
2164}
2165
2166static inline cube_t
2167_move_U2(cube_t c)
2168{
2169 uint8_t aux;
2170 cube_t ret = c;
2171
2172 PERM22(ret.e, _e_uf, _e_ub, _e_ul, _e_ur)
2173 PERM22(ret.c, _c_ufr, _c_ubl, _c_ufl, _c_ubr)
2174
2175 return ret;
2176}
2177
2178static inline cube_t
2179_move_U3(cube_t c)
2180{
2181 uint8_t aux;
2182 cube_t ret = c;
2183
2184 PERM4(ret.e, _e_uf, _e_ur, _e_ub, _e_ul)
2185 PERM4(ret.c, _c_ufr, _c_ubr, _c_ubl, _c_ufl)
2186
2187 return ret;
2188}
2189
2190static inline cube_t
2191_move_D(cube_t c)
2192{
2193 uint8_t aux;
2194 cube_t ret = c;
2195
2196 PERM4(ret.e, _e_df, _e_dr, _e_db, _e_dl)
2197 PERM4(ret.c, _c_dfr, _c_dbr, _c_dbl, _c_dfl)
2198
2199 return ret;
2200}
2201
2202static inline cube_t
2203_move_D2(cube_t c)
2204{
2205 uint8_t aux;
2206 cube_t ret = c;
2207
2208 PERM22(ret.e, _e_df, _e_db, _e_dr, _e_dl)
2209 PERM22(ret.c, _c_dfr, _c_dbl, _c_dbr, _c_dfl)
2210
2211 return ret;
2212}
2213
2214static inline cube_t
2215_move_D3(cube_t c)
2216{
2217 uint8_t aux;
2218 cube_t ret = c;
2219
2220 PERM4(ret.e, _e_df, _e_dl, _e_db, _e_dr)
2221 PERM4(ret.c, _c_dfr, _c_dfl, _c_dbl, _c_dbr)
2222
2223 return ret;
2224}
2225
2226static inline cube_t
2227_move_R(cube_t c)
2228{
2229 uint8_t aux, auy, auz;
2230 cube_t ret = c;
2231
2232 PERM4(ret.e, _e_ur, _e_br, _e_dr, _e_fr)
2233 PERM4(ret.c, _c_ufr, _c_ubr, _c_dbr, _c_dfr)
2234
2235 CO4(ret.c, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
2236
2237 return ret;
2238}
2239
2240static inline cube_t
2241_move_R2(cube_t c)
2242{
2243 uint8_t aux;
2244 cube_t ret = c;
2245
2246 PERM22(ret.e, _e_ur, _e_dr, _e_fr, _e_br)
2247 PERM22(ret.c, _c_ufr, _c_dbr, _c_ubr, _c_dfr)
2248
2249 return ret;
2250}
2251
2252static inline cube_t
2253_move_R3(cube_t c)
2254{
2255 uint8_t aux, auy, auz;
2256 cube_t ret = c;
2257
2258 PERM4(ret.e, _e_ur, _e_fr, _e_dr, _e_br)
2259 PERM4(ret.c, _c_ufr, _c_dfr, _c_dbr, _c_ubr)
2260
2261 CO4(ret.c, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
2262
2263 return ret;
2264}
2265
2266static inline cube_t
2267_move_L(cube_t c)
2268{
2269 uint8_t aux, auy, auz;
2270 cube_t ret = c;
2271
2272 PERM4(ret.e, _e_ul, _e_fl, _e_dl, _e_bl)
2273 PERM4(ret.c, _c_ufl, _c_dfl, _c_dbl, _c_ubl)
2274
2275 CO4(ret.c, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
2276
2277 return ret;
2278}
2279
2280static inline cube_t
2281_move_L2(cube_t c)
2282{
2283 uint8_t aux;
2284 cube_t ret = c;
2285
2286 PERM22(ret.e, _e_ul, _e_dl, _e_fl, _e_bl)
2287 PERM22(ret.c, _c_ufl, _c_dbl, _c_ubl, _c_dfl)
2288
2289 return ret;
2290}
2291
2292static inline cube_t
2293_move_L3(cube_t c)
2294{
2295 uint8_t aux, auy, auz;
2296 cube_t ret = c;
2297
2298 PERM4(ret.e, _e_ul, _e_bl, _e_dl, _e_fl)
2299 PERM4(ret.c, _c_ufl, _c_ubl, _c_dbl, _c_dfl)
2300
2301 CO4(ret.c, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
2302
2303 return ret;
2304}
2305
2306static inline cube_t
2307_move_F(cube_t c)
2308{
2309 uint8_t aux, auy, auz;
2310 cube_t ret = c;
2311
2312 PERM4(ret.e, _e_uf, _e_fr, _e_df, _e_fl)
2313 PERM4(ret.c, _c_ufr, _c_dfr, _c_dfl, _c_ufl)
2314
2315 EO4(ret.e, _e_uf, _e_fr, _e_df, _e_fl)
2316 CO4(ret.c, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
2317
2318 return ret;
2319}
2320
2321static inline cube_t
2322_move_F2(cube_t c)
2323{
2324 uint8_t aux;
2325 cube_t ret = c;
2326
2327 PERM22(ret.e, _e_uf, _e_df, _e_fr, _e_fl)
2328 PERM22(ret.c, _c_ufr, _c_dfl, _c_ufl, _c_dfr)
2329
2330 return ret;
2331}
2332
2333static inline cube_t
2334_move_F3(cube_t c)
2335{
2336 uint8_t aux, auy, auz;
2337 cube_t ret = c;
2338
2339 PERM4(ret.e, _e_uf, _e_fl, _e_df, _e_fr)
2340 PERM4(ret.c, _c_ufr, _c_ufl, _c_dfl, _c_dfr)
2341
2342 EO4(ret.e, _e_uf, _e_fr, _e_df, _e_fl)
2343 CO4(ret.c, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
2344
2345 return ret;
2346}
2347
2348static inline cube_t
2349_move_B(cube_t c)
2350{
2351 uint8_t aux, auy, auz;
2352 cube_t ret = c;
2353
2354 PERM4(ret.e, _e_ub, _e_bl, _e_db, _e_br)
2355 PERM4(ret.c, _c_ubr, _c_ubl, _c_dbl, _c_dbr)
2356
2357 EO4(ret.e, _e_ub, _e_br, _e_db, _e_bl)
2358 CO4(ret.c, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
2359
2360 return ret;
2361}
2362
2363static inline cube_t
2364_move_B2(cube_t c)
2365{
2366 uint8_t aux;
2367 cube_t ret = c;
2368
2369 PERM22(ret.e, _e_ub, _e_db, _e_br, _e_bl)
2370 PERM22(ret.c, _c_ubr, _c_dbl, _c_ubl, _c_dbr)
2371
2372 return ret;
2373}
2374
2375static inline cube_t
2376_move_B3(cube_t c)
2377{
2378 uint8_t aux, auy, auz;
2379 cube_t ret = c;
2380
2381 PERM4(ret.e, _e_ub, _e_br, _e_db, _e_bl)
2382 PERM4(ret.c, _c_ubr, _c_dbr, _c_dbl, _c_ubl)
2383
2384 EO4(ret.e, _e_ub, _e_br, _e_db, _e_bl)
2385 CO4(ret.c, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
2386
2387 return ret;
2388}
2389
2390static inline cube_t
2391_invertco(cube_t c)
2392{
2393 uint8_t i, piece, orien;
2394 cube_t ret;
2395
2396 ret = c;
2397 for (i = 0; i < 8; i++) {
2398 piece = get_corner(c, i);
2399 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
2400 set_corner(ret, i, (piece & _pbits) | orien);
2401 }
2402
2403 return ret;
2404}
2405
2406static inline cube_t
2407_trans_UFr(cube_t c)
2408{
2409 cube_t ret;
2410 cube_t tn = {
2411 .c = {0, 1, 2, 3, 4, 5, 6, 7},
2412 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
2413 };
2414 cube_t ti = {
2415 .c = {0, 1, 2, 3, 4, 5, 6, 7},
2416 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
2417 };
2418
2419 ret = compose(tn, c);
2420 ret = compose(ret, ti);
2421
2422 return ret;
2423}
2424
2425static inline cube_t
2426_trans_ULr(cube_t c)
2427{
2428 cube_t ret;
2429 cube_t tn = {
2430 .c = {4, 5, 7, 6, 1, 0, 2, 3},
2431 .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24}
2432 };
2433 cube_t ti = {
2434 .c = {5, 4, 6, 7, 0, 1, 3, 2},
2435 .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26}
2436 };
2437
2438 ret = compose(tn, c);
2439 ret = compose(ret, ti);
2440
2441 return ret;
2442}
2443
2444static inline cube_t
2445_trans_UBr(cube_t c)
2446{
2447 cube_t ret;
2448 cube_t tn = {
2449 .c = {1, 0, 3, 2, 5, 4, 7, 6},
2450 .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9}
2451 };
2452 cube_t ti = {
2453 .c = {1, 0, 3, 2, 5, 4, 7, 6},
2454 .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9}
2455 };
2456
2457 ret = compose(tn, c);
2458 ret = compose(ret, ti);
2459
2460 return ret;
2461}
2462
2463static inline cube_t
2464_trans_URr(cube_t c)
2465{
2466 cube_t ret;
2467 cube_t tn = {
2468 .c = {5, 4, 6, 7, 0, 1, 3, 2},
2469 .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26}
2470 };
2471 cube_t ti = {
2472 .c = {4, 5, 7, 6, 1, 0, 2, 3},
2473 .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24}
2474 };
2475
2476 ret = compose(tn, c);
2477 ret = compose(ret, ti);
2478
2479 return ret;
2480}
2481
2482static inline cube_t
2483_trans_DFr(cube_t c)
2484{
2485 cube_t ret;
2486 cube_t tn = {
2487 .c = {2, 3, 0, 1, 6, 7, 4, 5},
2488 .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10}
2489 };
2490 cube_t ti = {
2491 .c = {2, 3, 0, 1, 6, 7, 4, 5},
2492 .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10}
2493 };
2494
2495 ret = compose(tn, c);
2496 ret = compose(ret, ti);
2497
2498 return ret;
2499}
2500
2501static inline cube_t
2502_trans_DLr(cube_t c)
2503{
2504 cube_t ret;
2505 cube_t tn = {
2506 .c = {7, 6, 4, 5, 2, 3, 1, 0},
2507 .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27}
2508 };
2509 cube_t ti = {
2510 .c = {7, 6, 4, 5, 2, 3, 1, 0},
2511 .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27}
2512 };
2513
2514 ret = compose(tn, c);
2515 ret = compose(ret, ti);
2516
2517 return ret;
2518}
2519
2520static inline cube_t
2521_trans_DBr(cube_t c)
2522{
2523 cube_t ret;
2524 cube_t tn = {
2525 .c = {3, 2, 1, 0, 7, 6, 5, 4},
2526 .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8}
2527 };
2528 cube_t ti = {
2529 .c = {3, 2, 1, 0, 7, 6, 5, 4},
2530 .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8}
2531 };
2532
2533 ret = compose(tn, c);
2534 ret = compose(ret, ti);
2535
2536 return ret;
2537}
2538
2539static inline cube_t
2540_trans_DRr(cube_t c)
2541{
2542 cube_t ret;
2543 cube_t tn = {
2544 .c = {6, 7, 5, 4, 3, 2, 0, 1},
2545 .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25}
2546 };
2547 cube_t ti = {
2548 .c = {6, 7, 5, 4, 3, 2, 0, 1},
2549 .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25}
2550 };
2551
2552 ret = compose(tn, c);
2553 ret = compose(ret, ti);
2554
2555 return ret;
2556}
2557
2558static inline cube_t
2559_trans_RUr(cube_t c)
2560{
2561 cube_t ret;
2562 cube_t tn = {
2563 .c = {64, 67, 65, 66, 37, 38, 36, 39},
2564 .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3}
2565 };
2566 cube_t ti = {
2567 .c = {32, 34, 35, 33, 70, 68, 69, 71},
2568 .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21}
2569 };
2570
2571 ret = compose(tn, c);
2572 ret = compose(ret, ti);
2573
2574 return ret;
2575}
2576
2577static inline cube_t
2578_trans_RFr(cube_t c)
2579{
2580 cube_t ret;
2581 cube_t tn = {
2582 .c = {38, 37, 36, 39, 64, 67, 66, 65},
2583 .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18}
2584 };
2585 cube_t ti = {
2586 .c = {36, 39, 38, 37, 66, 65, 64, 67},
2587 .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17}
2588 };
2589
2590 ret = compose(tn, c);
2591 ret = compose(ret, ti);
2592
2593 return ret;
2594}
2595
2596static inline cube_t
2597_trans_RDr(cube_t c)
2598{
2599 cube_t ret;
2600 cube_t tn = {
2601 .c = {67, 64, 66, 65, 38, 37, 39, 36},
2602 .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1}
2603 };
2604 cube_t ti = {
2605 .c = {33, 35, 34, 32, 71, 69, 68, 70},
2606 .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20}
2607 };
2608
2609 ret = compose(tn, c);
2610 ret = compose(ret, ti);
2611
2612 return ret;
2613}
2614
2615static inline cube_t
2616_trans_RBr(cube_t c)
2617{
2618 cube_t ret;
2619 cube_t tn = {
2620 .c = {37, 38, 39, 36, 67, 64, 65, 66},
2621 .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16}
2622 };
2623 cube_t ti = {
2624 .c = {37, 38, 39, 36, 67, 64, 65, 66},
2625 .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16}
2626 };
2627
2628 ret = compose(tn, c);
2629 ret = compose(ret, ti);
2630
2631 return ret;
2632}
2633
2634static inline cube_t
2635_trans_LUr(cube_t c)
2636{
2637 cube_t ret;
2638 cube_t tn = {
2639 .c = {65, 66, 64, 67, 36, 39, 37, 38},
2640 .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2}
2641 };
2642 cube_t ti = {
2643 .c = {34, 32, 33, 35, 68, 70, 71, 69},
2644 .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23}
2645 };
2646
2647 ret = compose(tn, c);
2648 ret = compose(ret, ti);
2649
2650 return ret;
2651}
2652
2653static inline cube_t
2654_trans_LFr(cube_t c)
2655{
2656 cube_t ret;
2657 cube_t tn = {
2658 .c = {36, 39, 38, 37, 66, 65, 64, 67},
2659 .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17}
2660 };
2661 cube_t ti = {
2662 .c = {38, 37, 36, 39, 64, 67, 66, 65},
2663 .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18}
2664 };
2665
2666 ret = compose(tn, c);
2667 ret = compose(ret, ti);
2668
2669 return ret;
2670}
2671
2672static inline cube_t
2673_trans_LDr(cube_t c)
2674{
2675 cube_t ret;
2676 cube_t tn = {
2677 .c = {66, 65, 67, 64, 39, 36, 38, 37},
2678 .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0}
2679 };
2680 cube_t ti = {
2681 .c = {35, 33, 32, 34, 69, 71, 70, 68},
2682 .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22}
2683 };
2684
2685 ret = compose(tn, c);
2686 ret = compose(ret, ti);
2687
2688 return ret;
2689}
2690
2691static inline cube_t
2692_trans_LBr(cube_t c)
2693{
2694 cube_t ret;
2695 cube_t tn = {
2696 .c = {39, 36, 37, 38, 65, 66, 67, 64},
2697 .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19}
2698 };
2699 cube_t ti = {
2700 .c = {39, 36, 37, 38, 65, 66, 67, 64},
2701 .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19}
2702 };
2703
2704 ret = compose(tn, c);
2705 ret = compose(ret, ti);
2706
2707 return ret;
2708}
2709
2710static inline cube_t
2711_trans_FUr(cube_t c)
2712{
2713 cube_t ret;
2714 cube_t tn = {
2715 .c = {68, 70, 69, 71, 32, 34, 33, 35},
2716 .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6}
2717 };
2718 cube_t ti = {
2719 .c = {68, 70, 69, 71, 32, 34, 33, 35},
2720 .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6}
2721 };
2722
2723 ret = compose(tn, c);
2724 ret = compose(ret, ti);
2725
2726 return ret;
2727}
2728
2729static inline cube_t
2730_trans_FRr(cube_t c)
2731{
2732 cube_t ret;
2733 cube_t tn = {
2734 .c = {32, 34, 35, 33, 70, 68, 69, 71},
2735 .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21}
2736 };
2737 cube_t ti = {
2738 .c = {64, 67, 65, 66, 37, 38, 36, 39},
2739 .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3}
2740 };
2741
2742 ret = compose(tn, c);
2743 ret = compose(ret, ti);
2744
2745 return ret;
2746}
2747
2748static inline cube_t
2749_trans_FDr(cube_t c)
2750{
2751 cube_t ret;
2752 cube_t tn = {
2753 .c = {70, 68, 71, 69, 34, 32, 35, 33},
2754 .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4}
2755 };
2756 cube_t ti = {
2757 .c = {69, 71, 68, 70, 33, 35, 32, 34},
2758 .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7}
2759 };
2760
2761 ret = compose(tn, c);
2762 ret = compose(ret, ti);
2763
2764 return ret;
2765}
2766
2767static inline cube_t
2768_trans_FLr(cube_t c)
2769{
2770 cube_t ret;
2771 cube_t tn = {
2772 .c = {34, 32, 33, 35, 68, 70, 71, 69},
2773 .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23}
2774 };
2775 cube_t ti = {
2776 .c = {65, 66, 64, 67, 36, 39, 37, 38},
2777 .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2}
2778 };
2779
2780 ret = compose(tn, c);
2781 ret = compose(ret, ti);
2782
2783 return ret;
2784}
2785
2786static inline cube_t
2787_trans_BUr(cube_t c)
2788{
2789 cube_t ret;
2790 cube_t tn = {
2791 .c = {69, 71, 68, 70, 33, 35, 32, 34},
2792 .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7}
2793 };
2794 cube_t ti = {
2795 .c = {70, 68, 71, 69, 34, 32, 35, 33},
2796 .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4}
2797 };
2798
2799 ret = compose(tn, c);
2800 ret = compose(ret, ti);
2801
2802 return ret;
2803}
2804
2805static inline cube_t
2806_trans_BRr(cube_t c)
2807{
2808 cube_t ret;
2809 cube_t tn = {
2810 .c = {35, 33, 32, 34, 69, 71, 70, 68},
2811 .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22}
2812 };
2813 cube_t ti = {
2814 .c = {66, 65, 67, 64, 39, 36, 38, 37},
2815 .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0}
2816 };
2817
2818 ret = compose(tn, c);
2819 ret = compose(ret, ti);
2820
2821 return ret;
2822}
2823
2824static inline cube_t
2825_trans_BDr(cube_t c)
2826{
2827 cube_t ret;
2828 cube_t tn = {
2829 .c = {71, 69, 70, 68, 35, 33, 34, 32},
2830 .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5}
2831 };
2832 cube_t ti = {
2833 .c = {71, 69, 70, 68, 35, 33, 34, 32},
2834 .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5}
2835 };
2836
2837 ret = compose(tn, c);
2838 ret = compose(ret, ti);
2839
2840 return ret;
2841}
2842
2843static inline cube_t
2844_trans_BLr(cube_t c)
2845{
2846 cube_t ret;
2847 cube_t tn = {
2848 .c = {33, 35, 34, 32, 71, 69, 68, 70},
2849 .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20}
2850 };
2851 cube_t ti = {
2852 .c = {67, 64, 66, 65, 38, 37, 39, 36},
2853 .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1}
2854 };
2855
2856 ret = compose(tn, c);
2857 ret = compose(ret, ti);
2858
2859 return ret;
2860}
2861
2862static inline cube_t
2863_trans_UFm(cube_t c)
2864{
2865 cube_t ret;
2866 cube_t tn = {
2867 .c = {4, 5, 6, 7, 0, 1, 2, 3},
2868 .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10}
2869 };
2870 cube_t ti = {
2871 .c = {4, 5, 6, 7, 0, 1, 2, 3},
2872 .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10}
2873 };
2874
2875 ret = compose(tn, c);
2876 ret = compose(ret, ti);
2877 ret = _invertco(ret);
2878
2879 return ret;
2880}
2881
2882static inline cube_t
2883_trans_ULm(cube_t c)
2884{
2885 cube_t ret;
2886 cube_t tn = {
2887 .c = {0, 1, 3, 2, 5, 4, 6, 7},
2888 .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25}
2889 };
2890 cube_t ti = {
2891 .c = {0, 1, 3, 2, 5, 4, 6, 7},
2892 .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25}
2893 };
2894
2895 ret = compose(tn, c);
2896 ret = compose(ret, ti);
2897 ret = _invertco(ret);
2898
2899 return ret;
2900}
2901
2902static inline cube_t
2903_trans_UBm(cube_t c)
2904{
2905 cube_t ret;
2906 cube_t tn = {
2907 .c = {5, 4, 7, 6, 1, 0, 3, 2},
2908 .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8}
2909 };
2910 cube_t ti = {
2911 .c = {5, 4, 7, 6, 1, 0, 3, 2},
2912 .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8}
2913 };
2914
2915 ret = compose(tn, c);
2916 ret = compose(ret, ti);
2917 ret = _invertco(ret);
2918
2919 return ret;
2920}
2921
2922static inline cube_t
2923_trans_URm(cube_t c)
2924{
2925 cube_t ret;
2926 cube_t tn = {
2927 .c = {1, 0, 2, 3, 4, 5, 7, 6},
2928 .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27}
2929 };
2930 cube_t ti = {
2931 .c = {1, 0, 2, 3, 4, 5, 7, 6},
2932 .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27}
2933 };
2934
2935 ret = compose(tn, c);
2936 ret = compose(ret, ti);
2937 ret = _invertco(ret);
2938
2939 return ret;
2940}
2941
2942static inline cube_t
2943_trans_DFm(cube_t c)
2944{
2945 cube_t ret;
2946 cube_t tn = {
2947 .c = {6, 7, 4, 5, 2, 3, 0, 1},
2948 .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11}
2949 };
2950 cube_t ti = {
2951 .c = {6, 7, 4, 5, 2, 3, 0, 1},
2952 .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11}
2953 };
2954
2955 ret = compose(tn, c);
2956 ret = compose(ret, ti);
2957 ret = _invertco(ret);
2958
2959 return ret;
2960}
2961
2962static inline cube_t
2963_trans_DLm(cube_t c)
2964{
2965 cube_t ret;
2966 cube_t tn = {
2967 .c = {3, 2, 0, 1, 6, 7, 5, 4},
2968 .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26}
2969 };
2970 cube_t ti = {
2971 .c = {2, 3, 1, 0, 7, 6, 4, 5},
2972 .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24}
2973 };
2974
2975 ret = compose(tn, c);
2976 ret = compose(ret, ti);
2977 ret = _invertco(ret);
2978
2979 return ret;
2980}
2981
2982static inline cube_t
2983_trans_DBm(cube_t c)
2984{
2985 cube_t ret;
2986 cube_t tn = {
2987 .c = {7, 6, 5, 4, 3, 2, 1, 0},
2988 .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9}
2989 };
2990 cube_t ti = {
2991 .c = {7, 6, 5, 4, 3, 2, 1, 0},
2992 .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9}
2993 };
2994
2995 ret = compose(tn, c);
2996 ret = compose(ret, ti);
2997 ret = _invertco(ret);
2998
2999 return ret;
3000}
3001
3002static inline cube_t
3003_trans_DRm(cube_t c)
3004{
3005 cube_t ret;
3006 cube_t tn = {
3007 .c = {2, 3, 1, 0, 7, 6, 4, 5},
3008 .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24}
3009 };
3010 cube_t ti = {
3011 .c = {3, 2, 0, 1, 6, 7, 5, 4},
3012 .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26}
3013 };
3014
3015 ret = compose(tn, c);
3016 ret = compose(ret, ti);
3017 ret = _invertco(ret);
3018
3019 return ret;
3020}
3021
3022static inline cube_t
3023_trans_RUm(cube_t c)
3024{
3025 cube_t ret;
3026 cube_t tn = {
3027 .c = {68, 71, 69, 70, 33, 34, 32, 35},
3028 .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3}
3029 };
3030 cube_t ti = {
3031 .c = {70, 68, 69, 71, 32, 34, 35, 33},
3032 .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22}
3033 };
3034
3035 ret = compose(tn, c);
3036 ret = compose(ret, ti);
3037 ret = _invertco(ret);
3038
3039 return ret;
3040}
3041
3042static inline cube_t
3043_trans_RFm(cube_t c)
3044{
3045 cube_t ret;
3046 cube_t tn = {
3047 .c = {34, 33, 32, 35, 68, 71, 70, 69},
3048 .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18}
3049 };
3050 cube_t ti = {
3051 .c = {66, 65, 64, 67, 36, 39, 38, 37},
3052 .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18}
3053 };
3054
3055 ret = compose(tn, c);
3056 ret = compose(ret, ti);
3057 ret = _invertco(ret);
3058
3059 return ret;
3060}
3061
3062static inline cube_t
3063_trans_RDm(cube_t c)
3064{
3065 cube_t ret;
3066 cube_t tn = {
3067 .c = {71, 68, 70, 69, 34, 33, 35, 32},
3068 .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1}
3069 };
3070 cube_t ti = {
3071 .c = {71, 69, 68, 70, 33, 35, 34, 32},
3072 .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23}
3073 };
3074
3075 ret = compose(tn, c);
3076 ret = compose(ret, ti);
3077 ret = _invertco(ret);
3078
3079 return ret;
3080}
3081
3082static inline cube_t
3083_trans_RBm(cube_t c)
3084{
3085 cube_t ret;
3086 cube_t tn = {
3087 .c = {33, 34, 35, 32, 71, 68, 69, 70},
3088 .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16}
3089 };
3090 cube_t ti = {
3091 .c = {67, 64, 65, 66, 37, 38, 39, 36},
3092 .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19}
3093 };
3094
3095 ret = compose(tn, c);
3096 ret = compose(ret, ti);
3097 ret = _invertco(ret);
3098
3099 return ret;
3100}
3101
3102static inline cube_t
3103_trans_LUm(cube_t c)
3104{
3105 cube_t ret;
3106 cube_t tn = {
3107 .c = {69, 70, 68, 71, 32, 35, 33, 34},
3108 .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2}
3109 };
3110 cube_t ti = {
3111 .c = {68, 70, 71, 69, 34, 32, 33, 35},
3112 .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20}
3113 };
3114
3115 ret = compose(tn, c);
3116 ret = compose(ret, ti);
3117 ret = _invertco(ret);
3118
3119 return ret;
3120}
3121
3122static inline cube_t
3123_trans_LFm(cube_t c)
3124{
3125 cube_t ret;
3126 cube_t tn = {
3127 .c = {32, 35, 34, 33, 70, 69, 68, 71},
3128 .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17}
3129 };
3130 cube_t ti = {
3131 .c = {64, 67, 66, 65, 38, 37, 36, 39},
3132 .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17}
3133 };
3134
3135 ret = compose(tn, c);
3136 ret = compose(ret, ti);
3137 ret = _invertco(ret);
3138
3139 return ret;
3140}
3141
3142static inline cube_t
3143_trans_LDm(cube_t c)
3144{
3145 cube_t ret;
3146 cube_t tn = {
3147 .c = {70, 69, 71, 68, 35, 32, 34, 33},
3148 .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0}
3149 };
3150 cube_t ti = {
3151 .c = {69, 71, 70, 68, 35, 33, 32, 34},
3152 .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21}
3153 };
3154
3155 ret = compose(tn, c);
3156 ret = compose(ret, ti);
3157 ret = _invertco(ret);
3158
3159 return ret;
3160}
3161
3162static inline cube_t
3163_trans_LBm(cube_t c)
3164{
3165 cube_t ret;
3166 cube_t tn = {
3167 .c = {35, 32, 33, 34, 69, 70, 71, 68},
3168 .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19}
3169 };
3170 cube_t ti = {
3171 .c = {65, 66, 67, 64, 39, 36, 37, 38},
3172 .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16}
3173 };
3174
3175 ret = compose(tn, c);
3176 ret = compose(ret, ti);
3177 ret = _invertco(ret);
3178
3179 return ret;
3180}
3181
3182static inline cube_t
3183_trans_FUm(cube_t c)
3184{
3185 cube_t ret;
3186 cube_t tn = {
3187 .c = {64, 66, 65, 67, 36, 38, 37, 39},
3188 .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7}
3189 };
3190 cube_t ti = {
3191 .c = {32, 34, 33, 35, 68, 70, 69, 71},
3192 .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7}
3193 };
3194
3195 ret = compose(tn, c);
3196 ret = compose(ret, ti);
3197 ret = _invertco(ret);
3198
3199 return ret;
3200}
3201
3202static inline cube_t
3203_trans_FRm(cube_t c)
3204{
3205 cube_t ret;
3206 cube_t tn = {
3207 .c = {36, 38, 39, 37, 66, 64, 65, 67},
3208 .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20}
3209 };
3210 cube_t ti = {
3211 .c = {37, 38, 36, 39, 64, 67, 65, 66},
3212 .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2}
3213 };
3214
3215 ret = compose(tn, c);
3216 ret = compose(ret, ti);
3217 ret = _invertco(ret);
3218
3219 return ret;
3220}
3221
3222static inline cube_t
3223_trans_FDm(cube_t c)
3224{
3225 cube_t ret;
3226 cube_t tn = {
3227 .c = {66, 64, 67, 65, 38, 36, 39, 37},
3228 .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5}
3229 };
3230 cube_t ti = {
3231 .c = {33, 35, 32, 34, 69, 71, 68, 70},
3232 .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6}
3233 };
3234
3235 ret = compose(tn, c);
3236 ret = compose(ret, ti);
3237 ret = _invertco(ret);
3238
3239 return ret;
3240}
3241
3242static inline cube_t
3243_trans_FLm(cube_t c)
3244{
3245 cube_t ret;
3246 cube_t tn = {
3247 .c = {38, 36, 37, 39, 64, 66, 67, 65},
3248 .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22}
3249 };
3250 cube_t ti = {
3251 .c = {36, 39, 37, 38, 65, 66, 64, 67},
3252 .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3}
3253 };
3254
3255 ret = compose(tn, c);
3256 ret = compose(ret, ti);
3257 ret = _invertco(ret);
3258
3259 return ret;
3260}
3261
3262static inline cube_t
3263_trans_BUm(cube_t c)
3264{
3265 cube_t ret;
3266 cube_t tn = {
3267 .c = {65, 67, 64, 66, 37, 39, 36, 38},
3268 .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6}
3269 };
3270 cube_t ti = {
3271 .c = {34, 32, 35, 33, 70, 68, 71, 69},
3272 .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5}
3273 };
3274
3275 ret = compose(tn, c);
3276 ret = compose(ret, ti);
3277 ret = _invertco(ret);
3278
3279 return ret;
3280}
3281
3282static inline cube_t
3283_trans_BRm(cube_t c)
3284{
3285 cube_t ret;
3286 cube_t tn = {
3287 .c = {39, 37, 36, 38, 65, 67, 66, 64},
3288 .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23}
3289 };
3290 cube_t ti = {
3291 .c = {39, 36, 38, 37, 66, 65, 67, 64},
3292 .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1}
3293 };
3294
3295 ret = compose(tn, c);
3296 ret = compose(ret, ti);
3297 ret = _invertco(ret);
3298
3299 return ret;
3300}
3301
3302static inline cube_t
3303_trans_BDm(cube_t c)
3304{
3305 cube_t ret;
3306 cube_t tn = {
3307 .c = {67, 65, 66, 64, 39, 37, 38, 36},
3308 .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4}
3309 };
3310 cube_t ti = {
3311 .c = {35, 33, 34, 32, 71, 69, 70, 68},
3312 .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4}
3313 };
3314
3315 ret = compose(tn, c);
3316 ret = compose(ret, ti);
3317 ret = _invertco(ret);
3318
3319 return ret;
3320}
3321
3322static inline cube_t
3323_trans_BLm(cube_t c)
3324{
3325 cube_t ret;
3326 cube_t tn = {
3327 .c = {37, 39, 38, 36, 67, 65, 64, 66},
3328 .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21}
3329 };
3330 cube_t ti = {
3331 .c = {38, 37, 39, 36, 67, 64, 66, 65},
3332 .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0}
3333 };
3334
3335 ret = compose(tn, c);
3336 ret = compose(ret, ti);
3337 ret = _invertco(ret);
3338
3339 return ret;
3340}
3341
3342static cube_t
3343_arraytocube(cube_array_t a)
3344{
3345 cube_t c;
3346 memcpy(&c, &a, sizeof(cube_t));
3347 return c;
3348}
3349
3350static void
3351_cubetoarray(cube_t c, cube_array_t *a)
3352{
3353 memcpy(a, &c, sizeof(cube_t));
3354}
3355
3356static inline bool
3357_equal(cube_t c1, cube_t c2)
3358{
3359 uint8_t i;
3360 bool ret;
3361
3362 ret = true;
3363 for (i = 0; i < 8; i++)
3364 ret = ret && c1.c[i] == c2.c[i];
3365 for (i = 0; i < 12; i++)
3366 ret = ret && c1.e[i] == c2.e[i];
3367
3368 return ret;
3369}
3370
3371static inline cube_t
3372_inverse(cube_t c)
3373{
3374 cube_t ret;
3375 uint8_t i, piece, orien;
3376
3377 ret = _arraytocube(zerocube_array);
3378
3379 for (i = 0; i < 12; i++) {
3380 piece = get_edge(c, i);
3381 orien = piece & _eobit;
3382 set_edge(ret, piece & _pbits, i | orien);
3383 }
3384
3385 for (i = 0; i < 8; i++) {
3386 piece = get_corner(c, i);
3387 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
3388 set_corner(ret, piece & _pbits, i | orien);
3389 }
3390
3391 return ret;
3392}
3393
3394static inline cube_t
3395_compose(cube_t c1, cube_t c2)
3396{
3397 cube_t ret;
3398 uint8_t i, piece1, piece2, p, orien, aux, auy;
3399
3400 ret = _arraytocube(zerocube_array);
3401
3402 for (i = 0; i < 12; i++) {
3403 piece2 = get_edge(c2, i);
3404 p = piece2 & _pbits;
3405 piece1 = get_edge(c1, p);
3406 orien = (piece2 ^ piece1) & _eobit;
3407 set_edge(ret, i, (piece1 & _pbits) | orien);
3408 }
3409
3410 for (i = 0; i < 8; i++) {
3411 piece2 = get_corner(c2, i);
3412 p = piece2 & _pbits;
3413 piece1 = get_corner(c1, p);
3414 aux = (piece2 & _cobits) + (piece1 & _cobits);
3415 auy = (aux + _ctwist_cw) >> 2U;
3416 orien = (aux + auy) & _cobits2;
3417 set_corner(ret, i, (piece1 & _pbits) | orien);
3418 }
3419
3420 return ret;
3421}
3422
3423
3424#endif
3425
3426/******************************************************************************
3427Section: generic methods.
3428
3429This section contains functions that are based (directly or indirectly)
3430on the per-architecture functions defined in the previous sections. Many
3431of them are public functions from cube.h
3432******************************************************************************/
3433
3434cube_t
3435solvedcube(void)
3436{
3437 cube_t solved;
3438 solved = _arraytocube(solvedcube_array);
3439 return solved;
3440}
3441
3442cube_t
3443zerocube(void)
3444{
3445 cube_t solved;
3446 solved = _arraytocube(zerocube_array);
3447 return solved;
3448}
3449
3450cube_t
3451readcube(format_t format, char *buf)
3452{
3453 cube_array_t arr;
3454 arr = readcube_array(format, buf);
3455 return _arraytocube(arr);
3456}
3457
3458void
3459writecube(format_t format, cube_t cube, char *buf)
3460{
3461 cube_array_t arr;
3462 _cubetoarray(cube, &arr);
3463 writecube_array(format, arr, buf);
3464}
3465
3466bool
3467isconsistent(cube_t c)
3468{
3469 cube_array_t arr;
3470 _cubetoarray(c, &arr);
3471 return isconsistent_array(arr);
3472}
3473
3474bool
3475issolvable(cube_t c)
3476{
3477 cube_array_t arr;
3478 _cubetoarray(c, &arr);
3479 return issolvable_array(arr);
3480}
3481
3482bool
3483iserror(cube_t c)
3484{
3485 cube_array_t arr;
3486 _cubetoarray(c, &arr);
3487 return iserror_array(arr);
3488}
3489
3490bool
3491equal(cube_t c1, cube_t c2)
3492{
3493 return _equal(c1, c2);
3494}
3495
3496bool
3497issolved(cube_t cube)
3498{
3499 cube_t solved;
3500 solved = _arraytocube(solvedcube_array);
3501 return equal(cube, solved);
3502}
3503
3504cube_t
3505move(cube_t c, move_t m)
3506{
3507#ifdef DEBUG
3508 if (!isconsistent(c)) {
3509 fprintf(stderr, "move error, inconsistent cube\n");
3510 return _arraytocube(zerocube_array);
3511 }
3512#endif
3513
3514 switch (m) {
3515 case U:
3516 return _move_U(c);
3517 case U2:
3518 return _move_U2(c);
3519 case U3:
3520 return _move_U3(c);
3521 case D:
3522 return _move_D(c);
3523 case D2:
3524 return _move_D2(c);
3525 case D3:
3526 return _move_D3(c);
3527 case R:
3528 return _move_R(c);
3529 case R2:
3530 return _move_R2(c);
3531 case R3:
3532 return _move_R3(c);
3533 case L:
3534 return _move_L(c);
3535 case L2:
3536 return _move_L2(c);
3537 case L3:
3538 return _move_L3(c);
3539 case F:
3540 return _move_F(c);
3541 case F2:
3542 return _move_F2(c);
3543 case F3:
3544 return _move_F3(c);
3545 case B:
3546 return _move_B(c);
3547 case B2:
3548 return _move_B2(c);
3549 case B3:
3550 return _move_B3(c);
3551 default:
3552#ifdef DEBUG
3553 fprintf(stderr, "mover error, unknown move\n");
3554#endif
3555 return _arraytocube(zerocube_array);
3556 }
3557}
3558
3559cube_t
3560inverse(cube_t c)
3561{
3562#ifdef DEBUG
3563 if (!isconsistent(c)) {
3564 fprintf(stderr, "inverse error, inconsistent cube\n");
3565 return zerocube();
3566 }
3567#endif
3568
3569 return _inverse(c);
3570}
3571
3572cube_t
3573compose(cube_t c1, cube_t c2)
3574{
3575#ifdef DEBUG
3576 if (!isconsistent(c1) || !isconsistent(c2)) {
3577 fprintf(stderr, "compose error, inconsistent cube\n");
3578 return zerocube();
3579 }
3580#endif
3581
3582 return _compose(c1, c2);
3583}
3584
3585cube_t
3586transform(cube_t c, trans_t t)
3587{
3588#ifdef DEBUG
3589 if (!isconsistent(c)) {
3590 fprintf(stderr, "transform error, inconsistent cube\n");
3591 return zerocube();
3592 }
3593#endif
3594
3595 switch (t) {
3596 case UFr:
3597 return _trans_UFr(c);
3598 case ULr:
3599 return _trans_ULr(c);
3600 case UBr:
3601 return _trans_UBr(c);
3602 case URr:
3603 return _trans_URr(c);
3604 case DFr:
3605 return _trans_DFr(c);
3606 case DLr:
3607 return _trans_DLr(c);
3608 case DBr:
3609 return _trans_DBr(c);
3610 case DRr:
3611 return _trans_DRr(c);
3612 case RUr:
3613 return _trans_RUr(c);
3614 case RFr:
3615 return _trans_RFr(c);
3616 case RDr:
3617 return _trans_RDr(c);
3618 case RBr:
3619 return _trans_RBr(c);
3620 case LUr:
3621 return _trans_LUr(c);
3622 case LFr:
3623 return _trans_LFr(c);
3624 case LDr:
3625 return _trans_LDr(c);
3626 case LBr:
3627 return _trans_LBr(c);
3628 case FUr:
3629 return _trans_FUr(c);
3630 case FRr:
3631 return _trans_FRr(c);
3632 case FDr:
3633 return _trans_FDr(c);
3634 case FLr:
3635 return _trans_FLr(c);
3636 case BUr:
3637 return _trans_BUr(c);
3638 case BRr:
3639 return _trans_BRr(c);
3640 case BDr:
3641 return _trans_BDr(c);
3642 case BLr:
3643 return _trans_BLr(c);
3644 case UFm:
3645 return _trans_UFm(c);
3646 case ULm:
3647 return _trans_ULm(c);
3648 case UBm:
3649 return _trans_UBm(c);
3650 case URm:
3651 return _trans_URm(c);
3652 case DFm:
3653 return _trans_DFm(c);
3654 case DLm:
3655 return _trans_DLm(c);
3656 case DBm:
3657 return _trans_DBm(c);
3658 case DRm:
3659 return _trans_DRm(c);
3660 case RUm:
3661 return _trans_RUm(c);
3662 case RFm:
3663 return _trans_RFm(c);
3664 case RDm:
3665 return _trans_RDm(c);
3666 case RBm:
3667 return _trans_RBm(c);
3668 case LUm:
3669 return _trans_LUm(c);
3670 case LFm:
3671 return _trans_LFm(c);
3672 case LDm:
3673 return _trans_LDm(c);
3674 case LBm:
3675 return _trans_LBm(c);
3676 case FUm:
3677 return _trans_FUm(c);
3678 case FRm:
3679 return _trans_FRm(c);
3680 case FDm:
3681 return _trans_FDm(c);
3682 case FLm:
3683 return _trans_FLm(c);
3684 case BUm:
3685 return _trans_BUm(c);
3686 case BRm:
3687 return _trans_BRm(c);
3688 case BDm:
3689 return _trans_BDm(c);
3690 case BLm:
3691 return _trans_BLm(c);
3692 default:
3693#ifdef DEBUG
3694 fprintf(stderr, "transform error, unknown transformation\n");
3695#endif
3696 return zerocube();
3697 }
3698}

Generated with cgit - Back to sebastiano.tronto.net