diff --git a/day_12/example_data_01.txt b/day_12/example_data_01.txt new file mode 100644 index 0000000..cc5f968 --- /dev/null +++ b/day_12/example_data_01.txt @@ -0,0 +1,4 @@ +AAAA +BBCD +BBCC +EEEC \ No newline at end of file diff --git a/day_12/solution.go b/day_12/solution.go index 343bbf1..f3e1e54 100644 --- a/day_12/solution.go +++ b/day_12/solution.go @@ -23,6 +23,11 @@ func (m Map) At(x, y int) rune { return Empty } +func (v Visited) At(x, y int) bool { + _, visited := v[Point{x, y}] + return visited +} + // task:https://adventofcode.com/2024/day/12 func SolveBasic(input string) int { farmMap := loadMap(input) @@ -55,6 +60,7 @@ func SolveBasic(input string) int { parameter++ } } + sum += area * parameter } } @@ -63,6 +69,84 @@ func SolveBasic(input string) int { return sum } +// task:https://adventofcode.com/2024/day/12#part2 +func SolveComplex(input string) int { + farmMap := loadMap(input) + visited := Visited{} + + sum := 0 + + for y, row := range farmMap { + for x, value := range row { + p := Point{x, y} + field := Visited{} + if _, present := visited[p]; !present { + visit(farmMap, field, x, y, value) + area := len(field) + parameter := countEdges(farmMap, field) + + for point := range field { + // mark as visited to not visit it more than once + visited[point] = true + } + sum += area * parameter + } + } + } + return sum +} + +func countEdges(farmMap Map, field Visited) int { + borders := map[BorderPoint]bool{} + edges := 0 + + for y, row := range farmMap { + for x := range row { + if field.At(x, y) { + if !field.At(x-1, y) { + if !borders[BorderPoint{x, y - 1, LEFT}] { + edges++ + } + borders[BorderPoint{x, y, LEFT}] = true + } + if !field.At(x, y-1) { + if !borders[BorderPoint{x - 1, y, TOP}] { + edges++ + } + borders[BorderPoint{x, y, TOP}] = true + } + if !field.At(x, y+1) { + if !borders[BorderPoint{x - 1, y, BOTTOM}] { + edges++ + } + borders[BorderPoint{x, y, BOTTOM}] = true + } + if !field.At(x+1, y) { + if !borders[BorderPoint{x, y - 1, RIGHT}] { + edges++ + } + borders[BorderPoint{x, y, RIGHT}] = true + } + } + } + } + return edges +} + +type Direction int + +const ( + LEFT Direction = iota + TOP Direction = iota + RIGHT Direction = iota + BOTTOM Direction = iota +) + +type BorderPoint struct { + x, y int + direction Direction +} + func visit(farmMap Map, field Visited, x int, y int, value rune) { if _, visited := field[Point{x, y}]; visited { return @@ -77,11 +161,6 @@ func visit(farmMap Map, field Visited, x int, y int, value rune) { } } -// task:https://adventofcode.com/2024/day/12#part2 -func SolveComplex(input string) int { - return 0 -} - func loadMap(input string) Map { input = strings.ReplaceAll(input, "\r", "") topographicMap := Map{} diff --git a/day_12/solution_test.go b/day_12/solution_test.go index 53569bd..29a5048 100644 --- a/day_12/solution_test.go +++ b/day_12/solution_test.go @@ -9,6 +9,9 @@ import ( //go:embed example_data.txt var ExampleData string +//go:embed example_data_01.txt +var ExampleData01 string + func TestBasicSolutionExample(t *testing.T) { result := day_12.SolveBasic(ExampleData) if result != 1930 { @@ -18,7 +21,14 @@ func TestBasicSolutionExample(t *testing.T) { func TestComplexSolutionExample(t *testing.T) { result := day_12.SolveComplex(ExampleData) - if result != 2858 { - t.Fatalf("Expected 2858 received %d", result) + if result != 1206 { + t.Fatalf("Expected 1206 received %d", result) + } +} + +func TestComplexSolutionExample01(t *testing.T) { + result := day_12.SolveComplex(ExampleData01) + if result != 80 { + t.Fatalf("Expected 80 received %d", result) } }