add 2024/day6
This commit is contained in:
parent
b3eaa7e433
commit
6c64d1b62e
1 changed files with 109 additions and 0 deletions
109
2024/06/main.py
Normal file
109
2024/06/main.py
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||||
|
|
||||||
|
# Author: Sebastian Mark
|
||||||
|
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||||||
|
|
||||||
|
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||||||
|
|
||||||
|
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
|
||||||
|
def readinput() -> str:
|
||||||
|
with open("input", "r", encoding="utf-8") as file:
|
||||||
|
lines = [list(line.strip()) for line in file]
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def find_guard(maze: list) -> tuple:
|
||||||
|
for idx, row in enumerate(maze):
|
||||||
|
try:
|
||||||
|
x = row.index("^")
|
||||||
|
y = idx
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return (x, y)
|
||||||
|
return tuple(-1, -1)
|
||||||
|
|
||||||
|
|
||||||
|
def move_guard(maze: list, guard: tuple) -> tuple[int, bool]:
|
||||||
|
width = len(maze[0])
|
||||||
|
height = len(maze)
|
||||||
|
|
||||||
|
path_history = {}
|
||||||
|
|
||||||
|
# remember the start position as visited
|
||||||
|
visited = set()
|
||||||
|
visited.add(guard)
|
||||||
|
|
||||||
|
# start upwards
|
||||||
|
direction = (0, -1)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# get next position
|
||||||
|
nxt = (
|
||||||
|
guard[0] + direction[0],
|
||||||
|
guard[1] + direction[1],
|
||||||
|
)
|
||||||
|
|
||||||
|
# check borders
|
||||||
|
if not (0 <= nxt[0] < width and 0 <= nxt[1] < height):
|
||||||
|
visited.add(guard)
|
||||||
|
break
|
||||||
|
|
||||||
|
# check for obstacle and rotate clockwise
|
||||||
|
if maze[nxt[1]][nxt[0]] == "#":
|
||||||
|
direction = (-direction[1], direction[0])
|
||||||
|
continue
|
||||||
|
|
||||||
|
# loop detection
|
||||||
|
# (has the guard been here and walking in the same direction?)
|
||||||
|
if nxt not in path_history:
|
||||||
|
path_history[nxt] = (guard, direction)
|
||||||
|
elif path_history[nxt] == (guard, direction):
|
||||||
|
return 0, True
|
||||||
|
|
||||||
|
# mark spot as visited and move guard
|
||||||
|
visited.add(guard)
|
||||||
|
guard = nxt
|
||||||
|
|
||||||
|
return len(visited), False
|
||||||
|
|
||||||
|
|
||||||
|
def print_maze(maze: list):
|
||||||
|
for row in maze:
|
||||||
|
print("".join(row))
|
||||||
|
print("-")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# part 1
|
||||||
|
maze = readinput()
|
||||||
|
guard = find_guard(maze)
|
||||||
|
count, _ = move_guard(maze, guard)
|
||||||
|
print("Guard positions: %d" % count)
|
||||||
|
|
||||||
|
# part 2
|
||||||
|
count = 0
|
||||||
|
maze = readinput()
|
||||||
|
guard = find_guard(maze)
|
||||||
|
|
||||||
|
# brute force:
|
||||||
|
# place an obstacle everywhere (except the guards position)
|
||||||
|
for row, _ in enumerate(maze):
|
||||||
|
for col, _ in enumerate(maze[0]):
|
||||||
|
if (col, row) == guard:
|
||||||
|
continue
|
||||||
|
new_maze = deepcopy(maze)
|
||||||
|
new_maze[row][col] = "#"
|
||||||
|
_, loop = move_guard(new_maze, guard)
|
||||||
|
if loop:
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
print("Loop options: %d" % count)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in a new issue