Files
advent-of-code-2025/day2/main.go

98 lines
1.7 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"math"
"os"
"slices"
)
func main() {
debug := flag.Bool("debug", false, "Debug.")
flag.Parse()
ranges, err := readRanges(os.Stdin)
if err != nil {
log.Fatal(err)
}
var sum1, sum2 uint
for _, r := range ranges {
invalid1 := handleRange(r, scanPart1)
invalid2 := handleRange(r, scanPart2)
if *debug {
fmt.Printf("range: %d-%d\n", r.from, r.to)
}
if *debug && len(invalid1) > 0 {
fmt.Println("invalid (part 1):")
for _, id := range invalid1 {
fmt.Printf(" %d\n", id)
}
}
if *debug && len(invalid2) > 0 {
fmt.Println("invalid (part 2):")
for _, id := range invalid2 {
fmt.Printf(" %d\n", id)
}
}
for _, id := range invalid1 {
sum1 += id
}
for _, id := range invalid2 {
sum2 += id
}
}
fmt.Println("sum (part 1):", sum1)
fmt.Println("sum (part 2):", sum2)
}
func handleRange(r idRange, scan func(id uint) (advance uint, ok bool)) []uint {
var invalid []uint
for id := r.from; id <= r.to; {
advance, ok := scan(id)
if !ok {
invalid = append(invalid, id)
}
id += advance
}
return invalid
}
func scanPart1(id uint) (advance uint, ok bool) {
digits := digits(id)
if len(digits)%2 == 1 { // odd is always valid
nextSmallestEven := uint(math.Pow10(len(digits)))
return nextSmallestEven - id, true
}
var (
x = uint(math.Pow10(len(digits) / 2))
left = id / x
right = id % x
)
return 1, left != right
}
func scanPart2(id uint) (advance uint, ok bool) {
digits := digits(id)
if len(digits) <= 1 {
return 1, true
}
loop:
for i := 1; i <= len(digits)/2; i++ {
ref := digits[:i]
for chunk := range slices.Chunk(digits, i) {
if !slices.Equal(chunk, ref) {
continue loop
}
}
return 1, false
}
return 1, true
}