1
0
Fork 0
adventofcode/2020/18/day18.lua

50 lines
1.3 KiB
Lua

#!/usr/bin/env lua
-- Parse parentheses, evaluating sub-expressions using another function
local function eval(expr, eval_func)
-- Remove any extra parenthses around the entire expression
while expr:find("^%b()$") do
expr = expr:sub(2, #expr - 1)
end
-- Parse all of the outermost parentheses recursively
local matches = 0
repeat
expr, matches = expr:gsub("%b()", function (subexpr) return eval(subexpr, eval_func) end)
until matches < 1
return eval_func(expr)
end
local function part1_eval(expr)
local left, operator
for token in expr:gmatch "%S+" do
if left == nil then
left = tonumber(token)
elseif operator == nil then
operator = token
elseif operator == "+" then
left = left + tonumber(token)
operator = nil
elseif operator == "*" then
left = left * tonumber(token)
operator = nil
else
error("unexpected operator!")
end
end
return left
end
local function part2_eval(expr)
return eval(expr:gsub("(%d+%s+[%d%+%s]+%s+%d+)", "(%1)"), part1_eval)
end
local part1 = 0
local part2 = 0
for line in io.lines() do
part1 = part1 + eval(line, part1_eval)
part2 = part2 + eval(line, part2_eval)
end
print(part1)
print(part2)