Advertisement
Guest User

Untitled

a guest
Jan 3rd, 2023
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.75 KB | None | 0 0
  1. local function DFS(state, states, blueprint, maxMat)
  2.     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]
  3.     if tLeft == 0 then return geo end
  4.     local key = string.format("%d %d %d %d %d %d %d %d %d", tLeft, orer, clr, obsr, geor, ore, cl, obs, geo)
  5.     if states[key] then return states[key] end
  6.     local max = geo + geor * tLeft
  7.     for robot, ingrs in pairs(blueprint) do
  8.         if robot == "ore" and orer >= maxMat["ore"] then goto continue end
  9.         if robot == "clay" and clr >= maxMat["clay"] then goto continue end
  10.         if robot == "obsidian" and obsr >= maxMat["obsidian"] then goto continue end
  11.         local wait = 0
  12.         local canWait = true
  13.         for mat, amount in pairs(ingrs) do
  14.             if (mat == "ore" and orer == 0) or (mat == "clay" and clr == 0) or (mat == "obsidian" and obsr == 0) then canWait = false break end
  15.             local resnum = (mat == "ore" and ore) or (mat == "clay" and cl) or (mat == "obsidian" and obs)
  16.             local botnum = (mat == "ore" and orer) or (mat == "clay" and clr) or (mat == "obsidian" and obsr)
  17.             wait = math.max(wait, math.ceil((amount - resnum) / botnum))
  18.         end
  19.         if canWait then
  20.             local remTime = tLeft - wait - 1
  21.             if remTime <= 0 then goto continue end
  22.             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)
  23.             local nore, ncl, nobs, ngeo = ore + orer * (wait + 1), cl + clr * (wait + 1), obs + obsr * (wait + 1), geo + geor * (wait + 1)
  24.             for mat, amount in pairs(ingrs) do
  25.                 if mat == "ore" then nore = nore - amount end
  26.                 if mat == "clay" then ncl = ncl - amount end
  27.                 if mat == "obsidian" then nobs = nobs - amount end
  28.             end
  29.             nore = math.min(nore, maxMat["ore"] * remTime)
  30.             ncl = math.min(ncl, maxMat["clay"] * remTime)
  31.             nobs = math.min(nobs, maxMat["obsidian"] * remTime)
  32.             max = math.max(max, DFS({remTime, norer, nclr, nobsr, ngeor, nore, ncl, nobs, ngeo}, states, blueprint, maxMat))
  33.         end
  34.         ::continue::
  35.     end
  36.     states[key] = max
  37.     return max
  38. end
  39.  
  40. local n = 1
  41. local count = 0
  42. local count2 = 1
  43. for line in io.lines(arg[1]) do
  44.     local maxmat = {}
  45.     local blueprint = {}
  46.     for kind, cost in line:gmatch("Each (%w+) robot costs (.-)%.") do
  47.         blueprint[kind] = {}
  48.         for amount, mat in cost:gmatch("(%d+) (%w+)") do
  49.             maxmat[mat] = math.max(maxmat[mat] or 0, tonumber(amount))
  50.             blueprint[kind][mat] = tonumber(amount)
  51.         end
  52.     end
  53.     if n == 1 or n == 2 or n == 3 then
  54.         local geo = DFS({32, 1, 0, 0, 0, 0, 0, 0, 0}, {}, blueprint, maxmat)
  55.         count2 = count2 * geo
  56.     end
  57.     local geo = DFS({24, 1, 0, 0, 0, 0, 0, 0, 0}, {}, blueprint, maxmat)
  58.     count = count + geo * n
  59.     n = n + 1
  60. end
  61. print(count)
  62. print(count2)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement