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 typing import TypeAlias
from collections import defaultdict
from .aoc import Aoc2, AocSameParser
from .day11 import Matrix
@ -14,34 +13,172 @@ class Day14(AocSameParser[P1], Aoc2[P1, P2]):
return Matrix(inpt)
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 x in range(0, inpt.width): # enumerate(line):
pos_matrix[x, y] = (x, y)
north_matrix[x, y] = (x, y)
if y > 0:
if inpt[x, y - 1] == ".":
pos_matrix[x, y] = pos_matrix[x, y - 1]
if inpt[x, y - 1] == "O":
p = pos_matrix[x, y - 1]
pos_matrix[x, y] = (p[0], p[1] + 1)
north_matrix[x, y] = north_matrix[x, y - 1]
new_o_pos = []
for ox, oy in o_pos:
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
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
return sum(inpt.height - oy for _, oy in new_o_pos)
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:
aoc = Day14(2023, 14)
aoc = Day14(2023, 14, example_code_nr2=0)
aoc.run()