Slightly smarter day 11 solution

This commit is contained in:
Ceferino Patino 2024-12-11 22:54:47 -06:00
commit 1ba622901e
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI

View file

@ -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)
}
}