advent-of-code

advent of code attempts
git clone git://bvnf.space/advent-of-code.git
Log | Files | Refs

a.lua (1646B)


      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
local monkeys = {}
local f = assert(io.open(arg[1], "r"))
for line in f:lines() do
    local n, r = line:match("(%a+): (.*)$")
    local le, op, ri = r:match("(%a+) (.) (%a+)")
    if le == nil then
        local val = tonumber(r)
        monkeys[n] = {val=val}
    else
        monkeys[n] = {l = le, op = op, r = ri}
    end
end

function order(monkeys)
    local todo = {}
    local history = {}
    -- start at root.
    table.insert(todo, "root")
    table.insert(history, "root")
    while true do
        local cur = table.remove(todo, 1) -- queue
        if cur == nil then break end
        if monkeys[cur].val == nil then
            table.insert(todo, monkeys[cur].l)
            table.insert(todo, monkeys[cur].r)
            table.insert(history, monkeys[cur].l)
            table.insert(history, monkeys[cur].r)
        end
    end
    return history
end

function calc(monkeys, ordered)
    -- now step through in order filling in vals.
    for i=#ordered,1,-1 do
        local cur = ordered[i]
        if monkeys[cur].val == nil then
            local l = monkeys[monkeys[cur].l].val
            local r = monkeys[monkeys[cur].r].val
            local op = monkeys[cur].op
            assert(l); assert(r)
            local ans
            if op == '+' then
                ans = l + r
            elseif op == '-' then
                ans = l - r
            elseif op == '/' then
                ans = l / r
            elseif op == '*' then
                ans = l * r
            end
            monkeys[cur].val = ans
        end
    end
    return monkeys.root.val
end

local hist = order(monkeys)
print(calc(monkeys, hist))