cleanup
[advent21.git] / 08b.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include <stdbool.h>
6 #include <ctype.h>
7
8 #define INPUT_SIZE 10
9 #define OUTPUT_SIZE 4
10
11 // 000
12 // 1 2
13 // 1 2
14 // 333
15 // 4 5
16 // 4 5
17 // 666
18
19 void chars_keep(char *s, char *ks)
20 {
21 int i = 0;
22 int len = strlen(s);
23 for (int j = 0; j<len; j++)
24 if (strchr(ks, s[j]) != NULL)
25 s[i++] = s[j];
26
27 s[i] = '\0';
28 }
29
30 void chars_remove(char *s, char *rs)
31 {
32 int i = 0;
33 int len = strlen(s);
34 for (int j = 0; j<len; j++)
35 if (strchr(rs, s[j]) == NULL)
36 s[i++] = s[j];
37 s[i] = '\0';
38 }
39
40 int char_cmp(const void *l, const void *r)
41 {
42 return *(const char *)l-*(const char *)r;
43 }
44
45 int calculate(char input[INPUT_SIZE][8], char output[OUTPUT_SIZE][8])
46 {
47 char mapping[7][8] = {"abcdefg" ,"abcdefg" ,"abcdefg" ,"abcdefg" ,"abcdefg" ,"abcdefg" ,"abcdefg"};
48 // find mapping
49 for (int i = 0; i<INPUT_SIZE; i++) {
50 switch(strlen(input[i])) {
51 // 1
52 case 2:
53 chars_remove(mapping[0], input[i]);
54 chars_remove(mapping[1], input[i]);
55 chars_keep(mapping[2], input[i]);
56 chars_remove(mapping[3], input[i]);
57 chars_remove(mapping[4], input[i]);
58 chars_keep(mapping[5], input[i]);
59 chars_remove(mapping[6], input[i]);
60 break;
61 // 7
62 case 3:
63 chars_keep(mapping[0], input[i]);
64 chars_remove(mapping[1], input[i]);
65 chars_keep(mapping[2], input[i]);
66 chars_remove(mapping[3], input[i]);
67 chars_remove(mapping[4], input[i]);
68 chars_keep(mapping[5], input[i]);
69 chars_remove(mapping[6], input[i]);
70 break;
71 // 4
72 case 4:
73 chars_remove(mapping[0], input[i]);
74 chars_keep(mapping[1], input[i]);
75 chars_keep(mapping[2], input[i]);
76 chars_keep(mapping[3], input[i]);
77 chars_remove(mapping[4], input[i]);
78 chars_keep(mapping[5], input[i]);
79 chars_remove(mapping[6], input[i]);
80 break;
81 // 2, 3 or 5
82 case 5:
83 //No shared empties
84 //keep 0 3 6
85 chars_keep(mapping[0], input[i]);
86 chars_keep(mapping[3], input[i]);
87 chars_keep(mapping[6], input[i]);
88 break;
89 // 0, 6 or 9
90 case 6:
91 //No shared empties
92 //keep 0156
93 chars_keep(mapping[0], input[i]);
94 chars_keep(mapping[1], input[i]);
95 chars_keep(mapping[5], input[i]);
96 chars_keep(mapping[6], input[i]);
97 break;
98 // 8
99 case 7:
100 //No empties
101 //keep 0123456
102 chars_keep(mapping[0], input[i]);
103 chars_keep(mapping[1], input[i]);
104 chars_keep(mapping[2], input[i]);
105 chars_keep(mapping[3], input[i]);
106 chars_keep(mapping[4], input[i]);
107 chars_keep(mapping[5], input[i]);
108 chars_keep(mapping[6], input[i]);
109 break;
110 }
111 }
112 for (int i = 0; i<7; i++)
113 if (strlen(mapping[i]) == 1)
114 for (int j = 0; j<7; j++)
115 if (i != j)
116 chars_remove(mapping[j], mapping[i]);
117
118 //Apply mapping
119 int r = 0;
120 for (int i = 0; i<OUTPUT_SIZE; i++) {
121 for (char *p = &output[i][0]; *p != '\0'; p++) {
122 for (int j = 0; j<7; j++) {
123 if (mapping[j][0] == *p) {
124 *p = 'a'+j;
125 break;
126 }
127 }
128 }
129 qsort(output[i], strlen(output[i]), 1, &char_cmp);
130 r*=10;
131 if (strcmp(output[i], "abcefg") == 0) ;
132 else if (strcmp(output[i], "cf") == 0) r += 1;
133 else if (strcmp(output[i], "acdeg") == 0) r += 2;
134 else if (strcmp(output[i], "acdfg") == 0) r += 3;
135 else if (strcmp(output[i], "bcdf") == 0) r += 4;
136 else if (strcmp(output[i], "abdfg") == 0) r += 5;
137 else if (strcmp(output[i], "abdefg") == 0) r += 6;
138 else if (strcmp(output[i], "acf") == 0) r += 7;
139 else if (strcmp(output[i], "abcdefg") == 0) r += 8;
140 else if (strcmp(output[i], "abcdfg") == 0) r += 9;
141 else
142 printf("unknown sequence: %s\n", output[i]);
143 }
144
145 return r;
146 }
147
148 int main()
149 {
150 char *buf = NULL;
151 size_t len = 0;
152 int r = 0;
153
154 while (getline(&buf, &len, stdin) != -1) {
155 char input[INPUT_SIZE][8];
156 char output[OUTPUT_SIZE][8];
157 int i = 0;
158 char *p = strtok(buf, " ");
159 bool inoutput = false;
160 strcpy(input[i++], p);
161 while ((p = strtok(NULL, " ")) != NULL) {
162 if (strcmp(p, "|") == 0) {
163 inoutput = true;
164 } else if (inoutput) {
165 if (p[strlen(p)-1] == '\n')
166 p[strlen(p)-1] = '\0';
167 strcpy(output[(i++ % INPUT_SIZE)], p);
168 } else {
169 strcpy(input[i++], p);
170 }
171 }
172
173 r += calculate(input, output);
174
175 }
176 printf("%d\n", r);
177 }