Computer Programming Contest Preparation

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



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