diff --git a/README.md b/README.md index 15ed6ee..07ba4d1 100644 --- a/README.md +++ b/README.md @@ -16,21 +16,25 @@ Each day's solution is contained in a separate package. ### Running the Solutions -![TODO]: Update with instructions +To run a specific day's solution you can run the packages tests: + +```pwsh +go test ./cmd/01 +``` ## Challenges -| Day | Problem | Solution | Notes | -|-----|-------------------------------------------------|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 01 | [Problem](https://adventofcode.com/2025/day/1) | [Solution](./cmd/01/) | Part 1 seemed straight forward enough. Part 2 completely stumped me. The trickiest part was not counting zero's twice when you ended and then started from there. | -| 02 | [Problem](https://adventofcode.com/2025/day/2) | [Solution](./cmd/02/) | Part 1 should have been super straight-forward, but some whitespace screwed up my parsing of the final range. | -| 03 | [Problem](https://adventofcode.com/2025/day/3) | [Solution](./cmd/03/) | | -| 04 | [Problem](https://adventofcode.com/2025/day/4) | [Solution](./cmd/04/) | | -| 05 | [Problem](https://adventofcode.com/2025/day/5) | [Solution](./cmd/05/) | | -| 06 | [Problem](https://adventofcode.com/2025/day/6) | [Solution](./cmd/06/) | | -| 07 | [Problem](https://adventofcode.com/2025/day/7) | [Solution](./cmd/07/) | | -| 08 | [Problem](https://adventofcode.com/2025/day/8) | [Solution](./cmd/08/) | | -| 09 | [Problem](https://adventofcode.com/2025/day/9) | [Solution](./cmd/09/) | | -| 10 | [Problem](https://adventofcode.com/2025/day/10) | [Solution](./cmd/10/) | | -| 11 | [Problem](https://adventofcode.com/2025/day/11) | [Solution](./cmd/11/) | | -| 12 | [Problem](https://adventofcode.com/2025/day/12) | [Solution](./cmd/12/) | | +| Day | Problem | Solution | Notes | +|-----|-------------------------------------------------|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 01 | [Problem](https://adventofcode.com/2025/day/1) | [Solution](./cmd/01/) | Part 1 seemed straight forward enough. Part 2 completely stumped me. The trickiest part was not counting zero's twice when you ended and then started from there. | +| 02 | [Problem](https://adventofcode.com/2025/day/2) | [Solution](./cmd/02/) | Part 1 should have been super straight-forward, but some whitespace screwed up my parsing of the final range. I some how was able to stumble over a solution to part 2 rather blindly. | +| 03 | [Problem](https://adventofcode.com/2025/day/3) | [Solution](./cmd/03/) | | +| 04 | [Problem](https://adventofcode.com/2025/day/4) | [Solution](./cmd/04/) | | +| 05 | [Problem](https://adventofcode.com/2025/day/5) | [Solution](./cmd/05/) | | +| 06 | [Problem](https://adventofcode.com/2025/day/6) | [Solution](./cmd/06/) | | +| 07 | [Problem](https://adventofcode.com/2025/day/7) | [Solution](./cmd/07/) | | +| 08 | [Problem](https://adventofcode.com/2025/day/8) | [Solution](./cmd/08/) | | +| 09 | [Problem](https://adventofcode.com/2025/day/9) | [Solution](./cmd/09/) | | +| 10 | [Problem](https://adventofcode.com/2025/day/10) | [Solution](./cmd/10/) | | +| 11 | [Problem](https://adventofcode.com/2025/day/11) | [Solution](./cmd/11/) | | +| 12 | [Problem](https://adventofcode.com/2025/day/12) | [Solution](./cmd/12/) | | diff --git a/cmd/02/main.go b/cmd/02/main.go index 5c33839..66a7b6f 100644 --- a/cmd/02/main.go +++ b/cmd/02/main.go @@ -18,7 +18,24 @@ func SolvePartOne(filePath string) int64 { for r := range strRanges { rng := rnge.From(r) - for id := range rng.InvalidIds() { + for id := range rng.InvalidIdsWithEqualHalves() { + total += id + } + } + + return total +} + +func SolvePartTwo(filePath string) int64 { + input := file.ReadAllText(filePath) + strRanges := strings.SplitSeq(input, SeparatorCharacter) + + total := int64(0) + + for r := range strRanges { + rng := rnge.From(r) + + for id := range rng.InvalidIdsWithTwoOrMoreSeq() { total += id } } diff --git a/cmd/02/main_test.go b/cmd/02/main_test.go index 7b0f9ad..2cb418c 100644 --- a/cmd/02/main_test.go +++ b/cmd/02/main_test.go @@ -25,3 +25,23 @@ func TestSolvePartOneWithInput(t *testing.T) { t.Errorf("expected %d, got %d", expected, result) } } + +func TestSolvePartTwoWithExampleInput(t *testing.T) { + expected := int64(4_174_379_265) + + result := solution.SolvePartTwo("EXAMPLE.txt") + + if result != expected { + t.Errorf("expected %d, got %d", expected, result) + } +} + +func TestSolvePartTwoWithInput(t *testing.T) { + expected := int64(28858486244) + + result := solution.SolvePartTwo("INPUT.txt") + + if result != expected { + t.Errorf("expected %d, got %d", expected, result) + } +} diff --git a/cmd/02/rnge/rnge.go b/cmd/02/rnge/rnge.go index daf830f..4e72d78 100644 --- a/cmd/02/rnge/rnge.go +++ b/cmd/02/rnge/rnge.go @@ -10,7 +10,8 @@ import ( const RangeSeparatorCharacter = "-" type Range interface { - InvalidIds() iter.Seq[int64] + InvalidIdsWithEqualHalves() iter.Seq[int64] + InvalidIdsWithTwoOrMoreSeq() iter.Seq[int64] Start() int64 End() int64 } @@ -39,7 +40,7 @@ func (r rnge) End() int64 { return r.end } -func (r rnge) InvalidIds() iter.Seq[int64] { +func (r rnge) InvalidIdsWithEqualHalves() iter.Seq[int64] { return func(yield func(int64) bool) { for id := r.start; id <= r.end; id++ { idStr := strconv.FormatInt(id, 10) @@ -65,3 +66,43 @@ func (r rnge) InvalidIds() iter.Seq[int64] { } } } + +func (r rnge) InvalidIdsWithTwoOrMoreSeq() 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) + + isValid := true + + for pLen := 1; pLen <= idLength/2; pLen++ { + v := idLength % pLen + repeatedPatterDoesNotFit := v != 0 + + if repeatedPatterDoesNotFit { + continue + } + + pattern := idStr[:pLen] + numOfRepeats := idLength / pLen + repeatedPattern := strings.Repeat(pattern, numOfRepeats) + + if repeatedPattern != idStr { + continue + } + + isValid = false + } + + if isValid { + continue + } + + ok := yield(id) + + if !ok { + return + } + } + } +} diff --git a/cmd/02/rnge/rnge_test.go b/cmd/02/rnge/rnge_test.go index caf5cd7..03a33a8 100644 --- a/cmd/02/rnge/rnge_test.go +++ b/cmd/02/rnge/rnge_test.go @@ -42,12 +42,12 @@ func TestEnd(t *testing.T) { } } -func TestInvalidIds(t *testing.T) { +func TestInvalidIdsWithEqualValues(t *testing.T) { r := rnge.From("1000-1100") expectedInvalidIds := []int64{1010} resultInvalidIds := []int64{} - for id := range r.InvalidIds() { + for id := range r.InvalidIdsWithEqualHalves() { resultInvalidIds = append(resultInvalidIds, id) } @@ -55,3 +55,46 @@ func TestInvalidIds(t *testing.T) { t.Errorf("expected invalid IDs %v, got %v", expectedInvalidIds, resultInvalidIds) } } + +type TestCase struct { + rnge rnge.Range + expectedInvalidIds []int64 +} + +func TestInvalidIdsWithTwoOrMoreSeq(t *testing.T) { + testCases := []TestCase{ + { + rnge: rnge.From("11-22"), + expectedInvalidIds: []int64{11, 22}, + }, + { + rnge: rnge.From("95-115"), + expectedInvalidIds: []int64{99, 111}, + }, + { + rnge: rnge.From("998-1012"), + expectedInvalidIds: []int64{999, 1010}, + }, + { + rnge: rnge.From("1188511880-1188511890"), + expectedInvalidIds: []int64{1188511885}, + }, + { + rnge: rnge.From("222220-222224"), + expectedInvalidIds: []int64{222222}, + }, + } + + for _, c := range testCases { + resultInvalidIds := []int64{} + + for id := range c.rnge.InvalidIdsWithTwoOrMoreSeq() { + resultInvalidIds = append(resultInvalidIds, id) + } + + if slices.Equal(resultInvalidIds, c.expectedInvalidIds) == false { + t.Errorf("expected invalid IDs %v, got %v", c.expectedInvalidIds, resultInvalidIds) + } + } + +}