10 void debug(const char *fmt
, ...) {
12 if (getenv("DEBUG")) {
14 vfprintf(stderr
, fmt
, ap
);
29 static unsigned int max
;
31 static int lookup(const char *opcode
) {
34 return opcode
[3] == 'i';
36 return 2 + (opcode
[3] == 'i');
38 return 4 + 2 * (opcode
[1] == 'o') + (opcode
[3] == 'i');
40 return 8 + (opcode
[3] == 'i');
42 return 10 + (opcode
[2] == 'r') + (opcode
[3] == opcode
[2]);
44 return 13 + (opcode
[2] == 'r') + (opcode
[3] == opcode
[2]);
46 fprintf(stderr
, "failed decoding instruction %s\n", opcode
);
50 static int get(int r
) {
51 assert(0 <= r
&& r
< sizeof regs
/ sizeof *regs
);
55 static void set(int r
, int v
) {
56 assert(0 <= r
&& r
< sizeof regs
/ sizeof *regs
);
58 assert(v
>= 0 || !"resize regs to be larger type");
61 static const char *step(int op
, int a
, int b
, int c
) {
64 set(c
, get(a
) + get(b
)); return "addr";
66 set(c
, get(a
) + b
); return "addi";
68 set(c
, get(a
) * get(b
)); return "mulr";
70 set(c
, get(a
) * b
); return "muli";
72 set(c
, get(a
) & get(b
)); return "banr";
74 set(c
, get(a
) & b
); return "bani";
76 set(c
, get(a
) | get(b
)); return "borr";
78 set(c
, get(a
) | b
); return "bori";
80 set(c
, get(a
)); return "setr";
82 set(c
, a
); return "seti";
84 set(c
, a
> get(b
)); return "gtir";
86 set(c
, get(a
) > b
); return "gtri";
88 set(c
, get(a
) > get(b
)); return "gtrr";
90 set(c
, a
== get(b
)); return "eqir";
92 set(c
, get(a
) == b
); return "eqri";
94 set(c
, get(a
) == get(b
)); return "eqrr";
100 int main(int argc
, char **argv
) {
101 size_t len
= 0, count
= 0;
105 /* Part 1 - read in entire program */
107 regs
[0] = atoi(argv
[2]);
108 if (argc
> 1 && !(stdin
= freopen(argv
[1], "r", stdin
))) {
113 if (getline(&line
, &len
, stdin
) < 0 ||
114 sscanf(line
, "#ip %hhu\n", &ip
) != 1) {
115 fprintf(stderr
, "missing #ip line\n");
118 while (getline(&line
, &len
, stdin
) > 0) {
119 program
= reallocarray(program
, ++count
, sizeof *program
);
120 o
= &program
[count
- 1];
121 o
->op
= lookup(line
);
122 if (sscanf(line
+ 5, "%d %d %d\n", &o
->a
, &o
->b
, &o
->c
) != 3) {
123 fprintf(stderr
, "corrupt program\n");
128 printf("program has %u instructions\n", max
= count
);
130 /* Part 2 - run it */
132 while (regs
[ip
] < max
) {
133 bool d
= regs
[ip
] == 7;
135 if (!(count
% 1000000))
136 printf("%8zu...\n", count
);
138 debug("%5d: ip=%d [%d, %d, %d, %d, %d, %d] ", count
, regs
[ip
], regs
[0],
139 regs
[1], regs
[2], regs
[3], regs
[4], regs
[5]);
141 o
= &program
[regs
[ip
]];
142 s
= step(o
->op
, o
->a
, o
->b
, o
->c
);
144 debug("%s %d %d %d ", s
, o
->a
, o
->b
, o
->c
);
147 debug("[%d, %d, %d, %d, %d, %d] (%d)\n", regs
[0], regs
[1], regs
[2],
148 regs
[3], regs
[4], regs
[5], o
->visited
);
151 printf("completed execution after %zu steps, reg 0 contains %d, 5 is %d\n",
152 count
, regs
[0], regs
[5]);
153 for (int i
= 0; i
< max
; i
++) {
155 printf("program line %s %d %d %d executed %d times\n",
156 step(o
->op
, 0, 0, 0), o
->a
, o
->b
, o
->c
, o
->visited
);