Computer Programming Contest Preparation

ToolBox - Source for: 1/101/a.c



/home/toolbox/public_html/solutions/1/101/a.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 /*
   16  *  Author: Isaac Traxler
   17  *    Date: 2014-10-30
   18  * Purpose: fun
   19  * Problem: 101 - The Blocks Problem
   20  */
   21 
   22 #define MAX_LINE 256
   23 
   24 #define MOVE 0
   25 #define PILE 3
   26 #define ONTO 1
   27 #define OVER 2
   28 
   29 /*
   30 move onto 1 0 + 1
   31 move over 2 0 + 2
   32 pile onto 4 3 + 1
   33 pile over 5 3 + 2
   34 */
   35 
   36 #define MAX_BLOCKS 30
   37 
   38 typedef struct LOCATION_STRUCT
   39 {
   40     /* BEGIN LOCATION_STRUCT */
   41     int pile;
   42     int depth;
   43 } /* END LOCATION_STRUCT */ LOCATION_STRUCT;
   44 
   45 typedef struct PILE_STRUCT
   46 {
   47     /* BEGIN PILE_STRUCT */
   48     int cnt;
   49     int p[MAX_BLOCKS];
   50 } /* END PILE_STRUCT */ PILE_STRUCT;
   51 
   52 /*
   53  * This template reads data until a terminating value is reached.
   54  */
   55 
   56 int moreToDo;
   57 int size;
   58 int cmd;
   59 int a;
   60 int b;
   61 PILE_STRUCT blocks[MAX_BLOCKS];
   62 char commands[4][5] = { "move", "onto", "over", "pile" };
   63 
   64 
   65 void dump()
   66 {
   67     /* FUNCTION dump */
   68     int i;
   69     int j;
   70 
   71     for (i=0; size>i; i++)
   72         {
   73             /* for each pile */
   74             printf("%d:", i);
   75             for (j=0; blocks[i].cnt>j; j++)
   76                 {
   77                     /* for each element in the pile */
   78                     printf(" %d", blocks[i].p[j]);
   79                 } /* for each element in the pile */
   80             printf("\n");
   81         } /* for each pile */
   82 } /* FUNCTION dump */
   83 
   84 int getInput()
   85 {
   86     /* FUNCTION getInput */
   87     int moreToDO;
   88     char t[10];
   89     int c1;
   90     int c2;
   91 
   92     scanf(" %s ", t);
   93     moreToDo = 'q' != t[0];
   94     if (moreToDo)
   95         {
   96             /* got a command */
   97             /* assume valid command, so first letter is m or p, and p is 3 greater tham m */
   98             c1 = t[0] - 'm'; /* if m, c1 = 0, else c1 = 3 */
   99             /* now get second part of comand and 2 values */
  100             scanf(" %d %s %d ", &a, t, &b);
  101             if ('n' == t[1])
  102                 {
  103                     /* move */
  104                     c2 = ONTO;
  105                 } /* move */
  106             else
  107                 {
  108                     /* pile */
  109                     c2 = OVER;
  110                 } /* pile */
  111             cmd = c1 + c2;
  112             DEBUG printf("%s %d %s %d -- %d\n", commands[c1], a, commands[c2], b, cmd);
  113         } /* got a command */
  114     return moreToDo;
  115 } /* FUNCTION getInput */
  116 
  117 void init()
  118 {
  119     /* FUNCTION init */
  120     int i;
  121 
  122     scanf(" %d ", &size);
  123     for (i=0; i<size; i++)
  124         {
  125             /* for each i */
  126             blocks[i].cnt = 1;
  127             blocks[i].p[0] = i;
  128         } /* for each i */
  129 } /* FUNCTION init */
  130 
  131 LOCATION_STRUCT fnd(int f)
  132 {
  133     /* FUNCTION fnd */
  134     LOCATION_STRUCT toReturn;
  135     int p;
  136     int i;
  137 
  138     toReturn.pile = -1;  /* not found */
  139     for (p=0; size>p; p++)
  140         {
  141             /* try each pile */
  142             for (i=0; blocks[p].cnt>i; i++)
  143                 {
  144                     /* each item in this pile */
  145                     if (f == blocks[p].p[i])
  146                         {
  147                             /* found the desired block */
  148                             toReturn.pile = p;
  149                             toReturn.depth = i;
  150                             i = size;
  151                             p = size;
  152                         } /* found the desired block */
  153                 } /* each item in this pile */
  154         } /* try each pile */
  155     return toReturn;
  156 } /* FUNCTION fnd */
  157 
  158 void putOnTopOfPile(int x, int ple)
  159 {
  160     /* FUNCTION putOnTopOfPile */
  161     DEBUG printf("pile = %d  cnt = %d\n", ple, blocks[ple].cnt);
  162     blocks[ple].p[blocks[ple].cnt] = x;
  163     blocks[ple].cnt++;
  164 } /* FUNCTION putOnTopOfPile */
  165 
  166 void removeFromTopOfPile(int ple)
  167 {
  168     /* FUNCTION removeFromTopOfPile */
  169     blocks[ple].cnt--;
  170 } /* FUNCTION removeFromTopOfPile */
  171 
  172 void ClearPileAbovePoint(LOCATION_STRUCT x)
  173 {
  174     /* FUNCTION ClearPileAbovePoint */
  175     int i;
  176     int tmp;
  177 
  178     for (i=x.depth+1; blocks[x.pile].cnt>i; i++)
  179         {
  180             /* get each value above indicated point */
  181             tmp = blocks[x.pile].p[i];
  182             putOnTopOfPile(tmp, tmp);
  183         } /* get each value above indicated point */
  184     blocks[x.pile].cnt = x.depth + 1;
  185 } /* FUNCTION ClearPileAbovePoint */
  186 
  187 void movePileAbovePoint(LOCATION_STRUCT x, int ple)
  188 {
  189     /* FUNCTION movePileAbovePoint */
  190     int i;
  191     int tmp;
  192 
  193     for (i=x.depth; blocks[x.pile].cnt>i; i++)
  194         {
  195             /* get each value above indicated point */
  196             tmp = blocks[x.pile].p[i];
  197             putOnTopOfPile(tmp, ple);
  198         } /* get each value above indicated point */
  199     blocks[x.pile].cnt = x.depth;
  200 } /* FUNCTION movePileAbovePoint */
  201 
  202 void process()
  203 {
  204     /* FUNCTION process */
  205     LOCATION_STRUCT pa;
  206     LOCATION_STRUCT pb;
  207 
  208     pa = fnd(a);
  209     pb = fnd(b);
  210     if (pa.pile != pb.pile)
  211         {
  212             /* only do somethingif piles are different */
  213             switch (cmd)
  214                 {
  215                     /* switch */
  216                 case MOVE+OVER:
  217                 {
  218                     /* MOVER + OVER */
  219                     /*
  220                      * clear blocks above a
  221                      * clear a
  222                      * put a above b
  223                      */
  224                     ClearPileAbovePoint(pa); /* clears everything from above location */
  225                     removeFromTopOfPile(pa.pile); /* clears pa only -- which mustbe at top */
  226                     putOnTopOfPile(a, pb.pile); /* puts a on top of pb's pile */
  227                     break;
  228                 } /* MOVER + OVER */
  229                 case MOVE+ONTO:
  230                 {
  231                     /* MOVER + ONTO */
  232                     /*
  233                      * clear blocks above a
  234                      * clear a
  235                      * clear blocks above b
  236                      * put a above b
  237                      */
  238                     ClearPileAbovePoint(pa); /* clears everything from above location */
  239                     removeFromTopOfPile(pa.pile); /* clears pa only -- which mustbe at top */
  240                     ClearPileAbovePoint(pb);
  241                     putOnTopOfPile(a, pb.pile); /* puts a on top of pb's pile */
  242                     break;
  243                 } /* MOVER + ONTO */
  244                 case PILE+OVER:
  245                 {
  246                     /* PILE + OVER */
  247                     movePileAbovePoint(pa, pb.pile);
  248                     break;
  249                 } /* PILE + OVER */
  250                 case PILE+ONTO:
  251                 {
  252                     /* PILE + ONTO */
  253                     ClearPileAbovePoint(pb);
  254                     movePileAbovePoint(pa, pb.pile);
  255                     break;
  256                 } /* PILE + ONTO */
  257                 } /* switch */
  258         } /* only do somethingif piles are different */
  259     DEBUG dump();
  260 } /* FUNCTION process */
  261 
  262 int main ()
  263 {
  264     /* main */
  265     int moreToDo;
  266 
  267     init();
  268     moreToDo = getInput();
  269     DEBUG dump();
  270     while (moreToDo)
  271         {
  272             /* while */
  273             process();
  274             moreToDo = getInput();
  275         } /* while */
  276     dump();
  277     return EXIT_SUCCESS;
  278 } /* main */
  279