package year25 import ( "bufio" "bytes" "fmt" "strconv" "strings" "git.bizdoc.ro/gabi-public/Advent-of-Code.git/aoc" ) type day2Scanner struct { scanner *bufio.Scanner sep byte a, b int err error } func (s *day2Scanner) Err() error { return s.err } func (s *day2Scanner) Scan() bool { if s.scanner.Scan() { interval := s.scanner.Bytes() i := bytes.IndexByte(interval, s.sep) if i <= 0 { s.err = fmt.Errorf("interval separator not found in line %s", string(interval)) return false } start := interval[:i] end := interval[i+1:] s.a, s.err = strconv.Atoi(string(start)) if s.err != nil { s.err = fmt.Errorf("failed to scann number: %s", s.err) return false } s.b, s.err = strconv.Atoi(string(end)) if s.err != nil { s.err = fmt.Errorf("failed to scann number: %s", s.err) return false } return true } return false } func (s *day2Scanner) Bounds() (int, int) { return s.a, s.b } func Day2Part1Simple(ctx aoc.Context) (any, error) { input, err := ctx.BodyString() if err != nil { return nil, fmt.Errorf("failed to read input: %s", err) } ranges := strings.Split(strings.TrimSpace(input), ",") isRepeated := func(n int) bool { str := strconv.Itoa(n) if len(str)%2 != 0 { return false } half := len(str) / 2 return str[:half] == str[half:] } var sum int for _, r := range ranges { parts := strings.Split(r, "-") if len(parts) != 2 { continue } start, err := strconv.Atoi(parts[0]) if err != nil { return nil, fmt.Errorf("failed to parse number: %s", parts[0]) } end, err := strconv.Atoi(parts[1]) if err != nil { return nil, fmt.Errorf("failed to parse number: %s", parts[1]) } for v := start; v <= end; v++ { if isRepeated(v) { sum += v } } } return sum, nil } func Day2Part2Simple(ctx aoc.Context) (any, error) { input, err := ctx.BodyString() if err != nil { return nil, fmt.Errorf("failed to read input: %s", err) } ranges := strings.Split(strings.TrimSpace(input), ",") isRepeated := func(n int) bool { s := strconv.Itoa(n) l := len(s) // Try all possible pattern lengths for p := 1; p*2 <= l; p++ { // p <= l/2 ensures at least 2 repeats if l%p != 0 { continue } pat := s[:p] ok := true for i := 0; i < l; i += p { if s[i:i+p] != pat { ok = false break } } if ok { return true } } return false } var sum int for _, r := range ranges { parts := strings.Split(r, "-") if len(parts) != 2 { continue } start, err := strconv.Atoi(parts[0]) if err != nil { return nil, fmt.Errorf("failed to parse number: %s", parts[0]) } end, err := strconv.Atoi(parts[1]) if err != nil { return nil, fmt.Errorf("failed to parse number: %s", parts[1]) } for v := start; v <= end; v++ { if isRepeated(v) { sum += v } } } return sum, nil } func Day2Part1(ctx aoc.Context) (any, error) { scanner := &day2Scanner{scanner: ctx.Scanner(aoc.SplitComma), sep: '-'} var sum int for scanner.Scan() { start, end := scanner.Bounds() ctx.Println(start, "-", end) for i := start; i <= end; i++ { str := []byte(strconv.Itoa(i)) if len(str)%2 == 0 { firstHalf := str[:len(str)/2] secondHalf := str[len(str)/2:] if bytes.Equal(firstHalf, secondHalf) { ctx.Println("found ", i) sum += i } } } } return sum, scanner.Err() } func Day2Part2(ctx aoc.Context) (any, error) { scanner := &day2Scanner{scanner: ctx.Scanner(aoc.SplitComma), sep: '-'} var sum int for scanner.Scan() { start, end := scanner.Bounds() ctx.Println(start, "-", end) for i := start; i <= end; i++ { str := []byte(strconv.Itoa(i)) for digitIndex := 1; digitIndex*2 <= len(str); digitIndex++ { if len(str)%digitIndex != 0 { // skip cant compare continue } isInvalid := true for chunkStart := digitIndex; chunkStart+digitIndex <= len(str); chunkStart += digitIndex { if !bytes.Equal(str[0:digitIndex], str[chunkStart:chunkStart+digitIndex]) { isInvalid = false break } } if isInvalid { ctx.Println("found ", i) sum += i break } } } } return sum, scanner.Err() }