Merge pull request #18 from StevanFreeborn/stevanfreeborn/feat/day-seven-part-two
feat: solve day seven part two
This commit is contained in:
@@ -32,7 +32,7 @@ go test ./cmd/01
|
|||||||
| 04 | [Problem](https://adventofcode.com/2025/day/4) | [Solution](./cmd/04/) | Part 1 was by far the most straight-forward challenge so far. This was easiest day of AoC this year by far. |
|
| 04 | [Problem](https://adventofcode.com/2025/day/4) | [Solution](./cmd/04/) | Part 1 was by far the most straight-forward challenge so far. This was easiest day of AoC this year by far. |
|
||||||
| 05 | [Problem](https://adventofcode.com/2025/day/5) | [Solution](./cmd/05/) | Part 1 was fairly straight forward. Merging ranges was trickiest bit. I feel like I'm being led into a trap with how straight forward today was. |
|
| 05 | [Problem](https://adventofcode.com/2025/day/5) | [Solution](./cmd/05/) | Part 1 was fairly straight forward. Merging ranges was trickiest bit. I feel like I'm being led into a trap with how straight forward today was. |
|
||||||
| 06 | [Problem](https://adventofcode.com/2025/day/6) | [Solution](./cmd/06/) | Part 1 I don't think it is the best solution, but it does solve it. I kicked ass on part 2. 🥳 |
|
| 06 | [Problem](https://adventofcode.com/2025/day/6) | [Solution](./cmd/06/) | Part 1 I don't think it is the best solution, but it does solve it. I kicked ass on part 2. 🥳 |
|
||||||
| 07 | [Problem](https://adventofcode.com/2025/day/7) | [Solution](./cmd/07/) | FIFO for life. 🤣 |
|
| 07 | [Problem](https://adventofcode.com/2025/day/7) | [Solution](./cmd/07/) | FIFO for life. 🤣. Fuck me...part 2 I found really difficult and the use of DFS was obvious, but doing the memoizing was not. |
|
||||||
| 08 | [Problem](https://adventofcode.com/2025/day/8) | [Solution](./cmd/08/) | |
|
| 08 | [Problem](https://adventofcode.com/2025/day/8) | [Solution](./cmd/08/) | |
|
||||||
| 09 | [Problem](https://adventofcode.com/2025/day/9) | [Solution](./cmd/09/) | |
|
| 09 | [Problem](https://adventofcode.com/2025/day/9) | [Solution](./cmd/09/) | |
|
||||||
| 10 | [Problem](https://adventofcode.com/2025/day/10) | [Solution](./cmd/10/) | |
|
| 10 | [Problem](https://adventofcode.com/2025/day/10) | [Solution](./cmd/10/) | |
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/StevanFreeborn/advent-of-code-2025/internal/move"
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/move"
|
||||||
"github.com/StevanFreeborn/advent-of-code-2025/internal/position"
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/position"
|
||||||
"github.com/StevanFreeborn/advent-of-code-2025/internal/queue"
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/queue"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/stack"
|
||||||
)
|
)
|
||||||
|
|
||||||
const StartCharacter = "S"
|
const StartCharacter = "S"
|
||||||
@@ -68,3 +69,79 @@ func SolvePartOne(filePath string) int {
|
|||||||
|
|
||||||
return total
|
return total
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SolvePartTwo(filePath string) int {
|
||||||
|
input := file.ReadAllLines(filePath)
|
||||||
|
grid := grid.From(input)
|
||||||
|
|
||||||
|
var startPosition position.Position
|
||||||
|
|
||||||
|
for p, v := range grid.Positions() {
|
||||||
|
if v == StartCharacter {
|
||||||
|
startPosition = p
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if startPosition == nil {
|
||||||
|
panic("unable to find start location")
|
||||||
|
}
|
||||||
|
|
||||||
|
beamStartPosition := startPosition.Move(move.Down)
|
||||||
|
beamsStack := stack.New[position.Position]()
|
||||||
|
beamsStack.Push(beamStartPosition)
|
||||||
|
|
||||||
|
positionsToTimelinesMap := map[position.Position]int{}
|
||||||
|
|
||||||
|
for beamsStack.IsEmpty() == false {
|
||||||
|
currentBeam, _ := beamsStack.Peek()
|
||||||
|
|
||||||
|
_, hasBeenProcessed := positionsToTimelinesMap[currentBeam]
|
||||||
|
|
||||||
|
if hasBeenProcessed {
|
||||||
|
beamsStack.Pop()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
value := grid.GetValueAt(currentBeam)
|
||||||
|
nextTimelinePositions := []position.Position{}
|
||||||
|
|
||||||
|
if value == SplitterCharacter {
|
||||||
|
rightBeam := currentBeam.Move(move.Right)
|
||||||
|
leftBeam := currentBeam.Move(move.Left)
|
||||||
|
nextTimelinePositions = append(nextTimelinePositions, rightBeam, leftBeam)
|
||||||
|
} else {
|
||||||
|
nextBeam := currentBeam.Move(move.Down)
|
||||||
|
nextTimelinePositions = append(nextTimelinePositions, nextBeam)
|
||||||
|
}
|
||||||
|
|
||||||
|
numberOfTimelinesForPosition := 0
|
||||||
|
finalizePosition := true
|
||||||
|
|
||||||
|
for _, newTimelinePosition := range nextTimelinePositions {
|
||||||
|
if grid.InBounds(newTimelinePosition) == false {
|
||||||
|
numberOfTimelinesForPosition++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
v, existing := positionsToTimelinesMap[newTimelinePosition]
|
||||||
|
|
||||||
|
if existing {
|
||||||
|
numberOfTimelinesForPosition += v
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
beamsStack.Push(newTimelinePosition)
|
||||||
|
finalizePosition = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if finalizePosition == false {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
beamsStack.Pop()
|
||||||
|
positionsToTimelinesMap[currentBeam] = numberOfTimelinesForPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
return positionsToTimelinesMap[beamStartPosition]
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,3 +25,23 @@ func TestSolvePartOneWithInput(t *testing.T) {
|
|||||||
t.Errorf("SolvePartOne() = %d; want %d", result, expected)
|
t.Errorf("SolvePartOne() = %d; want %d", result, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSolvePartTwoWithExampleInput(t *testing.T) {
|
||||||
|
expected := 40
|
||||||
|
|
||||||
|
result := solution.SolvePartTwo("EXAMPLE.txt")
|
||||||
|
|
||||||
|
if result != expected {
|
||||||
|
t.Errorf("SolveTwoOne() = %d; want %d", result, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSolvePartTwoWithInput(t *testing.T) {
|
||||||
|
expected := 73_007_003_089_792
|
||||||
|
|
||||||
|
result := solution.SolvePartTwo("INPUT.txt")
|
||||||
|
|
||||||
|
if result != expected {
|
||||||
|
t.Errorf("SolveTwoOne() = %d; want %d", result, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// Package stack provides a thread-safe LIFO stack implementation.
|
||||||
|
package stack
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
type Stack[T any] interface {
|
||||||
|
Push(item T)
|
||||||
|
Peek() (T, bool)
|
||||||
|
Pop() (T, bool)
|
||||||
|
IsEmpty() bool
|
||||||
|
Size() int
|
||||||
|
}
|
||||||
|
|
||||||
|
type stack[T any] struct {
|
||||||
|
items []T
|
||||||
|
lock sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func New[T any]() Stack[T] {
|
||||||
|
return &stack[T]{items: []T{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack[T]) Push(item T) {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
s.items = append(s.items, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack[T]) Pop() (T, bool) {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
length := len(s.items)
|
||||||
|
|
||||||
|
if len(s.items) == 0 {
|
||||||
|
var zero T
|
||||||
|
return zero, false
|
||||||
|
}
|
||||||
|
|
||||||
|
lastItemIndex := length - 1
|
||||||
|
item := s.items[lastItemIndex]
|
||||||
|
s.items = s.items[:lastItemIndex]
|
||||||
|
return item, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack[T]) Peek() (T, bool) {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
length := len(s.items)
|
||||||
|
|
||||||
|
if len(s.items) == 0 {
|
||||||
|
var zero T
|
||||||
|
return zero, false
|
||||||
|
}
|
||||||
|
|
||||||
|
lastItemIndex := length - 1
|
||||||
|
item := s.items[lastItemIndex]
|
||||||
|
return item, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack[T]) IsEmpty() bool {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
return len(s.items) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack[T]) Size() int {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
return len(s.items)
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package stack_test
|
||||||
Reference in New Issue
Block a user