Compare commits

...

2 Commits

Author SHA1 Message Date
Tibor Bizjak 10d119a242 Added day 14 2023-03-14 00:58:34 +01:00
Tibor Bizjak 7bd4d01b31 Added shebang 2023-03-14 00:57:30 +01:00
2 changed files with 134 additions and 0 deletions

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
from itertools import combinations from itertools import combinations
from fractions import gcd from fractions import gcd
from functools import reduce from functools import reduce

132
day14.py 100644
View File

@ -0,0 +1,132 @@
#!/usr/bin/env python3
from collections import defaultdict
ORE = "ORE"
FUEL = "FUEL"
class Reactor:
def __init__(self, reactions, root=ORE):
self.reactions = reactions
self.root = root
self.produced = defaultdict(int)
self.leftover = defaultdict(int)
def produce(self, el, n):
if el == self.root:
self.produced[el] += n
return
min = self.reactions[el][el]
if type(min) == float:
k = (n + min - 1) / min
else:
k = (n + min - 1) // min
for el2, m in self.reactions[el].items():
if el2 == el:
continue
self.get(el2, k * m)
p = k*min
self.produced[el] += p
self.leftover[el] += p - n
def get(self, el, n):
n -= self.leftover[el]
self.leftover[el] = 0
if n <= 0:
self.leftover[el] = -n
return
self.produce(el, n)
def parse(line):
el = line.split()[-1]
line = line.replace(" => ", ', ')
return el, dict((m.split()[1], int(m.split()[0]))
for m in line.split(', '))
def ore_per_fuel(reactions, n=1):
reactor = Reactor(reactions)
reactor.get(FUEL, n)
return reactor.produced[ORE]
def ore_per_fuel_lim(reactions):
float_recs = {}
for el in reactions.keys():
min = float(reactions[el][el])
float_recs[el] = dict((el2, n/min) for el2, n in reactions[el].items())
return ore_per_fuel(float_recs)
def search(f, target, best):
step = best // 100
i = best
while step > 0:
while f(i) <= target:
i += step
i -= step
step //= 10
return i
def preproc(puzzle_input):
return dict(map(parse, puzzle_input.split('\n')))
def partI(reactions):
r = ore_per_fuel(reactions)
return r
def partII(reactions):
ore = 10**12
best = int(ore // ore_per_fuel_lim(reactions))
return search(lambda n: ore_per_fuel(reactions, n), ore, best)
from main import Tests
tests = Tests()
tests.add(
"""157 ORE => 5 NZVS
165 ORE => 6 DCFZ
44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
179 ORE => 7 PSHF
177 ORE => 5 HKGWZ
7 DCFZ, 7 PSHF => 2 XJWVT
165 ORE => 2 GPVTF
3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT""",
partI=13312)
tests.add(
"""2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
17 NVRVD, 3 JNWZP => 8 VPVL
53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL
22 VJHF, 37 MNCFX => 5 FWMGM
139 ORE => 4 NVRVD
144 ORE => 7 JNWZP
5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC
5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV
145 ORE => 6 MNCFX
1 NVRVD => 8 CXFTF
1 VJHF, 6 MNCFX => 4 RFSQX
176 ORE => 6 VJHF""",
partI=180697)
tests.add(
"""171 ORE => 8 CNZTR
7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL
114 ORE => 4 BHXH
14 VRPVC => 6 BMBT
6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL
6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT
15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW
13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW
5 BMBT => 4 WPTQ
189 ORE => 9 KTJDG
1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP
12 VRPVC, 27 CNZTR => 2 XDBXC
15 KTJDG, 12 BHXH => 5 XCVML
3 BHXH, 2 VRPVC => 7 MZWV
121 ORE => 7 VRPVC
7 XCVML => 6 RJRHP
5 BHXH, 4 VRPVC => 5 LTCX""",
partI=2210736)