Computer Programming Contest Preparation

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



/home/toolbox/public_html/solutions/5/509/d.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     for (ib=0; b>ib; ib++)
  177         {
  178             /* loop for each block */
  179             for (is=0; s>is; is++)
  180                 {
  181                     /* go across each block */
  182                     printf("ib(%d)  is(%d)  id(%d) disk[%d][%d] = %d\n", ib, is, id, id, (ib*s)+is, disk[id][(ib*s)+is]);
  183                     if ((ib % d) != id)
  184                         {
  185                             /* printable bit */
  186                             hx = hx + disk[id][(ib*s)+is] * mult;
  187                             if (1 == mult)
  188                                 {
  189                                     /* all four bits */
  190                                     printf("%1X", hx);
  191                                     hx = 0;
  192                                     mult = 8;
  193                                 } /* all four bits */
  194                             else
  195                                 {
  196                                     /* go on to next bot */
  197                                     mult = mult / 2;
  198                                 } /* go on to next bot */
  199                         } /* printable bit */
  200                 } /* go across each block */
  201             id = (id++) % d;
  202         } /* loop for each block */
  203 
  204 
  205     if (8 != mult)
  206         {
  207             /* print partial answer */
  208             printf("%1X", hx);
  209         } /* print partial answer */
  210 } /* FUNCTION doHex */
  211 
  212 
  213 void process()
  214 {
  215     /* FUNCTION process */
  216     int valid;
  217 
  218     if (fixMissing())
  219         {
  220             /* valid disk data */
  221             printf("valid, contents are: ");
  222             doHex();
  223         } /* valid disk data */
  224     else
  225         {
  226             /* unreadable disk */
  227             printf("invalid.");
  228         } /* unreadable disk */
  229     printf("\n");
  230 } /* FUNCTION process */
  231 
  232 int main()
  233 {
  234     /* main */
  235     int moreToDo;
  236     int cnt = 0;
  237 
  238     init();
  239     moreToDo = getInput();
  240     while (moreToDo)
  241         {
  242             /* while */
  243             cnt++;
  244             printf("Disk set %d is ", cnt);
  245             process();
  246             moreToDo = getInput();
  247         } /* while */
  248 
  249     return EXIT_SUCCESS;
  250 } /* main */
  251