day 17 generic† solution

† mostly, subject to a few broad assumptions
main
magical 2024-12-17 16:38:38 +00:00
parent 7fcfd8fcb6
commit d1a2b1eeb1
1 changed files with 85 additions and 0 deletions

85
day17/sol3.c 100644
View File

@ -0,0 +1,85 @@
#include <stdio.h>
int prog[] = {2,4,1,1,7,5,4,4,1,4,0,3,5,5,3,0};
int plen = sizeof(prog) / sizeof(int);
int run(long a, int i, int print) {
long b = 0;
long c = 0;
int ip;
for (ip = 0; ip+2 <= plen; ip += 2) {
int op = prog[ip];
long r = prog[ip+1];
if (op != 1 && op != 3 && op != 4 && r > 3) {
// combo op
if (r == 4) {
r = a;
} else if (r == 5) {
r = b;
} else if (r == 6) {
r = c;
} else if (r >= 7) {
return -1; // invalid
}
}
switch(op) {
case 0: a = a >> r; break; // adv
case 6: b = a >> r; break; // bdv
case 7: c = a >> r; break; // cdv
case 1: b ^= r; break; // bxl
case 2: b = r % 8; break; // bst
case 4: b ^= c; break; // bxc
case 3: if (a != 0) ip = r-2; break; // jnz
case 5: // out
int o = r % 8;
if (print) {
printf("%d ", o);
} else {
if (o != prog[i++]) {
return -2;
}
}
break;
default:
return -1; //invalid
}
}
if (print) printf("\b\n");
return 0;
}
// assumptions:
// - the whole program is a loop
// - 'a' is decoded 3 bits at a time
// - output only affected by higher bits, not lower bits
long reverse(long init, int i) {
if (i < 0) {
return init;
}
for (int b = 0; b < 8; b++) {
long a = init<<3 | b;
if (run(a, i, 0) == 0) {
printf("# %lo\n", a);
long ret = reverse(a, i-1);
if (ret >= 0) {
return ret;
}
}
}
//error
return -3;
}
int main() {
run(46337277, 0, 1);
run(202991746427434L, 0, 1);
long a = reverse(0, plen-1);
printf("%ld\n", a);
if (a >= 0) {
printf("%d\n", run(a, 0, 1));
}
return 0;
}