-- see if the file exists local function file_exists(file) local f = io.open(file, "rb") if f then f:close() end return f ~= nil end -- get all lines from a file, returns an empty -- list/table if the file does not exist local function lines_from(file) if not file_exists(file) then return {} end local lines = {} for line in io.lines(file) do lines[#lines + 1] = line end return lines end -- tests the functions above local file = "input" local lines = lines_from(file) local input = "" for _, line in pairs(lines) do input = input .. line end local instructions = {} -- print all line numbers and their contents for pos, a, b in string.gmatch(input, "()mul%((%d+),(%d+)%)") do ---@diagnostic disable-next-line: redefined-local local a, b = tonumber(a), tonumber(b) local product = a * b instructions[#instructions + 1] = { pos = pos, product = product, } end for pos in string.gmatch(input, "()do%(%)") do instructions[#instructions + 1] = { pos = pos, enable = true } end for pos in string.gmatch(input, "()don't%(%)") do instructions[#instructions + 1] = { pos = pos, enable = false } end table.sort(instructions, function(a, b) return a.pos < b.pos end) local total = 0 local enabled = true for _, instruction in ipairs(instructions) do if instruction.enable ~= nil then enabled = instruction.enable elseif enabled then total = total + instruction.product end end io.output():write(total)