code.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. var startIndex int
  45. for _, line := range lines {
  46. edge := len(line) - 1
  47. endIndex := edge
  48. reading := true
  49. for reading {
  50. if multiply {
  51. index := strings.Index(line[startIndex:edge], "don't()")
  52. multiply = false
  53. if index == -1 {
  54. endIndex = edge
  55. reading = false
  56. } else {
  57. endIndex = index
  58. }
  59. matches := re.FindAllString(line[startIndex:endIndex], -1)
  60. for _, match := range matches {
  61. mul := make([]int, 2)
  62. n, err := fmt.Sscanf(match, "mul(%d,%d)", &mul[0], &mul[1])
  63. if n != 2 || err != nil {
  64. log.Fatalf("Bad input: %s", err)
  65. }
  66. result += mul[0] * mul[1]
  67. }
  68. } else {
  69. index := strings.Index(line[startIndex:edge], "do()")
  70. if index == -1 {
  71. startIndex = 0
  72. reading = false
  73. } else {
  74. multiply = true
  75. startIndex = index
  76. }
  77. }
  78. }
  79. }
  80. return result
  81. }
  82. func main() {
  83. if len(os.Args) < 2 {
  84. log.Fatal("You need to specify a file!")
  85. }
  86. filePath := os.Args[1]
  87. file, err := os.Open(filePath)
  88. if err != nil {
  89. log.Fatalf("Failed to open %s!\n", filePath)
  90. }
  91. muls, lines := readInput(file)
  92. fmt.Println("Part1:", part1(muls))
  93. fmt.Println("Part2:", part2(lines))
  94. }