recipes = {} for line in io.lines(arg[1]) do input, output = line:match("(.-) *=> *(.+)") quant, name = output:match("(%d+) +(.+)") recipe = {quant=tonumber(quant), ingres={}} for quant, ingre in input:gmatch("(%d+) +(%a+),? *") do recipe.ingres[ingre] = quant end recipes[name] = recipe end recipes.ORE = {quant=0, ingres={}} function get_ore(fuel) local wanted = {FUEL=fuel} while true do for name, _ in pairs(wanted) do if name ~= "ORE" then recipe = recipes[name] if wanted[name] > 0 then amount = wanted[name] // recipe.quant if wanted[name] % recipe.quant > 0 then amount = amount + 1 end for ingre, ingre_quant in pairs(recipe.ingres) do if not wanted[ingre] then wanted[ingre] = 0 end wanted[ingre] = wanted[ingre] + ingre_quant * amount end wanted[name] = wanted[name] - recipe.quant * amount end end end if wanted["ORE"] then count = 0 for x, y in pairs(wanted) do if 0 < y then count = count + 1 end end if count == 1 then return wanted["ORE"] end end end end -- Manual brute forcing is actually doable, funnily enough ore = get_ore(tonumber(arg[2])) print(ore) if ore > 1000000000000 then print("Ding!") end