advent_of_code_2023/Day16/python/solution1.py
2023-12-16 21:35:31 +01:00

85 lines
2.6 KiB
Python

import sys
def read_grid(file_path):
"""Reads the grid from a file."""
try:
with open(file_path, "r") as file:
return [list(line.strip()) for line in file.readlines()]
except FileNotFoundError:
print(f"Error: File '{file_path}' not found.")
sys.exit(1)
except Exception as e:
print(f"Error reading file '{file_path}': {e}")
sys.exit(1)
def step(r, c, d, DR, DC):
"""Calculates the next position and direction of the beam."""
return (r + DR[d], c + DC[d], d)
def score(G, sr, sc, sd, DR, DC):
"""Calculates the number of unique tiles energized by the beam."""
POS = [(sr, sc, sd)]
SEEN = set()
SEEN2 = set()
while POS:
NP = []
for r, c, d in POS:
if 0 <= r < len(G) and 0 <= c < len(G[0]):
SEEN.add((r, c))
if (r, c, d) in SEEN2:
continue
SEEN2.add((r, c, d))
ch = G[r][c]
if ch == ".":
NP.append(step(r, c, d, DR, DC))
elif ch == "/":
NP.append(step(r, c, {0: 1, 1: 0, 2: 3, 3: 2}[d], DR, DC))
elif ch == "\\":
NP.append(step(r, c, {0: 3, 1: 2, 2: 1, 3: 0}[d], DR, DC))
elif ch == "|":
if d in [0, 2]:
NP.append(step(r, c, d, DR, DC))
else:
NP.append(step(r, c, 0, DR, DC))
NP.append(step(r, c, 2, DR, DC))
elif ch == "-":
if d in [1, 3]:
NP.append(step(r, c, d, DR, DC))
else:
NP.append(step(r, c, 1, DR, DC))
NP.append(step(r, c, 3, DR, DC))
else:
assert False, f"Invalid character '{ch}' in grid."
POS = NP
return len(SEEN)
def test():
"""Test function to verify the implementation with test data."""
G = read_grid("../test.txt")
DR = [-1, 0, 1, 0]
DC = [0, 1, 0, -1]
result = score(G, 0, 0, 1, DR, DC)
expected_result = 46 # Change this to the expected result of your test
assert (
result == expected_result
), f"Test failed: Expected {expected_result}, got {result}"
print("Test passed.")
def main():
"""Main function to run the algorithm with actual puzzle input."""
test() # Run test first
G = read_grid("../input.txt")
DR = [-1, 0, 1, 0]
DC = [0, 1, 0, -1]
result = score(G, 0, 0, 1, DR, DC)
print(f"Number of tiles energized: {result}")
if __name__ == "__main__":
main()