Skip to content

Commit 4a0cf5c

Browse files
committed
Factor out state in part 2
1 parent 26ff864 commit 4a0cf5c

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

day21/src/day21.scala

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,38 +107,41 @@ def shortestProgram(robots: Int, goal: String): String =
107107

108108
throw new RuntimeException("No shortest program found")
109109

110-
def cost(robots: Int, pos: Vec2, action: Char): Int = 1
111-
112110
def shortestProgramLength(robots: Int, goal: String): Int =
113-
case class Node(pos: Vec2, output: String = "", total: Int = 0) extends Ordered[Node] {
111+
case class State(pos: Vec2 = PadType.Num.locate('A'), output: String = "")
112+
113+
case class Node(state: State, total: Int = 0) extends Ordered[Node] {
114114
def compare(that: Node): Int = that.total compare total // Intentionally reversed for min-heap
115115
}
116116

117+
def cost(state: State, newState: State, action: Char): Int = 1
118+
117119
// Your run-of-the-mill Dijkstra implementation (this time on the numpad)
118120

119121
val queue = mutable.PriorityQueue[Node]()
120-
val visited = mutable.HashSet[(Vec2, String)]()
122+
val visited = mutable.HashSet[State]()
121123

122-
val startPos = PadType.Num.locate('A')
123-
val start = Node(startPos)
124+
val startState = State()
125+
val start = Node(startState)
124126
queue.enqueue(start)
125-
visited.add((start.pos, start.output))
127+
visited.add(startState)
126128

127129
while !queue.isEmpty do
128130
val node = queue.dequeue()
129-
if node.output == goal then
131+
if node.state.output == goal then
130132
return node.total
131133

132-
if node.output.length < goal.length then
134+
if node.state.output.length < goal.length then
133135
for
134136
action <- ACTIONS
135137
do
136-
val newPos = node.pos + DIRECTIONS.get(action).getOrElse(Vec2(0, 0))
138+
val newPos = node.state.pos + DIRECTIONS.get(action).getOrElse(Vec2(0, 0))
137139
if PAD_LAYOUTS(PadType.Num).contains(newPos) then
138-
val newOutput = if action == 'A' then node.output.appended(PAD_LAYOUTS(PadType.Num)(node.pos)) else node.output
139-
if !visited.contains((newPos, newOutput)) then
140-
visited.add((newPos, newOutput))
141-
queue.enqueue(Node(newPos, newOutput, node.total + cost(robots, node.pos, action)))
140+
val newOutput = if action == 'A' then node.state.output.appended(PAD_LAYOUTS(PadType.Num)(node.state.pos)) else node.state.output
141+
val newState = State(newPos, newOutput)
142+
if !visited.contains(newState) then
143+
visited.add(newState)
144+
queue.enqueue(Node(newState, node.total + cost(node.state, newState, action)))
142145

143146
throw new RuntimeException("No shortest program found")
144147

0 commit comments

Comments
 (0)