Skip to content

Commit abd063d

Browse files
committed
perf(2024): improve day 4
1 parent 781eae8 commit abd063d

File tree

3 files changed

+85
-66
lines changed

3 files changed

+85
-66
lines changed

go/2024/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Using Go's built-in benchmarking with the [testing](https://pkg.go.dev/testing#h
3636
| 1 | 116264 ns/op | 131233 ns/op | `3.53%` / `68.43%` |
3737
| 2 | 310935 ns/op | 723512 ns/op | |
3838
| 3 | 336448 ns/op | 785320 ns/op | - / `36.98%` |
39-
| 4 | 523315 ns/op | 217584 ns/op | `81.73%` / `26.09%` |
39+
| 4 | 250981 ns/op | 110358 ns/op | `91.24%` / `62.52%` |
4040
| 5 | 778880 ns/op | 3129873 ns/op | `53.34%` / `81.91%` |
4141
| 6 | 312461 ns/op | 1153391125 ns/op | |
4242
| 7 | 16480300 ns/op | 842853000 ns/op | `87.01%` / `91.67%` |
@@ -56,6 +56,7 @@ Using Go's built-in benchmarking with the [testing](https://pkg.go.dev/testing#h
5656
| 1 | 120513 ns/op | 155479 ns/op | - / `62,59%` | [Link](https://github.com/believer/advent-of-code/blob/ea42592462771b74de87eae6bea9c0ca892a4499/go/2024/puzzles/day01/main.go) |
5757
| 3 | 336448 ns/op | 1246155 ns/op | Baseline | [Link](https://github.com/believer/advent-of-code/blob/461c2dd40039c27102aa1790c650decb79d4f549/go/2024/puzzles/day03/main.go) |
5858
| 4 | 2864606 ns/op | 294413 ns/op | Baseline | [Link](https://github.com/believer/advent-of-code/blob/99909bb30f82cda079471134452d886a0eb6266f/go/2024/puzzles/day04/main.go) |
59+
| 4 | 523315 ns/op | 217584 ns/op | `81.73%` / `26.09%` | [Link](https://github.com/believer/advent-of-code/blob/431059e6b64faba3bc67c293b57ae299d3525bb9/go/2024/puzzles/day04/main.go) |
5960
| 5 | 1669175 ns/op | 17299190 ns/op | Baseline | [Link](https://github.com/believer/advent-of-code/blob/1db858ae3d391319511787d8935c76eecdf6b22f/go/2024/puzzles/day05/main.go) |
6061
| 7 | 126892714 ns/op | 10124683583 ns/op | Baseline | [Link](https://github.com/believer/advent-of-code/blob/dd735747021ce43ca3a7427c529813139737271e/go/2024/puzzles/day07/main.go) |
6162
| 7 | 110164692 ns/op | 7135839625 ns/op | `13.18%` / `29.52%` | [Link](https://github.com/believer/advent-of-code/blob/640d9604dfefa71f7bfef876750f378bd1a58a8b/go/2024/puzzles/day07/main.go) |

go/2024/puzzles/day04/main.go

Lines changed: 68 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55

66
"github.com/believer/aoc-2024/utils/files"
7+
"github.com/believer/aoc-2024/utils/grid"
78
)
89

910
// Changed part 1 to take a similar approach to what I did in part 2
@@ -14,43 +15,39 @@ func main() {
1415

1516
func part1(name string) int {
1617
lines := files.ReadLines(name)
18+
xmasGrid := grid.New(lines)
1719
xmas := 0
1820

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}
2124

22-
for r := range rows {
23-
for c := range cols {
2425
// Skip if not an X
25-
if string(lines[r][c]) != "X" {
26+
if xmasGrid.Get(point) != 'X' {
2627
continue
2728
}
2829

2930
// 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++
5451
}
5552
}
5653
}
@@ -61,53 +58,59 @@ func part1(name string) int {
6158

6259
func part2(name string) int {
6360
lines := files.ReadLines(name)
61+
xmasGrid := grid.New(lines)
6462
xmas := 0
6563

66-
rows := len(lines)
67-
cols := len(lines[0])
68-
6964
// 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+
7269
// 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 {
7479
continue
7580
}
7681

7782
// 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+
}
9094

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+
}
97101

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+
}
104108

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++
111114
}
112115
}
113116
}

go/2024/utils/grid/grid.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,22 @@ var UP = Point{0, -1}
1313
var DOWN = Point{0, 1}
1414
var RIGHT = Point{1, 0}
1515
var LEFT = Point{-1, 0}
16+
var TOPLEFT = Point{-1, -1}
17+
var TOPRIGHT = Point{1, -1}
18+
var BOTTOMLEFT = Point{-1, 1}
19+
var BOTTOMRIGHT = Point{1, 1}
20+
1621
var CARDINALS = []Point{UP, DOWN, LEFT, RIGHT}
22+
var ALL_DIRECTIONS = []Point{
23+
TOPLEFT,
24+
UP,
25+
TOPRIGHT,
26+
RIGHT,
27+
BOTTOMRIGHT,
28+
DOWN,
29+
BOTTOMLEFT,
30+
LEFT,
31+
}
1732

1833
func (p *Point) Add(p2 Point) Point {
1934
return Point{p.X + p2.X, p.Y + p2.Y}

0 commit comments

Comments
 (0)