89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
|
|
package main
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"regexp"
|
||
|
|
"strconv"
|
||
|
|
)
|
||
|
|
|
||
|
|
var mul_re *regexp.Regexp = regexp.MustCompile(`mul\(([0-9]+),([0-9]+)\)`)
|
||
|
|
|
||
|
|
func check(e error) {
|
||
|
|
if e != nil {
|
||
|
|
panic(e)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func handle_muls(input string) int {
|
||
|
|
total := 0
|
||
|
|
|
||
|
|
matches := mul_re.FindAllStringSubmatch(input, -1)
|
||
|
|
for _, match := range matches {
|
||
|
|
first, err := strconv.Atoi(match[1])
|
||
|
|
check(err)
|
||
|
|
second, err := strconv.Atoi(match[2])
|
||
|
|
check(err)
|
||
|
|
|
||
|
|
total += first * second
|
||
|
|
}
|
||
|
|
return total
|
||
|
|
}
|
||
|
|
|
||
|
|
func next(matches [][]int, start int) [][]int {
|
||
|
|
for i, match := range matches {
|
||
|
|
if match[0] > start {
|
||
|
|
return matches[i:]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func main() {
|
||
|
|
instructions, err := os.ReadFile("./three.txt")
|
||
|
|
check(err)
|
||
|
|
|
||
|
|
str_instructions := string(instructions)
|
||
|
|
|
||
|
|
// Find all mul instructions
|
||
|
|
fmt.Println(handle_muls(str_instructions))
|
||
|
|
|
||
|
|
// Handle disables and enables
|
||
|
|
total := 0
|
||
|
|
enable_re := regexp.MustCompile(`do\(\)`)
|
||
|
|
disable_re := regexp.MustCompile(`don't\(\)`)
|
||
|
|
dos := enable_re.FindAllStringIndex(str_instructions, -1)
|
||
|
|
donts := disable_re.FindAllStringIndex(str_instructions, -1)
|
||
|
|
|
||
|
|
enabled := true
|
||
|
|
done := false
|
||
|
|
|
||
|
|
start_i := 0
|
||
|
|
end_i := 0
|
||
|
|
|
||
|
|
for !done {
|
||
|
|
if enabled {
|
||
|
|
donts = next(donts, start_i)
|
||
|
|
if donts == nil {
|
||
|
|
total += handle_muls(str_instructions[start_i:])
|
||
|
|
done = true
|
||
|
|
} else {
|
||
|
|
end_i = donts[0][0]
|
||
|
|
total += handle_muls(str_instructions[start_i : end_i+1])
|
||
|
|
enabled = false
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
dos = next(dos, end_i)
|
||
|
|
if dos == nil {
|
||
|
|
done = true
|
||
|
|
} else {
|
||
|
|
start_i = dos[0][1]
|
||
|
|
enabled = true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
fmt.Println(dos)
|
||
|
|
fmt.Println(donts)
|
||
|
|
fmt.Println(total)
|
||
|
|
}
|