Files
advent-of-code-2024/day11/stones_cached.go

94 lines
1.9 KiB
Go
Raw Normal View History

2024-12-15 21:38:26 +01:00
package main
import (
"os"
"fmt"
"strconv"
"strings"
)
// ---------------------------------------
type Stone int64
func (s Stone) blink() [2]Stone {
stones := [...]Stone{-1, -1}
num_str := strconv.Itoa(int(s))
switch {
// rule 1
case s == 0:
stones[0] = 1
// rule 2
case len(num_str) % 2 == 0:
num1, err := strconv.Atoi(num_str[:len(num_str) / 2])
check(err)
num2, err := strconv.Atoi(num_str[len(num_str) / 2:])
check(err)
stones[0] = Stone(num1)
stones[1] = Stone(num2)
// rule 3
default:
stones[0] = s * 2024
}
return stones
}
// ---------------------------------------
type Pair struct {
s Stone
n_steps uint32
}
var population_number_cache map[Pair]uint64
func population_number(s Stone, n_steps uint32) uint64 {
cache := population_number_cache[Pair{s, n_steps}]
if cache != 0 { return cache }
new_stones := s.blink()
if n_steps == 0 { return 1 }
p := population_number(new_stones[0], n_steps - 1)
if new_stones[1] > -1 {
p += population_number(new_stones[1], n_steps - 1)
}
population_number_cache[Pair{s, n_steps}] = p
return p
}
func check(e error) { if e != nil { panic(e) } }
func main() {
// read in file
dat, err := os.ReadFile("data.txt")
check(err)
dat_str := strings.TrimSpace(string(dat))
line_arr := strings.Split(dat_str, " ")
// convert to list of numbers
stones := make([]Stone, 0, len(line_arr))
for _, e := range line_arr {
num, err := strconv.Atoi(e)
check(err)
stones = append(stones, Stone(num))
}
// init cache
population_number_cache = make(map[Pair]uint64)
// main calc
len_acc := uint64(0)
for _, stone := range stones {
len_acc += population_number(stone, 75)
}
fmt.Println(len_acc)
}