This commit is contained in:
Christoph Stahl 2023-12-14 20:06:48 +01:00
parent 06ac7e2b6d
commit 46edd68a1c

View file

@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
from typing import TypeAlias from typing import TypeAlias
from collections import defaultdict
from .aoc import Aoc2, AocSameParser from .aoc import Aoc2, AocSameParser
from .day11 import Matrix from .day11 import Matrix
@ -14,34 +13,172 @@ class Day14(AocSameParser[P1], Aoc2[P1, P2]):
return Matrix(inpt) return Matrix(inpt)
def part1(self, inpt: P1) -> int: def part1(self, inpt: P1) -> int:
pos_matrix = {} o_pos: frozenset[tuple[int, int]] = frozenset(
(o.x, o.y) for o in inpt.finditer("O")
)
for p in o_pos:
inpt[p] = "."
north_matrix = {}
for y in range(0, inpt.height): # enumerate(inpt.iter_rows()): for y in range(0, inpt.height): # enumerate(inpt.iter_rows()):
for x in range(0, inpt.width): # enumerate(line): for x in range(0, inpt.width): # enumerate(line):
pos_matrix[x, y] = (x, y) north_matrix[x, y] = (x, y)
if y > 0: if y > 0:
if inpt[x, y - 1] == ".": if inpt[x, y - 1] == ".":
pos_matrix[x, y] = pos_matrix[x, y - 1] north_matrix[x, y] = north_matrix[x, y - 1]
if inpt[x, y - 1] == "O": new_o_pos = []
p = pos_matrix[x, y - 1] for ox, oy in o_pos:
pos_matrix[x, y] = (p[0], p[1] + 1) new_x, new_y = north_matrix[ox, oy]
while (new_x, new_y) in new_o_pos:
new_y += 1
new_o_pos.append((new_x, new_y))
accum = 0 return sum(inpt.height - oy for _, oy in new_o_pos)
for o in inpt.finditer("O"):
# print(
# f"{o} -> {pos_matrix[(o.x,o.y)]} ({inpt.height - pos_matrix[(o.x,o.y)][1]})"
# )
accum += inpt.height - pos_matrix[(o.x, o.y)][1]
print(accum)
return accum
def part2(self, inpt: P2) -> int: def part2(self, inpt: P2) -> int:
return 0 o_pos: frozenset[tuple[int, int]] = frozenset(
(o.x, o.y) for o in inpt.finditer("O")
)
for p in o_pos:
inpt[p] = "."
north_matrix = {}
for y in range(0, inpt.height): # enumerate(inpt.iter_rows()):
for x in range(0, inpt.width): # enumerate(line):
north_matrix[x, y] = (x, y)
if y > 0:
if inpt[x, y - 1] == ".":
north_matrix[x, y] = north_matrix[x, y - 1]
west_matrix = {}
for y in range(0, inpt.height): # enumerate(inpt.iter_rows()):
for x in range(0, inpt.width): # enumerate(line):
west_matrix[x, y] = (x, y)
if x > 0:
if inpt[x - 1, y] == ".":
west_matrix[x, y] = west_matrix[x - 1, y]
south_matrix = {}
for y in reversed(range(0, inpt.height)): # enumerate(inpt.iter_rows()):
for x in range(0, inpt.width): # enumerate(line):
south_matrix[x, y] = (x, y)
if y < inpt.height - 1:
if inpt[x, y + 1] == ".":
south_matrix[x, y] = south_matrix[x, y + 1]
east_matrix = {}
for y in range(0, inpt.height): # enumerate(inpt.iter_rows()):
for x in reversed(range(0, inpt.width)): # enumerate(line):
east_matrix[x, y] = (x, y)
if x < inpt.width - 1:
if inpt[x + 1, y] == ".":
east_matrix[x, y] = east_matrix[x + 1, y]
cache = {}
stepsize = -1
loopstart = -1
for i in range(1_000_000_000):
# for i in range(2):
north_pos = set()
for ox, oy in o_pos:
new_x, new_y = north_matrix[ox, oy]
while (new_x, new_y) in north_pos:
new_y += 1
north_pos.add((new_x, new_y))
# west
west_pos = set()
for ox, oy in north_pos:
new_x, new_y = west_matrix[ox, oy]
while (new_x, new_y) in west_pos:
new_x += 1
west_pos.add((new_x, new_y))
# south
south_pos = set()
for ox, oy in west_pos:
new_x, new_y = south_matrix[ox, oy]
while (new_x, new_y) in south_pos:
new_y -= 1
south_pos.add((new_x, new_y))
# east
east_pos = set()
for ox, oy in south_pos:
new_x, new_y = east_matrix[ox, oy]
while (new_x, new_y) in east_pos:
new_x -= 1
east_pos.add((new_x, new_y))
o_pos = frozenset(east_pos)
# north_matrix = {}
# for y in range(0, inpt.height): # enumerate(inpt.iter_rows()):
# for x in range(0, inpt.width): # enumerate(line):
# north_matrix[x, y] = (x, y)
# if y > 0:
# if (x, y - 1) in o_pos:
# p = north_matrix[x, y - 1]
# north_matrix[x, y] = (p[0], p[1] + 1)
# elif inpt[x, y - 1] == ".":
# north_matrix[x, y] = north_matrix[x, y - 1]
# o_pos = frozenset(north_matrix[pos] for pos in o_pos)
#
# west_matrix = {}
# for y in range(0, inpt.height): # enumerate(inpt.iter_rows()):
# for x in range(0, inpt.width): # enumerate(line):
# west_matrix[x, y] = (x, y)
# if x > 0:
# if (x - 1, y) in o_pos:
# p = west_matrix[x - 1, y]
# west_matrix[x, y] = (p[0] + 1, p[1])
# elif inpt[x - 1, y] == ".":
# west_matrix[x, y] = west_matrix[x - 1, y]
# o_pos = frozenset(west_matrix[pos] for pos in o_pos)
#
# south_matrix = {}
# for y in reversed(range(0, inpt.height)): # enumerate(inpt.iter_rows()):
# for x in range(0, inpt.width): # enumerate(line):
# south_matrix[x, y] = (x, y)
# if y < inpt.height - 1:
# if (x, y + 1) in o_pos:
# p = south_matrix[x, y + 1]
# south_matrix[x, y] = (p[0], p[1] - 1)
# elif inpt[x, y + 1] == ".":
# south_matrix[x, y] = south_matrix[x, y + 1]
# o_pos = frozenset(south_matrix[pos] for pos in o_pos)
#
# east_matrix = {}
# for y in range(0, inpt.height): # enumerate(inpt.iter_rows()):
# for x in reversed(range(0, inpt.width)): # enumerate(line):
# east_matrix[x, y] = (x, y)
# if x < inpt.width - 1:
# if (x + 1, y) in o_pos:
# p = east_matrix[x + 1, y]
# east_matrix[x, y] = (p[0] - 1, p[1])
# elif inpt[x + 1, y] == ".":
# east_matrix[x, y] = east_matrix[x + 1, y]
# o_pos = frozenset(east_matrix[pos] for pos in o_pos)
if o_pos in cache:
if stepsize < 0:
loopstart = cache[o_pos]
stepsize = i - cache[o_pos]
if cache[o_pos] == (1000000000 - loopstart) % stepsize + loopstart - 1:
break
else:
cache[o_pos] = i
accum = 0
for _, oy in o_pos:
accum += inpt.height - oy
for p in o_pos:
inpt[p] = "O"
return accum
def main() -> None: def main() -> None:
aoc = Day14(2023, 14) aoc = Day14(2023, 14, example_code_nr2=0)
aoc.run() aoc.run()