refactor: clean up solution to part 1 on day 2

This commit is contained in:
Stevan Freeborn
2025-12-03 20:47:27 -06:00
parent 3b86c59044
commit e75a498018
3 changed files with 128 additions and 37 deletions
+4 -37
View File
@@ -1,57 +1,24 @@
package main
import (
"strconv"
"strings"
"github.com/StevanFreeborn/advent-of-code-2025/cmd/02/rnge"
"github.com/StevanFreeborn/advent-of-code-2025/internal/file"
)
const SeparatorCharacter = ","
const RangeSeparatorCharacter = "-"
type Range struct {
Start int64
End int64
}
func SolvePartOne(filePath string) int64 {
input := file.ReadAllText(filePath)
strRanges := strings.SplitSeq(input, SeparatorCharacter)
rngs := []Range{}
for r := range strRanges {
parts := strings.Split(strings.TrimSpace(r), "-")
start, _ := strconv.ParseInt(parts[0], 10, 64)
end, _ := strconv.ParseInt(parts[1], 10, 64)
rng := Range{
Start: start,
End: end,
}
rngs = append(rngs, rng)
}
total := int64(0)
for _, rng := range rngs {
for id := rng.Start; id <= rng.End; id++ {
idStr := strconv.FormatInt(id, 10)
idLength := len(idStr)
if idLength%2 != 0 {
continue
}
midpoint := idLength / 2
firstHalf := idStr[:midpoint]
secondHalf := idStr[midpoint:]
if firstHalf != secondHalf {
continue
}
for r := range strRanges {
rng := rnge.From(r)
for id := range rng.InvalidIds() {
total += id
}
}
+67
View File
@@ -0,0 +1,67 @@
// Package rnge provides a simple structure to represent a range with a start and end value.
package rnge
import (
"iter"
"strconv"
"strings"
)
const RangeSeparatorCharacter = "-"
type Range interface {
InvalidIds() iter.Seq[int64]
Start() int64
End() int64
}
type rnge struct {
start int64
end int64
}
func From(rngeStr string) Range {
parts := strings.Split(strings.TrimSpace(rngeStr), RangeSeparatorCharacter)
start, _ := strconv.ParseInt(parts[0], 10, 64)
end, _ := strconv.ParseInt(parts[1], 10, 64)
return rnge{
start: start,
end: end,
}
}
func (r rnge) Start() int64 {
return r.start
}
func (r rnge) End() int64 {
return r.end
}
func (r rnge) InvalidIds() iter.Seq[int64] {
return func(yield func(int64) bool) {
for id := r.start; id <= r.end; id++ {
idStr := strconv.FormatInt(id, 10)
idLength := len(idStr)
if idLength%2 != 0 {
continue
}
midpoint := idLength / 2
firstHalf := idStr[:midpoint]
secondHalf := idStr[midpoint:]
if firstHalf != secondHalf {
continue
}
ok := yield(id)
if !ok {
return
}
}
}
}
+57
View File
@@ -0,0 +1,57 @@
package rnge_test
import (
"slices"
"testing"
"github.com/StevanFreeborn/advent-of-code-2025/cmd/02/rnge"
)
func TestFrom(t *testing.T) {
expectedStart := int64(1000)
expectedEnd := int64(2000)
r := rnge.From("1000-2000")
if r.Start() != expectedStart {
t.Errorf("expected start %d, got %d", expectedStart, r.Start())
}
if r.End() != expectedEnd {
t.Errorf("expected end %d, got %d", expectedEnd, r.End())
}
}
func TestStart(t *testing.T) {
expectedStart := int64(500)
r := rnge.From("500-1500")
if r.Start() != expectedStart {
t.Errorf("expected start %d, got %d", expectedStart, r.Start())
}
}
func TestEnd(t *testing.T) {
expectedEnd := int64(1500)
r := rnge.From("500-1500")
if r.End() != expectedEnd {
t.Errorf("expected end %d, got %d", expectedEnd, r.End())
}
}
func TestInvalidIds(t *testing.T) {
r := rnge.From("1000-1100")
expectedInvalidIds := []int64{1010}
resultInvalidIds := []int64{}
for id := range r.InvalidIds() {
resultInvalidIds = append(resultInvalidIds, id)
}
if slices.Equal(resultInvalidIds, expectedInvalidIds) == false {
t.Errorf("expected invalid IDs %v, got %v", expectedInvalidIds, resultInvalidIds)
}
}