summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2023-12-16 09:45:40 +0000
committerTomasz Kramkowski <tomasz@kramkow.ski>2023-12-16 09:45:40 +0000
commitc30b831007c0e663d545c55cab87e7d257aa0293 (patch)
tree0be645219fe11f234c7a82d6c00dd1031a642c9e
parent26e310aeb37169d4d739dce00528bff944c9386f (diff)
downloadaoc2023-c30b831007c0e663d545c55cab87e7d257aa0293.tar.gz
aoc2023-c30b831007c0e663d545c55cab87e7d257aa0293.tar.xz
aoc2023-c30b831007c0e663d545c55cab87e7d257aa0293.zip
day 16
-rw-r--r--16.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/16.py b/16.py
new file mode 100644
index 0000000..aaf6d0c
--- /dev/null
+++ b/16.py
@@ -0,0 +1,85 @@
+from collections import deque
+from enum import Enum, auto
+from sys import stdin
+
+
+class Dir(Enum):
+ NORTH = auto()
+ EAST = auto()
+ SOUTH = auto()
+ WEST = auto()
+
+
+def step(direction: Dir, pos: tuple[int, int]) -> tuple[int, int]:
+ match direction:
+ case Dir.NORTH:
+ return pos[0], pos[1] - 1
+ case Dir.EAST:
+ return pos[0] + 1, pos[1]
+ case Dir.SOUTH:
+ return pos[0], pos[1] + 1
+ case Dir.WEST:
+ return pos[0] - 1, pos[1]
+
+
+inp = [line.rstrip("\n") for line in stdin]
+
+
+def solve(inp: list[str], start: tuple[Dir, tuple[int, int]]) -> int:
+ beams: deque[tuple[Dir, tuple[int, int]]] = deque((start,))
+ old_beams: set[tuple[Dir, tuple[int, int]]] = set()
+ covered: set[tuple[int, int]] = set()
+
+ def add(direction: Dir, pos: tuple[int, int]):
+ t = (direction, step(direction, pos))
+ if t in old_beams:
+ return
+ old_beams.add(t)
+ beams.append(t)
+
+ while beams:
+ direction, pos = beams.popleft()
+ x, y = pos
+ if x < 0 or x >= len(inp[0]) or y < 0 or y >= len(inp):
+ continue
+ covered.add(pos)
+ c = inp[y][x]
+ if (
+ c == "."
+ or (c == "-" and direction in {Dir.EAST, Dir.WEST})
+ or (c == "|" and direction in {Dir.NORTH, Dir.SOUTH})
+ ):
+ add(direction, pos)
+ elif c == "|":
+ add(Dir.NORTH, pos)
+ add(Dir.SOUTH, pos)
+ elif c == "-":
+ add(Dir.EAST, pos)
+ add(Dir.WEST, pos)
+ else:
+ mapping: dict[tuple[str, Dir], Dir] = {
+ ("/", Dir.NORTH): Dir.EAST,
+ ("/", Dir.EAST): Dir.NORTH,
+ ("/", Dir.SOUTH): Dir.WEST,
+ ("/", Dir.WEST): Dir.SOUTH,
+ ("\\", Dir.NORTH): Dir.WEST,
+ ("\\", Dir.EAST): Dir.SOUTH,
+ ("\\", Dir.SOUTH): Dir.EAST,
+ ("\\", Dir.WEST): Dir.NORTH,
+ }
+ add(mapping[c, direction], pos)
+
+ return len(covered)
+
+
+print(solve(inp, (Dir.EAST, (0, 0))))
+
+p2 = 0
+for x in range(len(inp[0])):
+ p2 = max(p2, solve(inp, (Dir.SOUTH, (x, 0))))
+ p2 = max(p2, solve(inp, (Dir.NORTH, (x, len(inp)))))
+
+for y in range(len(inp)):
+ p2 = max(p2, solve(inp, (Dir.EAST, (0, y))))
+ p2 = max(p2, solve(inp, (Dir.WEST, (len(inp[0]), y))))
+print(p2)