Solve 2019 day 14 and 15
This commit is contained in:
parent
6efa70ea51
commit
f88eb14d24
53
2019/d12.py
Normal file
53
2019/d12.py
Normal file
@ -0,0 +1,53 @@
|
||||
from lib import get_data, str_to_ints
|
||||
|
||||
|
||||
def freeze(coords, velos):
|
||||
coords = tuple(map(tuple, coords))
|
||||
velos = tuple(map(tuple, velos))
|
||||
return coords + velos
|
||||
|
||||
|
||||
def part_1(data):
|
||||
coords = []
|
||||
velos = []
|
||||
for line in data.splitlines():
|
||||
coords.append(str_to_ints(line))
|
||||
velos.append([0, 0, 0])
|
||||
|
||||
for _ in range(1_000):
|
||||
# apply gravity
|
||||
for i in range(len(coords)):
|
||||
for j in range(i + 1, len(coords)):
|
||||
for d in range(3):
|
||||
if coords[i][d] > coords[j][d]:
|
||||
velos[i][d] -= 1
|
||||
velos[j][d] += 1
|
||||
elif coords[i][d] < coords[j][d]:
|
||||
velos[i][d] += 1
|
||||
velos[j][d] -= 1
|
||||
|
||||
# update coords
|
||||
for i in range(len(coords)):
|
||||
for d in range(3):
|
||||
coords[i][d] += velos[i][d]
|
||||
|
||||
r = 0
|
||||
for i in range(len(coords)):
|
||||
p = sum(map(abs, coords[i]))
|
||||
k = sum(map(abs, velos[i]))
|
||||
r += p * k
|
||||
print(r)
|
||||
|
||||
|
||||
def part_2(data):
|
||||
raise Exception("TBD")
|
||||
|
||||
|
||||
def main():
|
||||
data = get_data(__file__)
|
||||
part_1(data)
|
||||
part_2(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
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()
|
116
2019/d15.py
Normal file
116
2019/d15.py
Normal file
@ -0,0 +1,116 @@
|
||||
from lib import get_data, str_to_ints, add2
|
||||
from collections import deque
|
||||
from d9 import Amp
|
||||
|
||||
|
||||
DIRS = {1: (-1, 0), 2: (1, 0), 3: (0, -1), 4: (0, 1)}
|
||||
PATH_REVERSED = {1: 2, 2: 1, 3: 4, 4: 3}
|
||||
|
||||
|
||||
def print_field(fields, walls, pos):
|
||||
dim = 40
|
||||
for y in range(-dim, dim + 1):
|
||||
row = ""
|
||||
for x in range(-dim, dim + 1):
|
||||
if (y, x) == pos:
|
||||
row += "X"
|
||||
elif (y, x) in fields:
|
||||
row += "."
|
||||
elif (y, x) in walls:
|
||||
row += "|"
|
||||
else:
|
||||
row += " "
|
||||
print(row)
|
||||
|
||||
|
||||
def part_1(data):
|
||||
xs = str_to_ints(data)
|
||||
a = Amp(xs)
|
||||
|
||||
walls = set()
|
||||
pos = (0, 0)
|
||||
target = None
|
||||
dir = None
|
||||
path = []
|
||||
dir_cmds_for_pos = {pos: [1, 2, 3, 4]}
|
||||
|
||||
while not a.done:
|
||||
if len(dir_cmds_for_pos[pos]) > 0:
|
||||
dir_cmd = dir_cmds_for_pos[pos].pop()
|
||||
dir = DIRS[dir_cmd]
|
||||
|
||||
new_pos = add2(pos, dir)
|
||||
if new_pos in dir_cmds_for_pos:
|
||||
continue
|
||||
|
||||
a.feed(dir_cmd)
|
||||
a.go()
|
||||
status = a.pop()
|
||||
|
||||
if status == 0:
|
||||
walls.add(new_pos)
|
||||
elif status == 1:
|
||||
pos = new_pos
|
||||
path.append(dir_cmd)
|
||||
elif status == 2:
|
||||
pos = new_pos
|
||||
path.append(dir_cmd)
|
||||
target = pos
|
||||
|
||||
if pos not in dir_cmds_for_pos:
|
||||
dir_cmds_for_pos[pos] = [1, 2, 3, 4]
|
||||
|
||||
elif len(path) > 0:
|
||||
dir_cmd = PATH_REVERSED[path.pop()]
|
||||
dir = DIRS[dir_cmd]
|
||||
pos = add2(pos, dir)
|
||||
a.feed(dir_cmd)
|
||||
a.go()
|
||||
status = a.pop()
|
||||
assert status == 1 or status == 2
|
||||
elif target is not None:
|
||||
break
|
||||
else:
|
||||
break
|
||||
fields = set(dir_cmds_for_pos.keys())
|
||||
# print_field(fields, walls, pos)
|
||||
|
||||
seen = set()
|
||||
to_visit = [(0, 0)]
|
||||
steps = 0
|
||||
while len(to_visit) > 0:
|
||||
new = []
|
||||
for current in to_visit:
|
||||
if current == target:
|
||||
print(steps)
|
||||
seen.add(current)
|
||||
for dir in DIRS.values():
|
||||
nb = add2(current, dir)
|
||||
if nb in fields and nb not in seen:
|
||||
new.append(nb)
|
||||
to_visit = new
|
||||
steps += 1
|
||||
|
||||
seen = set()
|
||||
to_visit = [target]
|
||||
steps = 0
|
||||
while len(to_visit) > 0:
|
||||
new = []
|
||||
for current in to_visit:
|
||||
seen.add(current)
|
||||
for dir in DIRS.values():
|
||||
nb = add2(current, dir)
|
||||
if nb in fields and nb not in seen:
|
||||
new.append(nb)
|
||||
to_visit = new
|
||||
steps += 1
|
||||
print(steps - 1)
|
||||
|
||||
|
||||
def main():
|
||||
data = get_data(__file__)
|
||||
part_1(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -13,6 +13,7 @@ class Amp:
|
||||
self.rel_base = 0
|
||||
|
||||
def feed(self, input):
|
||||
self.input_required = False
|
||||
self.inputs.append(input)
|
||||
|
||||
def pop(self):
|
||||
|
@ -123,6 +123,9 @@ Solutions and utility script for Advent of Code challenges in Python.
|
||||
- Day 11: 21:04 (Too slow, but fun.)
|
||||
- Day 12:
|
||||
- Day 13: >120:00 (Just struggling so much for some reason.)
|
||||
- Day 14: >120:00 (Hmm, wasn't that hard either.)
|
||||
- Day 15: >120:00 (I am really weak at the moment.)
|
||||
- Day 16:
|
||||
|
||||
## AoC 2022
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user