AdventOfCode-2019/intcode_fibers.cr

43 lines
1.1 KiB
Crystal

def new_interpreter(f, prog)
prog = prog.clone
input = Channel(Int32).new
output = Channel(Int32?).new
spawn do
op = ""
pc = 0
arg = ->(i : Int32) { op[-(3+i)] == '0' ? prog[prog[pc+1+i]] : prog[pc+1+i] }
loop do
op = "0000" + prog[pc].to_s
case op
when .ends_with? "1"
prog[prog[pc+3]] = arg.call(0) + arg.call(1)
pc += 4
when .ends_with? "2"
prog[prog[pc+3]] = arg.call(0) * arg.call(1)
pc += 4
when .ends_with? "3"
prog[prog[pc+1]] = input.receive
pc += 2
when .ends_with? "4"
output.send(arg.call(0))
pc += 2
when .ends_with? "5"
pc = arg.call(0) != 0 ? arg.call(1) : pc + 3
when .ends_with? "6"
pc = arg.call(0) == 0 ? arg.call(1) : pc + 3
when .ends_with? "7"
prog[prog[pc+3]] = arg.call(0) < arg.call(1) ? 1 : 0
pc += 4
when .ends_with? "8"
prog[prog[pc+3]] = arg.call(0) == arg.call(1) ? 1 : 0
pc += 4
when .ends_with? "99"
input.receive
output.send(nil)
break
end
end
end
{input, output}
end