summaryrefslogtreecommitdiff
path: root/19/1.lua
diff options
context:
space:
mode:
authorAlex Pickering <alex@cogarr.net>2025-02-07 12:49:48 -0600
committerAlex Pickering <alex@cogarr.net>2025-02-07 12:49:48 -0600
commit3555be54c2abb8d5ece008a60dbdfbde0ffbddd7 (patch)
tree278876284d07118ecdea5c48cb6453f3122887f0 /19/1.lua
downloadadvent_of_code_2022-master.tar.gz
advent_of_code_2022-master.tar.bz2
advent_of_code_2022-master.zip
inital commitHEADmaster
Diffstat (limited to '19/1.lua')
-rw-r--r--19/1.lua129
1 files changed, 129 insertions, 0 deletions
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