@@ -41,6 +41,8 @@ case class Pad(ptype: PadType, pos: Vec2) {
41
41
42
42
def activate : Char = layout(pos)
43
43
44
+ def isValid = layout.contains(pos)
45
+
44
46
def perform (action : Char ): (Option [Char ], Pad ) =
45
47
action match
46
48
case 'A' => (Some (activate), this )
@@ -53,15 +55,21 @@ object Pad {
53
55
54
56
case class State (pads : List [Pad ] = List (), output : String = " " ) {
55
57
def perform (action : Char ) =
56
- val (newPads, outAction) = pads.foldLeft[(List [Pad ], Option [Char ])]((List (), Some (action))) { case ((pads, action), pad) =>
57
- action match
58
- case Some (action) =>
59
- val (newAction, newPad) = pad.perform(action)
60
- (pads :+ newPad, newAction)
61
- case None => (pads :+ pad, None )
62
- }
63
- val newOutput = outAction.map(output.appended(_)).getOrElse(output)
64
- State (newPads, newOutput)
58
+ for
59
+ (newPads, outAction) <- pads.foldLeft[Option [(List [Pad ], Option [Char ])]](Some ((List (), Some (action)))) { (acc, pad) =>
60
+ acc.flatMap { case (pads, action) =>
61
+ action match
62
+ case Some (action) =>
63
+ for
64
+ (newAction, newPad) <- Some (pad.perform(action))
65
+ if newPad.isValid
66
+ yield (pads :+ newPad, newAction)
67
+ case None => Some ((pads :+ pad, None ))
68
+ }
69
+ }
70
+ yield
71
+ val newOutput = outAction.map(output.appended(_)).getOrElse(output)
72
+ State (newPads, newOutput)
65
73
}
66
74
67
75
case class Node (state : State = State (), program : String = " " ) extends Ordered [Node ] {
@@ -84,11 +92,14 @@ def shortestProgram(startState: State, goal: String): String =
84
92
if node.state.output == goal then
85
93
return node.program
86
94
87
- for action <- ACTIONS do
88
- val newState = node.state.perform(action)
89
- if ! visited.contains(newState) then
90
- visited.add(newState)
91
- queue.enqueue(Node (newState, node.program.appended(action)))
95
+ if node.state.output.length < goal.length then
96
+ for
97
+ action <- ACTIONS
98
+ newState <- node.state.perform(action)
99
+ do
100
+ if ! visited.contains(newState) then
101
+ visited.add(newState)
102
+ queue.enqueue(Node (newState, node.program.appended(action)))
92
103
93
104
throw new RuntimeException (" No shortest program found" )
94
105
0 commit comments