Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function DFS(state, states, blueprint, maxMat)
- local tLeft, orer, clr, obsr, geor, ore, cl, obs, geo = state[1], state[2], state[3], state[4], state[5], state[6], state[7], state[8], state[9]
- if tLeft == 0 then return geo end
- local key = string.format("%d %d %d %d %d %d %d %d %d", tLeft, orer, clr, obsr, geor, ore, cl, obs, geo)
- if states[key] then return states[key] end
- local max = geo + geor * tLeft
- for robot, ingrs in pairs(blueprint) do
- if robot == "ore" and orer >= maxMat["ore"] then goto continue end
- if robot == "clay" and clr >= maxMat["clay"] then goto continue end
- if robot == "obsidian" and obsr >= maxMat["obsidian"] then goto continue end
- local wait = 0
- local canWait = true
- for mat, amount in pairs(ingrs) do
- if (mat == "ore" and orer == 0) or (mat == "clay" and clr == 0) or (mat == "obsidian" and obsr == 0) then canWait = false break end
- local resnum = (mat == "ore" and ore) or (mat == "clay" and cl) or (mat == "obsidian" and obs)
- local botnum = (mat == "ore" and orer) or (mat == "clay" and clr) or (mat == "obsidian" and obsr)
- wait = math.max(wait, math.ceil((amount - resnum) / botnum))
- end
- if canWait then
- local remTime = tLeft - wait - 1
- if remTime <= 0 then goto continue end
- local norer, nclr, nobsr, ngeor = (robot == "ore" and orer + 1 or orer), (robot == "clay" and clr + 1 or clr), (robot == "obsidian" and obsr + 1 or obsr), (robot == "geode" and geor + 1 or geor)
- local nore, ncl, nobs, ngeo = ore + orer * (wait + 1), cl + clr * (wait + 1), obs + obsr * (wait + 1), geo + geor * (wait + 1)
- for mat, amount in pairs(ingrs) do
- if mat == "ore" then nore = nore - amount end
- if mat == "clay" then ncl = ncl - amount end
- if mat == "obsidian" then nobs = nobs - amount end
- end
- nore = math.min(nore, maxMat["ore"] * remTime)
- ncl = math.min(ncl, maxMat["clay"] * remTime)
- nobs = math.min(nobs, maxMat["obsidian"] * remTime)
- max = math.max(max, DFS({remTime, norer, nclr, nobsr, ngeor, nore, ncl, nobs, ngeo}, states, blueprint, maxMat))
- end
- ::continue::
- end
- states[key] = max
- return max
- end
- local n = 1
- local count = 0
- local count2 = 1
- for line in io.lines(arg[1]) do
- local maxmat = {}
- local blueprint = {}
- for kind, cost in line:gmatch("Each (%w+) robot costs (.-)%.") do
- blueprint[kind] = {}
- for amount, mat in cost:gmatch("(%d+) (%w+)") do
- maxmat[mat] = math.max(maxmat[mat] or 0, tonumber(amount))
- blueprint[kind][mat] = tonumber(amount)
- end
- end
- if n == 1 or n == 2 or n == 3 then
- local geo = DFS({32, 1, 0, 0, 0, 0, 0, 0, 0}, {}, blueprint, maxmat)
- count2 = count2 * geo
- end
- local geo = DFS({24, 1, 0, 0, 0, 0, 0, 0, 0}, {}, blueprint, maxmat)
- count = count + geo * n
- n = n + 1
- end
- print(count)
- print(count2)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement