diff --git a/2018/day12-2.go b/2018/day12-2.go index 4efd8b3..0cb6d72 100644 --- a/2018/day12-2.go +++ b/2018/day12-2.go @@ -12,13 +12,14 @@ const NumGenerations = 50000000000 func main() { data := util.ReadInput() plants, rules := day12.FastParseInput(data) - rootIndex := 0 + runner := day12.FastGenerationRunner() + rootIndex := 0 for i := 0; i < NumGenerations; i++ { - plants, rootIndex = day12.FastRunGeneration(plants, rules, rootIndex) + plants, rootIndex = runner(plants, rules, rootIndex) // debug - if i%1000000 == 0 { + if i%1000000000 == 0 { fmt.Println("DEBUG: Generation: ", i) } } diff --git a/2018/internal/day12/fastplants.go b/2018/internal/day12/fastplants.go index fb9ebbc..49e80b0 100644 --- a/2018/internal/day12/fastplants.go +++ b/2018/internal/day12/fastplants.go @@ -1,26 +1,39 @@ +// Unused solution: still not fast enough package day12 -func FastRunGeneration(plants []byte, rules map[string]byte, rootIndex int) ([]byte, int) { - newGen := make([]byte, len(plants), len(plants)+4) +func FastGenerationRunner() func([]byte, map[string]byte, int) ([]byte, int) { + cache := make(map[string]string) - for i := 0; i < len(plants); i++ { - newGen[i] = rules[getKey(plants, i)] + return func(current []byte, rules map[string]byte, rootIndex int) ([]byte, int) { + // check the cache + if cache[string(current)] != "" { + return []byte(cache[string(current)]), rootIndex + } + + newGen := make([]byte, len(current), len(current)+4) + + for i := 0; i < len(current); i++ { + newGen[i] = rules[getKey(current, i)] + } + + result1 := rules[getKey(current, -2)] + result2 := rules[getKey(current, -1)] + if result1 == '#' || result2 == '#' { + newGen = append([]byte{result1, result2}, newGen...) + rootIndex += 2 + } + + result1 = rules[getKey(current, len(current))] + result2 = rules[getKey(current, len(current)+1)] + if result1 == '#' || result2 == '#' { + newGen = append(newGen, result1, result2) + } + + // cache result + cache[string(current)] = string(newGen) + + return newGen, rootIndex } - - result1 := rules[getKey(plants, -2)] - result2 := rules[getKey(plants, -1)] - if result1 == '#' || result2 == '#' { - newGen = append([]byte{result1, result2}, newGen...) - rootIndex += 2 - } - - result1 = rules[getKey(plants, len(plants))] - result2 = rules[getKey(plants, len(plants)+1)] - if result1 == '#' || result2 == '#' { - newGen = append(newGen, result1, result2) - } - - return newGen, rootIndex } func getKey(plants []byte, i int) string { diff --git a/2018/internal/day12/plants.go b/2018/internal/day12/plants.go index c4e687d..82f427f 100644 --- a/2018/internal/day12/plants.go +++ b/2018/internal/day12/plants.go @@ -1,3 +1,4 @@ +// This works fine for 12.1, but it's way too slow for 12.2 package day12 type Rule struct {