package main import ( "log/slog" "strconv" "strings" "tangled.org/evan.jarrett.net/aoc2025/internal/puzzle" ) type ProductId struct { firstId int lastId int } type DayTwo struct { productIds []ProductId } func (d *DayTwo) ParseInput(input string) error { for productId := range strings.SplitSeq(strings.TrimSpace(input), ",") { productId = strings.TrimSpace(productId) if productId == "" { continue } parts := strings.Split(productId, "-") first, _ := strconv.Atoi(parts[0]) last, _ := strconv.Atoi(parts[1]) product := ProductId{ firstId: first, lastId: last, } d.productIds = append(d.productIds, product) } return nil } func findPattern(productId int, j int) int { s := strconv.Itoa(productId) n := len(s) if n%j == 0 { piece := s[:n/j] if strings.Repeat(piece, j) == s { slog.Debug("found invalid ID", "id", s) return productId } } return 0 } // find ids that have a repeating pattern. 55 = 5 twice, 6464 = 64 twice. func (d *DayTwo) Part1() (int, error) { sum := 0 for _, product := range d.productIds { for i := product.firstId; i <= product.lastId; i++ { sum += findPattern(i, 2) } } return sum, nil } func (d *DayTwo) Part2() (int, error) { sum := 0 for _, product := range d.productIds { for i := product.firstId; i <= product.lastId; i++ { s := strconv.Itoa(i) n := len(s) for j := 2; j <= n; j++ { if result := findPattern(i, j); result > 0 { sum += result break } } } } return sum, nil } func main() { puzzle.Run(2, &DayTwo{}) }