@@ -107,38 +107,41 @@ def shortestProgram(robots: Int, goal: String): String =
107
107
108
108
throw new RuntimeException (" No shortest program found" )
109
109
110
- def cost (robots : Int , pos : Vec2 , action : Char ): Int = 1
111
-
112
110
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 ] {
114
114
def compare (that : Node ): Int = that.total compare total // Intentionally reversed for min-heap
115
115
}
116
116
117
+ def cost (state : State , newState : State , action : Char ): Int = 1
118
+
117
119
// Your run-of-the-mill Dijkstra implementation (this time on the numpad)
118
120
119
121
val queue = mutable.PriorityQueue [Node ]()
120
- val visited = mutable.HashSet [( Vec2 , String ) ]()
122
+ val visited = mutable.HashSet [State ]()
121
123
122
- val startPos = PadType . Num .locate( 'A' )
123
- val start = Node (startPos )
124
+ val startState = State ( )
125
+ val start = Node (startState )
124
126
queue.enqueue(start)
125
- visited.add((start.pos, start.output) )
127
+ visited.add(startState )
126
128
127
129
while ! queue.isEmpty do
128
130
val node = queue.dequeue()
129
- if node.output == goal then
131
+ if node.state. output == goal then
130
132
return node.total
131
133
132
- if node.output.length < goal.length then
134
+ if node.state. output.length < goal.length then
133
135
for
134
136
action <- ACTIONS
135
137
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 ))
137
139
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)))
142
145
143
146
throw new RuntimeException (" No shortest program found" )
144
147
0 commit comments