65 lines
1.3 KiB
Go
65 lines
1.3 KiB
Go
package year25
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
)
|
|
|
|
func Day3Part1(r io.Reader, l Logger) (any, error) {
|
|
return Day3(r, l, 2)
|
|
}
|
|
func Day3Part2(r io.Reader, l Logger) (any, error) {
|
|
return Day3(r, l, 12)
|
|
}
|
|
func Day3(r io.Reader, logger Logger, size int) (int64, error) {
|
|
scanner := bufio.NewScanner(r)
|
|
scanner.Split(bufio.ScanLines)
|
|
var sum int64
|
|
|
|
findLargetDigit := func(digits []rune) (rune, int) {
|
|
largestDigit := rune(0)
|
|
index := 0
|
|
|
|
for i := len(digits) - 1; i >= 0; i-- {
|
|
if digits[i] >= largestDigit {
|
|
largestDigit = digits[i]
|
|
index = i
|
|
}
|
|
}
|
|
return rune(largestDigit) - '0', index
|
|
}
|
|
|
|
for scanner.Scan() {
|
|
text := strings.TrimSpace(scanner.Text())
|
|
if text == "" {
|
|
continue
|
|
}
|
|
line := []rune(text)
|
|
parts := make([]byte, size)
|
|
|
|
for index := range parts {
|
|
digit, start := findLargetDigit(line[:len(line)+index-len(parts)+1])
|
|
line = line[start+1:]
|
|
if digit < 0 || digit > 9 {
|
|
return 0, fmt.Errorf("ivalid char '%c' in line %s", digit, text)
|
|
} else {
|
|
parts[index] = byte(digit)
|
|
}
|
|
}
|
|
logger.Println("line: ", text)
|
|
|
|
var partSum int64
|
|
for _, part := range parts {
|
|
partSum *= 10
|
|
partSum += int64(part)
|
|
}
|
|
logger.Println("got: ", partSum)
|
|
logger.Println()
|
|
sum += partSum
|
|
}
|
|
|
|
return sum, scanner.Err()
|
|
}
|