day-14.jl (1919B)
1 function calc_fuel_cost(recipes, fuel_count) 2 chemicals = Dict("FUEL" => fuel_count) 3 leftovers = Dict() 4 ore_count = 0 5 while length(chemicals) != 0 6 target, amount = pop!(chemicals) 7 if target == "ORE" 8 ore_count += amount 9 continue 10 end 11 # Check leftovers before commiting to reaction. 12 leftover_amount = get!(leftovers, target, 0) 13 leftovers[target] -= min(amount, leftover_amount) 14 amount -= min(amount, leftover_amount) 15 if amount == 0 16 continue 17 end 18 # Initiate new reaction. 19 recipe = recipes[target] 20 reaction_count = Int(ceil(amount / recipe[target])) 21 for (k, v) in pairs(recipe) 22 if k != target 23 chemicals[k] = get(chemicals, k, 0) + v * reaction_count 24 else 25 # Place excess product in leftovers. 26 leftovers[target] = ( 27 get(leftovers, target, 0) 28 + v * reaction_count - amount 29 ) 30 end 31 end 32 end 33 ore_count 34 end 35 36 function part_1(input) 37 calc_fuel_cost(input, 1) 38 end 39 40 function part_2(input) 41 # Binary search. 42 ore_cargo = 1000000000000 43 lo = 1 44 hi = ore_cargo 45 while lo + 1 < hi 46 mi = lo + (hi - lo) ÷ 2 47 if calc_fuel_cost(input, mi) > ore_cargo 48 hi = mi 49 else 50 lo = mi 51 end 52 end 53 lo 54 end 55 56 input = map(readlines(open("input.txt"))) do line 57 material, product = match(r"(.*) => (.*)", line).captures 58 reaction = Dict() 59 material = map(split(material, ", ")) do term 60 num, name = split(term, " ") 61 reaction[name] = parse(Int, num) 62 end 63 num, name = split(product, " ") 64 reaction[name] = parse(Int, num) 65 name => reaction 66 end |> Dict 67 68 println("Julia:") 69 println("Part 1: ", part_1(input)) 70 println("Part 2: ", part_2(input))