98 lines
1.7 KiB
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
|
|
}
|