123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- package main
- import (
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "strings"
- )
- func readInput(file string) (map[string]int, map[byte]int, map[string][]string) {
- content, err := ioutil.ReadFile(file)
- if err != nil {
- log.Fatal(err)
- }
- lines := strings.Split(string(content), "\n")
- template := make(map[string]int)
- input := make(map[string][]string)
- count := make(map[byte]int)
- readingTemplate := true
- for _, line := range lines {
- if line == "" {
- readingTemplate = false
- continue
- }
- if readingTemplate {
- for i := 0; i < len(line); i++ {
- count[line[i]]++
- }
- for i := 0; i < len(line)-1; i++ {
- template[string(line[i:i+2])] += 1
- }
- continue
- }
- parts := strings.Split(line, " -> ")
- if len(parts) != 2 {
- log.Fatal("Invalid line: ", line)
- }
- input[parts[0]] = []string{fmt.Sprintf("%c%s", parts[0][0], parts[1]), fmt.Sprintf("%s%c", parts[1], parts[0][1])}
- }
- return template, count, input
- }
- func countElements(count map[byte]int) (int, int) {
- smallest := count['N']
- largest := count['N']
- for _, v := range count {
- if v < smallest {
- smallest = v
- }
- if v > largest {
- largest = v
- }
- }
- return smallest, largest
- }
- func process(template map[string]int, count map[byte]int, input map[string][]string, rounds int) (map[string]int, map[byte]int, int) {
- for i := 0; i < rounds; i++ {
- newTemplate := make(map[string]int)
- for k, v1 := range template {
- for _, v2 := range input[k] {
- newTemplate[v2] += v1
- }
- count[input[k][0][1]] += v1
- }
- template = newTemplate
- }
- smallest, largest := countElements(count)
- return template, count, largest - smallest
- }
- func main() {
- if len(os.Args) < 2 {
- log.Fatal("Please provide a file name as argument")
- }
- template, count, input := readInput(os.Args[1])
- var diff int
- template, count, diff = process(template, count, input, 10)
- fmt.Println("Part1:", diff)
- _, _, diff = process(template, count, input, 30)
- fmt.Println("Part2:", diff)
- }
|