aboutsummaryrefslogtreecommitdiff
path: root/2020/08/puzzles.c
diff options
context:
space:
mode:
authorThomas Voss <thomasvoss@live.com> 2021-10-29 23:02:39 +0200
committerThomas Voss <thomasvoss@live.com> 2021-10-29 23:02:39 +0200
commite7c9108b95e39d7ea5a29ae06d619c4727f11027 (patch)
tree237261eef3afd0720be77dbcbb9599fa66a24b67 /2020/08/puzzles.c
Initial commit
Diffstat (limited to '2020/08/puzzles.c')
-rw-r--r--2020/08/puzzles.c112
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;
+}