/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