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 }