Advertisement
Guest User

Julia AoC 2019 Day 7

a guest
Dec 7th, 2019
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 3.13 KB | None | 0 0
  1. using Combinatorics
  2. using OffsetArrays
  3.  
  4. mutable struct Computer
  5.     mem::OffsetVector{Int, Vector{Int}}
  6.     ptr::Int
  7.     halt::Bool
  8. end
  9.  
  10. Computer(mem::Vector{Int}, ptr = 0, halt = false) =
  11.     Computer(OffsetVector(copy(mem), 0:length(mem) - 1), ptr, halt)
  12.  
  13. function (c::Computer)(input...)
  14.     input = collect(input)
  15.     output = Int[]
  16.     mem = c.mem
  17.     modes = zeros(3)
  18.  
  19.     arg(idx) = modes[idx] == 0 ? mem[mem[c.ptr + idx]] : mem[c.ptr + idx]
  20.  
  21.     while c.halt == false
  22.         opcode = mem[c.ptr] % 100
  23.         modes .= digits(mem[c.ptr]; pad = 5)[3:end]
  24.  
  25.         # 1: addition
  26.         if opcode == 1
  27.             mem[mem[c.ptr + 3]] = arg(1) + arg(2)
  28.             c.ptr += 4
  29.         # 2: multiplication
  30.         elseif opcode == 2
  31.             mem[mem[c.ptr + 3]] = arg(1) * arg(2)
  32.             c.ptr += 4
  33.         # 3: input
  34.         elseif opcode == 3
  35.             if isempty(input)
  36.                 return output
  37.             else
  38.                 mem[mem[c.ptr + 1]] = popfirst!(input)
  39.                 c.ptr += 2
  40.             end
  41.         # 4: output
  42.         elseif opcode == 4
  43.             push!(output, mem[mem[c.ptr + 1]])
  44.             c.ptr += 2
  45.         # 5: jump-if-true
  46.         elseif opcode == 5
  47.             if arg(1) != 0
  48.                 c.ptr = arg(2)
  49.             else
  50.                 c.ptr += 3
  51.             end
  52.         # 6: jump-if-false
  53.         elseif opcode == 6
  54.             if arg(1) == 0
  55.                 c.ptr = arg(2)
  56.             else
  57.                 c.ptr += 3
  58.             end
  59.         # 7: less than
  60.         elseif opcode == 7
  61.             mem[mem[c.ptr + 3]] = arg(1) < arg(2) ? 1 : 0
  62.             c.ptr += 4
  63.         # 8: equals
  64.         elseif opcode == 8
  65.             mem[mem[c.ptr + 3]] = arg(1) == arg(2) ? 1 : 0
  66.             c.ptr += 4
  67.         # 99: halt
  68.         elseif opcode == 99
  69.             c.halt = true
  70.             return output
  71.         else
  72.             error("Program crashed: $opcode is not a valid opcode")
  73.         end
  74.     end
  75. end
  76.  
  77. struct Amplifier
  78.     computers::Vector{Computer}
  79. end
  80.  
  81. function Amplifier(program::Vector{Int}, phases::Vector{Int})
  82.     computers = [Computer(program) for _ in 1:length(phases)]
  83.     for (c, ph) in zip(computers, phases)
  84.         c(ph)
  85.     end
  86.     return Amplifier(computers)
  87. end
  88.  
  89. function (amp::Amplifier)(signal::Int)
  90.     for computer in amp.computers
  91.         if computer.halt == false
  92.             signal = pop!(computer(signal))
  93.         else
  94.             return nothing
  95.         end
  96.     end
  97.     return signal
  98. end
  99.  
  100. function feddback!(amp::Amplifier, s = 0)
  101.     signal = s
  102.     new_signal = 0
  103.     while !isnothing(new_signal)
  104.         signal = new_signal
  105.         new_signal = amp(signal)
  106.     end
  107.     return signal
  108. end
  109.  
  110. function part1(program)
  111.     return maximum(
  112.         Amplifier(program, phases)(0) for phases in permutations([0, 1, 2, 3, 4])
  113.     )
  114. end
  115.  
  116. function part2(program)
  117.     return maximum(
  118.         feddback!(Amplifier(program, phases)) for phases in permutations([5, 6, 7, 8, 9])
  119.     )
  120. end
  121.  
  122. input = parse.(Int, split(read("input_07.txt", String), ','))
  123. println("Part 1: ", part1(input))
  124. println("Part 2: ", part2(input))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement