Added 12. part 2. fast (10x) solution
This commit is contained in:
		
							parent
							
								
									26a7b87c31
								
							
						
					
					
						commit
						0af5c11e6d
					
				@ -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 (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								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 {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user