14_reactions.py 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #!/usr/bin/env python3
  2. import sys
  3. from collections import defaultdict
  4. def read_graph(f):
  5. graph = {'ORE': (1, {})}
  6. for line in f:
  7. lhs, rhs = line.strip().split(' => ')
  8. noutp, outp = rhs.split()
  9. assert outp not in graph
  10. edges = {}
  11. for inp in lhs.split(', '):
  12. ninp, inp = inp.split()
  13. edges[inp] = int(ninp)
  14. graph[outp] = int(noutp), edges
  15. return graph
  16. def ore_needed(reactions, fuel):
  17. def produce(outp, amount):
  18. from_stash = min(amount, stash[outp])
  19. stash[outp] -= from_stash
  20. amount -= from_stash
  21. noutp, inputs = reactions[outp]
  22. multiplier = amount // noutp + bool(amount % noutp)
  23. for inp, ninp in inputs.items():
  24. produce(inp, ninp * multiplier)
  25. stash[outp] += noutp * multiplier - amount
  26. produced[outp] += amount
  27. stash = defaultdict(int)
  28. produced = defaultdict(int)
  29. produce('FUEL', fuel)
  30. return produced['ORE']
  31. def fuel_with_ore(reactions, ore):
  32. fuel = 0
  33. step = ore
  34. while step:
  35. while ore_needed(reactions, fuel) < ore:
  36. fuel += step
  37. fuel -= step
  38. step //= 2
  39. return fuel
  40. reactions = read_graph(sys.stdin)
  41. print(ore_needed(reactions, 1))
  42. print(fuel_with_ore(reactions, 1000000000000))