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) } }