#include #include #include #include int main(int argc, char ** argv) { int part = 1, cyclelimit = 220; int cycle; char buf[BUFSIZ]; char * op, * arg; int opcycles = 0; int rx = 1, nextread = 20, interval = 40, total = 0; while ((cycle = getopt(argc, argv, "p:")) != -1) { switch (cycle) { case 'p': part = atoi(optarg); switch (part) { case 1: cyclelimit = 220; break; case 2: cyclelimit = 1000; break; default: fprintf(stderr, "Unexpected part: %d\n", part); return -1; } break; default: return -1; } } for (cycle = 1; cycle <= cyclelimit; ++cycle) { // Start of cycle. Do we need to read a new instruction? if (opcycles == 0) { char * toksave = NULL; if (!fgets(buf, sizeof(buf), stdin)) break; op = strtok_r(buf, " \n", &toksave); arg = strtok_r(NULL, "\n", &toksave); // Just read instruction. Set op cycle count, and // perform any immediate actions if (strcmp(op, "noop") == 0 && !arg) { opcycles = 1; } else if (strcmp(op, "addx") == 0 && arg) { opcycles = 2; } else { fprintf(stderr, "Unexpected op/arg: %s/%s\n", op, arg ? arg : "(null)"); return -1; } } // Mid-cycle debugger attachment. if (part == 1 && cycle >= nextread) { total += rx * cycle; nextread += interval; } // Mid-cycle CRT output. if (part == 2) { int pixel = (cycle - 1) % interval; int insprite = pixel >= rx - 1 && pixel <= rx + 1; fputc(insprite ? '#' : '.', stdout); if (pixel == interval - 1) fputc('\n', stdout); } // Perform cycle. Reduce opcycle count, do actions that occur on // op completion and increment cycle counter. --opcycles; if (opcycles == 0) { if (strcmp(op, "addx") == 0) { rx += atoi(arg); } } } if (part == 1) printf("Sum of interesting signal strengths: %d\n", total); return 0; }