From 0af5c11e6d2b2396427a5d4bbff3a49ab51ef8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Borna=20Rajkovi=C4=87?= Date: Thu, 12 Dec 2024 19:44:27 +0100 Subject: [PATCH] Added 12. part 2. fast (10x) solution --- day_12/solution.go | 80 +++++++++++++++++++++++++++++++++++++++++++--- main.go | 7 ++++ 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/day_12/solution.go b/day_12/solution.go index f3e1e54..4423009 100644 --- a/day_12/solution.go +++ b/day_12/solution.go @@ -47,16 +47,16 @@ func SolveBasic(input string) int { // mark as visited to not visit it more than once visited[point] = true - if _, present := field[Point{point.x - 1, point.y}]; !present { + if farmMap.At(point.x-1, point.y) != value { parameter++ } - if _, present := field[Point{point.x + 1, point.y}]; !present { + if farmMap.At(point.x+1, point.y) != value { parameter++ } - if _, present := field[Point{point.x, point.y - 1}]; !present { + if farmMap.At(point.x, point.y-1) != value { parameter++ } - if _, present := field[Point{point.x, point.y + 1}]; !present { + if farmMap.At(point.x, point.y+1) != value { parameter++ } } @@ -96,6 +96,35 @@ func SolveComplex(input string) int { return sum } +// task:https://adventofcode.com/2024/day/12#part2 +// there is no need to iterate over the whole table, +// more importantly there is no need to look at the set as we at the Map +func SolveComplexFast(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 := countEdgesFast(farmMap, field, value) + + 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 @@ -133,6 +162,49 @@ func countEdges(farmMap Map, field Visited) int { return edges } +func countEdgesFast(farmMap Map, field Visited, value rune) int { + edges := 0 + + for p := range field { + hasN := farmMap.At(p.x, p.y-1) == value + hasW := farmMap.At(p.x-1, p.y) == value + hasS := farmMap.At(p.x, p.y+1) == value + hasE := farmMap.At(p.x+1, p.y) == value + hasNW := farmMap.At(p.x-1, p.y-1) == value + hasNE := farmMap.At(p.x+1, p.y-1) == value + hasSW := farmMap.At(p.x-1, p.y+1) == value + hasSE := farmMap.At(p.x+1, p.y+1) == value + + // inner corner + if hasN && hasW && !hasNW { + edges++ + } + if hasN && hasE && !hasNE { + edges++ + } + if hasS && hasW && !hasSW { + edges++ + } + if hasS && hasE && !hasSE { + edges++ + } + // outer corner + if !hasN && !hasW { + edges++ + } + if !hasN && !hasE { + edges++ + } + if !hasS && !hasW { + edges++ + } + if !hasS && !hasE { + edges++ + } + } + return edges +} + type Direction int const ( diff --git a/main.go b/main.go index c77fd92..6cd5255 100644 --- a/main.go +++ b/main.go @@ -16,11 +16,14 @@ import ( _ "embed" "fmt" "os" + "time" ) func main() { selectedDay := selectSolutionRun() + start := time.Now() + switch selectedDay { case "01-basic": fmt.Printf("Day 01. Basic: %d\n", day_01.SolveBasic(Day01Data)) // 2113135 @@ -70,7 +73,11 @@ func main() { fmt.Printf("Day 12. Basic: %d\n", day_12.SolveBasic(Day12Data)) // case "12-complex": fmt.Printf("Day 12. Complex: %d\n", day_12.SolveComplex(Day12Data)) // + case "12-complex-fast": + fmt.Printf("Day 12. Complex (fast): %d\n", day_12.SolveComplexFast(Day12Data)) // } + elapsed := time.Since(start) + fmt.Printf("Solution took: %s", elapsed) } func selectSolutionRun() string {