您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

48 行
1.2KB

  1. import collections
  2. import math
  3. import re
  4. import sys
  5. text = sys.stdin.read()
  6. cookbook = {}
  7. for line in text.strip().splitlines():
  8. for i, (qty, name) in enumerate(re.findall(r'(\d+) ([A-Z]+)', line)[::-1]):
  9. if i == 0:
  10. output = name
  11. cookbook[output] = {output: -int(qty)}
  12. else:
  13. cookbook[output][name] = int(qty)
  14. def fuel_to_ore(state):
  15. state = collections.Counter(state)
  16. pending = state.copy()
  17. while pending:
  18. pending = {k: v for k, v in state.items() if k in cookbook and v > 0}
  19. for out, out_qty in pending.items():
  20. min_qty = -cookbook[out][out]
  21. n_times = math.ceil(out_qty / min_qty)
  22. state.update({k: v * n_times for k, v in cookbook[out].items()})
  23. return state
  24. def bsearch(fn, goal, lo, hi):
  25. while hi - lo > 1:
  26. mid = lo + (hi - lo) // 2
  27. if goal < fn(mid):
  28. lo, hi = lo, mid
  29. else:
  30. lo, hi = mid, hi
  31. # check
  32. a, b = fn(lo), fn(hi)
  33. assert a <= goal, 'lower bound too high'
  34. assert goal <= b, 'higher bound too low'
  35. return lo
  36. print(fuel_to_ore({'FUEL': 1})['ORE'])
  37. print(bsearch(lambda n: fuel_to_ore({'FUEL': n})['ORE'], 1E12, 1, 10_000_000))