Computer Programming Contest Preparation

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



/home/toolbox/public_html/solutions/103/10315/s.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 char cards[] = "23456789TJQKA";
   33 char suits[] = "CDHS";
   34 int  result[35];
   35 
   36 evalStruct white;
   37 evalStruct black;
   38 
   39 /*
   40  *  Author: Isaac Traxler, Josh Abadie
   41  *    Date: 20080324
   42  * Purpose:
   43  * Problem: 10315
   44  */
   45 
   46 void init()
   47 {
   48     /* FUNCTION init */ /* initialize state table */
   49     result[3] = 9;   /* straight flush */
   50     result[4] = 8;   /* four of a kind */
   51     result[6] = 8;
   52     result[24] = 7;  /* full house */
   53     result[26] = 7;
   54     result[2] = 6;   /* flush */
   55     result[10] = 6;
   56     result[18] = 6;
   57     result[34] = 6;
   58     result[1] = 5;   /*straight */
   59     result[8] = 4;   /* three of a kind */
   60     result[32] = 3;  /* two pair */
   61     result[16] = 2;  /* pair */
   62     result[0] = 1;   /* high card */
   63 } /* FUNCTION init */
   64 
   65 int rankCard(char value, char suit)
   66 {
   67     /* FUNCTION rankCard */
   68     int k; /* counters */
   69     int i = -1;
   70     int j = -1;
   71 
   72     for (k=0; (strlen(cards)>k) && (-1 == i); k++)
   73         {
   74             /* for */
   75             if (value == cards[k])
   76                 {
   77                     i = k;
   78                 }
   79         } /* for */
   80     for (k=0; (strlen(suits)>k) && (-1 == j); k++)
   81         {
   82             /* for */
   83             if (suit == suits[k])
   84                 {
   85                     j = k;
   86                 }
   87         } /* for */
   88     return (i * NSUITS + j);
   89 } /* FUNCTION rankCard */
   90 
   91 int suitIndex(int card)
   92 {
   93     /* FUNCTION suit */
   94     return (card % NSUITS);
   95 } /* FUNCTION suit */
   96 
   97 int cardIndex(int crd)
   98 {
   99     /* FUNCTION card */
  100     return (crd/NSUITS);
  101 } /* FUNCTION card */
  102 
  103 void initStruct(evalStruct *p)
  104 {
  105     /* FUNCTION initStruct */
  106     int i;
  107 
  108     for (i=0; 4>i; i++)
  109         {
  110             /* for */
  111             p->suits[i] = 0;
  112             p->values[i] = 0;
  113         } /* for */
  114     for (i=4; 13>i; i++)
  115         {
  116             /* for */
  117             p->values[i] = 0;
  118         } /* for */
  119 } /* FUNCTION initStruct */
  120 
  121 int getInput()
  122 {
  123     /* FUNCTION getInput */
  124     int dataReadFlag = TRUE;
  125     char buffer[5];
  126     int i;
  127 
  128     if (EOF == scanf(" %s ", buffer))
  129         {
  130             /* at EOF */
  131             dataReadFlag = FALSE;
  132         } /* at EOF */
  133     else
  134         {
  135             /* reading in the rest */
  136             black.hand[0] = rankCard(buffer[0], buffer[1]);
  137             for (i = 1; i < 5; i ++)
  138                 {
  139                     /* input loop */
  140                     scanf(" %s ", buffer);
  141                     black.hand[i] = rankCard(buffer[0], buffer[1]);
  142                 } /* input loop */
  143             for (i = 0; i < 5; i ++)
  144                 {
  145                     /* input loop */
  146                     scanf(" %s ", buffer);
  147                     white.hand[i] = rankCard(buffer[0], buffer[1]);
  148                 } /* input loop */
  149 
  150         } /* reading in the rest */
  151 
  152     return (dataReadFlag);
  153 } /* FUNCTION getInput */
  154 
  155 
  156 int detTest(int * ary, int count)
  157 {
  158     /* FUNCTION detTest */
  159     int i;
  160     int toReturn = 0;
  161 
  162     for (i = 0; 13 > i; i ++)
  163         {
  164             /* for loop */
  165             if (ary[i] == count)
  166                 {
  167                     /* found a match */
  168                     toReturn++;
  169                 } /* found a match */
  170         } /* for loop */
  171     return toReturn;
  172 } /* FUNCTION detTest */
  173 
  174 int detFlush(int * ary)
  175 {
  176     /* FUNCTION detFlush */
  177     int i;
  178     int toReturn = 0;
  179 
  180     for ( i = 0; 4 > i; i ++)
  181         {
  182             /* for */
  183             if (5 == ary[i])
  184                 {
  185                     /* flush found */
  186                     toReturn = 1;
  187                 } /* flush found */
  188         } /* for */
  189     return toReturn;
  190 } /* FUNCTION detFlush */
  191 
  192 int detStraight(int * ary)
  193 {
  194     /* FUNCTION detStraight */
  195     int i = 0;
  196     int toReturn = -1;
  197     int count = 0;
  198 
  199     while (-1 == toReturn)
  200         {
  201             /* while */
  202             if (ary[i] == 1)
  203                 {
  204                     count ++;
  205                     if (5 == count)
  206                         {
  207                             /* straight found */
  208                             toReturn = 1;
  209                         } /* straight found */
  210                 }
  211             else
  212                 {
  213                     if (0 < count)
  214                         {
  215                             /* bail out */
  216                             toReturn = 0;
  217                         } /* bail out */
  218                 }
  219             i++;
  220         } /* while */
  221     return toReturn;
  222 } /* FUNCTION detStraight */
  223 
  224 int calcHash(evalStruct eval)
  225 {
  226     /* FUNCTION calcHash */
  227     int i,j,k;
  228     int toReturn;
  229 
  230     toReturn = eval.cardHash; /* start wih kind of hand and then append each card */
  231     for (j = 4;  0 < j; j --)
  232         {
  233             /* for number of matching cards */
  234             for (i = 12; -1 < i; i --)
  235                 {
  236                     /* values */
  237                     if (eval.values[i] == j)
  238                         {
  239                             /* add to array */
  240                             for (k = 0; k < j; k ++)
  241                                 {
  242                                     /* handle each card */
  243                                     toReturn = toReturn *16 + i;
  244                                 } /* handle each card */
  245                         } /* add to array */
  246                 } /* values */
  247         } /* for number of matching cards */
  248     return toReturn;
  249 } /* FUNCTION calcHash */
  250 
  251 void evaluateHand(evalStruct *eval)
  252 {
  253     /* FUNCTION evaluateHand */
  254     int i;
  255 
  256     for (i=0; 5>i; i++)
  257         {
  258             /* for */
  259             eval->suits[suitIndex(eval->hand[i])]++;
  260             eval->values[cardIndex(eval->hand[i])]++;
  261         } /* for */
  262     /* determine number of pairs */
  263     eval->pairs = detTest(eval->values, 2);
  264     /* determine 3 of a kind */
  265     eval->triple = detTest(eval->values, 3);
  266     /* determine 4 of a kind */
  267     eval->quad = detTest(eval->values, 4);
  268     /* determine flush */
  269     eval->flush = detFlush(eval->suits);
  270     /* determine straight */
  271     eval->straight = detStraight(eval->values);
  272     eval->cardHash = result[(eval->pairs * 16) + (eval->triple * 8) +
  273                                                (eval->quad * 4) + (eval->flush * 2) +
  274                                                (eval->straight)];
  275     eval->cardHash = calcHash(*eval);
  276 } /* FUNCTION evaluateHand */
  277 
  278 void process()
  279 {
  280     /* FUNCTION process */
  281     initStruct(&black);
  282     initStruct(&white);
  283     evaluateHand(&black);
  284     evaluateHand(&white);
  285     if (white.cardHash > black.cardHash)
  286         {
  287             /* white wins */
  288             printf("White wins.\n");
  289         } /* white wins */
  290     else if (black.cardHash > white.cardHash)
  291         {
  292             /* black wins */
  293             printf("Black wins.\n");
  294         } /* black wins */
  295     else
  296         {
  297             /* tie for hands */
  298             printf("Tie.\n");
  299         } /* tie for hands */
  300 } /* FUNCTION process */
  301 
  302 int main ()
  303 {
  304     /* main */
  305     int moreToDo;
  306 
  307     init();
  308     moreToDo = getInput();
  309     while (moreToDo)
  310         {
  311             /* while */
  312             process();
  313             moreToDo = getInput();
  314         } /* while */
  315 
  316     return EXIT_SUCCESS;
  317 } /* main */
  318