solved Day16 in python
This commit is contained in:
84
Day16/python/solution1.py
Normal file
84
Day16/python/solution1.py
Normal file
@@ -0,0 +1,84 @@
|
||||
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()
|
||||
111
Day16/python/solution2.py
Normal file
111
Day16/python/solution2.py
Normal file
@@ -0,0 +1,111 @@
|
||||
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 find_best_configuration(G, DR, DC):
|
||||
"""Finds the configuration that energizes the most tiles."""
|
||||
max_energized = 0
|
||||
for r in range(len(G)):
|
||||
for c in range(len(G[0])):
|
||||
if r == 0: # Top row, beam enters downward
|
||||
energized = score(G, r, c, 2, DR, DC)
|
||||
max_energized = max(max_energized, energized)
|
||||
elif r == len(G) - 1: # Bottom row, beam enters upward
|
||||
energized = score(G, r, c, 0, DR, DC)
|
||||
max_energized = max(max_energized, energized)
|
||||
if c == 0: # Leftmost column, beam enters rightward
|
||||
energized = score(G, r, c, 1, DR, DC)
|
||||
max_energized = max(max_energized, energized)
|
||||
elif c == len(G[0]) - 1: # Rightmost column, beam enters leftward
|
||||
energized = score(G, r, c, 3, DR, DC)
|
||||
max_energized = max(max_energized, energized)
|
||||
return max_energized
|
||||
|
||||
|
||||
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}"
|
||||
|
||||
max_tiles_energized = find_best_configuration(G, DR, DC)
|
||||
expected_energized = 51
|
||||
assert (
|
||||
max_tiles_energized == expected_energized
|
||||
), f"Test failed: Expected {expected_energized}, got {max_tiles_energized}"
|
||||
|
||||
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]
|
||||
max_tiles_energized = find_best_configuration(G, DR, DC)
|
||||
print(f"Maximum number of tiles energized: {max_tiles_energized}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user