From e7c9108b95e39d7ea5a29ae06d619c4727f11027 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Fri, 29 Oct 2021 23:02:39 +0200 Subject: Initial commit --- 2020/08/puzzles.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 2020/08/puzzles.c (limited to '2020/08/puzzles.c') diff --git a/2020/08/puzzles.c b/2020/08/puzzles.c new file mode 100644 index 0000000..cfa9389 --- /dev/null +++ b/2020/08/puzzles.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include + +#define LINECOUNT 653 + +struct Inst { + char opp; + int val; +}; + +/* Check if the given instruction has been executed already */ +static bool +repeati(int const * const lines, int const rip) +{ + for (int i = 0; i < LINECOUNT; i++) { + if (lines[i] == rip) + return true; + } + return false; +} + +static int +run_circuit(struct Inst *circuit) +{ + int i, acc, rip; + int lines[LINECOUNT] = {0}; + + i = acc = rip = 0; + + /* Execute the circuit */ + do { + lines[i++] = rip; + switch (circuit[rip].opp) { + case 'j': + rip += circuit[rip].val; + if (rip >= LINECOUNT) + return acc; + break; + case 'a': + acc += circuit[rip].val; + /* FALLTHROUGH */ + case 'n': + rip++; + break; + } + } while (!repeati(lines, rip)); + +#ifdef PART2 + return -1; +#else + return acc; +#endif +} + +int +main(void) +{ + int i = 0; + char cl[10]; + FILE *fp; + struct Inst circuit[LINECOUNT]; + + if (!(fp = fopen("input", "r"))) + err(EXIT_FAILURE, "fopen"); + + /* Load the entire circuit */ + while (fgets(cl, sizeof(cl), fp)) { + char *val; + /* struct Inst operation; */ + + val = strtok(cl, " "); + circuit[i++] = (struct Inst) { + .opp = cl[0], + .val = atoi(strtok(NULL, " ")) + }; + } + fclose(fp); + + int result = -1; +#ifdef PART2 + int count, prev_count; + count = prev_count = 1; + + /* Run circuit until it completes successfully */ + while (result == -1 && count < LINECOUNT) { + for (i = 0; i < LINECOUNT; i++) { + if (circuit[i].opp == 'j' || circuit[i].opp == 'n') + count--; + + /* Swap jmp and nop */ + if (!count) { + circuit[i].opp = (circuit[i].opp == 'j') ? 'n' : 'j'; + break; + } + } + + count = ++prev_count; + result = run_circuit(circuit); + + /* Return to original array */ + circuit[i].opp = (circuit[i].opp == 'j') ? 'n' : 'j'; + } +#else + result = run_circuit(circuit); +#endif + + printf("%d\n", result); + return EXIT_SUCCESS; +} -- cgit v1.2.3