|
@@ -6,11 +6,13 @@ import (
|
|
"log"
|
|
"log"
|
|
"os"
|
|
"os"
|
|
"regexp"
|
|
"regexp"
|
|
|
|
+ "strings"
|
|
)
|
|
)
|
|
|
|
|
|
-func readInput(file *os.File) [][]int {
|
|
|
|
|
|
+func readInput(file *os.File) ([][]int, []string) {
|
|
scanner := bufio.NewScanner(file)
|
|
scanner := bufio.NewScanner(file)
|
|
var muls [][]int
|
|
var muls [][]int
|
|
|
|
+ var lines []string
|
|
|
|
|
|
for scanner.Scan() {
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
line := scanner.Text()
|
|
@@ -18,6 +20,8 @@ func readInput(file *os.File) [][]int {
|
|
break
|
|
break
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ lines = append(lines, line)
|
|
|
|
+
|
|
re := regexp.MustCompile(`mul\(\d+,\d+\)`)
|
|
re := regexp.MustCompile(`mul\(\d+,\d+\)`)
|
|
matches := re.FindAllString(line, -1)
|
|
matches := re.FindAllString(line, -1)
|
|
for _, match := range matches {
|
|
for _, match := range matches {
|
|
@@ -31,7 +35,7 @@ func readInput(file *os.File) [][]int {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return muls
|
|
|
|
|
|
+ return muls, lines
|
|
}
|
|
}
|
|
|
|
|
|
func part1(muls [][]int) int {
|
|
func part1(muls [][]int) int {
|
|
@@ -43,6 +47,53 @@ func part1(muls [][]int) int {
|
|
return result
|
|
return result
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func part2(lines []string) int {
|
|
|
|
+ var result int
|
|
|
|
+ multiply := true
|
|
|
|
+ re := regexp.MustCompile(`mul\(\d+,\d+\)`)
|
|
|
|
+
|
|
|
|
+ var startIndex int
|
|
|
|
+ for _, line := range lines {
|
|
|
|
+ edge := len(line) - 1
|
|
|
|
+ endIndex := edge
|
|
|
|
+ reading := true
|
|
|
|
+ for reading {
|
|
|
|
+ if multiply {
|
|
|
|
+ index := strings.Index(line[startIndex:edge], "don't()")
|
|
|
|
+ multiply = false
|
|
|
|
+ if index == -1 {
|
|
|
|
+ endIndex = edge
|
|
|
|
+ reading = false
|
|
|
|
+ } else {
|
|
|
|
+ endIndex = index
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ matches := re.FindAllString(line[startIndex:endIndex], -1)
|
|
|
|
+ for _, match := range matches {
|
|
|
|
+ mul := make([]int, 2)
|
|
|
|
+ n, err := fmt.Sscanf(match, "mul(%d,%d)", &mul[0], &mul[1])
|
|
|
|
+ if n != 2 || err != nil {
|
|
|
|
+ log.Fatalf("Bad input: %s", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ result += mul[0] * mul[1]
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ index := strings.Index(line[startIndex:edge], "do()")
|
|
|
|
+ if index == -1 {
|
|
|
|
+ startIndex = 0
|
|
|
|
+ reading = false
|
|
|
|
+ } else {
|
|
|
|
+ multiply = true
|
|
|
|
+ startIndex = index
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return result
|
|
|
|
+}
|
|
|
|
+
|
|
func main() {
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
if len(os.Args) < 2 {
|
|
log.Fatal("You need to specify a file!")
|
|
log.Fatal("You need to specify a file!")
|
|
@@ -54,6 +105,7 @@ func main() {
|
|
log.Fatalf("Failed to open %s!\n", filePath)
|
|
log.Fatalf("Failed to open %s!\n", filePath)
|
|
}
|
|
}
|
|
|
|
|
|
- muls := readInput(file)
|
|
|
|
|
|
+ muls, lines := readInput(file)
|
|
fmt.Println("Part1:", part1(muls))
|
|
fmt.Println("Part1:", part1(muls))
|
|
|
|
+ fmt.Println("Part2:", part2(lines))
|
|
}
|
|
}
|