1 #include <stdio.h> 2 3 /* 4 * flat layout answer layout 5 * image elements in order image elements in order 6 * corner numbers labeled 7 * 3---2 8 * | 1 | 9 * 3---0---1---2---3 \ 1 / 10 * | 2 | 3 | 4 | 5 | Y 11 * 7---4---5---6---7 3 | 2 12 * | 6 | 13 * 7---6 14 */ 15 char inbuf[512]; 16 17 int flatImage[6], flatOrient[6]; 18 int ansImage[5][3], ansOrient[5][3]; 19 int cornerImage[8][3], cornerOrient[8][3]; // images clockwise around each corner from flat 20 int nSolns; 21 char solnIndex[5]; 22 23 int GetCornerVals(int probNum) 24 { 25 // corner 0 = 1, 3, 2 26 cornerImage[0][0] = flatImage[0]; 27 cornerOrient[0][0] = (flatOrient[0] + 1) % 4; // up corresp to 2 28 cornerImage[0][1] = flatImage[2]; 29 cornerOrient[0][1] = flatOrient[2]; // up corresp to 1 30 cornerImage[0][2] = flatImage[1]; 31 cornerOrient[0][2] = (flatOrient[1] + 3) % 4; // up corresp to 4 32 // corner 1 = 1, 4, 3 33 cornerImage[1][0] = flatImage[0]; 34 cornerOrient[1][0] = (flatOrient[0] + 2) % 4; // up corresp to 3 35 cornerImage[1][1] = flatImage[3]; 36 cornerOrient[1][1] = flatOrient[3]; // up corresp to 1 37 cornerImage[1][2] = flatImage[2]; 38 cornerOrient[1][2] = (flatOrient[2] + 3) % 4; // up corresp to 4 39 // corner 2 = 1, 5, 4 40 cornerImage[2][0] = flatImage[0]; 41 cornerOrient[2][0] = (flatOrient[0] + 3) % 4; // up corresp to 3 42 cornerImage[2][1] = flatImage[4]; 43 cornerOrient[2][1] = flatOrient[4]; // up corresp to 1 44 cornerImage[2][2] = flatImage[3]; 45 cornerOrient[2][2] = (flatOrient[3] + 3) % 4; // up corresp to 4 46 // corner 3 = 1, 2, 5 47 cornerImage[3][0] = flatImage[0]; 48 cornerOrient[3][0] = flatOrient[0]; // up corresp to 1 49 cornerImage[3][1] = flatImage[1]; 50 cornerOrient[3][1] = flatOrient[1]; // up corresp to 1 51 cornerImage[3][2] = flatImage[4]; 52 cornerOrient[3][2] = (flatOrient[4] + 3) % 4; // up corresp to 4 53 // corner 4 = 6, 2, 3 54 cornerImage[4][0] = flatImage[5]; 55 cornerOrient[4][0] = flatOrient[5]; // up corresp to 1 56 cornerImage[4][1] = flatImage[1]; 57 cornerOrient[4][1] = (flatOrient[1] + 2) % 4; // up corresp to 3 58 cornerImage[4][2] = flatImage[2]; 59 cornerOrient[4][2] = (flatOrient[2] + 1) % 4; // up corresp to 2 60 // corner 5 = 6, 3, 4 61 cornerImage[5][0] = flatImage[5]; 62 cornerOrient[5][0] = (flatOrient[5] + 3) % 4; // up corresp to 4 63 cornerImage[5][1] = flatImage[2]; 64 cornerOrient[5][1] = (flatOrient[2] + 2) % 4; // up corresp to 3 65 cornerImage[5][2] = flatImage[3]; 66 cornerOrient[5][2] = (flatOrient[3] + 1) % 4; // up corresp to 2 67 // corner 6 = 6, 4, 5 68 cornerImage[6][0] = flatImage[5]; 69 cornerOrient[6][0] = (flatOrient[5] + 2) % 4; // up corresp to 3 70 cornerImage[6][1] = flatImage[3]; 71 cornerOrient[6][1] = (flatOrient[3] + 2) % 4; // up corresp to 3 72 cornerImage[6][2] = flatImage[4]; 73 cornerOrient[6][2] = (flatOrient[4] + 1) % 4; // up corresp to 2 74 // corner 7 = 6, 5, 2 75 cornerImage[7][0] = flatImage[5]; 76 cornerOrient[7][0] = (flatOrient[5] + 1) % 4; // up corresp to 2 77 cornerImage[7][1] = flatImage[4]; 78 cornerOrient[7][1] = (flatOrient[4] + 2) % 4; // up corresp to 3 79 cornerImage[7][2] = flatImage[1]; 80 cornerOrient[7][2] = (flatOrient[1] + 1) % 4; // up corresp to 2 81 82 return 0; 83 } 84 85 int TestAns(int *pImg, int *pOrient) 86 { 87 int corner, ort; 88 for (corner = 0; corner < 8 ; corner++) 89 { 90 for (ort = 0; ort < 3; ort++) 91 { 92 if ((cornerImage[corner][ort] == pImg[0]) && 93 (cornerOrient[corner][ort] == pOrient[0])) 94 { // first ans face matches, check the others 95 if ((cornerImage[corner][(ort + 1) %3] == pImg[1]) && 96 (cornerOrient[corner][(ort + 1) %3] == pOrient[1]) && 97 (cornerImage[corner][(ort + 2) %3] == pImg[2]) && 98 (cornerOrient[corner][(ort + 2) %3] == pOrient[2])) 99 { // complete match 100 return (3 * corner + ort); 101 } 102 } 103 } 104 } 105 return -1; 106 } 107 108 void CountPrintMatch(int probNum) 109 { 110 int i; 111 // count solns 112 nSolns = 0; 113 for (i = 0; i < 5; i++) 114 { 115 if (TestAns(&(ansImage[i][0]), &(ansOrient[i][0])) >= 0) 116 { // its a soln 117 solnIndex[i] = 'Y'; 118 nSolns++; 119 } 120 else 121 { 122 solnIndex[i] = 'N'; 123 } 124 } 125 // print result 126 printf("%d %d", probNum, nSolns); 127 for (i = 0; i < 5 ; i++) 128 { 129 printf(" %c", solnIndex[i]); 130 } 131 printf("\n"); 132 } 133 134 int ParseFlatLayout(int probNum) 135 { 136 int i, j; 137 char c; 138 139 if (fgets(&(inbuf[0]), 511, stdin) == NULL) 140 { 141 fprintf(stderr, "Read failed on flat layout problem %d\n", probNum); 142 return -4; 143 } 144 145 for (i = 0, j = 0; i < 6; i++) 146 { 147 c = inbuf[j]; 148 if ((c < 'A') || (c > 'F')) 149 { 150 fprintf(stderr, "bad face name[%d] %c (0x%02x) flat layout problem %d\n", 151 i+1, c, c, probNum); 152 return -5; 153 } 154 flatImage[i] = c - 'A'; 155 j++; 156 c = inbuf[j]; 157 if ((c < '1') || (c > '4')) 158 { 159 fprintf(stderr, "bad face orientation[%d] %c (0x%02x) flat layout problem %d\n", 160 i+1, c, c, probNum); 161 return -6; 162 } 163 flatOrient[i] = c - '1'; 164 j++; 165 } 166 return 0; 167 } 168 169 int ParseAnswer(int probNum, int ansNum) 170 { 171 int i, j; 172 char c; 173 174 if (fgets(&(inbuf[0]), 511, stdin) == NULL) 175 { 176 fprintf(stderr, "Read failed on flat layout problem %d\n", probNum); 177 return -7; 178 } 179 180 for (i = 0, j = 0; i < 3; i++) 181 { 182 c = inbuf[j]; 183 if ((c < 'A') || (c > 'F')) 184 { 185 fprintf(stderr, "bad face name[%d] %c (0x%02x) answer %d problem %d\n", 186 i+1, c, c, ansNum + 1, probNum); 187 return -8; 188 } 189 ansImage[ansNum][i] = c - 'A'; 190 j++; 191 c = inbuf[j]; 192 if ((c < '1') || (c > '4')) 193 { 194 fprintf(stderr, "bad face orientation[%d] %c (0x%02x) answer %d problem %d\n", 195 i+1, c, c, ansNum + 1, probNum); 196 return -9; 197 } 198 ansOrient[ansNum][i] = c - '1'; 199 j++; 200 } 201 return 0; 202 } 203 204 int main() 205 { 206 int nProbs, probNum, ret, ansInd; 207 208 if (fgets(&(inbuf[0]), 511, stdin) == NULL) 209 { 210 fprintf(stderr, "Read failed on problem count\n"); 211 return -1; 212 } 213 if (sscanf(&(inbuf[0]), "%d", &nProbs) != 1) 214 { 215 fprintf(stderr, "Scan failed on problem count\n"); 216 return -2; 217 } 218 if ((nProbs < 1) || (nProbs > 1000)) 219 { 220 fprintf(stderr, "problem count %d not in range 1 to 1000\n", nProbs); 221 return -3; 222 } 223 for (probNum = 1; probNum <= nProbs ; probNum++) 224 { 225 ret = ParseFlatLayout(probNum); 226 if (ret != 0) 227 { 228 return ret; 229 } 230 GetCornerVals(probNum); 231 for (ansInd = 0; ansInd < 5 ; ansInd++) 232 { 233 ret = ParseAnswer(probNum, ansInd); 234 if (ret != 0) 235 { 236 return ret; 237 } 238 } 239 CountPrintMatch(probNum); 240 } 241 return 0; 242 }