aboutsummaryrefslogtreecommitdiff
path: root/src/cube_array.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-10-05 15:28:45 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2023-10-05 15:30:21 +0200
commitffb67c9dcd22c4c3258b9ef78301e404e7d9a796 (patch)
tree67f90a2c988a08a14fc31de1731bf9fcc7439816 /src/cube_array.c
parent9e698917cb5b332cdbf1969ddfe3840239106c8d (diff)
downloadnissy-core-ffb67c9dcd22c4c3258b9ef78301e404e7d9a796.tar.gz
nissy-core-ffb67c9dcd22c4c3258b9ef78301e404e7d9a796.zip
Split isconsistent() and issolvable()
Diffstat (limited to 'src/cube_array.c')
-rw-r--r--src/cube_array.c102
1 files changed, 64 insertions, 38 deletions
diff --git a/src/cube_array.c b/src/cube_array.c
index b0b5e1e..a9b9709 100644
--- a/src/cube_array.c
+++ b/src/cube_array.c
@@ -149,6 +149,7 @@ cube_t solvedcube = {
149 149
150static cube_t errorcube = { .e = {0}, .c = {0} }; 150static cube_t errorcube = { .e = {0}, .c = {0} };
151 151
152static bool isconsistent(cube_t);
152static uint8_t readco(char *); 153static uint8_t readco(char *);
153static uint8_t readcp(char *); 154static uint8_t readcp(char *);
154static uint8_t readeo(char *); 155static uint8_t readeo(char *);
@@ -402,58 +403,41 @@ permsign(uint8_t *a, int n)
402 return ret % 2; 403 return ret % 2;
403} 404}
404 405
405bool 406static bool
406isconsistent(cube_t cube) 407isconsistent(cube_t c)
407{ 408{
408 int8_t p, psum, eosum, co, cosum; 409 uint8_t i, p, e;
409 bool found[12]; 410 bool found[12];
410 int i;
411 411
412 psum = 0;
413 for (i = 0; i < 12; i++) 412 for (i = 0; i < 12; i++)
414 found[i] = false; 413 found[i] = false;
415 for (i = 0; i < 12; i++) { 414 for (i = 0; i < 12; i++) {
416 p = cube.e[i] & _pbits; 415 p = c.e[i] & _pbits;
416 e = c.e[i] & ~_pbits;
417 if (p >= 12) 417 if (p >= 12)
418 goto inconsistent_ep; 418 goto inconsistent_ep;
419 if (e != 0 && e != _eobit)
420 goto inconsistent_eo;
419 found[p] = true; 421 found[p] = true;
420 } 422 }
421 for (i = 0; i < 12; i++) 423 for (i = 0; i < 12; i++)
422 if (!found[i]) 424 if (!found[i])
423 goto inconsistent_ep; 425 goto inconsistent_ep;
424 psum = permsign(cube.e, 12);
425 426
426 for (i = 0; i < 8; i++) 427 for (i = 0; i < 8; i++)
427 found[i] = false; 428 found[i] = false;
428 for (i = 0; i < 8; i++) { 429 for (i = 0; i < 8; i++) {
429 p = cube.c[i] & _pbits; 430 p = c.c[i] & _pbits;
431 e = c.c[i] & ~_pbits;
430 if (p >= 8) 432 if (p >= 8)
431 goto inconsistent_cp; 433 goto inconsistent_cp;
434 if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw)
435 goto inconsistent_co;
432 found[p] = true; 436 found[p] = true;
433 } 437 }
434 for (i = 0; i < 8; i++) 438 for (i = 0; i < 8; i++)
435 if (!found[i]) 439 if (!found[i])
436 goto inconsistent_cp;
437 psum += permsign(cube.c, 8);
438
439 if (psum % 2 != 0)
440 goto inconsistent_parity;
441
442 eosum = 0;
443 for (i = 0; i < 12; i++)
444 eosum += (cube.e[i] & _eobit) >> _eoshift;
445 if (eosum % 2 != 0)
446 goto inconsistent_eo;
447
448 cosum = 0;
449 for (i = 0; i < 8; i++) {
450 co = (cube.c[i] & _cobits) >> _coshift;
451 if (co > 2)
452 goto inconsistent_co; 440 goto inconsistent_co;
453 cosum += co;
454 }
455 if (cosum % 3 != 0)
456 goto inconsistent_co;
457 441
458 return true; 442 return true;
459 443
@@ -461,28 +445,70 @@ inconsistent_ep:
461#ifdef DEBUG 445#ifdef DEBUG
462 fprintf(stderr, "Inconsistent EP\n"); 446 fprintf(stderr, "Inconsistent EP\n");
463#endif 447#endif
464 goto inconsistent_return; 448 return false;
465inconsistent_cp: 449inconsistent_cp:
466#ifdef DEBUG 450#ifdef DEBUG
467 fprintf(stderr, "Inconsistent CP\n"); 451 fprintf(stderr, "Inconsistent CP\n");
468#endif 452#endif
469 goto inconsistent_return; 453 return false;
470inconsistent_parity:
471#ifdef DEBUG
472 fprintf(stderr, "Inconsistent parity\n");
473#endif
474 goto inconsistent_return;
475inconsistent_eo: 454inconsistent_eo:
476#ifdef DEBUG 455#ifdef DEBUG
477 fprintf(stderr, "Inconsistent EO\n"); 456 fprintf(stderr, "Inconsistent EO\n");
478#endif 457#endif
479 goto inconsistent_return; 458 return false;
480inconsistent_co: 459inconsistent_co:
481#ifdef DEBUG 460#ifdef DEBUG
482 fprintf(stderr, "Inconsistent CO\n"); 461 fprintf(stderr, "Inconsistent CO\n");
483#endif 462#endif
484 goto inconsistent_return; 463 return false;
485inconsistent_return: 464}
465
466bool
467issolvable(cube_t cube)
468{
469 int8_t i, eo, co;
470
471#ifdef DEBUG
472 if (!isconsistent(cube))
473 goto issolvable_inconsistent;
474#endif
475
476 if (permsign(cube.e, 12) != permsign(cube.c, 8))
477 goto issolvable_parity;
478
479 eo = 0;
480 for (i = 0; i < 12; i++)
481 eo += (cube.e[i] & _eobit) >> _eoshift;
482 if (eo % 2 != 0)
483 goto issolvable_eo;
484
485 co = 0;
486 for (i = 0; i < 8; i++)
487 co += (cube.c[i] & _cobits) >> _coshift;
488 if (co % 3 != 0)
489 goto issolvable_co;
490
491 return true;
492
493issolvable_inconsistent:
494#ifdef DEBUG
495 fprintf(stderr, "issolvable: cube is inconsistent\n");
496#endif
497 return false;
498issolvable_parity:
499#ifdef DEBUG
500 fprintf(stderr, "EP and CP parities are different\n");
501#endif
502 return false;
503issolvable_eo:
504#ifdef DEBUG
505 fprintf(stderr, "Odd number of flipped edges\n");
506#endif
507 return false;
508issolvable_co:
509#ifdef DEBUG
510 fprintf(stderr, "Sum of corner orientation is not multiple of 3\n");
511#endif
486 return false; 512 return false;
487} 513}
488 514

Generated with cgit - Back to sebastiano.tronto.net