advent-of-code

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

commit b1b2109acbcd8b3b5231655aab9b73c7396e593a
parent 322415223efdef2e6ea97254c2b5cf1539c45677
Author: aabacchus <ben@bvnf.space>
Date:   Sat, 17 Dec 2022 01:58:24 +0000

22.16.1 in Lua

Diffstat:
A2022/16/d.lua | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2022/16/example | 10++++++++++
A2022/16/input | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 214 insertions(+), 0 deletions(-)

diff --git a/2022/16/d.lua b/2022/16/d.lua @@ -0,0 +1,149 @@ +local f = assert(io.open(arg[1], "r")) + +function parse(f) + local nodes = {} + for line in f:lines() do + for name,flow,conns in line:gmatch("Valve (..) has flow rate=(%d+); tunnels? leads? to valves? (.*)$") do + local flow = tonumber(flow) + local c = split(conns, ",") + assert(nodes[name] == nil) + nodes[name] = {flow=flow, c=c, dists=nil, on=false} + end + end + return nodes +end + +function split(s, sep) + local c = {} + for a in s:gmatch("[^%s"..sep.."]+") do + table.insert(c, a) + end + return c +end + +-- make a grid of all the shortest paths between each nonzero node. +-- BFS to find shortest paths. + +-- k is the name of the node to find closest distances to. +-- returns a table with keys of node names and vals of distances. +function closest_dists(k, nodes) + v = nodes[k] + + local queue = {} + table.insert(queue, {name=k, d=0}) + + local cnt = 0 + local visited = {} + while true do + local n = table.remove(queue, 1) -- removing from front makes this BFS + if (n == nil) then + break + end + if visited[n.name] then + goto cont + end + visited[n.name] = n.d + + --[[ + if n.name == start and n.d ~= 0 then + break + end + --]] + + for _, c in ipairs(nodes[n.name].c) do + table.insert(queue, {name=c, d=n.d+1}) + end + + ::cont:: + end + return visited +end + +local nodes = parse(f) +for name in pairs(nodes) do + nodes[name].dists = closest_dists(name, nodes) + + -- remove self + nodes[name].dists[name] = nil + --print(name) +end + +function tableclone(t) + local copy = {} + for ok,ov in pairs(t) do + copy[ok] = ov + end + return copy +end + +-- DFS on all the possible paths, counting pressure released. +local stack = {} +local ends = {} +table.insert(stack, {name="AA", timeleft=30, pressure=0, parent={}, on={}}) +while true do + io.write(tostring(#stack), "\r") + local n = table.remove(stack) + if n == nil then break end + + if n.on[n.name] then + goto cont2 + end + n.on[n.name] = true + + if not ends[n.name] or ends[n.name].pressure < n.pressure or n.timeleft <= 0 then + -- save best paths as their ending valves + ends[n.name] = n + end + + if n.timeleft <= 0 then goto cont2 end + + local cntr = 0 + for k,v in pairs(nodes[n.name].dists) do + local nt = n.timeleft - v + local np = n.pressure + if nodes[k].flow > 0 and not n.on[k] then + nt = nt - 1 + if nt <= 0 then goto cont3 end + + np = np + nt*nodes[k].flow + + local non = tableclone(n.on) + cntr = cntr + 1 + + local npa = tableclone(n.parent) + table.insert(npa, n.name) + + table.insert(stack, {name=k, timeleft=nt, pressure = np, parent=npa, on=non}) + end + ::cont3:: + end + + ::cont2:: +end + +function sort_by_p(a, b) + return a.pressure > b.pressure +end + +local oends = {} +for k,v in pairs(ends) do + table.insert(oends, {name=k, pressure=v.pressure, timeleft=v.timeleft, parent=v.parent}) +end +table.sort(oends, sort_by_p) + +local max = 0 +local maxn = nil +print("==", "end", "pressure", "time left") +for _,v in ipairs(oends) do print("::",v.name,v.pressure,"",v.timeleft) + if v.pressure > max then + max = v.pressure + maxn = v + end +end +print("==") + +-- print path +io.write("Best path: ") +for _,p in ipairs(maxn.parent) do io.write(p, " -> ") end +print(maxn.name) +print(maxn.pressure) diff --git a/2022/16/example b/2022/16/example @@ -0,0 +1,10 @@ +Valve AA has flow rate=0; tunnels lead to valves DD, II, BB +Valve BB has flow rate=13; tunnels lead to valves CC, AA +Valve CC has flow rate=2; tunnels lead to valves DD, BB +Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE +Valve EE has flow rate=3; tunnels lead to valves FF, DD +Valve FF has flow rate=0; tunnels lead to valves EE, GG +Valve GG has flow rate=0; tunnels lead to valves FF, HH +Valve HH has flow rate=22; tunnel leads to valve GG +Valve II has flow rate=0; tunnels lead to valves AA, JJ +Valve JJ has flow rate=21; tunnel leads to valve II diff --git a/2022/16/input b/2022/16/input @@ -0,0 +1,55 @@ +Valve NA has flow rate=0; tunnels lead to valves MU, PH +Valve NW has flow rate=0; tunnels lead to valves KB, MH +Valve MR has flow rate=0; tunnels lead to valves GC, FI +Valve XD has flow rate=0; tunnels lead to valves UN, CN +Valve HK has flow rate=0; tunnels lead to valves AA, IF +Valve JL has flow rate=0; tunnels lead to valves IF, WB +Valve RQ has flow rate=13; tunnels lead to valves BL, DJ +Valve AB has flow rate=0; tunnels lead to valves BO, RU +Valve PE has flow rate=0; tunnels lead to valves AZ, IF +Valve QF has flow rate=0; tunnels lead to valves TD, AZ +Valve BA has flow rate=0; tunnels lead to valves RF, GU +Valve SY has flow rate=0; tunnels lead to valves MH, MU +Valve NT has flow rate=0; tunnels lead to valves DJ, UN +Valve GU has flow rate=21; tunnels lead to valves VJ, BA, YP +Valve AZ has flow rate=12; tunnels lead to valves QF, PI, AS, PE +Valve WQ has flow rate=23; tunnels lead to valves VJ, UM, CN +Valve DR has flow rate=0; tunnels lead to valves GA, CQ +Valve UM has flow rate=0; tunnels lead to valves IE, WQ +Valve XI has flow rate=0; tunnels lead to valves IE, IF +Valve SS has flow rate=0; tunnels lead to valves CQ, MH +Valve IE has flow rate=22; tunnels lead to valves YP, UM, XI, XA +Valve BT has flow rate=24; tunnels lead to valves KB, BL, GA +Valve GA has flow rate=0; tunnels lead to valves DR, BT +Valve AR has flow rate=0; tunnels lead to valves IF, FI +Valve DJ has flow rate=0; tunnels lead to valves RQ, NT +Valve PI has flow rate=0; tunnels lead to valves FI, AZ +Valve WB has flow rate=0; tunnels lead to valves TD, JL +Valve OQ has flow rate=0; tunnels lead to valves ME, TD +Valve RU has flow rate=19; tunnel leads to valve AB +Valve IF has flow rate=7; tunnels lead to valves AR, JL, HK, PE, XI +Valve BO has flow rate=0; tunnels lead to valves ME, AB +Valve CN has flow rate=0; tunnels lead to valves WQ, XD +Valve HH has flow rate=0; tunnels lead to valves AA, FS +Valve AS has flow rate=0; tunnels lead to valves AA, AZ +Valve FS has flow rate=0; tunnels lead to valves HH, MH +Valve PQ has flow rate=0; tunnels lead to valves TD, AA +Valve AA has flow rate=0; tunnels lead to valves HH, CO, AS, HK, PQ +Valve ME has flow rate=18; tunnels lead to valves OQ, BO, PH +Valve RF has flow rate=0; tunnels lead to valves UN, BA +Valve MH has flow rate=8; tunnels lead to valves FS, NW, SS, SY +Valve YP has flow rate=0; tunnels lead to valves IE, GU +Valve FI has flow rate=11; tunnels lead to valves PI, MR, AR, CO, DI +Valve UU has flow rate=0; tunnels lead to valves CQ, MU +Valve CO has flow rate=0; tunnels lead to valves AA, FI +Valve TD has flow rate=16; tunnels lead to valves QF, GC, OQ, WB, PQ +Valve MU has flow rate=15; tunnels lead to valves SY, UU, NA +Valve BL has flow rate=0; tunnels lead to valves BT, RQ +Valve PH has flow rate=0; tunnels lead to valves ME, NA +Valve XA has flow rate=0; tunnels lead to valves IE, DI +Valve GC has flow rate=0; tunnels lead to valves TD, MR +Valve KB has flow rate=0; tunnels lead to valves BT, NW +Valve DI has flow rate=0; tunnels lead to valves XA, FI +Valve CQ has flow rate=9; tunnels lead to valves UU, DR, SS +Valve VJ has flow rate=0; tunnels lead to valves WQ, GU +Valve UN has flow rate=20; tunnels lead to valves NT, XD, RF