-
Notifications
You must be signed in to change notification settings - Fork 0
/
day08.jl
102 lines (86 loc) · 2.45 KB
/
day08.jl
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
function build_instructions(filename)
boot_code = readlines(filename) .|> split
[Pair(first(line), parse(Int, last(line))) for line in boot_code]
end
function interpret_instruction(instruction, argument, accumulator, curr_idx)
if instruction == "acc"
accumulator += argument
new_idx = curr_idx + 1
elseif instruction == "jmp"
new_idx = curr_idx + argument
elseif instruction == "nop"
new_idx = curr_idx + 1
end
(accumulator, new_idx)
end
function main_loop(code)
n_ops = length(code)
curr_idx = 1
accumulator = 0
seen_idx = Set()
state = :unfinished
while true
# See if we've reached final instruction (one outside of bounds)
if curr_idx > n_ops
state = :valid
break
end
# If we have seen this index before, break the loop
if curr_idx in seen_idx
state = :infinite
break
else
push!(seen_idx, curr_idx)
end
# If we have not, execute the instruction and add it's index to those already
# seen
(accumulator, curr_idx) = interpret_instruction(
first(code[curr_idx]),
last(code[curr_idx]),
accumulator,
curr_idx
)
end
(accumulator, state)
end
function change_instructions_till_valid(code)
# Get the indices of jumps and no-ops.
jmps_and_nops_idx = findall(code .|> first .|> x -> (x == "nop") || (x == "jmp"))
# For each location, flip the instruction, test the main loop.
# Break if state is valid
accumulator = NaN
for idx in jmps_and_nops_idx
flipped_code = flip_code(code, idx)
(accumulator, state) = main_loop(flipped_code)
if state == :valid
break
end
end
accumulator
end
function flip_code(code, idx)
op = code[idx]
instruction = first(op)
arg = last(op)
new_code = copy(code)
if instruction == "jmp"
new_code[idx] = Pair("nop", arg)
else
new_code[idx] = Pair("jmp", arg)
end
new_code
end
function main()
# Script
filename = "inputs/day08.txt"
code = build_instructions(filename)
# Part 1
(final_value, state) = main_loop(code)
part1_solution = final_value
# Part 2
part2_solution = change_instructions_till_valid(code)
(part1_solution, part2_solution)
end
@time (part1_solution, part2_solution) = main()
@show part1_solution
@show part2_solution