diff --git a/14/main.go b/14/main.go new file mode 100644 index 0000000..0156ac1 --- /dev/null +++ b/14/main.go @@ -0,0 +1,157 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" + "time" +) + +func mustAtoi(line string) int { + i, _ := strconv.Atoi(line) + return i +} + +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() + + 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() + + 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) + } +}