101 lines
2.1 KiB
Go
101 lines
2.1 KiB
Go
package day19
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"tools"
|
|
)
|
|
|
|
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
|
input := puzzle.GetInputArray()
|
|
molecule := input[len(input)-1]
|
|
replacementStrings := input[:len(input)-2]
|
|
outcomes := tools.NewSet()
|
|
|
|
for _, line := range replacementStrings {
|
|
parts := strings.Split(line, " => ")
|
|
doubleChar := len(parts[0]) == 2
|
|
var result string
|
|
for i, c := range molecule {
|
|
if doubleChar && i == len(molecule)-1 {
|
|
break
|
|
}
|
|
if doubleChar {
|
|
if byte(c) == parts[0][0] && molecule[i+1] == parts[0][1] {
|
|
result = molecule[:i] + parts[1]
|
|
if i < len(molecule)-2 {
|
|
result += molecule[i+2:]
|
|
}
|
|
outcomes.Add(result)
|
|
}
|
|
} else {
|
|
if string(c) == parts[0] {
|
|
result = molecule[:i] + parts[1]
|
|
if i < len(molecule)-1 {
|
|
result += molecule[i+1:]
|
|
}
|
|
outcomes.Add(result)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return len(outcomes)
|
|
}
|
|
|
|
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
|
input := puzzle.GetInputArray()
|
|
molecule := input[len(input)-1]
|
|
replacementStrings := input[:len(input)-2]
|
|
|
|
replacements := make(map[string]string)
|
|
replacementLengths := make(map[int][]string)
|
|
var maxLen, minLen int
|
|
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]}
|
|
}
|
|
}
|
|
}
|
|
|
|
steps := 0
|
|
foundSomething := false
|
|
for len(molecule) > 1 {
|
|
foundSomething = false
|
|
for x := maxLen; x >= minLen; x-- {
|
|
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 steps
|
|
}
|