|
@@ -0,0 +1,640 @@ |
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
|
|
|
|
#define MAX_CHECK_PERM_N 24 |
|
|
|
|
|
|
|
|
|
|
|
#define CORNER_UFR 0 |
|
|
|
|
|
#define CORNER_URB 1 |
|
|
|
|
|
#define CORNER_UBL 2 |
|
|
|
|
|
#define CORNER_ULF 3 |
|
|
|
|
|
#define CORNER_DRF 4 |
|
|
|
|
|
#define CORNER_DFL 5 |
|
|
|
|
|
#define CORNER_DLB 6 |
|
|
|
|
|
#define CORNER_DBR 7 |
|
|
|
|
|
|
|
|
|
|
|
#define CORNER_FRU 8 |
|
|
|
|
|
#define CORNER_RBU 9 |
|
|
|
|
|
#define CORNER_BLU 10 |
|
|
|
|
|
#define CORNER_LFU 11 |
|
|
|
|
|
#define CORNER_RFD 12 |
|
|
|
|
|
#define CORNER_FLD 13 |
|
|
|
|
|
#define CORNER_LBD 14 |
|
|
|
|
|
#define CORNER_BRD 15 |
|
|
|
|
|
|
|
|
|
|
|
#define CORNER_RUF 16 |
|
|
|
|
|
#define CORNER_BUR 17 |
|
|
|
|
|
#define CORNER_LUB 18 |
|
|
|
|
|
#define CORNER_FUL 19 |
|
|
|
|
|
#define CORNER_FDR 20 |
|
|
|
|
|
#define CORNER_LDF 21 |
|
|
|
|
|
#define CORNER_BDL 22 |
|
|
|
|
|
#define CORNER_RDB 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define EDGE_UF 0 |
|
|
|
|
|
#define EDGE_UR 1 |
|
|
|
|
|
#define EDGE_UB 2 |
|
|
|
|
|
#define EDGE_UL 3 |
|
|
|
|
|
#define EDGE_DF 4 |
|
|
|
|
|
#define EDGE_DR 5 |
|
|
|
|
|
#define EDGE_DB 6 |
|
|
|
|
|
#define EDGE_DL 7 |
|
|
|
|
|
#define EDGE_FR 8 |
|
|
|
|
|
#define EDGE_FL 9 |
|
|
|
|
|
#define EDGE_BR 10 |
|
|
|
|
|
#define EDGE_BL 11 |
|
|
|
|
|
|
|
|
|
|
|
#define EDGE_FU 12 |
|
|
|
|
|
#define EDGE_RU 13 |
|
|
|
|
|
#define EDGE_BU 14 |
|
|
|
|
|
#define EDGE_LU 15 |
|
|
|
|
|
#define EDGE_FD 16 |
|
|
|
|
|
#define EDGE_RD 17 |
|
|
|
|
|
#define EDGE_BD 18 |
|
|
|
|
|
#define EDGE_LD 19 |
|
|
|
|
|
#define EDGE_RF 20 |
|
|
|
|
|
#define EDGE_LF 21 |
|
|
|
|
|
#define EDGE_RB 22 |
|
|
|
|
|
#define EDGE_LB 23 |
|
|
|
|
|
|
|
|
|
|
|
#define FACE_F 0 |
|
|
|
|
|
#define FACE_R 1 |
|
|
|
|
|
#define FACE_U 2 |
|
|
|
|
|
#define FACE_B 3 |
|
|
|
|
|
#define FACE_L 4 |
|
|
|
|
|
#define FACE_D 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct cube |
|
|
|
|
|
{ |
|
|
|
|
|
int centers[6]; |
|
|
|
|
|
int edges[24]; |
|
|
|
|
|
int corners[24]; |
|
|
|
|
|
} |
|
|
|
|
|
Cube; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *center_cubie_str[] = {"F", "R", "U", |
|
|
|
|
|
"B", "L", "D"}; |
|
|
|
|
|
|
|
|
|
|
|
static char *edge_cubie_str[] = {"UF", "UR", "UB", "UL", |
|
|
|
|
|
"DF", "DR", "DB", "DL", |
|
|
|
|
|
"FR", "FL", "BR", "BL", |
|
|
|
|
|
"FU", "RU", "BU", "LU", |
|
|
|
|
|
"FD", "RD", "BD", "LD", |
|
|
|
|
|
"RF", "LF", "RB", "LB"}; |
|
|
|
|
|
|
|
|
|
|
|
static char *corner_cubie_str[] = {"UFR", "URB", "UBL", "ULF", |
|
|
|
|
|
"DRF", "DFL", "DLB", "DBR", |
|
|
|
|
|
"FRU", "RBU", "BLU", "LFU", |
|
|
|
|
|
"RFD", "FLD", "LBD", "BRD", |
|
|
|
|
|
"RUF", "BUR", "LUB", "FUL", |
|
|
|
|
|
"FDR", "LDF", "BDL", "RDB"}; |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void two_cycle(int array[], int ind0, int ind1) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int temp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
temp = array[ind0]; |
|
|
|
|
|
array[ind0] = array[ind1]; |
|
|
|
|
|
array[ind1] = temp; |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void three_cycle(int array[], int ind0, int ind1, int ind2) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int temp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
temp = array[ind0]; |
|
|
|
|
|
array[ind0] = array[ind1]; |
|
|
|
|
|
array[ind1] = array[ind2]; |
|
|
|
|
|
array[ind2] = temp; |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void four_cycle(int array[], int ind0, int ind1, int ind2, int ind3) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int temp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
temp = array[ind0]; |
|
|
|
|
|
array[ind0] = array[ind1]; |
|
|
|
|
|
array[ind1] = array[ind2]; |
|
|
|
|
|
array[ind2] = array[ind3]; |
|
|
|
|
|
array[ind3] = temp; |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void print_cube(Cube *p_cube) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
printf("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", |
|
|
|
|
|
center_cubie_str[p_cube->centers[0]], center_cubie_str[p_cube->centers[1]], |
|
|
|
|
|
center_cubie_str[p_cube->centers[2]], center_cubie_str[p_cube->centers[3]], |
|
|
|
|
|
center_cubie_str[p_cube->centers[4]], center_cubie_str[p_cube->centers[5]], |
|
|
|
|
|
edge_cubie_str[p_cube->edges[0]], edge_cubie_str[p_cube->edges[1]], |
|
|
|
|
|
edge_cubie_str[p_cube->edges[2]], edge_cubie_str[p_cube->edges[3]], |
|
|
|
|
|
edge_cubie_str[p_cube->edges[4]], edge_cubie_str[p_cube->edges[5]], |
|
|
|
|
|
edge_cubie_str[p_cube->edges[6]], edge_cubie_str[p_cube->edges[7]], |
|
|
|
|
|
edge_cubie_str[p_cube->edges[8]], edge_cubie_str[p_cube->edges[9]], |
|
|
|
|
|
edge_cubie_str[p_cube->edges[10]], edge_cubie_str[p_cube->edges[11]], |
|
|
|
|
|
corner_cubie_str[p_cube->corners[0]], corner_cubie_str[p_cube->corners[1]], |
|
|
|
|
|
corner_cubie_str[p_cube->corners[2]], corner_cubie_str[p_cube->corners[3]], |
|
|
|
|
|
corner_cubie_str[p_cube->corners[4]], corner_cubie_str[p_cube->corners[5]], |
|
|
|
|
|
corner_cubie_str[p_cube->corners[6]], corner_cubie_str[p_cube->corners[7]]); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void perm_n_init(int nn, int array_out[]) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int ii; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < nn; ii++) |
|
|
|
|
|
array_out[ii] = ii; |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void cube_init(Cube *p_cube) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
perm_n_init(6, p_cube->centers); |
|
|
|
|
|
perm_n_init(24, p_cube->edges); |
|
|
|
|
|
perm_n_init(24, p_cube->corners); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
int cube_compare(Cube *cube0, Cube *cube1) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int ii; |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 6; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
if (cube0->centers[ii] < cube1->centers[ii]) |
|
|
|
|
|
return -1; |
|
|
|
|
|
else if (cube0->centers[ii] > cube1->centers[ii]) |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 24; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
if (cube0->edges[ii] < cube1->edges[ii]) |
|
|
|
|
|
return -1; |
|
|
|
|
|
else if (cube0->edges[ii] > cube1->edges[ii]) |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 24; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
if (cube0->corners[ii] < cube1->corners[ii]) |
|
|
|
|
|
return -1; |
|
|
|
|
|
else if (cube0->corners[ii] > cube1->corners[ii]) |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void cube_compose(Cube *in_cube0, Cube *in_cube1, Cube *out_cube) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
perm_n_compose(6, in_cube0->centers, in_cube1->centers, out_cube->centers); |
|
|
|
|
|
perm_n_compose(24, in_cube0->edges, in_cube1->edges, out_cube->edges); |
|
|
|
|
|
perm_n_compose(24, in_cube0->corners, in_cube1->corners, out_cube->corners); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
int perm_n_check(int nn, int array_in[]) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int count[MAX_CHECK_PERM_N], ii; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < nn; ii++) |
|
|
|
|
|
count[ii] = 0; |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < nn; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
if ((array_in[ii] < 0) || (array_in[ii] >= nn)) |
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
|
|
|
|
count[array_in[ii]]++; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < nn; ii++) |
|
|
|
|
|
if (count[ii] != 1) |
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
int perm_n_parity(int nn, int array_in[]) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int temp_array[MAX_CHECK_PERM_N]; |
|
|
|
|
|
int ii, jj, n_cycles; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < nn; ii++) |
|
|
|
|
|
temp_array[ii] = 0; |
|
|
|
|
|
|
|
|
|
|
|
n_cycles = 0; |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < nn; ii++) |
|
|
|
|
|
if (temp_array[ii] == 0) |
|
|
|
|
|
{ |
|
|
|
|
|
n_cycles++; |
|
|
|
|
|
jj = ii; |
|
|
|
|
|
while (temp_array[jj] == 0) |
|
|
|
|
|
{ |
|
|
|
|
|
temp_array[jj] = 1; |
|
|
|
|
|
jj = array_in[jj]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return (n_cycles + nn) % 2; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
int centers_check(int array_in[]) |
|
|
|
|
|
/* return -1 if invalid, 0 if even cube configuration, 1 for odd */ |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int parity = 0; |
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
int clone[6]; |
|
|
|
|
|
for(i = 0; i < 6; i++) |
|
|
|
|
|
clone[i] = array_in[i]; |
|
|
|
|
|
|
|
|
|
|
|
// put FACE_UP upwards |
|
|
|
|
|
for (i = 0; i<6; i++) |
|
|
|
|
|
if(clone[i] == FACE_U) |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
switch(i) { |
|
|
|
|
|
case FACE_U: |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_F: |
|
|
|
|
|
four_cycle(clone, FACE_U, FACE_F, FACE_D, FACE_B); |
|
|
|
|
|
parity++; |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_L: |
|
|
|
|
|
four_cycle(clone, FACE_U, FACE_L, FACE_D, FACE_R); |
|
|
|
|
|
parity++; |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_R: |
|
|
|
|
|
four_cycle(clone, FACE_U, FACE_R, FACE_D, FACE_L); |
|
|
|
|
|
parity++; |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_B: |
|
|
|
|
|
four_cycle(clone, FACE_U, FACE_B, FACE_D, FACE_F); |
|
|
|
|
|
parity++; |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_D: |
|
|
|
|
|
two_cycle(clone, FACE_U, FACE_D); |
|
|
|
|
|
two_cycle(clone, FACE_F, FACE_B); |
|
|
|
|
|
break; |
|
|
|
|
|
case 6: |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// now put FACE_FRONT in place |
|
|
|
|
|
for (i = 0; i<6; i++) |
|
|
|
|
|
if(clone[i] == FACE_F) |
|
|
|
|
|
break; |
|
|
|
|
|
switch(i) { |
|
|
|
|
|
case FACE_F: |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_L: |
|
|
|
|
|
four_cycle(clone, FACE_F, FACE_L, FACE_B, FACE_R); |
|
|
|
|
|
parity++; |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_R: |
|
|
|
|
|
four_cycle(clone, FACE_F, FACE_R, FACE_B, FACE_L); |
|
|
|
|
|
parity++; |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_B: |
|
|
|
|
|
two_cycle(clone, FACE_F, FACE_B); |
|
|
|
|
|
two_cycle(clone, FACE_L, FACE_R); |
|
|
|
|
|
break; |
|
|
|
|
|
case FACE_U: // this is not possible |
|
|
|
|
|
case FACE_D: |
|
|
|
|
|
case 6: |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(clone[FACE_R] != FACE_R || clone[FACE_L] != FACE_L |
|
|
|
|
|
|| clone[FACE_B] != FACE_B || clone[FACE_D] != FACE_D) |
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
|
|
return parity & 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
int string_to_cube(char string[], Cube *p_cube, int give_err_msg) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
/* input: string[] */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
char center_str[6][2], edge_str[12][3], corner_str[8][4]; |
|
|
|
|
|
int center_arr[6], edge_arr[12], corner_arr[8]; |
|
|
|
|
|
int ii, jj, twist, flip, edge_par, corner_par, center_par; |
|
|
|
|
|
int stat; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stat = 0; |
|
|
|
|
|
|
|
|
|
|
|
if (sscanf(string, "%1s %1s %1s %1s %1s %1s %2s %2s %2s %2s %2s %2s %2s %2s %2s %2s %2s %2s %3s %3s %3s %3s %3s %3s %3s %3s", |
|
|
|
|
|
center_str[0], center_str[1], center_str[2], |
|
|
|
|
|
center_str[3], center_str[4], center_str[5], |
|
|
|
|
|
edge_str[0], edge_str[1], edge_str[2], edge_str[3], |
|
|
|
|
|
edge_str[4], edge_str[5], edge_str[6], edge_str[7], |
|
|
|
|
|
edge_str[8], edge_str[9], edge_str[10], edge_str[11], |
|
|
|
|
|
corner_str[0], corner_str[1], corner_str[2], corner_str[3], |
|
|
|
|
|
corner_str[4], corner_str[5], corner_str[6], corner_str[7]) < 20) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("invalid input!\n"); |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 6 ; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
for (jj = 0; jj < 6; jj++) |
|
|
|
|
|
if(strcmp(center_str[ii], center_cubie_str[jj]) == 0) |
|
|
|
|
|
{ |
|
|
|
|
|
p_cube->centers[ii] = jj; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
if(jj == 6) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("invalid center cubie: %s\n", center_str[ii]); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 12; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
for (jj = 0; jj < 24; jj++) |
|
|
|
|
|
if (strcmp(edge_str[ii], edge_cubie_str[jj]) == 0) |
|
|
|
|
|
{ |
|
|
|
|
|
p_cube->edges[ii] = jj; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
if (jj == 24) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("invalid edge cubie: %s\n", edge_str[ii]); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 8; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
for (jj = 0; jj < 24; jj++) |
|
|
|
|
|
if (strcmp(corner_str[ii], corner_cubie_str[jj]) == 0) |
|
|
|
|
|
{ |
|
|
|
|
|
p_cube->corners[ii] = jj; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
if (jj == 24) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("invalid corner cubie: %s\n", corner_str[ii]); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (stat) |
|
|
|
|
|
return stat; |
|
|
|
|
|
|
|
|
|
|
|
/* fill out the remaining oriented edges and corners */ |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 12; ii < 24; ii++) |
|
|
|
|
|
p_cube->edges[ii] = (12 + p_cube->edges[ii - 12]) % 24; |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 8; ii < 24; ii++) |
|
|
|
|
|
p_cube->corners[ii] = (8 + p_cube->corners[ii - 8]) % 24; |
|
|
|
|
|
|
|
|
|
|
|
/* now check to see that it's a legal cube */ |
|
|
|
|
|
|
|
|
|
|
|
center_par = centers_check(p_cube->centers); |
|
|
|
|
|
if (center_par == -1) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("bad center cubies\n"); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (perm_n_check(24, p_cube->edges)) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("bad edge cubies\n"); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (perm_n_check(24, p_cube->corners)) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("bad corner cubies\n"); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (stat) |
|
|
|
|
|
return stat; |
|
|
|
|
|
|
|
|
|
|
|
flip = 0; |
|
|
|
|
|
for (ii = 0; ii < 12; ii++) |
|
|
|
|
|
flip += (p_cube->edges[ii] / 12); |
|
|
|
|
|
|
|
|
|
|
|
if ((flip % 2) != 0) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("flip any edge cubie!\n"); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
twist = 0; |
|
|
|
|
|
for (ii = 0; ii < 8; ii++) |
|
|
|
|
|
twist += (p_cube->corners[ii] / 8); |
|
|
|
|
|
|
|
|
|
|
|
twist %= 3; |
|
|
|
|
|
|
|
|
|
|
|
if (twist != 0) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("twist any corner cubie %sclockwise!\n", |
|
|
|
|
|
(twist == 1) ? "counter" : ""); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 12; ii++) |
|
|
|
|
|
edge_arr[ii] = p_cube->edges[ii] % 12; |
|
|
|
|
|
|
|
|
|
|
|
edge_par = perm_n_parity(12, edge_arr); |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 8; ii++) |
|
|
|
|
|
corner_arr[ii] = p_cube->corners[ii] % 8; |
|
|
|
|
|
|
|
|
|
|
|
corner_par = perm_n_parity(8, corner_arr); |
|
|
|
|
|
|
|
|
|
|
|
if (((edge_par + corner_par + center_par) & 1) == 1) |
|
|
|
|
|
{ |
|
|
|
|
|
if (give_err_msg) |
|
|
|
|
|
printf("swap any two edge cubies or any two corner cubies!\n"); |
|
|
|
|
|
stat = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return stat; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
int user_enters_cube(Cube *p_cube) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
char line_str[256]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("\nenter cube (Ctrl-D to exit):\n"); |
|
|
|
|
|
|
|
|
|
|
|
line_str[0] = '\n'; |
|
|
|
|
|
|
|
|
|
|
|
while (line_str[0] == '\n') /* ignore blank lines */ |
|
|
|
|
|
{ |
|
|
|
|
|
if (fgets(line_str, 256, stdin) == NULL) |
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
|
|
if (line_str[0] == '%') /* echo comments */ |
|
|
|
|
|
{ |
|
|
|
|
|
printf("%s", line_str); |
|
|
|
|
|
line_str[0] = '\n'; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return string_to_cube(line_str, p_cube, 1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
void pretty_print_unsigned_int(unsigned int nn) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
int digits[4], ii, started; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < 4; ii++) |
|
|
|
|
|
{ |
|
|
|
|
|
digits[ii] = nn % 1000; |
|
|
|
|
|
nn /= 1000; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
started = 0; |
|
|
|
|
|
|
|
|
|
|
|
for (ii = 3; ii >= 0; ii--) |
|
|
|
|
|
{ |
|
|
|
|
|
if (started) |
|
|
|
|
|
{ |
|
|
|
|
|
if (digits[ii] >= 100) |
|
|
|
|
|
printf("%3d", digits[ii]); |
|
|
|
|
|
else if (digits[ii] >= 10) |
|
|
|
|
|
printf("0%2d", digits[ii]); |
|
|
|
|
|
else |
|
|
|
|
|
printf("00%1d", digits[ii]); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
if (digits[ii] >= 100) |
|
|
|
|
|
{ |
|
|
|
|
|
printf("%3d", digits[ii]); |
|
|
|
|
|
started = 1; |
|
|
|
|
|
} |
|
|
|
|
|
else if (digits[ii] >= 10) |
|
|
|
|
|
{ |
|
|
|
|
|
printf(" %2d", digits[ii]); |
|
|
|
|
|
started = 1; |
|
|
|
|
|
} |
|
|
|
|
|
else if ((digits[ii] >= 1) || (ii == 0)) |
|
|
|
|
|
{ |
|
|
|
|
|
printf(" %1d", digits[ii]); |
|
|
|
|
|
started = 1; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
printf(" "); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ii > 0) |
|
|
|
|
|
printf("%c", started ? ',' : ' '); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
|
|
int main(void) |
|
|
|
|
|
/* ------------------------------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
Cube cube_struct; |
|
|
|
|
|
int stat; |
|
|
|
|
|
|
|
|
|
|
|
while (1) |
|
|
|
|
|
{ |
|
|
|
|
|
stat = user_enters_cube(&cube_struct); |
|
|
|
|
|
if (stat < 0) |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
exit(EXIT_SUCCESS); |
|
|
|
|
|
|
|
|
|
|
|
return 0; /* haha */ |
|
|
|
|
|
} |