Skip to content

Commit

Permalink
Added day 6 for 2024
Browse files Browse the repository at this point in the history
  • Loading branch information
RemcoSchrijver committed Dec 6, 2024
1 parent e2a9650 commit 42f68a0
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 1 deletion.
1 change: 0 additions & 1 deletion 2024/src/day05.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import re
import sys
from inputs import load_input

Expand Down
144 changes: 144 additions & 0 deletions 2024/src/day06.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import copy
import sys
from inputs import load_input


def part1() -> int:
input_strings = load_input("./input/day06")
grid = create_grid(input_strings)
starting_position = get_starting_position(input_strings)
traversed_tiles = get_traversed_tiles(starting_position, grid)
return len(set(traversed_tiles))


def part2() -> int:
input_strings = load_input("./input/day06")
grid = create_grid(input_strings)
starting_position = get_starting_position(input_strings)
sum = traverse_while_introducing_blockers(starting_position, (-1, 0), grid)
return sum


def create_grid(input_strings: list[str]) -> list[list[bool]]:
grid = []
for y in range(len(input_strings)):
row = []
input_row = input_strings[y].strip()
for x in range(len(input_row)):
if input_strings[y][x] == "#":
row.append(False)
else:
row.append(True)
grid.append(row)
return grid


def get_starting_position(input_strings: list[str]) -> tuple[int, int]:
for y in range(len(input_strings)):
for x in range(len(input_strings[y])):
if input_strings[y][x] == "^":
return (y, x)
raise RuntimeError("Starting position not found")


def get_traversed_tiles(
starting_position: tuple[int, int], grid: list[list[bool]]
) -> list[tuple[int, int]]:
current_position = starting_position
traversed_tiles = [starting_position]
vector = (-1, 0)
while not out_of_bounds(current_position, vector, grid):
next_position = calculate_next_position(current_position, vector, grid)
if current_position != next_position:
current_position = next_position
traversed_tiles.append(next_position)
else:
vector = rotate_vector(vector)
return traversed_tiles


def calculate_next_position(
current_position: tuple[int, int], vector: tuple[int, int], grid: list[list[bool]]
) -> tuple[int, int]:
continued_vector = add_tuple(current_position, vector)
if get_tile(continued_vector, grid):
current_position = continued_vector
return current_position


def traverse_while_introducing_blockers(
starting_position: tuple[int, int],
start_vector: tuple[int, int],
grid: list[list[bool]],
) -> int:
traversed_tiles = set(get_traversed_tiles(starting_position, grid))
traversed_tiles.remove(starting_position)
sum = 0
for each in traversed_tiles:
new_grid = introduce_blocker(each, grid)
can_be_blocked = traverse_with_loop_check(
starting_position, start_vector, new_grid
)
if can_be_blocked:
sum += 1
return sum


def introduce_blocker(
blocker_position: tuple[int, int], grid: list[list[bool]]
) -> list[list[bool]]:
new_grid = copy.deepcopy(grid)
new_grid[blocker_position[0]][blocker_position[1]] = False
return new_grid


def traverse_with_loop_check(
starting_position: tuple[int, int],
start_vector: tuple[int, int],
grid: list[list[bool]],
) -> bool:
current_position = starting_position
vector = start_vector
traversed: set[tuple[tuple[int, int], tuple[int, int]]] = set()
while not out_of_bounds(current_position, vector, grid):
if (current_position, vector) in traversed:
return True
next_position = calculate_next_position(current_position, vector, grid)
if current_position != next_position:
traversed.add((current_position, vector))
current_position = next_position
else:
vector = rotate_vector(vector)
return False


def out_of_bounds(
position: tuple[int, int], vector: tuple[int, int], grid: list[list[bool]]
) -> bool:
y_max = len(grid)
(y, x) = add_tuple(position, vector)
return y < 0 or y >= y_max or x < 0 or x >= len(grid[y])


def add_tuple(tuple1: tuple[int, int], tuple2: tuple[int, int]) -> tuple[int, int]:
return (tuple1[0] + tuple2[0], tuple1[1] + tuple2[1])


def get_tile(position: tuple[int, int], grid: list[list[bool]]) -> bool:
return grid[position[0]][position[1]]


def rotate_vector(vector: tuple[int, int]) -> tuple[int, int]:
if vector == (-1, 0):
return (0, 1)
elif vector == (0, 1):
return (1, 0)
elif vector == (1, 0):
return (0, -1)
elif vector == (0, -1):
return (-1, 0)
raise RuntimeError("Invalid rotation")


if __name__ == "__main__":
print(globals()[sys.argv[1]]())

0 comments on commit 42f68a0

Please sign in to comment.