Files
adventofcode/2025/gareth/day02/day02.go
Gareth 90083f28e5 Day02
2025-12-02 06:54:15 +00:00

120 lines
2.0 KiB
Go

package day02
import (
"math"
"strconv"
"strings"
)
// Very messy and not my finest work but not too bad for 6am
func parseInput(input string) [][2]int {
var ranges [][2]int
lines := strings.Split(strings.TrimSpace(input), ",")
for _, part := range lines {
if part == "" {
continue
}
ab := strings.Split(part, "-")
if len(ab) != 2 {
continue
}
a, _ := strconv.Atoi(ab[0])
b, _ := strconv.Atoi(ab[1])
ranges = append(ranges, [2]int{a, b})
}
return ranges
}
func divisors(n int) []int {
out := make([]int, 0)
for i := 1; i <= n; i++ {
if n%i == 0 {
out = append(out, i)
}
}
return out
}
func Part1(input string) int {
ranges := parseInput(input)
invalidSum := 0
for _, r := range ranges {
low, high := r[0], r[1]
minLen := len(strconv.Itoa(low))
maxLen := len(strconv.Itoa(high))
for digits := minLen; digits <= maxLen; digits++ {
if digits%2 != 0 {
continue
}
half := digits / 2
start := int(math.Pow(10, float64(half-1)))
end := int(math.Pow(10, float64(half)))
for first := start; first < end; first++ {
s := strconv.Itoa(first)
selected, _ := strconv.Atoi(s + s)
if selected < low {
continue
}
if selected > high {
break
}
invalidSum += selected
}
}
}
return invalidSum
}
func Part2(input string) int {
ranges := parseInput(input)
total := 0
for _, r := range ranges {
low, high := r[0], r[1]
seen := make(map[int]bool)
minLen := len(strconv.Itoa(low))
maxLen := len(strconv.Itoa(high))
for d := minLen; d <= maxLen; d++ {
for _, L := range divisors(d) {
k := d / L
if k < 2 {
continue
}
start := int(math.Pow(10, float64(L-1)))
end := int(math.Pow(10, float64(L)))
for base := start; base < end; base++ {
s := strings.Repeat(strconv.Itoa(base), k)
selected, _ := strconv.Atoi(s)
if selected < low {
continue
}
if selected > high {
break
}
if !seen[selected] {
seen[selected] = true
total += selected
}
}
}
}
}
return total
}