From 3555be54c2abb8d5ece008a60dbdfbde0ffbddd7 Mon Sep 17 00:00:00 2001 From: Alex Pickering Date: Fri, 7 Feb 2025 12:49:48 -0600 Subject: inital commit --- 19/1.lua | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 19/1.lua (limited to '19/1.lua') diff --git a/19/1.lua b/19/1.lua new file mode 100644 index 0000000..209efc1 --- /dev/null +++ b/19/1.lua @@ -0,0 +1,129 @@ +require "ext" +local blueprints = {} +for line in io.lines() do + local bpn = line:match("Blueprint (%d+):") + bpn = tonumber(bpn) + blueprints[bpn] = {} + for robot, cost in line:gmatch("Each (%w+) robot costs (%d+) ore.") do --ore and clay + blueprints[bpn][robot] = {ore = tonumber(cost)} + end + for robot, c1, r1, c2, r2 in line:gmatch("Each (%w+) robot costs (%d+) (%w+) and (%w+) (%w+).") do + --obsidian and geode + blueprints[bpn][robot] = {[r1] = tonumber(c1),[r2]=tonumber(c2)} + end +end +print("Blueprints:") +print(blueprints) +local time = 24 + +local function perm_yields(n) + local memgen = {} -- memoize generation + -- permutate all the ways to yield n geodes + local function permgen(left,tbl) + --print("Perm",left) + if left < 0 then return end + if left == 0 then + local ty = table.concat(tbl) + if memgen[ty] == nil then + coroutine.yield(tbl) + memgen[ty] = true + end + end + for i = time - 1,time-left - 1,-1 do + local minesfor = time - i + if tbl[i] == nil and (minesfor <= left) then + tbl[i] = "geode" + permgen(left - minesfor,tbl) + tbl[i] = nil + end + end + end + return coroutine.wrap(function() permgen(n,{}) end) +end + +local dependencies = {"clay","obsidian"} +local function rperm(a,n,perm) + local function rperm_helper(a,n,rst,restrict) + if n == 0 then + coroutine.yield(rst) + else + for _,v in pairs(a) do + local lc = #rst + rst[lc + 1] = v + rperm_helper(a,n-1,rst) + rst[lc + 1] = nil + end + end + end + return coroutine.wrap(function() rperm_helper(a,n,{}) end) +end + +local state = { + minute = 0, + resources = {ore = 0, clay = 0, obsidian = 0, geode = 0}, + robots = {ore = 1, clay = 0, obsidian = 0, geode = 0} +} + +local function copy_state(tbl) + local newtbl = {} + for k,v in pairs(tbl) do + newtbl[k] = v + end + for _,n in pairs({"resources","robots"}) do + newtbl[n] = {} + for k,v in pairs(tbl[n]) do + newtbl[n][k] = v + end + end + return newtbl +end + +local function can_build(state,blueprint,name) + ---print("state",state,"blueprint",blueprint,"name",name) + for res, amt in pairs(blueprint[name]) do + if state.resources[res] < amt then + return false + end + end + return true +end + +local function simulate(blueprint, state, build_order, geode_times) + while state.minute <= time do + if geode_times[state.minute] then + if not can_build(state,blueprint,"geode") then + print("Failed to build geode at",state.minute) + return false + end + elseif #build_order > 0 and can_build(state,blueprint,build_order[1]) then + local rname = build_order[1] + for res,amt in pairs(blueprint[rname]) do + state.resources[res] = state.resources[res] - amt + end + state.robots[rname] = state.robots[rname] + 1 + table.remove(build_order,1) + end + for res,count in pairs(state.robots) do + state.resources[res] = state.resources[res] + count + end + state.minute = state.minute + 1 + end + return true +end + +local function feasable(blueprint, geode_times) + for i = 1,12 do + print("Trying with",i,"other robots") + for perm in rperm({"ore","clay","obsidian"},i) do + local state = copy_state(state) + if simulate(blueprint, state, perm, geode_times) then + print("Successful simulation") + return true + end + end + end +end + +for combo in perm_yields(56) do + print("combo:",combo) +end -- cgit v1.2.3-70-g09d2