Computer Programming Contest Preparation

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



/home/toolbox/public_html/solutions/5/509/b.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 j;
  172     int cnt = -2;
  173     int flag = FALSE; /* false during parity, true during actual data */
  174     int hx = 0;
  175     int mult = 8;
  176 
  177     for (i=0; d>i; i++)
  178         {
  179             /* for each disk */
  180             for (j=0; width>j; j++)
  181                 {
  182                     /* for each bot per disk */
  183                     cnt++;
  184                     printf("flag(%d) cnt(%d)  disk[%d][%d] = %d\n", flag, cnt, i, j, disk[i][j]);
  185                     if (flag)
  186                         {
  187                             /* printable bit */
  188                             hx = hx + disk[i][j] * mult;
  189                             if (1 == mult)
  190                                 {
  191                                     /* all four bits */
  192                                     printf("%1X", hx);
  193                                     hx = 0;
  194                                     mult = 8;
  195                                 } /* all four bits */
  196                             else
  197                                 {
  198                                     /* go on to next bot */
  199                                     mult = mult / 2;
  200                                 } /* go on to next bot */
  201                             if (width == cnt)
  202                                 {
  203                                     /* end of stripe -- shift to parity */
  204                                     flag = FALSE;
  205                                     cnt = -2;
  206                                 } /* end of stripe -- shift to parity */
  207                         } /* printable bit */
  208                     else
  209                         {
  210                             /* skip parity bit */
  211                             if (0 == cnt)
  212                                 {
  213                                     /* time to end parity */
  214                                     flag = TRUE;
  215                                 } /* time to end parity */
  216                         } /* skip parity bit */
  217                 } /* for each disk */
  218         } /* for each bot per disk */
  219     if (8 != mult)
  220         {
  221             /* print partial answer */
  222             printf("%1X", hx);
  223         } /* print partial answer */
  224 } /* FUNCTION doHex */
  225 
  226 
  227 void process()
  228 {
  229     /* FUNCTION process */
  230     int valid;
  231 
  232     if (fixMissing())
  233         {
  234             /* valid disk data */
  235             printf("valid, contents are: ");
  236             doHex();
  237         } /* valid disk data */
  238     else
  239         {
  240             /* unreadable disk */
  241             printf("invalid.");
  242         } /* unreadable disk */
  243     printf("\n");
  244 } /* FUNCTION process */
  245 
  246 int main()
  247 {
  248     /* main */
  249     int moreToDo;
  250     int cnt = 0;
  251 
  252     init();
  253     moreToDo = getInput();
  254     while (moreToDo)
  255         {
  256             /* while */
  257             cnt++;
  258             printf("Disk set %d is ", cnt);
  259             process();
  260             moreToDo = getInput();
  261         } /* while */
  262 
  263     return EXIT_SUCCESS;
  264 } /* main */
  265