From c30b831007c0e663d545c55cab87e7d257aa0293 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Sat, 16 Dec 2023 09:45:40 +0000 Subject: day 16 --- 16.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 16.py 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) -- cgit v1.2.3-54-g00ecf