aboutsummaryrefslogtreecommitdiff
path: root/cube.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-11-08 14:04:36 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2023-11-08 14:04:36 +0100
commit72c9082c9824c7ffecc97a94083aa350956285e4 (patch)
tree77f1184e58887f618f30678821b8e2672799d852 /cube.c
parent41d6b7aea5f1c9abddf5377dc6f37d8d197e548b (diff)
downloadnissy-core-72c9082c9824c7ffecc97a94083aa350956285e4.tar.gz
nissy-core-72c9082c9824c7ffecc97a94083aa350956285e4.zip
Change include statement
Diffstat (limited to '')
-rw-r--r--cube.c111
1 files changed, 61 insertions, 50 deletions
diff --git a/cube.c b/cube.c
index b485a0f..cc38be7 100644
--- a/cube.c
+++ b/cube.c
@@ -2,6 +2,10 @@
2#include <stdbool.h> 2#include <stdbool.h>
3#include <string.h> 3#include <string.h>
4 4
5#ifdef CUBE_AVX2
6#include <immintrin.h>
7#endif
8
5#ifdef DEBUG 9#ifdef DEBUG
6#include <stdio.h> 10#include <stdio.h>
7#define DBG_LOG(...) fprintf(stderr, __VA_ARGS__) 11#define DBG_LOG(...) fprintf(stderr, __VA_ARGS__)
@@ -250,11 +254,6 @@ typedef struct {
250 uint8_t e[12]; 254 uint8_t e[12];
251} cube_array_t; 255} cube_array_t;
252 256
253#define get_edge(cube, i) (cube).e[(i)]
254#define get_corner(cube, i) (cube).c[(i)]
255#define set_edge(cube, i, p) (cube).e[(i)] = (p)
256#define set_corner(cube, i, p) (cube).c[(i)] = (p)
257
258static bool equal_array(cube_array_t, cube_array_t); 257static bool equal_array(cube_array_t, cube_array_t);
259static bool iserror_array(cube_array_t); 258static bool iserror_array(cube_array_t);
260static bool isconsistent_array(cube_array_t); 259static bool isconsistent_array(cube_array_t);
@@ -372,7 +371,7 @@ readcube_array_H48(char *buf)
372 if ((orient = readeo(b)) == _error) 371 if ((orient = readeo(b)) == _error)
373 return _zerocube_array; 372 return _zerocube_array;
374 b++; 373 b++;
375 set_edge(ret, i, piece | orient); 374 ret.e[i] = piece | orient;
376 } 375 }
377 for (i = 0; i < 8; i++) { 376 for (i = 0; i < 8; i++) {
378 while (*b == ' ' || *b == '\t' || *b == '\n') 377 while (*b == ' ' || *b == '\t' || *b == '\n')
@@ -383,7 +382,7 @@ readcube_array_H48(char *buf)
383 if ((orient = readco(b)) == _error) 382 if ((orient = readco(b)) == _error)
384 return _zerocube_array; 383 return _zerocube_array;
385 b++; 384 b++;
386 set_corner(ret, i, piece | orient); 385 ret.c[i] = piece | orient;
387 } 386 }
388 387
389 return ret; 388 return ret;
@@ -441,7 +440,7 @@ writecube_array_AVX(cube_array_t cube, char *buf)
441 ptr = 30; 440 ptr = 30;
442 441
443 for (i = 11; i >= 0; i--) { 442 for (i = 11; i >= 0; i--) {
444 piece = get_edge(cube, i); 443 piece = cube.e[i];
445 ptr += writepiece_SRC(piece, buf + ptr); 444 ptr += writepiece_SRC(piece, buf + ptr);
446 } 445 }
447 446
@@ -449,7 +448,7 @@ writecube_array_AVX(cube_array_t cube, char *buf)
449 ptr += 25; 448 ptr += 25;
450 449
451 for (i = 7; i >= 0; i--) { 450 for (i = 7; i >= 0; i--) {
452 piece = get_corner(cube, i); 451 piece = cube.c[i];
453 ptr += writepiece_SRC(piece, buf + ptr); 452 ptr += writepiece_SRC(piece, buf + ptr);
454 } 453 }
455 454
@@ -463,7 +462,7 @@ writecube_array_H48(cube_array_t cube, char *buf)
463 int i; 462 int i;
464 463
465 for (i = 0; i < 12; i++) { 464 for (i = 0; i < 12; i++) {
466 piece = get_edge(cube, i); 465 piece = cube.e[i];
467 perm = piece & _pbits; 466 perm = piece & _pbits;
468 orient = (piece & _eobit) >> _eoshift; 467 orient = (piece & _eobit) >> _eoshift;
469 buf[4*i ] = edgestr[perm][0]; 468 buf[4*i ] = edgestr[perm][0];
@@ -472,7 +471,7 @@ writecube_array_H48(cube_array_t cube, char *buf)
472 buf[4*i + 3] = ' '; 471 buf[4*i + 3] = ' ';
473 } 472 }
474 for (i = 0; i < 8; i++) { 473 for (i = 0; i < 8; i++) {
475 piece = get_corner(cube, i); 474 piece = cube.c[i];
476 perm = piece & _pbits; 475 perm = piece & _pbits;
477 orient = (piece & _cobits) >> _coshift; 476 orient = (piece & _cobits) >> _coshift;
478 buf[48 + 5*i ] = cornerstr[perm][0]; 477 buf[48 + 5*i ] = cornerstr[perm][0];
@@ -495,7 +494,7 @@ writecube_array_SRC(cube_array_t cube, char *buf)
495 ptr = 9; 494 ptr = 9;
496 495
497 for (i = 0; i < 8; i++) { 496 for (i = 0; i < 8; i++) {
498 piece = get_corner(cube, i); 497 piece = cube.c[i];
499 ptr += writepiece_SRC(piece, buf + ptr); 498 ptr += writepiece_SRC(piece, buf + ptr);
500 } 499 }
501 500
@@ -503,7 +502,7 @@ writecube_array_SRC(cube_array_t cube, char *buf)
503 ptr += 8; 502 ptr += 8;
504 503
505 for (i = 0; i < 12; i++) { 504 for (i = 0; i < 12; i++) {
506 piece = get_edge(cube, i); 505 piece = cube.e[i];
507 ptr += writepiece_SRC(piece, buf + ptr); 506 ptr += writepiece_SRC(piece, buf + ptr);
508 } 507 }
509 508
@@ -673,7 +672,7 @@ isconsistent_array(cube_array_t c)
673 for (i = 0; i < 12; i++) 672 for (i = 0; i < 12; i++)
674 found[i] = false; 673 found[i] = false;
675 for (i = 0; i < 12; i++) { 674 for (i = 0; i < 12; i++) {
676 piece = get_edge(c, i); 675 piece = c.e[i];
677 p = piece & _pbits; 676 p = piece & _pbits;
678 e = piece & _eobit; 677 e = piece & _eobit;
679 if (p >= 12) 678 if (p >= 12)
@@ -689,7 +688,7 @@ isconsistent_array(cube_array_t c)
689 for (i = 0; i < 8; i++) 688 for (i = 0; i < 8; i++)
690 found[i] = false; 689 found[i] = false;
691 for (i = 0; i < 8; i++) { 690 for (i = 0; i < 8; i++) {
692 piece = get_corner(c, i); 691 piece = c.c[i];
693 p = piece & _pbits; 692 p = piece & _pbits;
694 e = piece & _cobits; 693 e = piece & _cobits;
695 if (p >= 8) 694 if (p >= 8)
@@ -727,16 +726,16 @@ issolvable_array(cube_array_t c)
727 "issolvable: cube is inconsistent\n"); 726 "issolvable: cube is inconsistent\n");
728 727
729 for (i = 0; i < 12; i++) 728 for (i = 0; i < 12; i++)
730 edges[i] = get_edge(c, i) & _pbits; 729 edges[i] = c.e[i] & _pbits;
731 for (i = 0; i < 8; i++) 730 for (i = 0; i < 8; i++)
732 corners[i] = get_corner(c, i) & _pbits; 731 corners[i] = c.c[i] & _pbits;
733 732
734 if (permsign(edges, 12) != permsign(corners, 8)) 733 if (permsign(edges, 12) != permsign(corners, 8))
735 goto issolvable_parity; 734 goto issolvable_parity;
736 735
737 eo = 0; 736 eo = 0;
738 for (i = 0; i < 12; i++) { 737 for (i = 0; i < 12; i++) {
739 piece = get_edge(c, i); 738 piece = c.e[i];
740 eo += (piece & _eobit) >> _eoshift; 739 eo += (piece & _eobit) >> _eoshift;
741 } 740 }
742 if (eo % 2 != 0) 741 if (eo % 2 != 0)
@@ -744,7 +743,7 @@ issolvable_array(cube_array_t c)
744 743
745 co = 0; 744 co = 0;
746 for (i = 0; i < 8; i++) { 745 for (i = 0; i < 8; i++) {
747 piece = get_corner(c, i); 746 piece = c.c[i];
748 co += (piece & _cobits) >> _coshift; 747 co += (piece & _cobits) >> _coshift;
749 } 748 }
750 if (co % 3 != 0) 749 if (co % 3 != 0)
@@ -2395,9 +2394,9 @@ _invertco(cube_t c)
2395 2394
2396 ret = c; 2395 ret = c;
2397 for (i = 0; i < 8; i++) { 2396 for (i = 0; i < 8; i++) {
2398 piece = get_corner(c, i); 2397 piece = c.c[i];
2399 orien = ((piece << 1) | (piece >> 1)) & _cobits2; 2398 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
2400 set_corner(ret, i, (piece & _pbits) | orien); 2399 ret.c[i] = (piece & _pbits) | orien;
2401 } 2400 }
2402 2401
2403 return ret; 2402 return ret;
@@ -3377,15 +3376,15 @@ _inverse(cube_t c)
3377 ret = _zerocube; 3376 ret = _zerocube;
3378 3377
3379 for (i = 0; i < 12; i++) { 3378 for (i = 0; i < 12; i++) {
3380 piece = get_edge(c, i); 3379 piece = c.e[i];
3381 orien = piece & _eobit; 3380 orien = piece & _eobit;
3382 set_edge(ret, piece & _pbits, i | orien); 3381 ret.e[piece & _pbits] = i | orien;
3383 } 3382 }
3384 3383
3385 for (i = 0; i < 8; i++) { 3384 for (i = 0; i < 8; i++) {
3386 piece = get_corner(c, i); 3385 piece = c.c[i];
3387 orien = ((piece << 1) | (piece >> 1)) & _cobits2; 3386 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
3388 set_corner(ret, piece & _pbits, i | orien); 3387 ret.c[piece & _pbits] = i | orien;
3389 } 3388 }
3390 3389
3391 return ret; 3390 return ret;
@@ -3400,21 +3399,21 @@ _compose(cube_t c1, cube_t c2)
3400 ret = _zerocube; 3399 ret = _zerocube;
3401 3400
3402 for (i = 0; i < 12; i++) { 3401 for (i = 0; i < 12; i++) {
3403 piece2 = get_edge(c2, i); 3402 piece2 = c2.e[i];
3404 p = piece2 & _pbits; 3403 p = piece2 & _pbits;
3405 piece1 = get_edge(c1, p); 3404 piece1 = c1.e[p];
3406 orien = (piece2 ^ piece1) & _eobit; 3405 orien = (piece2 ^ piece1) & _eobit;
3407 set_edge(ret, i, (piece1 & _pbits) | orien); 3406 ret.e[i] = (piece1 & _pbits) | orien;
3408 } 3407 }
3409 3408
3410 for (i = 0; i < 8; i++) { 3409 for (i = 0; i < 8; i++) {
3411 piece2 = get_corner(c2, i); 3410 piece2 = c2.c[i];
3412 p = piece2 & _pbits; 3411 p = piece2 & _pbits;
3413 piece1 = get_corner(c1, p); 3412 piece1 = c1.c[p];
3414 aux = (piece2 & _cobits) + (piece1 & _cobits); 3413 aux = (piece2 & _cobits) + (piece1 & _cobits);
3415 auy = (aux + _ctwist_cw) >> 2U; 3414 auy = (aux + _ctwist_cw) >> 2U;
3416 orien = (aux + auy) & _cobits2; 3415 orien = (aux + auy) & _cobits2;
3417 set_corner(ret, i, (piece1 & _pbits) | orien); 3416 ret.c[i] = (piece1 & _pbits) | orien;
3418 } 3417 }
3419 3418
3420 return ret; 3419 return ret;
@@ -3692,24 +3691,29 @@ implementation of all the solving algorithms.
3692 3691
3693typedef struct { 3692typedef struct {
3694 cube_t cube; 3693 cube_t cube;
3695 uint8_t d; 3694 int (*estimate)(cube_t);
3696 int max; 3695 uint8_t depth;
3697 move_t *sol; 3696 int maxsols;
3698 int ns; 3697 move_t *sols;
3699 int nm; 3698 int nsols;
3700 move_t m[20]; 3699 int nmoves;
3700 move_t moves[20];
3701} dfs_arg_t; 3701} dfs_arg_t;
3702 3702
3703int 3703int
3704solve_small_dfs(dfs_arg_t arg) 3704solve_generic_dfs(dfs_arg_t arg)
3705{ 3705{
3706 if (arg.ns == arg.max) 3706 int bound = arg.estimate(arg.cube);
3707
3708 if (arg.nsols == arg.maxsols || bound + arg.nmoves > arg.depth)
3707 return 0; 3709 return 0;
3708 3710
3709 if (issolved(arg.cube)) { 3711 if (bound == 0) {
3710 if (arg.nm != arg.d) 3712 if (arg.nmoves != arg.depth)
3711 return 0; 3713 return 0;
3712 memcpy(&arg.sol[arg.d*arg.ns], arg.m, arg.d * sizeof(move_t)); 3714 memcpy(&arg.sols[arg.depth * arg.nsols],
3715 arg.moves,
3716 arg.depth * sizeof(move_t));
3713 return 1; 3717 return 1;
3714 } 3718 }
3715 3719
@@ -3718,7 +3722,13 @@ solve_small_dfs(dfs_arg_t arg)
3718} 3722}
3719 3723
3720int 3724int
3721solve_small(cube_t cube, uint8_t depth, int max, move_t *sol) 3725solve_generic(
3726 cube_t cube,
3727 int (*estimate)(cube_t),
3728 uint8_t depth,
3729 int maxsols,
3730 move_t *sols
3731)
3722{ 3732{
3723 dfs_arg_t arg; 3733 dfs_arg_t arg;
3724 3734
@@ -3727,15 +3737,16 @@ solve_small(cube_t cube, uint8_t depth, int max, move_t *sol)
3727 3737
3728 arg = (dfs_arg_t) { 3738 arg = (dfs_arg_t) {
3729 .cube = cube, 3739 .cube = cube,
3730 .d = depth, 3740 .estimate = estimate,
3731 .max = max, 3741 .depth = depth,
3732 .sol = sol, 3742 .maxsols = maxsols,
3733 .ns = 0, 3743 .sols = sols,
3734 .nm = 0, 3744 .nsols = 0,
3735 .m = {0} 3745 .nmoves = 0,
3746 .moves = {0}
3736 }; 3747 };
3737 3748
3738 return solve_small_dfs(arg); 3749 return solve_generic_dfs(arg);
3739 3750
3740 return 0; 3751 return 0;
3741} 3752}

Generated with cgit - Back to sebastiano.tronto.net