Noëlle Anthony 2 settimane fa
parent
commit
cc071ab7a5
1 ha cambiato i file con 219 aggiunte e 0 eliminazioni
  1. 219
    0
      day06-1.py

+ 219
- 0
day06-1.py Vedi File

@@ -0,0 +1,219 @@
import argparse
import enum
import logging

from sys import stdout
from typing import List, Tuple

logger = logging.Logger(__name__)
logger_2 = logging.Logger(f"{__name__}_2")
formatter = logging.Formatter('[%(asctime)s][%(levelname)s] %(message)s')
sh = logging.StreamHandler(stdout)
sh.setLevel(logging.INFO)
sh.setFormatter(formatter)
fh = logging.FileHandler("./day02-2.log", mode="w", encoding="utf-8")
fh_2 = logging.FileHandler("./day02-2_round2.log", mode="w", encoding="utf-8")
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
fh_2.setLevel(logging.DEBUG)
fh_2.setFormatter(formatter)
logger.addHandler(sh)
logger.addHandler(fh)
logger_2.addHandler(fh_2)

class Direction(enum.Enum):
UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3

class Guard:
def __init__(self, grid: List[List[str]], initial_x: int = None, initial_y: int = None, initial_dir: int = None, test_mode: bool = False) -> object:
self.grid = grid
self.height = len(self.grid)
self.width = len(self.grid[0])
logger.info(f"Received a grid with {self.height} lines and {self.width} characters per line.")
self.initial_x = initial_x
self.x = self.initial_x
self.initial_y = initial_y
self.y = self.initial_y
self.initial_dir = initial_dir
self.dir = self.initial_dir
self.test_mode = test_mode
self.visited = set()
self.traveled = 1

def whereami(self) -> Tuple[int,int]:
# Identify the guard's initial position and direction in the grid
breakout = False
x,y,dir = None,None,None
for j, line in enumerate(self.grid):
if breakout:
break
for i, char in enumerate(line):
if char in ["^",">","<","v"]:
x, y = i, j
match char:
case "^":
dir = Direction.UP
case ">":
dir = Direction.RIGHT
case "v":
dir = Direction.DOWN
case "<":
dir = Direction.LEFT
case "_":
raise ValueError(f"char must be one of '^','>','v','<', received {char}")
breakout = True
break
self.initial_x = x
self.x = self.initial_x
self.initial_y = y
self.y = self.initial_y
self.initial_dir = dir
self.dir = self.initial_dir

return (x,y)

def proceed(self):
if self.dir is None:
logger.error("You can't move until you have a direction set.")
raise ValueError
logger.info(f"Proceeding {self.dir}")
match self.dir:
case Direction.UP:
return self.go_north()
case Direction.RIGHT:
return self.go_east()
case Direction.DOWN:
return self.go_south()
case Direction.LEFT:
return self.go_west()
case _:
logger.error(f"Unknown direction! {self.dir}")
raise ValueError
def go_north(self) -> bool:
path = [self.grid[y][self.x] for y in range(self.y-1, -1, -1)]
logger.info(f"Path created from {self.x},{self.y} to {self.x},{0}: {path}.")
exited = "#" not in path
if exited:
blocked = 999999
else:
blocked = path.index("#")
if self.test_mode:
logger.info(f"Found a blocker at ({self.x}, {self.y-blocked-1}).")
for i, char in enumerate(path[:blocked+1]):
j = i + 1 if exited else i
if self.test_mode:
logger.info(f"Walked to ({self.x}, {self.y-j}).")
self.visited.add((self.x, self.y-j))
self.traveled += 1
new_y = self.y - (blocked)
self.y = new_y
self.dir = Direction.RIGHT
return exited
def go_east(self) -> bool:
path = [self.grid[self.y][x] for x in range(self.x+1, self.width)]
logger.info(f"Path created from {self.x},{self.y} to {self.width-1},{self.y}: {path}.")
exited = "#" not in path
if exited:
blocked = 999999
else:
blocked = path.index("#")
if self.test_mode:
logger.info(f"Found a blocker at ({self.x+blocked+1}, {self.y}).")
for i, char in enumerate(path[:blocked+1]):
j = i + 1 if exited else i
if self.test_mode:
logger.info(f"Walked to ({self.x+j}, {self.y}).")
self.visited.add((self.x+j, self.y))
self.traveled += 1
new_x = self.x + (blocked)
self.x = new_x
self.dir = Direction.DOWN
return exited
def go_south(self) -> bool:
path = [self.grid[y][self.x] for y in range(self.y+1, self.height)]
logger.info(f"Path created from {self.x},{self.y} to {self.x},{self.height}: {path}.")
exited = "#" not in path
if exited:
blocked = 999999
else:
blocked = path.index("#")
if self.test_mode:
logger.info(f"Found a blocker at ({self.x}, {self.y+blocked+1}).")
for i, char in enumerate(path[:blocked+1]):
j = i + 1 if exited else i
if self.test_mode:
logger.info(f"Walked to ({self.x}, {self.y+j}).")
self.visited.add((self.x, self.y+j))
self.traveled += 1
new_y = self.y + (blocked)
self.y = new_y
self.dir = Direction.LEFT
return exited
def go_west(self) -> bool:
path = [self.grid[self.y][x] for x in range(self.x-1, -1, -1)]
logger.info(f"Path created from {self.x},{self.y} to {0},{self.y}: {path}.")
exited = "#" not in path
if exited:
blocked = 999999
else:
blocked = path.index("#")
if self.test_mode:
logger.info(f"Found a blocker at ({self.x-blocked-1}, {self.y}).")
for i, char in enumerate(path[:blocked+1]):
j = i + 1 if exited else i
if self.test_mode:
logger.info(f"Walked to ({self.x-j}, {self.y}).")
self.visited.add((self.x-j, self.y))
self.traveled += 1
new_x = self.x - (blocked)
self.x = new_x
self.dir = Direction.UP
return exited
def pathfind(self):
exited = False
while not exited:
exited = self.proceed()
logger.info(f"Found an exit after {self.traveled} steps!")


parser = argparse.ArgumentParser()
parser.add_argument("--test", action="store_true", help="Do a test run instead of the full puzzle")

def main061():
args = parser.parse_args()
if args.test:
input_grid = """....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#..."""
grid = [list(l) for l in input_grid.split("\n")]
print("\n".join(["".join(line) for line in grid]))
else:
with open("input06.txt", "r", encoding="utf-8") as f:
grid = [list(l) for l in f.readlines()]

guard = Guard(grid, test_mode=args.test)
logger.info(f"Guard has been created: x:{guard.x}, y:{guard.y}, dir:{guard.dir}, test_mode:{guard.test_mode}, width:{guard.width}, height:{guard.height}.")
guard_position = guard.whereami()
logger.info(f"Starting guard's walk at {guard_position}.")
guard.pathfind()
logger.info(f"The guard visited {len(guard.visited)} unique positions.")


if __name__ == "__main__":
main061()

Loading…
Annulla
Salva