1
+ from typing import List
2
+
3
+ def get_board () -> List [List [str ]]:
4
+ board : List [List [str ]] = []
5
+ with open ('input' , 'r' ) as file :
6
+ for line in file :
7
+ board .append (line .strip ())
8
+
9
+ return board
10
+
11
+
12
+ def find_words (board : List [List [str ]]) -> int :
13
+ rows : int = len (board )
14
+ columns : int = len (board [0 ])
15
+
16
+ count : int = 0
17
+
18
+ for i in range (rows ):
19
+ for j in range (columns ):
20
+ # Initiate search only on X or S (looking for XMAS or SAMX)
21
+ if board [i ][j ] != 'X' and board [i ][j ] != 'S' :
22
+ continue
23
+
24
+ if j < columns - 3 :
25
+ if look_right (board , i , j ):
26
+ count = count + 1
27
+ if i > 2 :
28
+ if look_up (board , i , j ):
29
+ count = count + 1
30
+ if i > 2 and j < columns - 3 :
31
+ if look_up_right (board , i , j ):
32
+ count = count + 1
33
+ if i > 2 and j > 2 :
34
+ if look_up_left (board , i , j ):
35
+ count = count + 1
36
+ return count
37
+
38
+
39
+ def look_up (board : List [List [str ]], i : int , j : int ) -> bool :
40
+ if board [i ][j ] == 'X' and board [i - 1 ][j ] == 'M' and board [i - 2 ][j ] == 'A' and board [i - 3 ][j ] == 'S' :
41
+ return True
42
+ if board [i ][j ] == 'S' and board [i - 1 ][j ] == 'A' and board [i - 2 ][j ] == 'M' and board [i - 3 ][j ] == 'X' :
43
+ return True
44
+ return False
45
+
46
+
47
+ def look_up_right (board : List [List [str ]], i : int , j : int ) -> bool :
48
+ if board [i ][j ] == 'X' and board [i - 1 ][j + 1 ] == 'M' and board [i - 2 ][j + 2 ] == 'A' and board [i - 3 ][j + 3 ] == 'S' :
49
+ return True
50
+ if board [i ][j ] == 'S' and board [i - 1 ][j + 1 ] == 'A' and board [i - 2 ][j + 2 ] == 'M' and board [i - 3 ][j + 3 ] == 'X' :
51
+ return True
52
+ return False
53
+
54
+
55
+ def look_up_left (board : List [List [str ]], i : int , j : int ) -> bool :
56
+ if board [i ][j ] == 'X' and board [i - 1 ][j - 1 ] == 'M' and board [i - 2 ][j - 2 ] == 'A' and board [i - 3 ][j - 3 ] == 'S' :
57
+ return True
58
+ if board [i ][j ] == 'S' and board [i - 1 ][j - 1 ] == 'A' and board [i - 2 ][j - 2 ] == 'M' and board [i - 3 ][j - 3 ] == 'X' :
59
+ return True
60
+ return False
61
+
62
+
63
+ def look_right (board : List [List [str ]], i : int , j : int ) -> bool :
64
+ if board [i ][j ] == 'X' and board [i ][j + 1 ] == 'M' and board [i ][j + 2 ] == 'A' and board [i ][j + 3 ] == 'S' :
65
+ return True
66
+ if board [i ][j ] == 'S' and board [i ][j + 1 ] == 'A' and board [i ][j + 2 ] == 'M' and board [i ][j + 3 ] == 'X' :
67
+ return True
68
+ return False
69
+
70
+
71
+ def find_mas_cross (board : List [List [str ]]) -> int :
72
+ rows : int = len (board )
73
+ columns : int = len (board [0 ])
74
+
75
+ count : int = 0
76
+
77
+ for i in range (rows ):
78
+ for j in range (columns ):
79
+ # Initiate search only on A
80
+ if board [i ][j ] != 'A' :
81
+ continue
82
+
83
+ # Don't look for an 'A' on the outer borders since the cross can't appear there
84
+ if i > 0 and i < rows - 1 and j > 0 and j < columns - 1 :
85
+ if positive_slope_mas (board , i , j ) and negative_slope_mas (board , i , j ):
86
+ count = count + 1
87
+ return count
88
+
89
+
90
+ def positive_slope_mas (board : List [List [str ]], i : int , j : int ) -> bool :
91
+ if board [i - 1 ][j + 1 ] == 'M' and board [i + 1 ][j - 1 ] == 'S' :
92
+ return True
93
+ if board [i - 1 ][j + 1 ] == 'S' and board [i + 1 ][j - 1 ] == 'M' :
94
+ return True
95
+ return False
96
+
97
+
98
+ def negative_slope_mas (board : List [List [str ]], i : int , j : int ) -> bool :
99
+ if board [i - 1 ][j - 1 ] == 'M' and board [i + 1 ][j + 1 ] == 'S' :
100
+ return True
101
+ if board [i - 1 ][j - 1 ] == 'S' and board [i + 1 ][j + 1 ] == 'M' :
102
+ return True
103
+ return False
104
+
105
+
106
+ def main ():
107
+ board = get_board ()
108
+ #num_words = find_words(board) # Part 1
109
+ num_words = find_mas_cross (board ) # Part 2
110
+ print (num_words )
111
+
112
+
113
+ if __name__ == "__main__" :
114
+ main ()
0 commit comments