day 24 optimize
[aoc_eblake.git] / 2018 / day7b.c
blob969d502c1f4123c0bd2d069b16a1fbabdd79862f
1 #define _GNU_SOURCE 1
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdarg.h>
6 #include <stdbool.h>
8 void debug(const char *fmt, ...) {
9 va_list ap;
10 if (getenv("DEBUG")) {
11 va_start(ap, fmt);
12 vfprintf(stderr, fmt, ap);
13 va_end(ap);
17 static struct data {
18 char state;
19 char wait[26];
20 } list[26];
22 int main(int argc, char **argv) {
23 size_t len = 0, count = 0;
24 char *line;
25 int i, j;
26 char a, b;
27 char *p;
28 int offset = 60;
29 int workers = 5;
30 char work[5] = "";
32 /* Part 1 - read in lines */
33 if (argc > 2)
34 offset = atoi(argv[2]);
35 if (argc > 3)
36 workers = atoi(argv[3]);
37 if (argc > 1)
38 if (!(stdin = freopen(argv[1], "r", stdin))) {
39 perror("failure");
40 exit(2);
43 while (getline(&line, &len, stdin) >= 0) {
44 ++count;
45 if (sscanf(line, "Step %c must be finished before step %c can begin. ", &a,
46 &b) != 2 || (unsigned)(a-'A') > 25 || (unsigned)(b-'A') > 25) {
47 fprintf(stderr, "bad input\n");
48 exit(1);
50 list[a - 'A'].state = a - 'A' + 1 + offset;
51 list[b - 'A'].state = b - 'A' + 1 + offset;
52 strchrnul(list[b - 'A'].wait, '\0')[0] = a;
54 printf("Read %zu lines\n", count);
56 /* Part 2 - determine output */
57 count = 0;
58 do {
59 count++;
60 for (j = 0; j < workers; j++)
61 if (work[j])
62 if (!++list[work[j] - 'A'].state)
63 work[j] = 0;
64 for (j = 0; j < workers; j++) {
65 if (work[j])
66 continue;
67 for (i = 0; i < 26; i++) {
68 if (list[i].state <= 0)
69 continue;
70 p = list[i].wait;
71 while (*p) {
72 if (list[*p - 'A'].state)
73 break;
74 p++;
76 if (*p)
77 continue;
78 list[i].state = -list[i].state;
79 work[j] = i + 'A';
80 debug("time %zu worker %d starting job %c\n", count - 1, j, i + 'A');
81 break;
84 } while (work[0] || work[1] || work[2] || work[3] || work[4]);
85 printf("took %zu seconds\n", count - 1);
86 return 0;