/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