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))