day 8 fix for POSIX
[aoc_eblake.git] / 2017 / advent8.c
blob135251fcd046e286a8791e3f16fef1613c5eec2f
1 #define _GNU_SOURCE 1
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <unistd.h>
7 // cheat - pre-examined input to learn max name length (3+NUL)
8 #define MAXNAME 4
10 typedef struct reg reg;
11 struct reg {
12 char name[MAXNAME];
13 int value;
14 reg *next;
16 reg *list;
18 static int
19 get(const char *name)
21 for (reg *iter = list; iter; iter = iter->next)
22 if (!strcmp (iter->name, name))
23 return iter->value;
24 reg *r = calloc (1, sizeof *r);
25 strcpy (r->name, name); // safe because of max name
26 r->next = list;
27 list = r;
28 return 0;
31 static int
32 set(const char *name, int adjust)
34 if (getenv ("DEBUG"))
35 printf(" adjusting %s by %d\n", name, adjust);
36 for (reg *iter = list; iter; iter = iter->next)
37 if (!strcmp (iter->name, name)) {
38 iter->value += adjust;
39 return iter->value;
41 reg *r = calloc (1, sizeof *r);
42 strcpy (r->name, name); // safe because of max name
43 r->value = adjust;
44 r->next = list;
45 list = r;
46 return adjust;
49 int main(void)
51 char d[MAXNAME], s[MAXNAME], dir, op[3];
52 int adjust, v;
53 int count = 0;
54 int high = 0;
55 // ugly, but works because our data is sane
56 while (scanf("%3[a-z] %c%*[ne]c %d if %3[a-z] %2[><!=] %d\n",
57 d, &dir, &adjust, s, op, &v) == 6) {
58 switch (dir) {
59 case 'i':
60 break;
61 case 'd':
62 adjust = -adjust;
63 break;
64 default:
65 return 2;
67 int r = get (s);
68 if (getenv("DEBUG"))
69 printf("%s %d if %s (%d) %s %d\n", d, adjust, s, r, op, v);
70 count++;
71 int doit = 0;
72 switch (op[0] + op[1]) {
73 case '>':
74 if (r > v)
75 doit = 1;
76 break;
77 case '<':
78 if (r < v)
79 doit = 1;
80 break;
81 case '>' + '=':
82 if (r >= v)
83 doit = 1;
84 break;
85 case '<' + '=':
86 if (r <= v)
87 doit = 1;
88 break;
89 case '=' + '=':
90 if (r == v)
91 doit = 1;
92 break;
93 case '!' + '=':
94 if (r != v)
95 doit = 1;
96 break;
97 default:
98 return 3;
100 if (doit) {
101 v = set(d, adjust);
102 if (v > high)
103 high = v;
106 printf("parsed %d lines\n", count);
107 int max = 0;
108 for (reg *iter = list; iter; iter = iter->next)
109 if (iter->value > max)
110 max = iter->value;
111 printf("largest register contains %d\n", max);
112 printf("largest value seen %d\n", high);
113 return 0;