Skip to content

Commit 0c7c54b

Browse files
committed
Implement 2024 day 6
1 parent e9a5770 commit 0c7c54b

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

2024/src/aoc/days/day6.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import numpy
2+
3+
from . import SeparateRunner
4+
5+
6+
def does_loop(
7+
grid: numpy.array,
8+
x: int,
9+
y: int,
10+
dx: int,
11+
dy: int,
12+
visited: set[tuple[int, int, int, int]],
13+
) -> bool:
14+
try:
15+
while True:
16+
while y + dy >= 0 and x + dx >= 0 and grid[y + dy, x + dx] == "#":
17+
dx, dy = -dy, dx
18+
19+
x += dx
20+
y += dy
21+
22+
if x < 0 or y < 0:
23+
return False
24+
25+
pos = (x, y, dx, dy)
26+
27+
if pos in visited:
28+
return True
29+
else:
30+
visited.add(pos)
31+
except IndexError:
32+
return False
33+
34+
35+
class DayRunner(SeparateRunner):
36+
@classmethod
37+
def part1(cls, input: str) -> int:
38+
grid = input.strip().split("\n")
39+
40+
for y, line in enumerate(grid):
41+
if (x := line.find("^")) != -1:
42+
break
43+
44+
dx = 0
45+
dy = -1
46+
47+
visited = {(x, y)}
48+
49+
try:
50+
while True:
51+
nx = x + dx
52+
ny = y + dy
53+
54+
if grid[ny][nx] == "#":
55+
dx, dy = -dy, dx
56+
else:
57+
x, y = nx, ny
58+
visited.add((x, y))
59+
except IndexError:
60+
pass
61+
62+
return len(visited)
63+
64+
@classmethod
65+
def part2(cls, input: str) -> int:
66+
grid = numpy.array(list(map(list, input.strip().split("\n"))))
67+
y, x = numpy.where(grid == "^")
68+
69+
y = y[0]
70+
x = x[0]
71+
72+
dx = 0
73+
dy = -1
74+
loops = 0
75+
76+
visited = {(x, y, dx, dy)}
77+
tiles_visited = {(x, y)}
78+
79+
try:
80+
while True:
81+
while y + dy >= 0 and x + dx >= 0 and grid[y + dy, x + dx] == "#":
82+
dx, dy = -dy, dx
83+
84+
nx = x + dx
85+
ny = y + dy
86+
87+
if nx < 0 or ny < 0:
88+
break
89+
90+
if (nx, ny) not in tiles_visited:
91+
# check for a loop
92+
grid[ny, nx] = "#"
93+
if does_loop(grid, x, y, dx, dy, visited.copy()):
94+
loops += 1
95+
grid[ny, nx] = "L"
96+
else:
97+
grid[ny, nx] = "."
98+
99+
x, y = nx, ny
100+
tiles_visited.add((x, y))
101+
visited.add((x, y, dx, dy))
102+
except IndexError:
103+
pass
104+
105+
return loops

2024/tests/samples/06.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
....#.....
2+
.........#
3+
..........
4+
..#.......
5+
.......#..
6+
..........
7+
.#..^.....
8+
........#.
9+
#.........
10+
......#...

2024/tests/test_day6.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import os
2+
3+
from aoc.days.day6 import DayRunner
4+
5+
6+
def get_data() -> str:
7+
sample = os.path.dirname(__file__) + "/samples/06.txt"
8+
with open(sample, mode="rt", encoding="utf-8") as f:
9+
return f.read()
10+
11+
12+
def test_sample_part1() -> None:
13+
assert DayRunner.part1(get_data()) == 41
14+
15+
16+
def test_sample_part2() -> None:
17+
assert DayRunner.part2(get_data()) == 6

0 commit comments

Comments
 (0)