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))