181 lines
2.9 KiB
Go
181 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
aoc "AoC/2021/common"
|
|
"bufio"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
challenge := aoc.New(2021, 14)
|
|
|
|
challenge.Test(`NNCB
|
|
|
|
CH -> B
|
|
HH -> N
|
|
CB -> H
|
|
NH -> C
|
|
HB -> C
|
|
HC -> B
|
|
HN -> C
|
|
NN -> C
|
|
BH -> H
|
|
NC -> B
|
|
NB -> B
|
|
BN -> B
|
|
BB -> N
|
|
BC -> B
|
|
CC -> N
|
|
CN -> C`, []int{1588, 2188189693529})
|
|
|
|
challenge.Solution(1, func (input *bufio.Scanner) int {
|
|
subs := make(map[string]string, 0)
|
|
|
|
input.Scan()
|
|
polymer := input.Text()
|
|
fmt.Printf("Template:\t%s\n", polymer)
|
|
|
|
input.Scan()
|
|
for input.Scan() {
|
|
line := input.Text()
|
|
s := strings.Split(line, " ")
|
|
|
|
subs[s[0]] = s[2]
|
|
}
|
|
|
|
for step := 1; step <= 10; step++ {
|
|
// First find all the matches
|
|
indices := make(map[int]string, 0)
|
|
for k, v := range subs {
|
|
index := 0
|
|
for true {
|
|
i := strings.Index(polymer[index:], k)
|
|
if i == -1 {
|
|
break
|
|
}
|
|
|
|
index += i + 1
|
|
indices[index] = v
|
|
}
|
|
}
|
|
|
|
keys := make([]int, len(indices))
|
|
i := 0
|
|
for k := range indices {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
sort.Ints(keys)
|
|
|
|
// Insert the new chars
|
|
inserted := 0
|
|
for _, k := range keys {
|
|
index := k + inserted
|
|
inserted++
|
|
|
|
polymer = polymer[:index] + indices[k] + polymer[index:]
|
|
}
|
|
|
|
// fmt.Printf("Step %d:\t\t%s\n", step, polymer)
|
|
}
|
|
|
|
min := -1
|
|
max := -1
|
|
for _, v := range subs {
|
|
c := strings.Count(polymer, v)
|
|
|
|
if c < min || min == -1 {
|
|
min = c
|
|
}
|
|
|
|
if c > max || max == -1 {
|
|
max = c
|
|
}
|
|
}
|
|
|
|
return max - min
|
|
})
|
|
|
|
challenge.Solution(2, func (input *bufio.Scanner) int {
|
|
subs := make(map[string]string, 0)
|
|
|
|
input.Scan()
|
|
polymer := input.Text()
|
|
fmt.Printf("Template:\t%s\n", polymer)
|
|
|
|
// Create the mapping
|
|
input.Scan()
|
|
for input.Scan() {
|
|
line := input.Text()
|
|
s := strings.Split(line, " ")
|
|
|
|
subs[s[0]] = s[2]
|
|
}
|
|
|
|
// Find all different pairs in the initial polymer
|
|
pairs := make(map[string]int, 0)
|
|
for k := range subs {
|
|
pairs[k] = 0
|
|
|
|
index := 0
|
|
for true {
|
|
i := strings.Index(polymer[index:], k)
|
|
if i == -1 {
|
|
break
|
|
}
|
|
|
|
index += i + 1
|
|
pairs[k]++
|
|
}
|
|
}
|
|
|
|
counter := make(map[string]int, 0)
|
|
for i := range polymer {
|
|
counter[string(polymer[i])]++
|
|
}
|
|
|
|
// Execute each step
|
|
for step := 1; step <= 40; step++ {
|
|
pairsNew := make(map[string]int, 0)
|
|
for p, c := range pairs {
|
|
// Each pair will form a new 3 long segment
|
|
n := string(p[0]) + subs[p] + string(p[1])
|
|
counter[subs[p]] += c
|
|
|
|
// Find the two pairs in this segment
|
|
// These are added to the new list of pairs
|
|
for k := range subs {
|
|
index := 0
|
|
for true {
|
|
i := strings.Index(n[index:], k)
|
|
if i == -1 {
|
|
break
|
|
}
|
|
|
|
index += i + 1
|
|
pairsNew[k] += c
|
|
}
|
|
}
|
|
}
|
|
|
|
pairs = pairsNew
|
|
}
|
|
|
|
min := -1
|
|
max := -1
|
|
for _, c := range counter {
|
|
if c < min || min == -1 {
|
|
min = c
|
|
}
|
|
|
|
if c > max || max == -1 {
|
|
max = c
|
|
}
|
|
}
|
|
|
|
return max - min
|
|
})
|
|
}
|