First attempt at a faster / more efficient implementation. This is orders of magnitude faster than the first, but still not nearly fast enough.
This commit is contained in:
parent
fbd7c8fb00
commit
5d4757d4cb
27
2018/day12-2.go
Normal file
27
2018/day12-2.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"internal/day12"
|
||||||
|
"internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
const NumGenerations = 50000000000
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := util.ReadInput()
|
||||||
|
plants, rules := day12.FastParseInput(data)
|
||||||
|
rootIndex := 0
|
||||||
|
|
||||||
|
for i := 0; i < NumGenerations; i++ {
|
||||||
|
plants, rootIndex = day12.FastRunGeneration(plants, rules, rootIndex)
|
||||||
|
|
||||||
|
// debug
|
||||||
|
if i%1000000 == 0 {
|
||||||
|
fmt.Println("DEBUG: Generation: ", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(day12.FastSumPlants(plants, rootIndex))
|
||||||
|
}
|
56
2018/internal/day12/fastplants.go
Normal file
56
2018/internal/day12/fastplants.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package day12
|
||||||
|
|
||||||
|
func FastRunGeneration(plants []byte, rules map[string]byte, rootIndex int) ([]byte, int) {
|
||||||
|
newGen := make([]byte, len(plants), len(plants)+4)
|
||||||
|
|
||||||
|
for i := 0; i < len(plants); i++ {
|
||||||
|
newGen[i] = rules[getKey(plants, i)]
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if i < 2 {
|
||||||
|
key := ""
|
||||||
|
for j := 0; j < 2-i; j++ {
|
||||||
|
key += "."
|
||||||
|
}
|
||||||
|
key += string(plants[0 : i+2])
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
if i > len(plants)-2 {
|
||||||
|
key := string(plants[i-2 : len(plants)-1])
|
||||||
|
for j := 0; j < len(plants)-1-i; j++ {
|
||||||
|
key += "."
|
||||||
|
}
|
||||||
|
key += string(plants[0 : i+2])
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(plants[i-2 : i+2])
|
||||||
|
}
|
||||||
|
|
||||||
|
func FastSumPlants(plants []byte, rootIndex int) int {
|
||||||
|
sum := 0
|
||||||
|
for index, value := range plants {
|
||||||
|
if value == '#' {
|
||||||
|
sum += index - rootIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
|
@ -40,3 +40,21 @@ func ParseInput(data []string) (map[int]bool, []*Rule) {
|
||||||
|
|
||||||
return plants, rules
|
return plants, rules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The function isn't fast, the resulting data is.
|
||||||
|
func FastParseInput(data []string) ([]byte, map[string]byte) {
|
||||||
|
stateStrings := strings.Split(data[0], " ")
|
||||||
|
ruleStrings := data[2:]
|
||||||
|
|
||||||
|
// Populate plant list
|
||||||
|
plants := []byte(stateStrings[len(stateStrings)-1])
|
||||||
|
|
||||||
|
// Create rules
|
||||||
|
rules := make(map[string]byte)
|
||||||
|
for _, ruleStr := range ruleStrings {
|
||||||
|
ruleData := strings.Split(ruleStr, " ")
|
||||||
|
rules[ruleData[0]] = []byte(ruleData[2])[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return plants, rules
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ func RunGeneration(plants map[int]bool, rules []*Rule) map[int]bool {
|
||||||
for _, rule := range rules {
|
for _, rule := range rules {
|
||||||
if checkRule(plants, rule, i) {
|
if checkRule(plants, rule, i) {
|
||||||
newGen[i] = rule.Result
|
newGen[i] = rule.Result
|
||||||
|
break // only one rule will match a given slice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user