day 25 solved in C
[aoc_eblake.git] / 2017 / advent23.c
blob4ff7bfedc501c1fda5edd8f59396fef6190b8ef3
1 #define _GNU_SOURCE 1
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <stdbool.h>
7 #include <ctype.h>
9 #if 0
11 typedef struct state state;
12 struct state {
13 long long regs[26];
14 unsigned int pc;
15 int count;
16 int mul;
17 } states;
19 char *program[50]; // sized based on pre-inspecting file
20 int instr;
22 long long
23 get (state *s, const char *value)
25 if (isalpha(*value))
26 return s->regs[*value - 'a'];
27 return atoi (value);
30 void
31 set (state *s, const char *reg, long long value)
33 s->regs[*reg - 'a'] = value;
34 if (getenv ("DEBUG"))
35 printf (" %s=%lld\n", reg, value);
38 bool
39 run (state *s, int id)
41 while (s->pc < instr) {
42 char arg1[10], arg2[10];
43 if (getenv ("DEBUG"))
44 printf ("p%d instr %d at pc %d: %s\n", id, s->count, s->pc,
45 program[s->pc]);
46 if (!(s->count % 10000))
47 printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%10d h=%lld", s->count,
48 s->regs['h' - 'a']);
49 if (s->pc == 8) {
50 printf ("\nstarting computation at count %d,", s->count);
51 for (int i = 'a'; i <= 'h'; i++)
52 printf (" %c=%lld", i, s->regs[i - 'a']);
53 printf ("\n");
55 sscanf (program[s->pc], "%*s %9s %9s", arg1, arg2);
56 switch ((program[s->pc][0] << 8) + program[s->pc][1]) {
57 case ('s' << 8) + 'e': // set X Y
58 set (s, arg1, get (s, arg2));
59 break;
60 case ('s' << 8) + 'u': // sub X Y
61 set (s, arg1, get (s, arg1) - get (s, arg2));
62 break;
63 case ('a' << 8) + 'd': // add X Y
64 set (s, arg1, get (s, arg1) + get (s, arg2));
65 break;
66 case ('m' << 8) + 'u': // mul X Y
67 s->mul++;
68 set (s, arg1, get (s, arg1) * get (s, arg2));
69 break;
70 case ('m' << 8) + 'o': // mod X Y
71 set (s, arg1, get (s, arg1) % get (s, arg2));
72 break;
73 case ('j' << 8) + 'n': // jnz X Y
74 if (get (s, arg1))
75 s->pc += get (s, arg2) - 1;
76 break;
77 default:
78 return 1;
80 s->count++;
81 s->pc++;
83 return false;
86 int main(int argc, char **argv)
88 char buf[400]; // sized based on pre-inspecting file
89 int nread = fread (buf, 1, sizeof buf, stdin);
90 char *p = buf;
91 while (p < buf + nread) {
92 program[instr++] = p;
93 p = strchr (p, '\n');
94 *p++ = '\0';
96 printf ("program consists of %d instructions\n", instr);
97 states.regs[0] = 1;
98 if (argc > 1)
99 states.regs[0] = atoi (argv[1]);
100 if (argc > 2) {
101 states.regs[1] = atoi (argv[2]);
102 states.pc = 2;
104 if (argc > 3)
105 states.regs[2] = atoi (argv[3]);
106 run (&states, 0);
107 printf ("\nafter %d operations, reg h is %lld\n", states.count,
108 states.regs['h' - 'a']);
109 return 0;
112 #else
114 int main(int argc, char **argv)
116 int a = 1, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
117 bool skip_a = false;
118 if (argc > 1)
119 a = atoi (argv[1]);
120 if (argc > 2) {
121 b = atoi (argv[2]);
122 skip_a = true;
124 if (argc > 3)
125 c = atoi (argv[3]);
126 if (skip_a)
127 goto l9;
129 l1: // set b 57
130 b = 57;
131 l2: // set c b
132 c = b;
133 l3: // jnz a 2
134 if (a)
135 goto l5;
136 l4: // jnz 1 5
137 goto l9;
138 l5: // mul b 100
139 b *= 100;
140 l6: // sub b -100000
141 b -= -100000;
142 l7: // set c b
143 c = b;
144 l8: // sub c -17000
145 c -= -17000;
146 l9: // set f 1
147 f = 1;
148 l10: // set d 2
149 d = 2;
150 l11: // set e 2
151 e = 2;
152 l12: // set g d
153 g = d;
154 l13: // mul g e
155 g *= e;
156 l14: // sub g b
157 g -= b;
158 l15: // jnz g 2
159 if (g)
160 goto l17;
161 l16: // set f 0
162 printf ("b=%d c=%d d=%d e=%d f=%d g=%d h=%d\n", b, c, d, e, f, g, h);
163 f = 0;
164 l17: // sub e -1
165 e -= -1;
166 l18: // set g e
167 g = e;
168 l19: // sub g b
169 g -= b;
170 l20: // jnz g -8
171 if (g)
172 goto l12;
173 l21: // sub d -1
174 d -= -1;
175 l22: // set g d
176 g = d;
177 l23: // sub g b
178 g -= b;
179 l24: // jnz g -13
180 if (g)
181 goto l11;
182 l25: // jnz f 2
183 if (f)
184 goto l27;
185 l26: // sub h -1
186 printf (" b=%d c=%d d=%d e=%d f=%d g=%d h=%d\n", b, c, d, e, f, g, h);
187 h -= -1;
188 l27: // set g b
189 g = b;
190 l28: // sub g c
191 g -= c;
192 l29: // jnz g 2
193 if (g)
194 goto l31;
195 l30: // jnz 1 3
196 goto end;
197 l31: // sub b -17
198 b -= -17;
199 l32: // jnz 1 -23
200 goto l9;
201 end:
202 printf ("final value of h: %d\n", h);
205 #endif