Computer Programming Contest Preparation

ToolBox - Source for: 5/509/e.c



/home/toolbox/public_html/solutions/5/509/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 /*
   16  *  Author: Isaac Traxler
   17  *    Date: 2019-09-19
   18  * Purpose: fun
   19  * Problem: 509
   20  */
   21 
   22 /*
   23  * This template reads data until a terminating value is reached.
   24  */
   25 
   26 #define MAX_DISKS 6
   27 #define MAX_BITS (64 * 100)
   28 #define EVEN 0
   29 #define ODD  1
   30 #define MISSING -1
   31 
   32 int d;       /* number of disks */
   33 int s;       /* block size */
   34 int b;       /* block count */
   35 int width;   /* size * count */
   36 int disk[MAX_DISKS][MAX_BITS];
   37 int parity;  /* 0 for even, 1 for odd */
   38 int flip[2] = {1, 0};  /* used to flip bits */
   39 
   40 void init()
   41 {
   42     /* FUNCTION init */
   43 } /* FUNCTION init */
   44 
   45 void dump()
   46 {
   47     /* FUNCTION dump */
   48 } /* FUNCTION dump */
   49 
   50 int getInput()
   51 {
   52     /* FUNCTION getInput */
   53     int dataReadFlag;
   54     char x;
   55     char line[MAX_BITS+5];
   56     int i;
   57     int j;
   58 
   59     scanf(" %d ", &d);
   60     dataReadFlag = (0 != d);
   61     if (dataReadFlag)
   62         {
   63             /* get disk info */
   64             scanf(" %d %d ", &s, &b);
   65             width = s * b;
   66             scanf("%c ", &x);
   67             if ('E' == x)
   68                 {
   69                     parity = EVEN;
   70                 }
   71             else
   72                 {
   73                     parity = ODD;
   74                 }
   75             DEBUG printf(" d(%d) s(%d) b(%d) width(%d) parity(%c,%d)\n", d, s, b, width, x, parity);
   76             for (i=0; d>i; i++)
   77                 {
   78                     /* process each disk */
   79                     scanf(" %s ", line);
   80                     DEBUG printf("line[%s]\n", line);
   81                     for (j=0; width>j; j++)
   82                         {
   83                             /* for each bit */
   84                             switch (line[j])
   85                                 {
   86                                 /* switch */
   87                                 case '0':
   88                                     disk[i][j] =    EVEN;
   89                                     break;
   90                                 case '1':
   91                                     disk[i][j] =     ODD;
   92                                     break;
   93                                 case 'x':
   94                                     disk[i][j] = MISSING;
   95                                     break;
   96                                 } /* switch */
   97                             DEBUG printf("%2d", disk[i][j]);
   98                         } /* for each bit */
   99                     DEBUG printf("\n");
  100                 } /* process each disk */
  101         } /* get disk info */
  102     return (dataReadFlag);
  103 } /* FUNCTION getInput */
  104 
  105 int fixMissing()
  106 {
  107     /* FUNCTION fixMissing */
  108     int i;
  109     int j;
  110     int bad;  /* index of missing data */
  111     int cnt;  /* number of missing bits */
  112     int par;  /* calculated paroty -- to determine what to replace missing with */
  113     int valid = TRUE;
  114 
  115     DEBUG printf("\n%d\n", disk[2][0]);
  116     for (j=0; ((valid) && (width>j)); j++)
  117         {
  118             /* for each bit */
  119             par = EVEN;
  120             cnt = 0;
  121             for (i=0; ((valid) && (d>i)); i++)
  122                 {
  123                     /* for each disk */
  124                     DEBUG printf("%2d", disk[i][j]);
  125                     switch (disk[i][j])
  126                         {
  127                         /* switch */
  128                         case -1:
  129                             bad = i;
  130                             cnt++;
  131                             break;
  132                         case 0:
  133                             break;  /* do nothing since 0s do not change parity */
  134                         case 1:
  135                             par = flip[par]; /* flip parity since a one encountered */
  136                             break;
  137                         } /* switch */
  138                 } /* for each disk */
  139             DEBUG printf("   bit(%d)  cnt(%d)  parity(%d)  par(%d)", j, cnt, parity, par);
  140             DEBUG printf("\n");
  141             switch (cnt)
  142                 {
  143                 /* switch */
  144                 case 0: /* all bits found -- check parity */
  145                     valid = (par == parity);
  146                     break;
  147                 case 1: /* one missing bit - correct it */
  148                     if (par == parity)
  149                         {
  150                             /* parity right -- put 0 */
  151                             disk[bad][j] = EVEN;
  152                         } /* parity right -- put 0 */
  153                     else
  154                         {
  155                             /* paritys do not match, bit needs to be odd */
  156                             disk[bad][j] = ODD;
  157                             par = parity;
  158                         } /* paritys do not match, bit needs to be odd */
  159                     break;
  160                 default: /* more than 1 missing bit */
  161                     valid = FALSE;
  162                 } /* switch */
  163         } /* for each bit */
  164     return valid;
  165 } /* FUNCTION fixMissing */
  166 
  167 void doHex()
  168 {
  169     /* FUNCTION doHex */
  170     int i;
  171     int ib, is, id;
  172     int hx = 0;
  173     int mult = 8;
  174 
  175     id = 0;
  176     ib = 0;
  177     is = 0;
  178     printf("\n");
  179     for (i=0; (b*d*s)>i; i++)
  180         {
  181             /* for each bit */
  182             DEBUG printf("i(%d)  is(%d)  ib(%d)  id(%d)  d(%d)\n", i, is, ib, id, d);
  183             if ((ib % d) != id)
  184                 {
  185                     /* block is not a parity block */
  186                     printf("hx(%d)   ib(%d)  s(%d)  is(%d)  disk[%d][%d]=%d   mult(%d)\n", hx, ib, s, is, id, ((ib*s)+is), disk[id][(ib*s)+is], mult);
  187                     hx = hx + disk[id][(ib*s)+is] * mult;
  188                     mult = mult / 2;
  189                     if (0 == mult)
  190                         {
  191                             /* all four bits */
  192                             printf("%1X", hx);
  193                             hx = 0;
  194                             mult = 8;
  195                         } /* all four bits */
  196                 } /* block is not a parity block */
  197             is++;
  198             if (s <= is)
  199                 {
  200                     /* end of block */
  201                     is = 0;
  202                     ib++;
  203                     if (0 == (ib % d))
  204                         {
  205                             /* last block of this disk reached */
  206                             id = ((id + 1) % d);
  207                         } /* last block of this disk reached */
  208                 } /* end of block */
  209         } /* for each bit */
  210 
  211     if (8 != mult)
  212         {
  213             /* print partial answer */
  214             printf("%1X", hx);
  215         } /* print partial answer */
  216 } /* FUNCTION doHex */
  217 
  218 
  219 void process()
  220 {
  221     /* FUNCTION process */
  222     int valid;
  223 
  224     if (fixMissing())
  225         {
  226             /* valid disk data */
  227             printf("valid, contents are: ");
  228             doHex();
  229         } /* valid disk data */
  230     else
  231         {
  232             /* unreadable disk */
  233             printf("invalid.");
  234         } /* unreadable disk */
  235     printf("\n");
  236 } /* FUNCTION process */
  237 
  238 int main()
  239 {
  240     /* main */
  241     int moreToDo;
  242     int cnt = 0;
  243 
  244     init();
  245     moreToDo = getInput();
  246     while (moreToDo)
  247         {
  248             /* while */
  249             cnt++;
  250             printf("Disk set %d is ", cnt);
  251             process();
  252             moreToDo = getInput();
  253         } /* while */
  254 
  255     return EXIT_SUCCESS;
  256 } /* main */
  257