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 | |
| parent | 9e698917cb5b332cdbf1969ddfe3840239106c8d (diff) | |
| download | nissy-core-ffb67c9dcd22c4c3258b9ef78301e404e7d9a796.tar.gz nissy-core-ffb67c9dcd22c4c3258b9ef78301e404e7d9a796.zip | |
Split isconsistent() and issolvable()
Diffstat (limited to '')
23 files changed, 134 insertions, 104 deletions
| @@ -4,7 +4,9 @@ Work in progress. | |||
| 4 | 4 | ||
| 5 | TODO: | 5 | TODO: |
| 6 | 6 | ||
| 7 | * transformations | 7 | * finish second half of transformations |
| 8 | * implement writecubesrc() to make it easy to implement transformations | ||
| 9 | * implement transformations | ||
| 8 | * setup benchmarks | 10 | * setup benchmarks |
| 9 | * coordinates: co, eo, epsep, cpsep_sym, cocpsep_sym, cphtr_sym, cocphtr_sym | 11 | * coordinates: co, eo, epsep, cpsep_sym, cocpsep_sym, cphtr_sym, cocphtr_sym |
| 10 | * pruning tables (1 bit per entry + fallback) | 12 | * pruning tables (1 bit per entry + fallback) |
diff --git a/src/constants.h b/src/constants.h index 6a7e3f9..b2b1b77 100644 --- a/src/constants.h +++ b/src/constants.h | |||
| @@ -19,53 +19,53 @@ | |||
| 19 | #define B3 17U | 19 | #define B3 17U |
| 20 | 20 | ||
| 21 | /* Regular transformations (rotations) */ | 21 | /* Regular transformations (rotations) */ |
| 22 | #define UF_i 0 | 22 | #define UFr 0 |
| 23 | #define UL_i 1 | 23 | #define ULr 1 |
| 24 | #define UB_i 2 | 24 | #define UBr 2 |
| 25 | #define UR_i 3 | 25 | #define URr 3 |
| 26 | #define DF_i 4 | 26 | #define DFr 4 |
| 27 | #define DL_i 5 | 27 | #define DLr 5 |
| 28 | #define DB_i 6 | 28 | #define DBr 6 |
| 29 | #define DR_i 7 | 29 | #define DRr 7 |
| 30 | #define RU_i 8 | 30 | #define RUr 8 |
| 31 | #define RF_i 9 | 31 | #define RFr 9 |
| 32 | #define RD_i 10 | 32 | #define RDr 10 |
| 33 | #define RB_i 11 | 33 | #define RBr 11 |
| 34 | #define LU_i 12 | 34 | #define LUr 12 |
| 35 | #define LF_i 13 | 35 | #define LFr 13 |
| 36 | #define LD_i 14 | 36 | #define LDr 14 |
| 37 | #define LB_i 15 | 37 | #define LBr 15 |
| 38 | #define FU_i 16 | 38 | #define FUr 16 |
| 39 | #define FR_i 16 | 39 | #define FRr 16 |
| 40 | #define FD_i 18 | 40 | #define FDr 18 |
| 41 | #define FL_i 19 | 41 | #define FLr 19 |
| 42 | #define BU_i 20 | 42 | #define BUr 20 |
| 43 | #define BR_i 21 | 43 | #define BRr 21 |
| 44 | #define BD_i 22 | 44 | #define BDr 22 |
| 45 | #define BL_i 23 | 45 | #define BLr 23 |
| 46 | 46 | ||
| 47 | /* Mirrored transformations */ | 47 | /* Mirrored transformations */ |
| 48 | #define UF_m 24 | 48 | #define UFm 24 |
| 49 | #define UL_m 25 | 49 | #define ULm 25 |
| 50 | #define UB_m 26 | 50 | #define UBm 26 |
| 51 | #define UR_m 27 | 51 | #define URm 27 |
| 52 | #define DF_m 28 | 52 | #define DFm 28 |
| 53 | #define DL_m 29 | 53 | #define DLm 29 |
| 54 | #define DB_m 30 | 54 | #define DBm 30 |
| 55 | #define DR_m 31 | 55 | #define DRm 31 |
| 56 | #define RU_m 32 | 56 | #define RUm 32 |
| 57 | #define RF_m 33 | 57 | #define RFm 33 |
| 58 | #define RD_m 34 | 58 | #define RDm 34 |
| 59 | #define RB_m 35 | 59 | #define RBm 35 |
| 60 | #define LU_m 36 | 60 | #define LUm 36 |
| 61 | #define LF_m 37 | 61 | #define LFm 37 |
| 62 | #define LD_m 38 | 62 | #define LDm 38 |
| 63 | #define LB_m 39 | 63 | #define LBm 39 |
| 64 | #define FU_m 40 | 64 | #define FUm 40 |
| 65 | #define FR_m 41 | 65 | #define FRm 41 |
| 66 | #define FD_m 42 | 66 | #define FDm 42 |
| 67 | #define FL_m 43 | 67 | #define FLm 43 |
| 68 | #define BU_m 44 | 68 | #define BUm 44 |
| 69 | #define BR_m 45 | 69 | #define BRm 45 |
| 70 | #define BD_m 46 | 70 | #define BDm 46 |
| 71 | #define BL_m 47 | 71 | #define BLm 47 |
| @@ -11,7 +11,10 @@ extern cube_t solvedcube; | |||
| 11 | cube_t readcube(char *); | 11 | cube_t readcube(char *); |
| 12 | void writecube(cube_t, char *); | 12 | void writecube(cube_t, char *); |
| 13 | 13 | ||
| 14 | bool isconsistent(cube_t); | 14 | /* Writes a cube in C source code format */ |
| 15 | void writecubesrc(cube_t, char *); | ||
| 16 | |||
| 17 | bool issolvable(cube_t); | ||
| 15 | bool equal(cube_t, cube_t); | 18 | bool equal(cube_t, cube_t); |
| 16 | bool issolved(cube_t); | 19 | bool issolved(cube_t); |
| 17 | bool iserror(cube_t); | 20 | bool iserror(cube_t); |
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 | ||
diff --git a/test/00_basic/all.out b/test/00_basic/all.out index aad167e..892ad22 100644 --- a/test/00_basic/all.out +++ b/test/00_basic/all.out | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | Solved is consistent | 1 | Solved is solvable |
| 2 | Solved is solved | 2 | Solved is solved |
| 3 | Zero is NOT consistent | 3 | Zero is NOT solvable |
| 4 | Zero is NOT solved | 4 | Zero is NOT solved |
| 5 | Solved and Solved are equal | 5 | Solved and Solved are equal |
| 6 | Solved and Zero are NOT equal | 6 | Solved and Zero are NOT equal |
diff --git a/test/00_basic/basic_tests.c b/test/00_basic/basic_tests.c index 8c52941..a3ae0b9 100644 --- a/test/00_basic/basic_tests.c +++ b/test/00_basic/basic_tests.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | void | 7 | void |
| 8 | check(cube_t cube, char *name) | 8 | check(cube_t cube, char *name) |
| 9 | { | 9 | { |
| 10 | printf("%s is%s consistent\n", name, isconsistent(cube) ? "" : " NOT"); | 10 | printf("%s is%s solvable\n", name, issolvable(cube) ? "" : " NOT"); |
| 11 | printf("%s is%s solved\n", name, issolved(cube) ? "" : " NOT"); | 11 | printf("%s is%s solved\n", name, issolved(cube) ? "" : " NOT"); |
| 12 | } | 12 | } |
| 13 | 13 | ||
diff --git a/test/01_io/04_inconsistent_ep.out b/test/01_io/04_inconsistent_ep.out deleted file mode 100644 index cb70902..0000000 --- a/test/01_io/04_inconsistent_ep.out +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | Cube is inconsistent | ||
diff --git a/test/01_io/04_inconsistent_ep.in b/test/01_io/04_unsolvable_ep.in index 8483962..8483962 100644 --- a/test/01_io/04_inconsistent_ep.in +++ b/test/01_io/04_unsolvable_ep.in | |||
diff --git a/test/01_io/04_unsolvable_ep.out b/test/01_io/04_unsolvable_ep.out new file mode 100644 index 0000000..e35c6e4 --- /dev/null +++ b/test/01_io/04_unsolvable_ep.out | |||
| @@ -0,0 +1 @@ | |||
| Cube is not solvable | |||
diff --git a/test/01_io/05_inconsistent_eo.out b/test/01_io/05_inconsistent_eo.out deleted file mode 100644 index cb70902..0000000 --- a/test/01_io/05_inconsistent_eo.out +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | Cube is inconsistent | ||
diff --git a/test/01_io/05_inconsistent_eo.in b/test/01_io/05_unsolvable_eo.in index a92089d..a92089d 100644 --- a/test/01_io/05_inconsistent_eo.in +++ b/test/01_io/05_unsolvable_eo.in | |||
diff --git a/test/01_io/05_unsolvable_eo.out b/test/01_io/05_unsolvable_eo.out new file mode 100644 index 0000000..e35c6e4 --- /dev/null +++ b/test/01_io/05_unsolvable_eo.out | |||
| @@ -0,0 +1 @@ | |||
| Cube is not solvable | |||
diff --git a/test/01_io/06_inconsistent_cp.out b/test/01_io/06_inconsistent_cp.out deleted file mode 100644 index cb70902..0000000 --- a/test/01_io/06_inconsistent_cp.out +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | Cube is inconsistent | ||
diff --git a/test/01_io/06_inconsistent_cp.in b/test/01_io/06_unsolvable_cp.in index 2085dd5..2085dd5 100644 --- a/test/01_io/06_inconsistent_cp.in +++ b/test/01_io/06_unsolvable_cp.in | |||
diff --git a/test/01_io/06_unsolvable_cp.out b/test/01_io/06_unsolvable_cp.out new file mode 100644 index 0000000..e35c6e4 --- /dev/null +++ b/test/01_io/06_unsolvable_cp.out | |||
| @@ -0,0 +1 @@ | |||
| Cube is not solvable | |||
diff --git a/test/01_io/07_inconsistent_co.out b/test/01_io/07_inconsistent_co.out deleted file mode 100644 index cb70902..0000000 --- a/test/01_io/07_inconsistent_co.out +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | Cube is inconsistent | ||
diff --git a/test/01_io/07_inconsistent_co.in b/test/01_io/07_unsolvable_co.in index abd74e2..abd74e2 100644 --- a/test/01_io/07_inconsistent_co.in +++ b/test/01_io/07_unsolvable_co.in | |||
diff --git a/test/01_io/07_unsolvable_co.out b/test/01_io/07_unsolvable_co.out new file mode 100644 index 0000000..e35c6e4 --- /dev/null +++ b/test/01_io/07_unsolvable_co.out | |||
| @@ -0,0 +1 @@ | |||
| Cube is not solvable | |||
diff --git a/test/01_io/io_tests.c b/test/01_io/io_tests.c index 42ef9b8..913ec1d 100644 --- a/test/01_io/io_tests.c +++ b/test/01_io/io_tests.c | |||
| @@ -17,8 +17,8 @@ int main() { | |||
| 17 | 17 | ||
| 18 | if (iserror(cube)) { | 18 | if (iserror(cube)) { |
| 19 | printf("Error reading cube\n"); | 19 | printf("Error reading cube\n"); |
| 20 | } else if (!isconsistent(cube)) { | 20 | } else if (!issolvable(cube)) { |
| 21 | printf("Cube is inconsistent\n"); | 21 | printf("Cube is not solvable\n"); |
| 22 | } else { | 22 | } else { |
| 23 | writecube(cube, str); | 23 | writecube(cube, str); |
| 24 | printf("%s\n", str); | 24 | printf("%s\n", str); |
diff --git a/test/02_move/move_tests.c b/test/02_move/move_tests.c index ac25de3..333c8ee 100644 --- a/test/02_move/move_tests.c +++ b/test/02_move/move_tests.c | |||
| @@ -29,8 +29,8 @@ int main() { | |||
| 29 | 29 | ||
| 30 | if (iserror(cube)) { | 30 | if (iserror(cube)) { |
| 31 | printf("Error moving cube\n"); | 31 | printf("Error moving cube\n"); |
| 32 | } else if (!isconsistent(cube)) { | 32 | } else if (!issolvable(cube)) { |
| 33 | printf("Moved cube is inconsistent\n"); | 33 | printf("Moved cube is not solvable\n"); |
| 34 | } else { | 34 | } else { |
| 35 | writecube(cube, str); | 35 | writecube(cube, str); |
| 36 | printf("%s\n", str); | 36 | printf("%s\n", str); |
diff --git a/test/03_inverse/inverse_tests.c b/test/03_inverse/inverse_tests.c index 5fab71a..c8d8d95 100644 --- a/test/03_inverse/inverse_tests.c +++ b/test/03_inverse/inverse_tests.c | |||
| @@ -16,8 +16,8 @@ int main() { | |||
| 16 | 16 | ||
| 17 | if (iserror(inv)) { | 17 | if (iserror(inv)) { |
| 18 | printf("Error inverting cube\n"); | 18 | printf("Error inverting cube\n"); |
| 19 | } else if (!isconsistent(inv)) { | 19 | } else if (!issolvable(inv)) { |
| 20 | printf("Inverted cube is inconsistent\n"); | 20 | printf("Inverted cube is not solvable\n"); |
| 21 | } else { | 21 | } else { |
| 22 | writecube(inv, str); | 22 | writecube(inv, str); |
| 23 | printf("%s\n", str); | 23 | printf("%s\n", str); |
diff --git a/test/04_compose/compose_tests.c b/test/04_compose/compose_tests.c index ae34f6d..575c2c9 100644 --- a/test/04_compose/compose_tests.c +++ b/test/04_compose/compose_tests.c | |||
| @@ -19,8 +19,8 @@ int main() { | |||
| 19 | 19 | ||
| 20 | if (iserror(c3)) { | 20 | if (iserror(c3)) { |
| 21 | printf("Error composing cubes\n"); | 21 | printf("Error composing cubes\n"); |
| 22 | } else if (!isconsistent(c3)) { | 22 | } else if (!issolvable(c3)) { |
| 23 | printf("Composed cube is inconsistent\n"); | 23 | printf("Composed cube is not solvable\n"); |
| 24 | } else { | 24 | } else { |
| 25 | writecube(c3, str); | 25 | writecube(c3, str); |
| 26 | printf("%s\n", str); | 26 | printf("%s\n", str); |
diff --git a/utils/solved.txt b/utils/solved.txt index 07cf178..dff224d 100644 --- a/utils/solved.txt +++ b/utils/solved.txt | |||
| @@ -1,2 +1 @@ | |||
| 1 | |||
| 2 | UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 | UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 | |
