Solve 2019 day 14 and 15
This commit is contained in:
83
2019/d14.py
Normal file
83
2019/d14.py
Normal file
@@ -0,0 +1,83 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user