Slightly smarter day 11 solution
This commit is contained in:
parent
773a676ba0
commit
1ba622901e
1 changed files with 61 additions and 30 deletions
|
|
@ -8,47 +8,78 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func update(stones map[int]int) map[int]int {
|
||||
processed := make(map[int]int)
|
||||
for stone, count := range stones {
|
||||
if stone == 0 {
|
||||
processed[1] += count
|
||||
continue
|
||||
}
|
||||
|
||||
places := int(math.Log10(float64(stone))) + 1
|
||||
if places%2 == 0 {
|
||||
half := places / 2
|
||||
divisor := int(math.Pow10(half))
|
||||
|
||||
left := stone / divisor
|
||||
right := stone % divisor
|
||||
|
||||
processed[left] += count
|
||||
processed[right] += count
|
||||
continue
|
||||
}
|
||||
|
||||
processed[stone*2024] += count
|
||||
}
|
||||
|
||||
return processed
|
||||
type Key struct {
|
||||
times, stone int
|
||||
}
|
||||
|
||||
func Part1(stones map[int]int, steps int) int {
|
||||
for i := 0; i < steps; i++ {
|
||||
stones = update(stones)
|
||||
var splitCache = make(map[int][]int)
|
||||
var splitCacheHits, splitCacheMisses int
|
||||
|
||||
var cache = make(map[Key]int)
|
||||
var cacheHits, cacheMisses int
|
||||
|
||||
func split(stone int) (int, int) {
|
||||
if val, ok := splitCache[stone]; ok {
|
||||
splitCacheHits++
|
||||
return val[0], val[1]
|
||||
}
|
||||
|
||||
sum := 0
|
||||
for _, count := range stones {
|
||||
sum += count
|
||||
}
|
||||
splitCacheMisses++
|
||||
|
||||
return sum
|
||||
half := (int(math.Log10(float64(stone))) + 1) / 2
|
||||
divisor := int(math.Pow10(half))
|
||||
|
||||
left := stone / divisor
|
||||
right := stone % divisor
|
||||
|
||||
splitCache[stone] = []int{left, right}
|
||||
|
||||
return left, right
|
||||
}
|
||||
|
||||
func Part2(stones map[int]int, steps int) int {
|
||||
func cacheKey(key Key, value int) int {
|
||||
cache[key] = value
|
||||
return value
|
||||
}
|
||||
|
||||
func update(stone int, depth int) int {
|
||||
key := Key{depth, stone}
|
||||
|
||||
if count, exists := cache[key]; exists {
|
||||
cacheMisses++
|
||||
return count
|
||||
}
|
||||
|
||||
cacheHits++
|
||||
|
||||
if depth == 0 {
|
||||
return cacheKey(key, 1)
|
||||
}
|
||||
|
||||
if stone == 0 {
|
||||
return cacheKey(key, update(1, depth-1))
|
||||
}
|
||||
|
||||
places := int(math.Log10(float64(stone))) + 1
|
||||
if places%2 == 0 {
|
||||
split1, split2 := split(stone)
|
||||
result := update(split1, depth-1) + update(split2, depth-1)
|
||||
return cacheKey(key, result)
|
||||
}
|
||||
|
||||
return cacheKey(key, update(stone*2024, depth-1))
|
||||
}
|
||||
|
||||
func Part1(stones []int, steps int) int {
|
||||
result := 0
|
||||
for _, stone := range stones {
|
||||
result += update(stone, steps)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Part2(stones []int, steps int) int {
|
||||
return Part1(stones, steps)
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +90,7 @@ func Run(filename string) (int, int) {
|
|||
}
|
||||
defer file.Close()
|
||||
|
||||
stones := make(map[int]int)
|
||||
stones := []int{}
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
|
|
@ -71,7 +102,7 @@ func Run(filename string) (int, int) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
stones[id] += 1
|
||||
stones = append(stones, id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue