1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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;
}
|