code.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "regexp"
  8. "strings"
  9. )
  10. func readInput(file *os.File) ([][]int, []string) {
  11. scanner := bufio.NewScanner(file)
  12. var muls [][]int
  13. var lines []string
  14. for scanner.Scan() {
  15. line := scanner.Text()
  16. if line == "" {
  17. break
  18. }
  19. lines = append(lines, line)
  20. re := regexp.MustCompile(`mul\(\d+,\d+\)`)
  21. matches := re.FindAllString(line, -1)
  22. for _, match := range matches {
  23. mul := make([]int, 2)
  24. n, err := fmt.Sscanf(match, "mul(%d,%d)", &mul[0], &mul[1])
  25. if n != 2 || err != nil {
  26. log.Fatalf("Bad input: %s", err)
  27. }
  28. muls = append(muls, mul)
  29. }
  30. }
  31. return muls, lines
  32. }
  33. func part1(muls [][]int) int {
  34. var result int
  35. for _, mul := range muls {
  36. result += mul[0] * mul[1]
  37. }
  38. return result
  39. }
  40. func part2(lines []string) int {
  41. var result int
  42. multiply := true
  43. re := regexp.MustCompile(`mul\(\d+,\d+\)`)
  44. for _, line := range lines {
  45. var startIndex, endIndex int
  46. reading := true
  47. for reading {
  48. if multiply {
  49. index := strings.Index(line, "don't()")
  50. multiply = false
  51. if index == -1 {
  52. endIndex = len(line)
  53. reading = false
  54. } else {
  55. endIndex = index
  56. }
  57. if startIndex > endIndex {
  58. startIndex++
  59. continue
  60. }
  61. matches := re.FindAllString(line[startIndex:endIndex], -1)
  62. for _, match := range matches {
  63. mul := make([]int, 2)
  64. n, err := fmt.Sscanf(match, "mul(%d,%d)", &mul[0], &mul[1])
  65. if n != 2 || err != nil {
  66. log.Fatalf("Bad input: %s", err)
  67. }
  68. result += mul[0] * mul[1]
  69. }
  70. line = line[endIndex:]
  71. startIndex = 0
  72. } else {
  73. index := strings.Index(line, "do()")
  74. if index == -1 {
  75. reading = false
  76. } else {
  77. multiply = true
  78. startIndex = 0
  79. line = line[index:]
  80. }
  81. }
  82. }
  83. }
  84. return result
  85. }
  86. func main() {
  87. if len(os.Args) < 2 {
  88. log.Fatal("You need to specify a file!")
  89. }
  90. filePath := os.Args[1]
  91. file, err := os.Open(filePath)
  92. if err != nil {
  93. log.Fatalf("Failed to open %s!\n", filePath)
  94. }
  95. muls, lines := readInput(file)
  96. fmt.Println("Part1:", part1(muls))
  97. fmt.Println("Part2:", part2(lines))
  98. }