code.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "os"
  7. "strings"
  8. )
  9. func readInput(file string) (map[string]int, map[byte]int, map[string][]string) {
  10. content, err := ioutil.ReadFile(file)
  11. if err != nil {
  12. log.Fatal(err)
  13. }
  14. lines := strings.Split(string(content), "\n")
  15. template := make(map[string]int)
  16. input := make(map[string][]string)
  17. count := make(map[byte]int)
  18. readingTemplate := true
  19. for _, line := range lines {
  20. if line == "" {
  21. readingTemplate = false
  22. continue
  23. }
  24. if readingTemplate {
  25. for i := 0; i < len(line); i++ {
  26. count[line[i]]++
  27. }
  28. for i := 0; i < len(line)-1; i++ {
  29. template[string(line[i:i+2])] += 1
  30. }
  31. continue
  32. }
  33. parts := strings.Split(line, " -> ")
  34. if len(parts) != 2 {
  35. log.Fatal("Invalid line: ", line)
  36. }
  37. input[parts[0]] = []string{fmt.Sprintf("%c%s", parts[0][0], parts[1]), fmt.Sprintf("%s%c", parts[1], parts[0][1])}
  38. }
  39. return template, count, input
  40. }
  41. func countElements(count map[byte]int) (int, int) {
  42. smallest := count['N']
  43. largest := count['N']
  44. for _, v := range count {
  45. if v < smallest {
  46. smallest = v
  47. }
  48. if v > largest {
  49. largest = v
  50. }
  51. }
  52. return smallest, largest
  53. }
  54. func process(template map[string]int, count map[byte]int, input map[string][]string, rounds int) (map[string]int, map[byte]int, int) {
  55. for i := 0; i < rounds; i++ {
  56. newTemplate := make(map[string]int)
  57. for k, v1 := range template {
  58. for _, v2 := range input[k] {
  59. newTemplate[v2] += v1
  60. }
  61. count[input[k][0][1]] += v1
  62. }
  63. template = newTemplate
  64. }
  65. smallest, largest := countElements(count)
  66. return template, count, largest - smallest
  67. }
  68. func main() {
  69. if len(os.Args) < 2 {
  70. log.Fatal("Please provide a file name as argument")
  71. }
  72. template, count, input := readInput(os.Args[1])
  73. var diff int
  74. template, count, diff = process(template, count, input, 10)
  75. fmt.Println("Part1:", diff)
  76. _, _, diff = process(template, count, input, 30)
  77. fmt.Println("Part2:", diff)
  78. }