day-07.jl (6209B)
1 function computer(program, input)
2 program = copy(program)
3 input = copy(input)
4 output = []
5 pc = 1
6 while true
7 pc, finished, step_output = computer_step!(
8 program, pc,
9 isempty(input) ? nothing : popfirst!(input)
10 )
11 # println(finished, " ", step_output)
12 append!(output, step_output)
13 if finished
14 break
15 end
16 end
17 output
18 end
19
20 function computer_step!(program, pc, input)
21 # Runs from given pc until completion or next request for input.
22 # Modifies program and pc.
23 # Returns if the program has terminated and the output.
24 output = []
25 get_param(loc, im_mode) = (im_mode ? program[loc] : program[program[loc] + 1])
26 while true
27 op_code = program[pc] % 100
28 im_mode_1 = (program[pc] % 1000) ÷ 100 > 0;
29 im_mode_2 = (program[pc] % 10000) ÷ 1000 > 0;
30 if op_code == 1
31 program[program[pc + 3] + 1] = (
32 get_param(pc + 1, im_mode_1)
33 + get_param(pc + 2, im_mode_2)
34 )
35 pc += 4
36 elseif op_code == 2
37 program[program[pc + 3] + 1] = (
38 get_param(pc + 1, im_mode_1)
39 * get_param(pc + 2, im_mode_2)
40 )
41 pc += 4
42 elseif op_code == 3
43 if !isnothing(input)
44 program[program[pc + 1] + 1] = input
45 input = nothing
46 else
47 return (pc, false, output)
48 end
49 pc += 2
50 elseif op_code == 4
51 push!(output, get_param(pc + 1, im_mode_1))
52 pc += 2
53 elseif op_code == 5
54 if get_param(pc + 1, im_mode_1) != 0
55 pc = get_param(pc + 2, im_mode_2) + 1
56 else
57 pc += 3;
58 end
59 elseif op_code == 6
60 if get_param(pc + 1, im_mode_1) == 0
61 pc = get_param(pc + 2, im_mode_2) + 1
62 else
63 pc += 3;
64 end
65 elseif op_code == 7
66 program[program[pc + 3] + 1] = (
67 get_param(pc + 1, im_mode_1)
68 < get_param(pc + 2, im_mode_2)
69 ) ? 1 : 0;
70 pc += 4;
71 elseif op_code == 8
72 program[program[pc + 3] + 1] = (
73 get_param(pc + 1, im_mode_1)
74 == get_param(pc + 2, im_mode_2)
75 ) ? 1 : 0;
76 pc += 4;
77 elseif op_code == 99
78 break
79 else
80 println("Unknown op code: ", op_code)
81 break
82 end
83 end
84 (pc, true, output)
85 end
86
87 function feedback_amp(program, phase)
88 num_amps = length(phase)
89 programs = repeat([copy(program)], num_amps)
90 pcs = repeat([1], num_amps)
91 inputs = map(x -> [x], phase)
92 # Additional input for first amplifier.
93 push!(inputs[1], 0)
94 # Index of currently working amp.
95 work_idx = 1
96 while true
97 # Run current amp.
98 pcs[work_idx], finished, step_output = computer_step!(
99 programs[work_idx],
100 pcs[work_idx],
101 popfirst!(inputs[work_idx])
102 )
103 # Pipe output to next amp.
104 work_idx_next = work_idx + 1 - (work_idx + 1) ÷ (num_amps + 1) * num_amps
105 append!(inputs[work_idx_next], step_output)
106 # Check for completion.
107 if finished && work_idx == num_amps
108 break
109 end
110 # Move to next amp.
111 work_idx = work_idx_next
112 end
113 inputs[1][end]
114 end
115
116 function part_1(input)
117 max_output = 0
118 for phase_1 in 0:4
119 out_1 = computer(input, [phase_1, 0])[end]
120 for phase_2 in 0:4
121 if phase_2 == phase_1
122 continue
123 end
124 out_2 = computer(input, [phase_2, out_1])[end]
125 for phase_3 in 0:4
126 if phase_3 == phase_2 || phase_3 == phase_1
127 continue
128 end
129 out_3 = computer(input, [phase_3, out_2])[end]
130 for phase_4 in 0:4
131 if phase_4 == phase_1 || phase_4 == phase_2 || phase_4 == phase_3
132 continue
133 end
134 out_4 = computer(input, [phase_4, out_3])[end]
135 for phase_5 in 0:4
136 if (
137 phase_5 == phase_1
138 || phase_5 == phase_2
139 || phase_5 == phase_3
140 || phase_5 == phase_4
141 )
142 continue
143 end
144 out_5 = computer(input, [phase_5, out_4])[end]
145 max_output = max(max_output, out_5)
146 end
147 end
148 end
149 end
150 end
151 max_output
152 end
153
154 function part_2(input)
155 max_output = 0
156 for phase_1 in 5:9
157 for phase_2 in 5:9
158 if phase_2 == phase_1
159 continue
160 end
161 for phase_3 in 5:9
162 if phase_3 == phase_2 || phase_3 == phase_1
163 continue
164 end
165 for phase_4 in 5:9
166 if phase_4 == phase_1 || phase_4 == phase_2 || phase_4 == phase_3
167 continue
168 end
169 for phase_5 in 5:9
170 if (
171 phase_5 == phase_1
172 || phase_5 == phase_2
173 || phase_5 == phase_3
174 || phase_5 == phase_4
175 )
176 continue
177 end
178 max_output = max(
179 max_output,
180 feedback_amp(
181 input,
182 [phase_1, phase_2, phase_3, phase_4, phase_5]
183 )
184 )
185 end
186 end
187 end
188 end
189 end
190 max_output
191 end
192
193 input = map(x -> parse(Int32, x), split(readlines(open("input.txt"))[1], ','))
194
195 println("Julia:")
196 println("Part 1: ", part_1(input))
197 println("Part 2: ", part_2(input))