Skip to content

Commit ea4f8a7

Browse files
committed
feat(2025): add day 7
1 parent 587b5f5 commit ea4f8a7

File tree

4 files changed

+148
-0
lines changed

4 files changed

+148
-0
lines changed

go/2025/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Collect stars by solving puzzles. Two puzzles will be made available on each day
2424
| [Day 4: Printing Department](https://github.com/believer/advent-of-code/blob/master/go/2025/puzzles/day04/main.go) | 🌟 | 1320 | 🌟 | 8354 |
2525
| [Day 5: Cafeteria](https://github.com/believer/advent-of-code/blob/master/go/2025/puzzles/day05/main.go) | 🌟 | 885 | 🌟 | 348115621205535 |
2626
| [Day 6: Trash Compactor](https://github.com/believer/advent-of-code/blob/master/go/2025/puzzles/day06/main.go) | 🌟 | 6209956042374 | 🌟 | 12608160008022 |
27+
| [Day 7: Laboratories](https://github.com/believer/advent-of-code/blob/master/go/2025/puzzles/day07/main.go) | 🌟 | 1711 | 🌟 | 36706966158365 |
2728

2829
## Benchmarks
2930

@@ -37,6 +38,7 @@ Using Go's built-in benchmarking with the [testing](https://pkg.go.dev/testing#h
3738
| 4 | 214451 | 5483916 | |
3839
| 5 | 116258 | 68155 | `96,29%` / - |
3940
| 6 | 149919 | 986335 | `30,99%` / - |
41+
| 7 | 671799 | 508323 | |
4042

4143
All values are ns/op. \* compared to first solution.
4244

go/2025/puzzles/day07/main.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/believer/aoc-utils/files"
7+
"github.com/believer/aoc-utils/grid"
8+
)
9+
10+
// I spent too much time trying to make a flawed solution work.
11+
// I thought of BFS (I've had it in the back of my mind that
12+
// it would appear at some point) but kept working on the path I had taken ':D
13+
// Eventually, I gave up and looked at my solution from day 18 2024 to remember.
14+
15+
func main() {
16+
fmt.Println("Part 1: ", part1("input.txt"))
17+
fmt.Println("Part 2: ", part2("input.txt"))
18+
}
19+
20+
func part1(name string) (splits int) {
21+
lines := files.ReadLines(name)
22+
manifold := grid.New(lines)
23+
start, _ := manifold.Find('S')
24+
25+
queue := []grid.Point{start}
26+
seen := map[grid.Point]bool{}
27+
28+
for len(queue) > 0 {
29+
beam := queue[0]
30+
queue = queue[1:]
31+
32+
// Keep track of what we've seen since beams
33+
// can split into the same position
34+
if _, ok := seen[beam]; ok {
35+
continue
36+
}
37+
38+
if !manifold.InBounds(beam) {
39+
continue
40+
}
41+
42+
seen[beam] = true
43+
44+
if manifold.Get(beam) == '^' {
45+
splits += 1
46+
leftSplit := beam.Add(grid.LEFT)
47+
rightSplit := beam.Add(grid.RIGHT)
48+
49+
queue = append(queue, leftSplit)
50+
queue = append(queue, rightSplit)
51+
} else {
52+
queue = append(queue, beam.Add(grid.DOWN))
53+
}
54+
}
55+
56+
return
57+
}
58+
59+
// Another thing I've had in mind would show up is Dynamic Programming (DP) which
60+
// I first learnt about in 2023 day 12. Essentially, it's taking a problem and breaking
61+
// it down into smaller subproblems and recursively solving them.
62+
//
63+
// I solved it without a seen cache first, which worked for the example, but it was
64+
// immediately clear that didn't work for the real input. A simple change and it worked.
65+
func part2(name string) int {
66+
lines := files.ReadLines(name)
67+
manifold := grid.New(lines)
68+
start, _ := manifold.Find('S')
69+
seen := map[grid.Point]int{}
70+
71+
return timelines(manifold, start, seen)
72+
}
73+
74+
func timelines(g grid.Grid, point grid.Point, seen map[grid.Point]int) int {
75+
if v, ok := seen[point]; ok {
76+
return v
77+
}
78+
79+
if !g.InBounds(point) {
80+
return 1
81+
}
82+
83+
if g.Get(point) == '^' {
84+
leftSplit := point.Add(grid.LEFT)
85+
rightSplit := point.Add(grid.RIGHT)
86+
87+
return timelines(g, leftSplit, seen) + timelines(g, rightSplit, seen)
88+
}
89+
90+
down := point.Add(grid.DOWN)
91+
result := timelines(g, down, seen)
92+
seen[down] = result
93+
94+
return result
95+
}

go/2025/puzzles/day07/main_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestPart1(t *testing.T) {
10+
t.Run("Part 1", func(t *testing.T) {
11+
expected := 21
12+
actual := part1("test-input.txt")
13+
assert.Equal(t, expected, actual)
14+
})
15+
}
16+
17+
func TestPart2(t *testing.T) {
18+
t.Run("Part 2", func(t *testing.T) {
19+
expected := 40
20+
actual := part2("test-input.txt")
21+
assert.Equal(t, expected, actual)
22+
})
23+
}
24+
25+
func BenchmarkPart1(b *testing.B) {
26+
for b.Loop() {
27+
part1("input.txt")
28+
}
29+
}
30+
31+
func BenchmarkPart2(b *testing.B) {
32+
for b.Loop() {
33+
part2("input.txt")
34+
}
35+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.......S.......
2+
...............
3+
.......^.......
4+
...............
5+
......^.^......
6+
...............
7+
.....^.^.^.....
8+
...............
9+
....^.^...^....
10+
...............
11+
...^.^...^.^...
12+
...............
13+
..^...^.....^..
14+
...............
15+
.^.^.^.^.^...^.
16+
...............

0 commit comments

Comments
 (0)