new idea for d19p2 actually works

2015 finished!
This commit is contained in:
Stefan Harmuth 2021-10-24 13:55:06 +02:00
parent 7b7f4f563b
commit e160010441

View File

@ -1,6 +1,8 @@
package day19 package day19
import ( import (
"fmt"
"os"
"strings" "strings"
"tools" "tools"
) )
@ -42,63 +44,57 @@ func Part1(puzzle tools.AoCPuzzle) interface{} {
return len(outcomes) return len(outcomes)
} }
func getPossibleTransformations(from tools.Set, replacments map[string]tools.Set, maxLen int) tools.Set {
returnSet := tools.NewSet()
var result string
for interfaceMolecule := range from {
currentMolecule := interfaceMolecule.(string)
for i := range currentMolecule {
if transSet, ok := replacments[string(currentMolecule[i])]; ok {
for replacement := range transSet {
result = currentMolecule[:i] + replacement.(string)
if i < len(currentMolecule)-1 {
result += currentMolecule[i+1:]
}
if len(result) <= maxLen {
returnSet.Add(result)
}
}
}
if i < len(currentMolecule)-1 {
if transSet, ok := replacments[currentMolecule[i:i+2]]; ok {
for replacment := range transSet {
result = currentMolecule[:i] + replacment.(string)
if i < len(currentMolecule)-2 {
result += currentMolecule[i+2:]
}
if len(result) <= maxLen {
returnSet.Add(result)
}
}
}
}
}
}
return returnSet
}
func Part2(puzzle tools.AoCPuzzle) interface{} { func Part2(puzzle tools.AoCPuzzle) interface{} {
input := puzzle.GetInputArray() input := puzzle.GetInputArray()
molecule := input[len(input)-1] molecule := input[len(input)-1]
replacementStrings := input[:len(input)-2] replacementStrings := input[:len(input)-2]
replacements := make(map[string]tools.Set)
for _, line := range replacementStrings { replacements := make(map[string]string)
parts := strings.Split(line, " => ") replacementLengths := make(map[int][]string)
if _, ok := replacements[parts[0]]; !ok { var maxLen, minLen int
replacements[parts[0]] = tools.NewSet() for _, s := range replacementStrings {
parts := strings.Split(s, " => ")
if _, ok := replacements[parts[1]]; ok {
fmt.Println("Double target string found!")
os.Exit(1)
} else {
replacements[parts[1]] = parts[0]
x := len(parts[1])
if x > maxLen {
maxLen = x
}
if x < minLen {
minLen = x
}
if _, ok := replacementLengths[x]; ok {
replacementLengths[x] = append(replacementLengths[x], parts[1])
} else {
replacementLengths[x] = []string{parts[1]}
}
} }
replacements[parts[0]].Add(parts[1])
} }
currentMolecules := tools.NewSet() steps := 0
currentMolecules.Add("e") foundSomething := false
transformCount := 0 for len(molecule) > 1 {
for !currentMolecules.Contains(molecule) { foundSomething = false
transformCount++ for x := maxLen; x >= minLen; x-- {
currentMolecules = getPossibleTransformations(currentMolecules, replacements, len(molecule)) for _, replacement := range replacementLengths[x] {
if strings.Contains(molecule, replacement) {
molecule = strings.Replace(molecule, replacement, replacements[replacement], 1)
foundSomething = true
steps++
break
}
}
if foundSomething {
break
}
}
if !foundSomething {
break
}
} }
return transformCount return steps
} }