1from __future__ import annotations
2
3import collections
4import dataclasses
5
6@dataclasses.dataclass
7class TentativeMatch:
8 desired_letter: str
9 y: int
10 x: int
11 dy: int
12 dx: int
13
14def get_data():
15 data = []
16 with open("day_4_input.txt") as f:
17 for line in f:
18 data.append(line.strip())
19 return data
20
21def main(grid):
22 queue = collections.deque()
23 for y, row in enumerate(grid):
24 for x, _ in enumerate(row):
25 queue.append(TentativeMatch("X", y, x, 0, 0))
26
27 total = 0
28 while queue:
29 tm = queue.popleft()
30 if tm.y < 0 or tm.y >= len(grid):
31 continue
32 if tm.x < 0 or tm.x >= len(grid[0]):
33 continue
34
35 current_char = grid[tm.y][tm.x]
36
37 if current_char != tm.desired_letter:
38 continue
39
40 match current_char:
41 case 'X':
42 for dy, dx in [
43 [-1, -1],
44 [-1, 0],
45 [-1, 1],
46 [0, -1],
47 [0, 1],
48 [1, -1],
49 [1, 0],
50 [1, 1],
51 ]:
52 queue.append(TentativeMatch("M", tm.y + dy, tm.x + dx, dy, dx))
53 case 'M':
54 queue.append(TentativeMatch("A", tm.y + tm.dy, tm.x + tm.dx, tm.dy, tm.dx))
55 case "A":
56 queue.append(TentativeMatch("S", tm.y + tm.dy, tm.x + tm.dx, tm.dy, tm.dx))
57 case "S":
58 total += 1
59 case _:
60 pass
61
62 return total
63
64
65if __name__ == "__main__":
66 print(f"{main(get_data()) = }")
1from __future__ import annotations
2
3import collections
4import dataclasses
5
6@dataclasses.dataclass
7class TentativeMatch:
8 desired_letter: str
9 y: int
10 x: int
11
12def get_data():
13 data = []
14 with open("day_4_input_2.txt") as f:
15 for line in f:
16 data.append(line.strip())
17 return data
18
19def main(grid):
20 queue = collections.deque()
21 for y in range(1, len(grid) - 1):
22 for x in range(1, len(grid[0]) - 1):
23 queue.append(TentativeMatch("A", y, x))
24
25 total = 0
26 while queue:
27 tm = queue.popleft()
28
29 current_char = grid[tm.y][tm.x]
30
31 if current_char != tm.desired_letter:
32 continue
33
34 valid_1 = (grid[tm.y - 1][tm.x - 1], grid[tm.y + 1][tm.x + 1]) in [("M", "S"), ("S", "M")]
35 valid_2 = (grid[tm.y - 1][tm.x + 1], grid[tm.y + 1][tm.x - 1]) in [("M", "S"), ("S", "M")]
36
37 if valid_1 and valid_2:
38 total += 1
39
40 return total
41
42
43if __name__ == "__main__":
44 print(f"{main(get_data()) = }")