@@ -30,7 +30,36 @@ val PAD_LAYOUTS = Map(
30
30
)
31
31
32
32
extension (ptype : PadType ) {
33
- def locate (c : Char ) = PAD_LAYOUTS (ptype).find(_._2 == c).get._1
33
+ def layout = PAD_LAYOUTS (ptype)
34
+
35
+ def locate (c : Char ) = ptype.layout.find(_._2 == c).get._1
36
+
37
+ def shortestPath (startPos : Vec2 , endPos : Vec2 ): String =
38
+ case class Node (pos : Vec2 , program : String = " " ) extends Ordered [Node ] {
39
+ def compare (that : Node ): Int = that.program.length compare program.length // Intentionally reversed for min-heap
40
+ }
41
+
42
+ val queue = mutable.PriorityQueue [Node ]()
43
+ val visited = mutable.Set [Vec2 ]()
44
+
45
+ queue.enqueue(Node (startPos))
46
+ visited.add(startPos)
47
+
48
+ while ! queue.isEmpty do
49
+ val node = queue.dequeue()
50
+ if node.pos == endPos then
51
+ return node.program.appended('A' )
52
+
53
+ for (action, dir) <- DIRECTIONS do
54
+ val neigh = node.pos + dir
55
+ if layout.contains(neigh) && ! visited.contains(neigh) then
56
+ visited.add(neigh)
57
+ queue.enqueue(Node (neigh, node.program.appended(action)))
58
+
59
+ throw RuntimeException (" No shortest program found" )
60
+
61
+ def shortestPaths : Map [(Char , Char ), String ] =
62
+ layout.flatMap { case (p1, a1) => layout.map { case (p2, a2) => ((a1, a2), shortestPath(p1, p2)) } }.toMap
34
63
}
35
64
36
65
val DIRECTIONS = Map (
@@ -43,7 +72,7 @@ val DIRECTIONS = Map(
43
72
val ACTIONS = List ('A' ) ++ DIRECTIONS .keySet
44
73
45
74
case class Pad (ptype : PadType , pos : Vec2 ) {
46
- def layout = PAD_LAYOUTS ( ptype)
75
+ def layout = ptype.layout
47
76
48
77
def activate : Char = layout(pos)
49
78
@@ -86,7 +115,7 @@ def shortestProgram(robots: Int, goal: String): String =
86
115
// Your run-of-the-mill Dijkstra implementation
87
116
88
117
val queue = mutable.PriorityQueue [Node ]()
89
- val visited = mutable.HashSet [State ]()
118
+ val visited = mutable.Set [State ]()
90
119
91
120
val startState = State ()
92
121
val start = Node (startState)
@@ -107,7 +136,7 @@ def shortestProgram(robots: Int, goal: String): String =
107
136
visited.add(newState)
108
137
queue.enqueue(Node (newState, node.program.appended(action)))
109
138
110
- throw new RuntimeException (" No shortest program found" )
139
+ throw RuntimeException (" No shortest program found" )
111
140
112
141
def shortestProgramLength (robots : Int , goal : String ): Int =
113
142
case class State (pos : Vec2 = PadType .Num .locate('A' ), dPos : Vec2 = PadType .Dir .locate('A' ), output : String = " " )
@@ -129,7 +158,7 @@ def shortestProgramLength(robots: Int, goal: String): Int =
129
158
// Your run-of-the-mill Dijkstra implementation (this time on the numpad)
130
159
131
160
val queue = mutable.PriorityQueue [Node ]()
132
- val visited = mutable.HashSet [State ]()
161
+ val visited = mutable.Set [State ]()
133
162
134
163
val startState = State ()
135
164
val start = Node (startState)
@@ -154,7 +183,7 @@ def shortestProgramLength(robots: Int, goal: String): Int =
154
183
visited.add(newState)
155
184
queue.enqueue(Node (newState, node.total + c))
156
185
157
- throw new RuntimeException (" No shortest program found" )
186
+ throw RuntimeException (" No shortest program found" )
158
187
159
188
def solve (robots : Int , goals : List [String ], func : (Int , String ) => Int ): Int =
160
189
goals.map { goal =>
@@ -167,8 +196,11 @@ def solve(robots: Int, goals: List[String], func: (Int, String) => Int): Int =
167
196
// println(s"Part 1: ${solve(2, goals)}")
168
197
// println(s"Part 2: ${solve(25, goals)}")
169
198
170
- for i <- (0 to 3 ) do
171
- println(s " ${solve(i, goals, { (r, g) => shortestProgram(r, g).length })} vs ${solve(i, goals, shortestProgramLength)}" )
199
+ println(PadType .Num .shortestPaths)
200
+ println(PadType .Dir .shortestPaths)
201
+
202
+ // for i <- (0 to 3) do
203
+ // println(s"${solve(i, goals, { (r, g) => shortestProgram(r, g).length })} vs ${solve(i, goals, shortestProgramLength)}")
172
204
173
205
// for c <- ('0' to '5') do
174
206
// println(s"$c -> ${(0 to 3).map { i => shortestProgram(makeState(i), s"$c").length }}")
0 commit comments