feat: don't bruteforce every number, use recursion to generate patterns to look for

This commit is contained in:
2025-12-02 18:09:45 +01:00
parent b0d16b1bac
commit d662f693b8

View File

@@ -39,32 +39,49 @@ func PartOne(input []string) int {
} }
func PartTwo(input []string) int { func PartTwo(input []string) int {
sum := 0 totalSum := 0
for _, line := range input { for _, line := range input {
for newRange := range strings.SplitSeq(line, ",") { for rangeSpec := range strings.SplitSeq(line, ",") {
parts := strings.Split(newRange, "-") rangeStartStr, rangeEndStr, _ := strings.Cut(rangeSpec, "-")
start, _ := strconv.Atoi(parts[0]) rangeStart, _ := strconv.Atoi(rangeStartStr)
end, _ := strconv.Atoi(parts[1]) rangeEnd, _ := strconv.Atoi(rangeEndStr)
for id := start; id <= end; id++ {
sID := strconv.Itoa(id) seenNumbers := make(map[int]bool)
found := false maxDigits := len(rangeEndStr)
for patternLength := 1; patternLength <= len(sID)/2 && !found; patternLength++ {
if len(sID)%patternLength == 0 { var generatePatterns func(string, int, int)
matches := true generatePatterns = func(currentPattern string, targetPatternLength, currentDepth int) {
for idx := 0; idx < len(sID)-patternLength; idx++ { if currentDepth == targetPatternLength {
if sID[idx] != sID[idx+patternLength] { repeated := currentPattern + currentPattern
matches = false for len(repeated) <= maxDigits {
break number, err := strconv.Atoi(repeated)
} if err != nil || number > rangeEnd {
break
} }
if matches { if number >= rangeStart && !seenNumbers[number] {
sum += id totalSum += number
found = true seenNumbers[number] = true
} }
repeated += currentPattern
} }
return
} }
minDigit := 0
if currentDepth == 0 {
minDigit = 1
}
for digit := minDigit; digit <= 9; digit++ {
extendedPattern := currentPattern + strconv.Itoa(digit)
generatePatterns(extendedPattern, targetPatternLength, currentDepth+1)
}
}
for patternLength := 1; patternLength <= maxDigits/2; patternLength++ {
generatePatterns("", patternLength, 0)
} }
} }
} }
return sum return totalSum
} }