function check_mem(max, offs) if max < offs then print(string.format("Error: Memory offset out of bounds: %d", offs)) os.exit(false) end end function interpret(mem) pos = 1 while true do if #mem < pos then print(string.format("Instruction pointer ran off of memory")) os.exit(false) end if mem[pos] == 1 or mem[pos] == 2 then if #mem < pos + 3 then print(string.format("Error: Opcode too short at end of memory: %d", pos)) os.exit(false) end arg1 = mem[pos + 1] + 1 arg2 = mem[pos + 2] + 1 res = mem[pos + 3] + 1 check_mem(#mem, arg1) check_mem(#mem, arg2) check_mem(#mem, res) if mem[pos] == 1 then mem[res] = mem[arg1] + mem[arg2] else mem[res] = mem[arg1] * mem[arg2] end pos = pos + 4 elseif mem[pos] == 99 then return else print(string.format("Error: Invalid opcode %d at %d", mem[pos], pos - 1)) os.exit(false) end end end file = io.open(arg[1]) memory = {} for num in string.gmatch(file:read(), "(%d+),") do table.insert(memory, tonumber(num)) end file:close() memory_p1 = {table.unpack(memory)} memory_p1[2] = 12 memory_p1[3] = 2 interpret(memory_p1) print("Part 1:", memory_p1[1]) -- Brute force for noun = 0, 99 do for verb = 0, 99 do memory_p2 = {table.unpack(memory)} memory_p2[2] = noun memory_p2[3] = verb interpret(memory_p2) if memory_p2[1] == 19690720 then print("Part 2:", 100 * noun + verb) os.exit(true) end end end