diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/constants.h | 96 | ||||
| -rw-r--r-- | src/cube.h | 5 | ||||
| -rw-r--r-- | src/cube_array.c | 102 |
3 files changed, 116 insertions, 87 deletions
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 | ||
