Solve 2019 day 14 and 15
This commit is contained in:
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()
|
||||||
@@ -8,13 +8,13 @@ def part_1(data):
|
|||||||
while not a.done:
|
while not a.done:
|
||||||
a.go()
|
a.go()
|
||||||
|
|
||||||
r = sum([a.outputs[i:i+3][2] == 2 for i in range(0, len(a.outputs), 3)])
|
r = sum([a.outputs[i : i + 3][2] == 2 for i in range(0, len(a.outputs), 3)])
|
||||||
print(r)
|
print(r)
|
||||||
|
|
||||||
|
|
||||||
def part_2(data):
|
def part_2(data):
|
||||||
xs = str_to_ints(data)
|
xs = str_to_ints(data)
|
||||||
xs[0] = 2 # play for free
|
xs[0] = 2 # play for free
|
||||||
a = Amp(xs)
|
a = Amp(xs)
|
||||||
ball_x = 0
|
ball_x = 0
|
||||||
paddle_x = 0
|
paddle_x = 0
|
||||||
|
|||||||
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
|
self.rel_base = 0
|
||||||
|
|
||||||
def feed(self, input):
|
def feed(self, input):
|
||||||
|
self.input_required = False
|
||||||
self.inputs.append(input)
|
self.inputs.append(input)
|
||||||
|
|
||||||
def pop(self):
|
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 11: 21:04 (Too slow, but fun.)
|
||||||
- Day 12:
|
- Day 12:
|
||||||
- Day 13: >120:00 (Just struggling so much for some reason.)
|
- 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
|
## AoC 2022
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user