AdventOfCode2021/14/main.go

154 lines
2.6 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
)
func main() {
start := time.Now()
partOne()
duration := time.Since(start)
partTwo()
duration2 := time.Since(start)
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
}
func makeScanner(test bool) *bufio.Scanner {
var f *os.File
if test {
f, _ = os.Open("inputs/testinput")
} else {
f, _ = os.Open("inputs/input")
}
reader := bufio.NewReader(f)
return bufio.NewScanner(reader)
}
func partOne() {
scanner := makeScanner(false)
polymer := map[string]int{}
// initial state
scanner.Scan()
initial := scanner.Text()
for i := 0; i < len(initial)-1; i++ {
pair := string(initial[i]) + string(initial[i+1])
polymer[pair]++
}
// eat empty line
scanner.Scan()
// parse rules
rulemap := map[string][]string{}
for scanner.Scan() {
rule := strings.Split(scanner.Text(), " -> ")
rulemap[rule[0]] = []string{
string(rule[0][0]) + rule[1],
rule[1] + string(rule[0][1]),
}
}
// apply rules
for i := 0; i < 10; i++ {
newPolymer := map[string]int{}
for p, c := range polymer {
newPolymer[rulemap[p][0]] += c
newPolymer[rulemap[p][1]] += c
}
polymer = newPolymer
}
// count elements
count := map[string]int{}
for p, c := range polymer {
count[string(p[0])] += c
count[string(p[1])] += c
}
// find max and min
max, min := 0, 0
for _, c := range count {
if c > max {
max = c
}
if c < min || min == 0 {
min = c
}
}
// handle rounding
if (max-min)%2 == 1 {
fmt.Println((max-min)/2 + 1)
} else {
fmt.Println((max - min) / 2)
}
}
func partTwo() {
scanner := makeScanner(false)
polymer := map[string]int{}
// initial state
scanner.Scan()
initial := scanner.Text()
for i := 0; i < len(initial)-1; i++ {
pair := string(initial[i]) + string(initial[i+1])
polymer[pair]++
}
// eat empty line
scanner.Scan()
// parse rules
rulemap := map[string][]string{}
for scanner.Scan() {
rule := strings.Split(scanner.Text(), " -> ")
rulemap[rule[0]] = []string{
string(rule[0][0]) + rule[1],
rule[1] + string(rule[0][1]),
}
}
// apply rules
for i := 0; i < 40; i++ {
newPolymer := map[string]int{}
for p, c := range polymer {
newPolymer[rulemap[p][0]] += c
newPolymer[rulemap[p][1]] += c
}
polymer = newPolymer
}
// count elements
count := map[string]int{}
for p, c := range polymer {
count[string(p[0])] += c
count[string(p[1])] += c
}
// find max and min
max, min := 0, 0
for _, c := range count {
if c > max {
max = c
}
if c < min || min == 0 {
min = c
}
}
// handle rounding
if (max-min)%2 == 1 {
fmt.Println((max-min)/2 + 1)
} else {
fmt.Println((max - min) / 2)
}
}