Day02
This commit is contained in:
119
2025/gareth/day02/day02.go
Normal file
119
2025/gareth/day02/day02.go
Normal file
@@ -0,0 +1,119 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user