89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package year25
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.bizdoc.ro/gabi-public/Advent-of-Code.git/aocutils"
|
|
)
|
|
|
|
func Day3Part1(ctx aocutils.Context) (any, error) {
|
|
return Day3(ctx, 2)
|
|
}
|
|
func Day3Part2(ctx aocutils.Context) (any, error) {
|
|
return Day3(ctx, 12)
|
|
}
|
|
func Day3(ctx aocutils.Context, size int) (int64, error) {
|
|
scanner := ctx.Scanner(bufio.ScanLines)
|
|
var sum int64
|
|
|
|
findLargetDigit := func(digits []rune) (rune, int) {
|
|
var largestDigit rune
|
|
index := 0
|
|
|
|
for i := len(digits) - 1; i >= 0; i-- {
|
|
if digits[i] >= largestDigit {
|
|
largestDigit = digits[i]
|
|
index = i
|
|
}
|
|
}
|
|
return largestDigit, 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)
|
|
}
|
|
}
|
|
|
|
partSum, err := strconv.Atoi(string(parts))
|
|
if err != nil {
|
|
return 0, fmt.Errorf("invalid result %s for line %s", string(parts), text)
|
|
}
|
|
|
|
ctx.Println("line: ", text)
|
|
ctx.Println("got: ", string(parts))
|
|
ctx.Println()
|
|
sum += int64(partSum)
|
|
}
|
|
|
|
return sum, scanner.Err()
|
|
}
|
|
|
|
func Day3Compact(input string, size int) (total int64, _ error) {
|
|
findLargetDigit := func(digits string, skip int) (digit byte, idx int, next string) {
|
|
for i := len(digits) - 1 - skip; i >= 0; i-- {
|
|
if digits[i] >= digit {
|
|
digit, idx = digits[i], i
|
|
}
|
|
}
|
|
return digit, idx, digits[idx+1:]
|
|
}
|
|
for _, line := range strings.Split(input, "\n") {
|
|
var parts = make([]byte, size)
|
|
for index := range size {
|
|
parts[index], _, line = findLargetDigit(line, size-1-index)
|
|
}
|
|
if partSum, err := strconv.ParseInt(string(parts), 10, 64); err != nil {
|
|
return 0, fmt.Errorf("invalid result %s", string(parts))
|
|
} else {
|
|
total += partSum
|
|
}
|
|
}
|
|
return total, nil
|
|
}
|