2018/Day20/Day20.py

131 lines
3.3 KiB
Python

from collections import deque
from pprint import pprint
NORTH = 1
EAST = 2
SOUTH = 4
WEST = 8
ROOT = 0
IN_PARENS = 1
SKIPPING = 2
start_pos = 200, 200
grid = [[0] * start_pos[0] * 2 for _ in range(start_pos[1] * 2)]
min_x, max_x = start_pos
min_y, max_y = start_pos
def print_grid(x_=None, y_=None):
for y in range(min_y, max_y + 1):
for x in range(min_x, max_x + 1):
print(end="@")
print(end="-" if grid[y][x] & NORTH else "@")
print("#")
for x in range(min_x, max_x + 1):
print(end="|" if grid[y][x] & WEST else "@")
if (x, y) == start_pos:
print(end="X")
elif x == x_ and y == y_:
print(end=".")
else:
print(end=" ")
print("@")
print("@" * ((max_x - min_x) * 2 + 3))
def parse_input(inp):
global min_x, max_x, min_y, max_y
# print(inp, end="\n\n")
# print("\033[2J\033[;H")
stack = [(0, start_pos[0], start_pos[1])]
while stack:
# print("===================================")
# print(stack, end=" -> ")
start, x, y = stack.pop()
# print(start)
depth = 0
skip_to_end = False
for i in range(start, len(inp)):
c = inp[i]
if depth == 0 and not skip_to_end:
# print(f"{depth} {inp[:i]}\033[4;3{depth+1}m{inp[i]}\033[0m{inp[i+1:]} ({x:>2},{y:>2}) -> ", end="")
if c == "N": grid[y][x] |= NORTH; y -= 1; grid[y][x] |= SOUTH
elif c == "E": grid[y][x] |= EAST; x += 1; grid[y][x] |= WEST
elif c == "S": grid[y][x] |= SOUTH; y += 1; grid[y][x] |= NORTH
elif c == "W": grid[y][x] |= WEST; x -= 1; grid[y][x] |= EAST
if x < min_x: min_x = x
if x > max_x: max_x = x
if y < min_y: min_y = y
if y > max_y: max_y = y
# print(f"({x:>2},{y:>2})")
# print_grid(x, y)
# print()
if c == "(" and not skip_to_end:
if depth == 0:
stack.append((i + 1, x, y))
depth += 1
elif c == "|" and not skip_to_end:
if depth == 1:
stack.append((i + 1, x, y))
elif depth == 0:
skip_to_end = True
elif c == ")":
depth -= 1
if depth == -1:
skip_to_end = False
break
# print()
# print("\033[0;0H", end="")
# print_grid()
def bfs():
pos = start_pos
queue = deque([(pos, 0)])
seen = set()
lengths = []
max_len = 0
long_paths = 0
while queue:
(x, y), depth = queue.popleft()
if (x, y) in seen:
continue
seen.add((x, y))
if depth > max_len:
max_len = depth
if depth >= 1000:
long_paths += 1
if grid[y][x] & WEST: queue.append(((x - 1, y), depth + 1))
if grid[y][x] & EAST: queue.append(((x + 1, y), depth + 1))
if grid[y][x] & NORTH: queue.append(((x, y - 1), depth + 1))
if grid[y][x] & SOUTH: queue.append(((x, y + 1), depth + 1))
print("part 1:", max_len)
print("part 2:", long_paths)
def main():
inp = input()
parse_input(inp[1:-1])
bfs()
main()