|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
func isdigit(b byte) bool {
|
|
|
|
return b >= 48 && b <= 57
|
|
|
|
}
|
|
|
|
|
|
|
|
type enginepart struct {
|
|
|
|
value int
|
|
|
|
pos int
|
|
|
|
raw string
|
|
|
|
}
|
|
|
|
|
|
|
|
func engineparts(buf *bufio.Reader) []enginepart {
|
|
|
|
parts := make([]enginepart, 0, 150)
|
|
|
|
|
|
|
|
outer:
|
|
|
|
for pos := 0; ; pos++ {
|
|
|
|
head, err := buf.ReadByte()
|
|
|
|
if err != nil {
|
|
|
|
return parts
|
|
|
|
}
|
|
|
|
|
|
|
|
if isdigit(head) {
|
|
|
|
// start recording digits
|
|
|
|
b := make([]byte, 0, 10)
|
|
|
|
b = append(b, head)
|
|
|
|
|
|
|
|
// continue reading until number is exhausted
|
|
|
|
for {
|
|
|
|
digit, err := buf.ReadByte()
|
|
|
|
if !isdigit(digit) {
|
|
|
|
value, _ := strconv.Atoi(string(b))
|
|
|
|
for range b {
|
|
|
|
parts = append(parts, enginepart{value: value, pos: pos, raw: string(b)})
|
|
|
|
}
|
|
|
|
pos += len(b) - 1
|
|
|
|
|
|
|
|
if err == io.EOF {
|
|
|
|
return parts
|
|
|
|
}
|
|
|
|
|
|
|
|
buf.UnreadByte()
|
|
|
|
continue outer
|
|
|
|
}
|
|
|
|
|
|
|
|
b = append(b, digit)
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if head != '.' {
|
|
|
|
// head is a symbol
|
|
|
|
parts = append(parts, enginepart{value: -1, pos: pos, raw: string(head)})
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// head is a '.'
|
|
|
|
parts = append(parts, enginepart{value: 0, pos: pos, raw: string(head)})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type day03 struct{}
|
|
|
|
|
|
|
|
func (d day03) solve1(r io.Reader) string {
|
|
|
|
sum := 0
|
|
|
|
parts := make([][]enginepart, 0, 100)
|
|
|
|
scanner := bufio.NewScanner(r)
|
|
|
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
line := scanner.Text()
|
|
|
|
buf := bufio.NewReader(strings.NewReader(line))
|
|
|
|
lineparts := engineparts(buf)
|
|
|
|
parts = append(parts, lineparts)
|
|
|
|
}
|
|
|
|
|
|
|
|
for row := range parts {
|
|
|
|
for item := range parts[row] {
|
|
|
|
if sym := parts[row][item]; sym.value == -1 {
|
|
|
|
|
|
|
|
for i := -1; i < 2; i++ {
|
|
|
|
for j := -1; j < 2; {
|
|
|
|
x := row + i
|
|
|
|
y := item + j
|
|
|
|
|
|
|
|
if x >= 0 && y >= 0 && x < len(parts) && y < len(parts[row]) {
|
|
|
|
part := parts[x][y]
|
|
|
|
if part.value > 0 {
|
|
|
|
sum += part.value
|
|
|
|
j += (part.pos + len(part.raw) - y)
|
|
|
|
} else {
|
|
|
|
j++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("%d", sum)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d day03) solve2(r io.Reader) string {
|
|
|
|
return "incomplete"
|
|
|
|
}
|