4
4
"fmt"
5
5
6
6
"github.com/believer/aoc-2024/utils/files"
7
+ "github.com/believer/aoc-2024/utils/grid"
7
8
)
8
9
9
10
// Changed part 1 to take a similar approach to what I did in part 2
@@ -14,43 +15,39 @@ func main() {
14
15
15
16
func part1 (name string ) int {
16
17
lines := files .ReadLines (name )
18
+ xmasGrid := grid .New (lines )
17
19
xmas := 0
18
20
19
- rows := len (lines )
20
- cols := len (lines [0 ])
21
+ for y := range xmasGrid .Height {
22
+ for x := range xmasGrid .Width {
23
+ point := grid.Point {X : x , Y : y }
21
24
22
- for r := range rows {
23
- for c := range cols {
24
25
// Skip if not an X
25
- if string ( lines [ r ][ c ] ) != "X" {
26
+ if xmasGrid . Get ( point ) != 'X' {
26
27
continue
27
28
}
28
29
29
30
// Check all directions
30
- for _ , dr := range []int {- 1 , 0 , 1 } {
31
- for _ , dc := range []int {- 1 , 0 , 1 } {
32
- if dr == 0 && dc == 0 {
33
- continue
34
- }
35
-
36
- // Check bounds
37
- threeDown := r + 3 * dr
38
- threeForwards := c + 3 * dc
39
- hasSpaceDown := threeDown >= 0 && threeDown < rows
40
- hasSpaceForwards := threeForwards >= 0 && threeForwards < cols
41
-
42
- if ! hasSpaceDown || ! hasSpaceForwards {
43
- continue
44
- }
45
-
46
- // Check that the next three letters are MAS
47
- nextIsM := string (lines [r + dr ][c + dc ]) == "M"
48
- nextIsA := string (lines [r + 2 * dr ][c + 2 * dc ]) == "A"
49
- nextIsS := string (lines [r + 3 * dr ][c + 3 * dc ]) == "S"
50
-
51
- if nextIsM && nextIsA && nextIsS {
52
- xmas ++
53
- }
31
+ for _ , d := range grid .ALL_DIRECTIONS {
32
+ dx , dy := d .X , d .Y
33
+
34
+ // Do we have enough items to check?
35
+ offByThree := grid.Point {X : x + 3 * dx , Y : y + 3 * dy }
36
+
37
+ if _ , ok := xmasGrid .Contains (offByThree ); ! ok {
38
+ continue
39
+ }
40
+
41
+ offByOne := grid.Point {X : x + dx , Y : y + dy }
42
+ offByTwo := grid.Point {X : x + 2 * dx , Y : y + 2 * dy }
43
+
44
+ // Check that the next three letters are MAS
45
+ isM := xmasGrid .Get (offByOne ) == 'M'
46
+ isA := xmasGrid .Get (offByTwo ) == 'A'
47
+ isS := xmasGrid .Get (offByThree ) == 'S'
48
+
49
+ if isM && isA && isS {
50
+ xmas ++
54
51
}
55
52
}
56
53
}
@@ -61,53 +58,59 @@ func part1(name string) int {
61
58
62
59
func part2 (name string ) int {
63
60
lines := files .ReadLines (name )
61
+ xmasGrid := grid .New (lines )
64
62
xmas := 0
65
63
66
- rows := len (lines )
67
- cols := len (lines [0 ])
68
-
69
64
// Skip checking edge characters since any A here can't result in a X-MAS
70
- for r := range rows - 1 {
71
- for c := range cols - 1 {
65
+ for y := range xmasGrid .Height - 1 {
66
+ for x := range xmasGrid .Width - 1 {
67
+ point := grid.Point {X : x , Y : y }
68
+
72
69
// A's are always in the middle
73
- if string (lines [r ][c ]) != "A" {
70
+ if xmasGrid .Get (point ) != 'A' {
71
+ continue
72
+ }
73
+
74
+ if _ , ok := xmasGrid .Contains (point .Add (grid .TOPLEFT )); ! ok {
75
+ continue
76
+ }
77
+
78
+ if _ , ok := xmasGrid .Contains (point .Add (grid .BOTTOMRIGHT )); ! ok {
74
79
continue
75
80
}
76
81
77
82
// Check line above and below
78
- if r - 1 >= 0 && c - 1 >= 0 && r + 1 < rows && c + 1 < cols {
79
- diagonalTopLeft := string (lines [r - 1 ][c - 1 ])
80
- diagonalTopRight := string (lines [r - 1 ][c + 1 ])
81
- diagonalBottomLeft := string (lines [r + 1 ][c - 1 ])
82
- diagonalBottomRight := string (lines [r + 1 ][c + 1 ])
83
-
84
- // M.M
85
- // .A.
86
- // S.S
87
- if diagonalTopLeft == "M" && diagonalBottomRight == "S" && diagonalTopRight == "M" && diagonalBottomLeft == "S" {
88
- xmas ++
89
- }
83
+ diagonalTopLeft := xmasGrid .Get (point .Add (grid .TOPLEFT ))
84
+ diagonalTopRight := xmasGrid .Get (point .Add (grid .TOPRIGHT ))
85
+ diagonalBottomLeft := xmasGrid .Get (point .Add (grid .BOTTOMLEFT ))
86
+ diagonalBottomRight := xmasGrid .Get (point .Add (grid .BOTTOMRIGHT ))
87
+
88
+ // M.M
89
+ // .A.
90
+ // S.S
91
+ if diagonalTopLeft == 'M' && diagonalBottomRight == 'S' && diagonalTopRight == 'M' && diagonalBottomLeft == 'S' {
92
+ xmas ++
93
+ }
90
94
91
- // M.S
92
- // .A.
93
- // M.S
94
- if diagonalTopLeft == "M" && diagonalBottomRight == "S" && diagonalTopRight == "S" && diagonalBottomLeft == "M" {
95
- xmas ++
96
- }
95
+ // M.S
96
+ // .A.
97
+ // M.S
98
+ if diagonalTopLeft == 'M' && diagonalBottomRight == 'S' && diagonalTopRight == 'S' && diagonalBottomLeft == 'M' {
99
+ xmas ++
100
+ }
97
101
98
- // S.S
99
- // .A.
100
- // M.M
101
- if diagonalTopLeft == "S" && diagonalBottomRight == "M" && diagonalTopRight == "S" && diagonalBottomLeft == "M" {
102
- xmas ++
103
- }
102
+ // S.S
103
+ // .A.
104
+ // M.M
105
+ if diagonalTopLeft == 'S' && diagonalBottomRight == 'M' && diagonalTopRight == 'S' && diagonalBottomLeft == 'M' {
106
+ xmas ++
107
+ }
104
108
105
- // S.M
106
- // .A.
107
- // S.M
108
- if diagonalTopLeft == "S" && diagonalBottomRight == "M" && diagonalTopRight == "M" && diagonalBottomLeft == "S" {
109
- xmas ++
110
- }
109
+ // S.M
110
+ // .A.
111
+ // S.M
112
+ if diagonalTopLeft == 'S' && diagonalBottomRight == 'M' && diagonalTopRight == 'M' && diagonalBottomLeft == 'S' {
113
+ xmas ++
111
114
}
112
115
}
113
116
}
0 commit comments