AOC 2024 Day 3 #23
|
@ -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
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user