def new_interpreter(f, p) prog = {} of Int64 => Int64 p.each_with_index do |v, i| prog[i.to_i64] = v.to_i64 end input = Channel(Int64).new output = Channel(Int64?).new spawn do op = "" pc = 0_i64 base = 0_i64 index = ->(i : Int32) { case op[-(3+i)] when '0' prog[pc+1+i] when '1' pc+1+i else prog[pc+1+i] + base end } get = ->(i : Int32) { prog[index.call(i)]? || 0_i64 } set = ->(i : Int32, v : Int64) { prog[index.call(i)] = v } loop do op = "0000" + prog[pc].to_s case op when .ends_with? "1" set.call(2, get.call(0) + get.call(1)) pc += 4 when .ends_with? "2" set.call(2, get.call(0) * get.call(1)) pc += 4 when .ends_with? "3" set.call(0, input.receive) pc += 2 when .ends_with? "4" output.send(get.call(0)) pc += 2 when .ends_with? "5" pc = get.call(0) != 0 ? get.call(1) : pc + 3 when .ends_with? "6" pc = get.call(0) == 0 ? get.call(1) : pc + 3 when .ends_with? "7" set.call(2, get.call(0) < get.call(1) ? 1_i64 : 0_i64) pc += 4 when .ends_with? "8" set.call(2, get.call(0) == get.call(1) ? 1_i64 : 0_i64) pc += 4 when .ends_with? "99" input.receive output.send(nil) break when .ends_with? "9" base += get.call(0) pc += 2 end end end {input, output} end