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

Generated with cgit - Back to sebastiano.tronto.net