Computer Programming Contest Preparation

ToolBox - Source for: 103/10315/d.c



/home/toolbox/public_html/solutions/103/10315/d.c
    1 #include <stdio.h>
    2 #include <string.h>
    3 #include <sys/types.h>
    4 #include <sys/stat.h>
    5 #include <fcntl.h>
    6 #include <stdint.h>
    7 #include <math.h>
    8 #include <stdlib.h>
    9 
   10 #define TRUE  (1 == 1)
   11 #define FALSE (1 != 1)
   12 
   13 #define DEBUG if (FALSE)
   14 
   15 #define NCARDS 52
   16 #define NSUITS 4
   17 
   18 typedef struct
   19 {
   20     int hand[5];     /* holds number of each card in players hand */
   21     int suits[4];    /* has count of how of each suit in players hand */
   22     int values[13];  /* has count of how many of each value in players hand */
   23     int cardHash;    /* 6 hex digit number, first digit is how hand evaluates,
   24                         next 5 digits are the value of each card */
   25     int pairs;       /* how many pairs are in hand */
   26     int triple;      /* how many 3 of a kinds in hand */
   27     int quad;        /* how many 4 of a kinds in hand */
   28     int flush;       /* 0 if not flush, 1 is a flush - how many flushes in hand */
   29     int straight;    /* 0 if not straight, 1 if straight */
   30 } evalStruct;
   31 
   32 /****************************************************************
   33 Table of possibilities:
   34                  pairs | triple | quad | flush | straight ||
   35                 +------+--------+------+-------+----------++
   36  Straight Flush |  0   |    0   |  0   |   1   |    1     || 3
   37  Four of a Kind |  0   |    0   |  1   |   0   |    0     || 4
   38                 |      |        |      |   1   |          || 6
   39      Full House |  1   |    1   |  0   |   0   |    0     || 24
   40                 |      |        |      |   1   |          || 26
   41           Flush |  0   |    0   |  0   |   1   |    0     || 2
   42                 |  1   |    0   |      |       |          || 18
   43                 |  2   |    0   |      |       |          || 34
   44                 |  0   |    1   |      |       |          || 10
   45        Straight |  0   |    0   |   0  |   0   |     1    || 1
   46 Three of a Kind |  0   |    1   |   0  |   0   |     0    || 8
   47        Two Pair |  2   |    0   |   0  |   0   |     0    || 32
   48        One Pair |  1   |    0   |   0  |   0   |     0    || 16
   49       High Card |  0   |    0   |   0  |   0   |     0    || 0
   50 
   51 At this point, we have a state table describing every possible outcome. The array
   52 result implements this state table.
   53 ****************************************************************/
   54 
   55 char cards[] = "23456789TJQKA";
   56 char suits[] = "CDHS";
   57 int  result[35];
   58 
   59 evalStruct white;
   60 evalStruct black;
   61 
   62 /*
   63  *  Author: Isaac Traxler, Josh Abadie
   64  *    Date: 20080324
   65  * Purpose:
   66  * Problem: 10315
   67  */
   68 
   69 void init()
   70 {
   71     /* FUNCTION init */ /* initialize state table */
   72     result[3] = 9;   /* straight flush */
   73     result[4] = 8;   /* four of a kind */
   74     result[6] = 8;
   75     result[24] = 7;  /* full house */
   76     result[26] = 7;
   77     result[2] = 6;   /* flush */
   78     result[10] = 6;
   79     result[18] = 6;
   80     result[34] = 6;
   81     result[1] = 5;   /*straight */
   82     result[8] = 4;   /* three of a kind */
   83     result[32] = 3;  /* two pair */
   84     result[16] = 2;  /* pair */
   85     result[0] = 1;   /* high card */
   86 } /* FUNCTION init */
   87 
   88 int rankCard(char value, char suit)
   89 {
   90     /* FUNCTION rankCard */
   91     /* adapted from Programming Challenges */
   92     /* This routine will take the value (2-A) and the suit and from that determine
   93        the card's number (2C - 0, 2D - 1, 2H - 2, 2S - 3, 3C -4 ... AH - 50, AS - 51)
   94     */
   95     int k; /* counters */
   96     int i = -1;
   97     int j = -1;
   98 
   99     for (k=0; (strlen(cards)>k) && (-1 == i); k++)
  100         {
  101             /* for */
  102             if (value == cards[k])
  103                 {
  104                     i = k;
  105                 }
  106         } /* for */
  107     for (k=0; (strlen(suits)>k) && (-1 == j); k++)
  108         {
  109             /* for */
  110             if (suit == suits[k])
  111                 {
  112                     j = k;
  113                 }
  114         } /* for */
  115     DEBUG printf("%c %c - %d %d %d\n",value, suit, i, j, i * NSUITS + j);
  116     return (i * NSUITS + j);
  117 } /* FUNCTION rankCard */
  118 
  119 int suitIndex(int card)
  120 {
  121     /* FUNCTION suit */
  122     /* adapted from Programming Challenges */
  123     return (card % NSUITS);
  124 } /* FUNCTION suit */
  125 
  126 int cardIndex(int crd)
  127 {
  128     /* FUNCTION card */
  129     /* adapted from Programming Challenges */
  130     return (crd/NSUITS);
  131 } /* FUNCTION card */
  132 
  133 void initStruct(evalStruct *p)
  134 {
  135     /* FUNCTION initStruct */
  136     int i;
  137 
  138     for (i=0; 4>i; i++)
  139         {
  140             /* for */
  141             p->suits[i] = 0;
  142             p->values[i] = 0;
  143         } /* for */
  144     for (i=4; 13>i; i++)
  145         {
  146             /* for */
  147             p->values[i] = 0;
  148         } /* for */
  149 } /* FUNCTION initStruct */
  150 
  151 void dump(evalStruct p, char * color)
  152 {
  153     /* FUNCTION dump */
  154     int i;
  155 
  156     printf("%s:\n", color);
  157     printf("\tpairs:%d\n", p.pairs);
  158     printf("\ttriple:%d\n", p.triple);
  159     printf("\tquad:%d\n", p.quad);
  160     printf("\tstraight:%d\n", p.straight);
  161     printf("\tflush:%d\n", p.flush);
  162     printf("\tHand:");
  163     for (i = 0; i < 5; i ++)
  164         {
  165             printf("\t%d", p.hand[i]);
  166         }
  167     printf("\n");
  168     printf("\tSuits:");
  169     for (i = 0; i < 4; i ++)
  170         {
  171             printf("\t%d", p.suits[i]);
  172         }
  173     printf("\n");
  174     printf("\tCounts:");
  175     for (i = 0; i < 13; i ++)
  176         {
  177             printf("\t%d", p.values[i]);
  178         }
  179     printf("\n");
  180     printf("\tcardHash:\t%d %x\n", p.cardHash, p.cardHash);
  181 } /* FUNCTION dump */
  182 
  183 int getInput()
  184 {
  185     /* FUNCTION getInput */
  186     int dataReadFlag = TRUE;
  187     char buffer[5];
  188     int i;
  189 
  190     if (EOF == scanf(" %s ", buffer))
  191         {
  192             /* at EOF */
  193             dataReadFlag = FALSE;
  194         } /* at EOF */
  195     else
  196         {
  197             /* reading in the rest */
  198             black.hand[0] = rankCard(buffer[0], buffer[1]);
  199             for (i = 1; i < 5; i ++)
  200                 {
  201                     /* input loop */
  202                     scanf(" %s ", buffer);
  203                     black.hand[i] = rankCard(buffer[0], buffer[1]);
  204                 } /* input loop */
  205             for (i = 0; i < 5; i ++)
  206                 {
  207                     /* input loop */
  208                     scanf(" %s ", buffer);
  209                     white.hand[i] = rankCard(buffer[0], buffer[1]);
  210                 } /* input loop */
  211 
  212         } /* reading in the rest */
  213 
  214     return (dataReadFlag);
  215 } /* FUNCTION getInput */
  216 
  217 
  218 int detTest(int * ary, int count)
  219 {
  220     /* FUNCTION detTest */
  221     int i;
  222     int toReturn = 0;
  223 
  224     for (i = 0; 13 > i; i ++)
  225         {
  226             /* for loop */
  227             if (ary[i] == count)
  228                 {
  229                     /* found a match */
  230                     toReturn++;
  231                 } /* found a match */
  232         } /* for loop */
  233     return toReturn;
  234 } /* FUNCTION detTest */
  235 
  236 int detFlush(int * ary)
  237 {
  238     /* FUNCTION detFlush */
  239     int i;
  240     int toReturn = 0;
  241 
  242     for ( i = 0; 4 > i; i ++)
  243         {
  244             /* for */
  245             if (5 == ary[i])
  246                 {
  247                     /* flush found */
  248                     toReturn = 1;
  249                 } /* flush found */
  250         } /* for */
  251     return toReturn;
  252 } /* FUNCTION detFlush */
  253 
  254 
  255 int detStraight(int * ary)
  256 {
  257     /* FUNCTION detStraight */
  258     int i = 0;
  259     int toReturn = -1;
  260     int count = 0;
  261 
  262     /* loop makes sure that once a 1 is encountered, 5 consecutive are found */
  263     while (-1 == toReturn)
  264         {
  265             /* while */
  266             if (ary[i] == 1)
  267                 {
  268                     count ++;
  269                     if (5 == count)
  270                         {
  271                             /* straight found */
  272                             toReturn = 1;
  273                         } /* straight found */
  274                 }
  275             else
  276                 {
  277                     if (0 < count)
  278                         {
  279                             /* bail out */
  280                             toReturn = 0;
  281                         } /* bail out */
  282                 }
  283             i++;
  284         } /* while */
  285     return toReturn;
  286 } /* FUNCTION detStraight */
  287 
  288 int calcHash(evalStruct eval)
  289 {
  290     /* FUNCTION calcHash */
  291     int i,j,k;
  292     int toReturn;
  293 
  294     toReturn = eval.cardHash; /* start wih kind of hand and then append each card */
  295     for (j = 4;  0 < j; j --)
  296         {
  297             /* for number of matching cards */
  298             for (i = 12; -1 < i; i --)
  299                 {
  300                     /* values */
  301                     if (eval.values[i] == j)
  302                         {
  303                             /* add to array */
  304                             for (k = 0; k < j; k ++)
  305                                 {
  306                                     /* handle each card */
  307                                     toReturn = toReturn *16 + i;
  308                                 } /* handle each card */
  309                         } /* add to array */
  310                 } /* values */
  311         } /* for number of matching cards */
  312     return toReturn;
  313 } /* FUNCTION calcHash */
  314 
  315 void evaluateHand(evalStruct *eval)
  316 {
  317     /* FUNCTION evaluateHand */
  318     int i;
  319 
  320     for (i=0; 5>i; i++)
  321         {
  322             /* for */
  323             eval->suits[suitIndex(eval->hand[i])]++;
  324             eval->values[cardIndex(eval->hand[i])]++;
  325         } /* for */
  326     /* determine number of pairs */
  327     eval->pairs = detTest(eval->values, 2);
  328     /* determine 3 of a kind */
  329     eval->triple = detTest(eval->values, 3);
  330     /* determine 4 of a kind */
  331     eval->quad = detTest(eval->values, 4);
  332     /* determine flush */
  333     eval->flush = detFlush(eval->suits);
  334     /* determine straight */
  335     eval->straight = detStraight(eval->values);
  336     eval->cardHash = result[(eval->pairs * 16) + (eval->triple * 8) +
  337                                                (eval->quad * 4) + (eval->flush * 2) +
  338                                                (eval->straight)];
  339     eval->cardHash = calcHash(*eval);
  340 } /* FUNCTION evaluateHand */
  341 
  342 void process()
  343 {
  344     /* FUNCTION process */
  345     initStruct(&black);
  346     initStruct(&white);
  347     evaluateHand(&black);
  348     evaluateHand(&white);
  349     if (white.cardHash > black.cardHash)
  350         {
  351             /* white wins */
  352             printf("White wins.\n");
  353         } /* white wins */
  354     else if (black.cardHash > white.cardHash)
  355         {
  356             /* black wins */
  357             printf("Black wins.\n");
  358         } /* black wins */
  359     else
  360         {
  361             /* tie for hands */
  362             printf("Tie.\n");
  363         } /* tie for hands */
  364 
  365     DEBUG dump(black, "Black");
  366     DEBUG dump(white, "White");
  367 } /* FUNCTION process */
  368 
  369 int main ()
  370 {
  371     /* main */
  372     int moreToDo;
  373 
  374     init();
  375     moreToDo = getInput();
  376     while (moreToDo)
  377         {
  378             /* while */
  379             process();
  380             moreToDo = getInput();
  381         } /* while */
  382 
  383     return EXIT_SUCCESS;
  384 } /* main */
  385