diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2023-10-05 15:28:45 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2023-10-05 15:30:21 +0200 |
| commit | ffb67c9dcd22c4c3258b9ef78301e404e7d9a796 (patch) | |
| tree | 67f90a2c988a08a14fc31de1731bf9fcc7439816 /src/cube_array.c | |
| parent | 9e698917cb5b332cdbf1969ddfe3840239106c8d (diff) | |
| download | nissy-core-ffb67c9dcd22c4c3258b9ef78301e404e7d9a796.tar.gz nissy-core-ffb67c9dcd22c4c3258b9ef78301e404e7d9a796.zip | |
Split isconsistent() and issolvable()
Diffstat (limited to '')
| -rw-r--r-- | src/cube_array.c | 102 |
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 | ||
| 150 | static cube_t errorcube = { .e = {0}, .c = {0} }; | 150 | static cube_t errorcube = { .e = {0}, .c = {0} }; |
| 151 | 151 | ||
| 152 | static bool isconsistent(cube_t); | ||
| 152 | static uint8_t readco(char *); | 153 | static uint8_t readco(char *); |
| 153 | static uint8_t readcp(char *); | 154 | static uint8_t readcp(char *); |
| 154 | static uint8_t readeo(char *); | 155 | static 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 | ||
| 405 | bool | 406 | static bool |
| 406 | isconsistent(cube_t cube) | 407 | isconsistent(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; |
| 465 | inconsistent_cp: | 449 | inconsistent_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; |
| 470 | inconsistent_parity: | ||
| 471 | #ifdef DEBUG | ||
| 472 | fprintf(stderr, "Inconsistent parity\n"); | ||
| 473 | #endif | ||
| 474 | goto inconsistent_return; | ||
| 475 | inconsistent_eo: | 454 | inconsistent_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; |
| 480 | inconsistent_co: | 459 | inconsistent_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; |
| 485 | inconsistent_return: | 464 | } |
| 465 | |||
| 466 | bool | ||
| 467 | issolvable(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 | |||
| 493 | issolvable_inconsistent: | ||
| 494 | #ifdef DEBUG | ||
| 495 | fprintf(stderr, "issolvable: cube is inconsistent\n"); | ||
| 496 | #endif | ||
| 497 | return false; | ||
| 498 | issolvable_parity: | ||
| 499 | #ifdef DEBUG | ||
| 500 | fprintf(stderr, "EP and CP parities are different\n"); | ||
| 501 | #endif | ||
| 502 | return false; | ||
| 503 | issolvable_eo: | ||
| 504 | #ifdef DEBUG | ||
| 505 | fprintf(stderr, "Odd number of flipped edges\n"); | ||
| 506 | #endif | ||
| 507 | return false; | ||
| 508 | issolvable_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 | ||
