98 lines
1.5 KiB
Go
98 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
content, err := os.ReadFile("data.txt")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(part1("xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"))
|
|
fmt.Println(part1(string(content)))
|
|
|
|
fmt.Println(part2("xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"))
|
|
fmt.Println(part2(string(content)))
|
|
}
|
|
|
|
func part1(s string) (result int) {
|
|
for {
|
|
index := strings.Index(s, "mul(")
|
|
if index < 0 {
|
|
return
|
|
}
|
|
|
|
s = s[index+4:]
|
|
op1, opLength := parseOperand(&s)
|
|
if opLength < 1 || opLength > 3 {
|
|
continue
|
|
}
|
|
|
|
if !expectChar(&s, ',') {
|
|
continue
|
|
}
|
|
|
|
op2, opLength := parseOperand(&s)
|
|
if opLength < 1 || opLength > 3 {
|
|
continue
|
|
}
|
|
|
|
if !expectChar(&s, ')') {
|
|
continue
|
|
}
|
|
|
|
result += op1 * op2
|
|
}
|
|
}
|
|
|
|
func part2(s string) (result int) {
|
|
for {
|
|
dont_index := strings.Index(s, "don't()")
|
|
if dont_index < 0 {
|
|
result += part1(s)
|
|
return
|
|
}
|
|
|
|
result += part1(s[:dont_index])
|
|
s = s[dont_index+7:]
|
|
|
|
do_index := strings.Index(s, "do()")
|
|
if do_index < 0 {
|
|
return
|
|
}
|
|
|
|
s = s[do_index+4:]
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func expectChar(s *string, r byte) bool {
|
|
if len(*s) == 0 || (*s)[0] != r {
|
|
return false
|
|
} else {
|
|
*s = (*s)[1:]
|
|
return true
|
|
}
|
|
}
|
|
|
|
func parseOperand(s *string) (operand int, length int) {
|
|
for len(*s) > 0 {
|
|
c := (*s)[0]
|
|
|
|
if c < '0' || c > '9' {
|
|
return
|
|
}
|
|
|
|
operand = operand*10 + int(c-'0')
|
|
*s = (*s)[1:]
|
|
length++
|
|
}
|
|
|
|
return
|
|
}
|