Skip to content

Commit 89fa671

Browse files
committed
[2024] Solution for Day 12
1 parent 311284c commit 89fa671

File tree

2 files changed

+134
-4
lines changed

2 files changed

+134
-4
lines changed

2024/day12/main.go

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77

88
"github.com/kfarnung/advent-of-code/2024/lib"
9+
"golang.org/x/exp/slices"
910
)
1011

1112
type point struct {
@@ -33,8 +34,25 @@ func part1(input string) int64 {
3334
return sum
3435
}
3536

36-
func part2(_ string) int64 {
37-
return int64(0)
37+
func part2(input string) int64 {
38+
garden := parseInput(input)
39+
40+
sum := int64(0)
41+
seen := make(map[point]bool)
42+
43+
for i, row := range garden {
44+
for j, _ := range row {
45+
location := point{i, j}
46+
if seen[location] {
47+
continue
48+
}
49+
50+
area, perimeter := findAreaAndSides(garden, i, j, seen)
51+
sum += area * perimeter
52+
}
53+
}
54+
55+
return sum
3856
}
3957

4058
func findAreaAndPerimeter(garden [][]rune, i, j int, seen map[point]bool) (int64, int64) {
@@ -84,6 +102,118 @@ func findAreaAndPerimeter(garden [][]rune, i, j int, seen map[point]bool) (int64
84102
return area, perimeter
85103
}
86104

105+
func findAreaAndSides(garden [][]rune, i, j int, seen map[point]bool) (int64, int64) {
106+
area := int64(0)
107+
region := garden[i][j]
108+
109+
var queue []point
110+
queue = append(queue, point{x: i, y: j})
111+
112+
edgesTop := make(map[point]bool)
113+
edgesBottom := make(map[point]bool)
114+
edgesLeft := make(map[point]bool)
115+
edgesRight := make(map[point]bool)
116+
117+
for len(queue) > 0 {
118+
current := queue[0]
119+
queue = queue[1:]
120+
121+
if seen[current] {
122+
continue
123+
}
124+
125+
seen[current] = true
126+
area++
127+
128+
if current.x > 0 && garden[current.x-1][current.y] == region {
129+
queue = append(queue, point{x: current.x - 1, y: current.y})
130+
} else {
131+
edgesTop[current] = true
132+
}
133+
134+
if current.x < len(garden)-1 && garden[current.x+1][current.y] == region {
135+
queue = append(queue, point{x: current.x + 1, y: current.y})
136+
} else {
137+
edgesBottom[current] = true
138+
}
139+
140+
if current.y > 0 && garden[current.x][current.y-1] == region {
141+
queue = append(queue, point{x: current.x, y: current.y - 1})
142+
} else {
143+
edgesLeft[current] = true
144+
}
145+
146+
if current.y < len(garden[0])-1 && garden[current.x][current.y+1] == region {
147+
queue = append(queue, point{x: current.x, y: current.y + 1})
148+
} else {
149+
edgesRight[current] = true
150+
}
151+
}
152+
153+
return area, countEdges(edgesTop, false) + countEdges(edgesBottom, false) + countEdges(edgesLeft, true) + countEdges(edgesRight, true)
154+
}
155+
156+
func countEdges(edges map[point]bool, leftRight bool) int64 {
157+
var keys []point
158+
for k := range edges {
159+
keys = append(keys, k)
160+
}
161+
162+
slices.SortFunc(keys, func(i, j point) int {
163+
if leftRight {
164+
if i.y < j.y {
165+
return -1
166+
}
167+
168+
if i.y > j.y {
169+
return 1
170+
}
171+
172+
if i.x < j.x {
173+
return -1
174+
}
175+
176+
if i.x > j.x {
177+
return 1
178+
}
179+
} else {
180+
if i.x < j.x {
181+
return -1
182+
}
183+
184+
if i.x > j.x {
185+
return 1
186+
}
187+
188+
if i.y < j.y {
189+
return -1
190+
}
191+
192+
if i.y > j.y {
193+
return 1
194+
}
195+
}
196+
197+
return 0
198+
})
199+
200+
x := -2
201+
y := -2
202+
sides := int64(0)
203+
for _, key := range keys {
204+
if !leftRight && (x != key.x || y+1 != key.y) {
205+
sides++
206+
} else if leftRight && (y != key.y || x+1 != key.x) {
207+
sides++
208+
}
209+
210+
x = key.x
211+
y = key.y
212+
}
213+
214+
return sides
215+
}
216+
87217
func parseInput(input string) [][]rune {
88218
var data [][]rune
89219
for _, line := range lib.SplitLines(input) {

2024/day12/main_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ func TestPart1(t *testing.T) {
3434
}
3535

3636
func TestPart2(t *testing.T) {
37-
assert.Equal(t, int64(0), part2(input))
37+
assert.Equal(t, int64(1206), part2(input))
3838

3939
inputContent, err := lib.GetInputContent()
4040
if err != nil {
4141
t.Fatal(err)
4242
}
4343

44-
assert.Equal(t, int64(0), part2(inputContent))
44+
assert.Equal(t, int64(914966), part2(inputContent))
4545
}

0 commit comments

Comments
 (0)