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 }