Computer Programming Contest Preparation

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



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