solutions for the Advent of Code 2023
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.0 KiB

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"
}