AOC 2024 Day 3 #23

Merged
xuu merged 4 commits from working2024D3 into main 2024-12-03 16:16:24 -07:00
Showing only changes of commit 127257c494 - Show all commits

View File

@ -22,33 +22,66 @@ type result struct {
func (r result) String() string { return fmt.Sprintf("%#v", r) } func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(read io.Reader) (*result, error) { func run(read io.Reader) (*result, error) {
sum := 0 sum := 0
sum2 := 0
lexer := Lexer(read) lexer := Lexer(read)
for typ, token := range lexer.Iter() { active := true
if m := readMul(lexer); m != 0 { for typ, _ := range lexer.Iter() {
fmt.Println(typ, string(token)) // fmt.Println(typ, string(token))
sum += m switch {
case typ == "TokMUL":
if m := readMul(lexer); m != 0 {
sum += m
if active {
sum2 += m
}
}
case typ == "TokDONT":
if readDont(lexer) {
println("don't()", active)
active = false
}
case typ == "TokDO":
if readDo(lexer) {
println("do()", active)
active = true
}
} }
} }
return &result{sum, sum2}, nil
return &result{sum, -1}, nil
} }
func Lexer(in io.Reader) *lexer { func Lexer(in io.Reader) *lexer {
seq := func(yield func(rune) bool) { seq := func(yield func(rune) bool) {
defer func() {
if err := recover(); err != nil {
fmt.Println("ERR", err)
return
}
fmt.Println("NO DEFER AND NO PANIC??")
}()
buf := make([]byte, 256) buf := make([]byte, 256)
s, _ := in.Read(buf) s, _ := in.Read(buf)
buf = buf[:s] buf = buf[:s]
for len(buf) > 0 { for len(buf) > 0 {
for _, r := range string(buf) { for i, r := range string(buf) {
println(i, r)
if i >= 72 {
fmt.Println("START")
}
if !yield(r) { if !yield(r) {
return return
} }
if i >= 72 {
fmt.Println("STOP")
}
} }
s, _ := in.Read(buf) s, _ := in.Read(buf)
buf = buf[:s] buf = buf[:s]
@ -71,8 +104,8 @@ type lexer struct {
iter func() (rune, bool) iter func() (rune, bool)
stop func() stop func()
buf []rune buf []rune
token string token string
literal []rune literal []rune
} }
@ -118,7 +151,24 @@ func (l *lexer) NextTok() bool {
case 'm': case 'm':
l.loadString("mul") l.loadString("mul")
l.token = "TokMUL" l.token = "TokMUL"
if string(l.literal) != "mul" {
l.token = "TokILLEGAL"
return false
}
return true return true
case 'd':
l.loadString("don't")
switch string(l.literal) {
case "don't":
l.token = "TokDONT"
case "do":
l.token = "TokDO"
default:
l.token = "TokILLEGAL"
return false
}
return true
case '(': case '(':
l.loadRune("TokLPAREN") l.loadRune("TokLPAREN")
return true return true
@ -162,7 +212,7 @@ func readMul(lex *lexer) int {
if !lex.NextTok() || lex.token != "TokLPAREN" { if !lex.NextTok() || lex.token != "TokLPAREN" {
return 0 return 0
} }
if !lex.NextTok() || lex.token != "TokNUMBER" { if !lex.NextTok() || lex.token != "TokNUMBER" {
return 0 return 0
} }
@ -183,3 +233,29 @@ func readMul(lex *lexer) int {
fmt.Println(a, "*", b) fmt.Println(a, "*", b)
return a * b return a * b
} }
func readDont(lex *lexer) bool {
if lex.token != "TokDONT" || string(lex.literal) != "don't" {
return false
}
if !lex.NextTok() || lex.token != "TokLPAREN" {
return false
}
if !lex.NextTok() || lex.token != "TokRPAREN" {
return false
}
return true
}
func readDo(lex *lexer) bool {
if lex.token != "TokDO" || string(lex.literal) != "do" {
return false
}
if !lex.NextTok() || lex.token != "TokLPAREN" {
return false
}
if !lex.NextTok() || lex.token != "TokRPAREN" {
return false
}
return true
}