#include 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; }