diff options
author | Thomas Voss <thomasvoss@live.com> | 2021-10-29 23:02:39 +0200 |
---|---|---|
committer | Thomas Voss <thomasvoss@live.com> | 2021-10-29 23:02:39 +0200 |
commit | e7c9108b95e39d7ea5a29ae06d619c4727f11027 (patch) | |
tree | 237261eef3afd0720be77dbcbb9599fa66a24b67 /2020/08/puzzles.c |
Initial commit
Diffstat (limited to '2020/08/puzzles.c')
-rw-r--r-- | 2020/08/puzzles.c | 112 |
1 files changed, 112 insertions, 0 deletions
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 <err.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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; +} |