Init commit
This commit is contained in:
97
cmd/day2/main.go
Normal file
97
cmd/day2/main.go
Normal file
@@ -0,0 +1,97 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user