Skip to content
This repository was archived by the owner on Dec 28, 2024. It is now read-only.

Commit 279074e

Browse files
committed
Add solution day 12 part 1
1 parent 6856b68 commit 279074e

File tree

4 files changed

+184
-2
lines changed

4 files changed

+184
-2
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
main
2+
13
input/*
24
!input/.gitkeep
35

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,5 @@ automatically rebuilt and redeployed ever time the `common` module or their own
5656
| 09 | | 22 | |
5757
| 10 | ⭐ ⭐ | 23 | |
5858
| 11 | ⭐ ⭐ | 24 | |
59-
| 12 | | 25 | |
59+
| 12 | | 25 | |
6060
| 13 | | | |

main

-7.2 MB
Binary file not shown.

solutions/day12/main.go

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,189 @@
11
package main
22

33
import (
4+
"fmt"
45
"github.com/terminalnode/adventofcode2024/common"
6+
"github.com/terminalnode/adventofcode2024/common/util"
7+
"log"
8+
"strings"
59
)
610

11+
type plotMap = [][]plot
12+
type plot struct {
13+
Label int
14+
Hash string
15+
}
16+
717
func main() {
8-
common.Setup(12, nil, nil)
18+
common.Setup(12, part1, nil)
19+
}
20+
21+
func part1(
22+
input string,
23+
) string {
24+
sum := 0
25+
fields := 0
26+
plots := parsePlots(input)
27+
visited := make(map[string]bool)
28+
29+
rows := len(plots)
30+
for y := 0; y < rows; y++ {
31+
columns := len(plots[y])
32+
for x := 0; x < columns; x++ {
33+
c := util.Coordinate{X: x, Y: y}
34+
area, perimeter, _ := countField(plots, c, visited)
35+
sum += area * perimeter
36+
37+
if area != 0 {
38+
label := plots[y][x].Label
39+
log.Printf("Field %c at (%d,%d), area=%d, perim=%d", label, x, y, area, perimeter)
40+
fields++
41+
}
42+
}
43+
}
44+
45+
return fmt.Sprintf("Area * perimeter of %d fields: %d", fields, sum)
46+
}
47+
48+
func part2(
49+
input string,
50+
) string {
51+
sum := 0
52+
fields := 0
53+
plots := parsePlots(input)
54+
visited := make(map[string]bool)
55+
56+
rows := len(plots)
57+
for y := 0; y < rows; y++ {
58+
columns := len(plots[y])
59+
for x := 0; x < columns; x++ {
60+
c := util.Coordinate{X: x, Y: y}
61+
area, _, corners := countField(plots, c, visited)
62+
sum += area * corners
63+
64+
if area != 0 {
65+
label := plots[y][x].Label
66+
log.Printf("Field %c at (%d,%d), area=%d, corners=%d", label, x, y, area, corners)
67+
fields++
68+
}
69+
}
70+
}
71+
72+
return fmt.Sprintf("Area * sides of %d fields: %d", fields, sum)
73+
}
74+
75+
func parsePlots(
76+
input string,
77+
) plotMap {
78+
lines := strings.Split(input, "\n")
79+
m := make([][]plot, len(lines))
80+
81+
for y, row := range lines {
82+
m[y] = make([]plot, len(row))
83+
for x, char := range row {
84+
c := util.Coordinate{X: x, Y: y}
85+
p := plot{Label: int(char), Hash: c.String()}
86+
m[y][x] = p
87+
}
88+
}
89+
90+
return m
91+
}
92+
93+
func countField(
94+
plots plotMap,
95+
c util.Coordinate,
96+
visited map[string]bool,
97+
) (int, int, int) {
98+
if visited[c.String()] {
99+
return 0, 0, 0
100+
}
101+
visited[c.String()] = true
102+
103+
area := 1
104+
perimeter := 0
105+
106+
n := c.North()
107+
e := c.East()
108+
s := c.South()
109+
w := c.West()
110+
111+
label := plots[c.Y][c.X].Label
112+
nSame := isSameField(plots, label, n)
113+
eSame := isSameField(plots, label, e)
114+
sSame := isSameField(plots, label, s)
115+
wSame := isSameField(plots, label, w)
116+
corners := countCorners(nSame, eSame, sSame, wSame)
117+
118+
if nSame {
119+
a, p, c := countField(plots, n, visited)
120+
area += a
121+
perimeter += p
122+
corners += c
123+
} else {
124+
perimeter++
125+
}
126+
127+
if eSame {
128+
a, p, c := countField(plots, e, visited)
129+
area += a
130+
perimeter += p
131+
corners += c
132+
} else {
133+
perimeter++
134+
}
135+
136+
if sSame {
137+
a, p, c := countField(plots, s, visited)
138+
area += a
139+
perimeter += p
140+
corners += c
141+
} else {
142+
perimeter++
143+
}
144+
145+
if wSame {
146+
a, p, c := countField(plots, w, visited)
147+
area += a
148+
perimeter += p
149+
corners += c
150+
} else {
151+
perimeter++
152+
}
153+
154+
return area, perimeter, corners
155+
}
156+
157+
func isSameField(
158+
plots plotMap,
159+
label int,
160+
c util.Coordinate,
161+
) bool {
162+
if !util.In2DArray(c, plots) {
163+
return false
164+
}
165+
cell := plots[c.Y][c.X]
166+
return cell.Label == label
167+
}
168+
169+
func countCorners(
170+
nSame bool,
171+
eSame bool,
172+
sSame bool,
173+
wSame bool,
174+
) int {
175+
sum := 0
176+
if !nSame && !eSame {
177+
sum++
178+
}
179+
if !nSame && !wSame {
180+
sum++
181+
}
182+
if !sSame && !eSame {
183+
sum++
184+
}
185+
if !sSame && !wSame {
186+
sum++
187+
}
188+
return sum
9189
}

0 commit comments

Comments
 (0)