124 lines
3.6 KiB
Python
124 lines
3.6 KiB
Python
import numpy as np
|
|
from queue import Queue
|
|
|
|
with open(r'advent_of_code\2023\day_10\input.txt', 'r') as file:
|
|
input = file.read()
|
|
|
|
simple_test_input = '''.....
|
|
.S-7.
|
|
.|.|.
|
|
.L-J.
|
|
.....'''
|
|
|
|
complex_test_input = '''7-F7-
|
|
.FJ|7
|
|
SJLL7
|
|
|F--J
|
|
LJ.LJ'''
|
|
|
|
# print(simple_test_input)
|
|
# print(complex_test_input)
|
|
|
|
#input = simple_test_input.split('\n')
|
|
#input = complex_test_input.split('\n')
|
|
input = input.split('\n')
|
|
#print(input)
|
|
|
|
|
|
NORTH = (-1, 0)
|
|
SOUTH = (1, 0)
|
|
WEST = (0, -1)
|
|
EAST = (0, 1)
|
|
|
|
pipe_directions = {
|
|
'|': (NORTH, SOUTH),
|
|
'-': (WEST, EAST),
|
|
'L': (NORTH, EAST),
|
|
'J': (NORTH, WEST),
|
|
'7': (WEST, SOUTH),
|
|
'F': (SOUTH, EAST),
|
|
'.': (),
|
|
}
|
|
|
|
|
|
def performLeeAlgorithm(pipe_map: list[list], distance_map: list[list], start_position: tuple[int]) -> None:
|
|
# Initialize a queue and add the start position to it
|
|
queue = Queue()
|
|
queue.put(start_position)
|
|
# Set the distance of the start position to 0
|
|
distance_map[start_position[0]][start_position[1]] = 0
|
|
|
|
# Continue until the queue is empty
|
|
while not queue.empty():
|
|
# Get the next position from the queue
|
|
current_row, current_col = queue.get()
|
|
# Iterate over the directions that the pipe at the current position allows
|
|
for delta_row, delta_col in pipe_directions[pipe_map[current_row][current_col]]:
|
|
# Calculate the next position
|
|
next_row, next_col = current_row + delta_row, current_col + delta_col
|
|
# If the next position is a pipe and its distance has not been set yet
|
|
if pipe_map[next_row][next_col] != '.' and distance_map[next_row][next_col] == -1:
|
|
# Set the distance of the next position
|
|
distance_map[next_row][next_col] = distance_map[current_row][current_col] + 1
|
|
# Add the next position to the queue
|
|
queue.put((next_row, next_col))
|
|
|
|
|
|
|
|
# Convert each row in the input to a list and store them in a list
|
|
pipe_map = [list(row) for row in input]
|
|
|
|
# Pad the pipe_map with '.' on all sides
|
|
pipe_map = np.pad(pipe_map, 1, constant_values='.')
|
|
|
|
# Create a distance_map with the same shape as pipe_map, filled with -1
|
|
distance_map = np.full_like(pipe_map, -1, dtype=np.int32)
|
|
|
|
# Convert pipe_map and distance_map to lists
|
|
pipe_map = pipe_map.tolist()
|
|
distance_map = distance_map.tolist()
|
|
|
|
# find start location
|
|
START = None
|
|
for i, row in enumerate(pipe_map):
|
|
for j, x in enumerate(row):
|
|
if x == 'S':
|
|
START = (i, j)
|
|
break
|
|
if START:
|
|
break
|
|
|
|
# Initialize the directions for the start ('S') pipe as an empty list
|
|
pipe_directions['S'] = []
|
|
|
|
# Define the start position
|
|
start_row, start_col = START
|
|
|
|
# Check the pipe in each direction from the start position
|
|
# If the pipe in that direction allows movement towards the start position, add the opposite direction to pipe_directions['S']
|
|
|
|
# Check the pipe to the north
|
|
north_pipe = pipe_map[start_row + NORTH[0]][start_col + NORTH[1]]
|
|
if SOUTH in pipe_directions[north_pipe]:
|
|
pipe_directions['S'].append(NORTH)
|
|
|
|
# Check the pipe to the south
|
|
south_pipe = pipe_map[start_row + SOUTH[0]][start_col + SOUTH[1]]
|
|
if NORTH in pipe_directions[south_pipe]:
|
|
pipe_directions['S'].append(SOUTH)
|
|
|
|
# Check the pipe to the east
|
|
east_pipe = pipe_map[start_row + EAST[0]][start_col + EAST[1]]
|
|
if WEST in pipe_directions[east_pipe]:
|
|
pipe_directions['S'].append(EAST)
|
|
|
|
# Check the pipe to the west
|
|
west_pipe = pipe_map[start_row + WEST[0]][start_col + WEST[1]]
|
|
if EAST in pipe_directions[west_pipe]:
|
|
pipe_directions['S'].append(WEST)
|
|
|
|
performLeeAlgorithm(pipe_map, distance_map, START)
|
|
|
|
print(np.max(distance_map))
|
|
|