Files

148 lines
3.2 KiB
Go

package main
import (
"github.com/StevanFreeborn/advent-of-code-2025/internal/file"
"github.com/StevanFreeborn/advent-of-code-2025/internal/grid"
"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/queue"
"github.com/StevanFreeborn/advent-of-code-2025/internal/stack"
)
const StartCharacter = "S"
const SplitterCharacter = "^"
func SolvePartOne(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")
}
beamStart := startPosition.Move(move.Down)
beamsQueue := queue.New[position.Position]()
beamsQueue.Enqueue(beamStart)
visited := map[position.Position]bool{}
total := 0
for beamsQueue.IsEmpty() == false {
currentBeam, _ := beamsQueue.Dequeue()
if visited[currentBeam] {
continue
}
if grid.InBounds(currentBeam) == false {
continue
}
visited[currentBeam] = true
value := grid.GetValueAt(currentBeam)
if value == SplitterCharacter {
total++
rightBeam := currentBeam.Move(move.Right)
leftBeam := currentBeam.Move(move.Left)
beamsQueue.Enqueue(rightBeam)
beamsQueue.Enqueue(leftBeam)
continue
}
nextBeam := currentBeam.Move(move.Down)
beamsQueue.Enqueue(nextBeam)
}
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]
}