Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Combinatorics
- using OffsetArrays
- mutable struct Computer
- mem::OffsetVector{Int, Vector{Int}}
- ptr::Int
- halt::Bool
- end
- Computer(mem::Vector{Int}, ptr = 0, halt = false) =
- Computer(OffsetVector(copy(mem), 0:length(mem) - 1), ptr, halt)
- function (c::Computer)(input...)
- input = collect(input)
- output = Int[]
- mem = c.mem
- modes = zeros(3)
- arg(idx) = modes[idx] == 0 ? mem[mem[c.ptr + idx]] : mem[c.ptr + idx]
- while c.halt == false
- opcode = mem[c.ptr] % 100
- modes .= digits(mem[c.ptr]; pad = 5)[3:end]
- # 1: addition
- if opcode == 1
- mem[mem[c.ptr + 3]] = arg(1) + arg(2)
- c.ptr += 4
- # 2: multiplication
- elseif opcode == 2
- mem[mem[c.ptr + 3]] = arg(1) * arg(2)
- c.ptr += 4
- # 3: input
- elseif opcode == 3
- if isempty(input)
- return output
- else
- mem[mem[c.ptr + 1]] = popfirst!(input)
- c.ptr += 2
- end
- # 4: output
- elseif opcode == 4
- push!(output, mem[mem[c.ptr + 1]])
- c.ptr += 2
- # 5: jump-if-true
- elseif opcode == 5
- if arg(1) != 0
- c.ptr = arg(2)
- else
- c.ptr += 3
- end
- # 6: jump-if-false
- elseif opcode == 6
- if arg(1) == 0
- c.ptr = arg(2)
- else
- c.ptr += 3
- end
- # 7: less than
- elseif opcode == 7
- mem[mem[c.ptr + 3]] = arg(1) < arg(2) ? 1 : 0
- c.ptr += 4
- # 8: equals
- elseif opcode == 8
- mem[mem[c.ptr + 3]] = arg(1) == arg(2) ? 1 : 0
- c.ptr += 4
- # 99: halt
- elseif opcode == 99
- c.halt = true
- return output
- else
- error("Program crashed: $opcode is not a valid opcode")
- end
- end
- end
- struct Amplifier
- computers::Vector{Computer}
- end
- function Amplifier(program::Vector{Int}, phases::Vector{Int})
- computers = [Computer(program) for _ in 1:length(phases)]
- for (c, ph) in zip(computers, phases)
- c(ph)
- end
- return Amplifier(computers)
- end
- function (amp::Amplifier)(signal::Int)
- for computer in amp.computers
- if computer.halt == false
- signal = pop!(computer(signal))
- else
- return nothing
- end
- end
- return signal
- end
- function feddback!(amp::Amplifier, s = 0)
- signal = s
- new_signal = 0
- while !isnothing(new_signal)
- signal = new_signal
- new_signal = amp(signal)
- end
- return signal
- end
- function part1(program)
- return maximum(
- Amplifier(program, phases)(0) for phases in permutations([0, 1, 2, 3, 4])
- )
- end
- function part2(program)
- return maximum(
- feddback!(Amplifier(program, phases)) for phases in permutations([5, 6, 7, 8, 9])
- )
- end
- input = parse.(Int, split(read("input_07.txt", String), ','))
- println("Part 1: ", part1(input))
- println("Part 2: ", part2(input))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement