Files
aocpy/2019/d14.py
2024-08-16 19:45:10 -04:00

84 lines
2.3 KiB
Python

from lib import get_data
from math import ceil
def ore_for_fuel(fuel_n, reactions_store):
ore_qty = 0
required = [(fuel_n, "FUEL")]
store = {}
while required:
required_qty, required_code = required.pop()
if required_code == "ORE":
ore_qty += required_qty
continue
if required_code in store:
if store[required_code] == required_qty:
del store[required_code]
continue
elif store[required_code] > required_qty:
store[required_code] -= required_qty
continue
elif store[required_code] < required_qty:
required_qty -= store[required_code]
del store[required_code]
inputs, output = reactions_store[required_code]
output_qty, output_code = output
assert required_code == output_code
# how often must this process be executed
n = ceil(required_qty / output_qty)
leftover_output_qty = n * output_qty - required_qty
assert leftover_output_qty >= 0
if leftover_output_qty > 0:
store[output_code] = leftover_output_qty
for qty_input, input_code in inputs:
required.append((qty_input * n, input_code))
return ore_qty
def part_1(data):
reactions = []
to_get = {}
for line in data.splitlines():
left, right = line.split(" => ")
inputs = left.split(", ")
inputs = [(int(i.split()[0]), i.split()[1]) for i in inputs]
output = (int(right.split()[0]), right.split()[1])
reactions.append((inputs, output))
if output[1] in to_get:
assert False
else:
to_get[output[1]] = (inputs, output)
ore_qty = ore_for_fuel(1, to_get)
print(ore_qty)
min_fuel, max_fuel = 1, 100_000_000
target = 10**12 # trillion
while max_fuel - min_fuel > 1:
half_fuel = min_fuel + (max_fuel - min_fuel) // 2
ore_qty = ore_for_fuel(half_fuel, to_get)
if ore_qty < target:
min_fuel = half_fuel
elif ore_qty > target:
max_fuel = half_fuel
else:
min_fuel = half_fuel
max_fuel = half_fuel
print(min_fuel)
def main():
data = get_data(__file__)
part_1(data)
if __name__ == "__main__":
main()