2023/day10.py

152 lines
3.8 KiB
Python

from collections import deque
import fileinput
from pprint import pprint
from dataclasses import dataclass
map = []
(sx, sy) = (0, 0)
for (j, line) in enumerate(fileinput.input()):
map.append(list(line.strip()))
if (x := line.find("S")) != -1:
(sx, sy) = (x, j)
seen = set()
queue: deque[tuple[int, int, int]] = deque([(sx, sy, 0)])
distances = [[None] * len(map[0]) for _ in range(len(map))]
NS = "|"
WE = "-"
NE = "L"
NW = "J"
SW = "7"
SE = "F"
part1 = 0
while queue:
(x, y, l) = queue.popleft()
if (x, y) in seen:
continue
seen.add((x, y))
distances[y][x] = l
part1 = l
match map[y][x]:
case "S":
if map[y - 1][x] in "|7F":
queue.append((x, y - 1, l + 1))
if map[y + 1][x] in "|LJ":
queue.append((x, y + 1, l + 1))
if map[y][x - 1] in "-LF":
queue.append((x - 1, y, l + 1))
if map[y][x + 1] in "-J7":
queue.append((x + 1, y, l + 1))
case "|":
queue.append((x, y - 1, l + 1))
queue.append((x, y + 1, l + 1))
case "-":
queue.append((x - 1, y, l + 1))
queue.append((x + 1, y, l + 1))
case "L":
queue.append((x + 1, y, l + 1))
queue.append((x, y - 1, l + 1))
case "J":
queue.append((x - 1, y, l + 1))
queue.append((x, y - 1, l + 1))
case "7":
queue.append((x - 1, y, l + 1))
queue.append((x, y + 1, l + 1))
case "F":
queue.append((x + 1, y, l + 1))
queue.append((x, y + 1, l + 1))
part1 = 0
for l in distances:
part1 = max(part1, 0, *[i for i in l if i])
print(part1)
side = set()
for y in range(len(map)):
if map[y][0] == ".": side.add((0, y))
if map[y][-1] == ".": side.add((len(map[0]) - 1, y))
for x in range(len(map[0])):
if map[0][x] == ".": side.add((x, 0))
if map[-1][x] == ".": side.add((x, len(map) - 1))
mapp = []
for (x, row) in enumerate(map):
r = []
for (y, c) in enumerate(row):
match c:
case ".":
r.append(["..."]*3)
case "S":
r.append([".X.","XXX",".X."])
case "-":
r.append(["...","XXX","..."])
case "|":
r.append([".X.",".X.",".X."])
case "7":
r.append(["...","XX.",".X."])
case "F":
r.append(["...",".XX",".X."])
case "J":
r.append([".X.","XX.","..."])
case "L":
r.append([".X.",".XX","..."])
mapp.append(r)
bigmap = []
for row in mapp:
for y in range(3):
r = []
for col in row:
for x in range(3):
r.append(col[y][x])
bigmap.append(r)
print(r)
exterior = []
for y in range(len(bigmap)):
if bigmap[y][0] == ".":
exterior.append((0, y))
if bigmap[y][-1] == ".":
exterior.append((len(bigmap[0]) - 1, y))
for x in range(len(bigmap[0])):
if bigmap[0][x] == ".":
exterior.append((x, 0))
if bigmap[-1][x] == ".":
exterior.append((x, len(bigmap) - 1))
for (x, y) in exterior:
if y < 0 or y > len(bigmap) - 1:
continue
if x < 0 or x > len(bigmap[y]) - 1:
continue
if bigmap[y][x] != ".":
continue
bigmap[y][x] = "O"
exterior.append((x - 1, y))
exterior.append((x + 1, y))
exterior.append((x, y - 1))
exterior.append((x, y + 1))
for row in distances:
for c in row:
print("X" if c is not None else ".", end="")
print()
part2 = 0
for y in range(1, len(bigmap), 3):
for x in range(1, len(bigmap[y]), 3):
if bigmap[y][x] == "." or (distances[y // 3][x // 3] is None):
part2 += 1
map[y//3][x//3] = 'I'
print(part1, part2)