@@ -11,9 +11,10 @@ import kotlin.collections.component1
11
11
import kotlin.collections.component2
12
12
13
13
fun solveA (text : String , debug : Debug = Debug .Disabled ): Int {
14
- val (mapText, instructionsText) = text.split(" \n\n " )
15
- val map = mapText.lines()
16
- val instructions = instructionsText.replace(" \n " , " " )
14
+ val (map, instructions) = text.split(" \n\n " ).let { (first, second) ->
15
+ first.lines() to second.replace(" \n " , " " )
16
+ }
17
+
17
18
val walls = mutableSetOf<Point >()
18
19
val boxes = mutableSetOf<Point >()
19
20
var robot = map.indexOf(' @' )
@@ -26,31 +27,18 @@ fun solveA(text: String, debug: Debug = Debug.Disabled): Int {
26
27
}
27
28
}
28
29
29
-
30
30
instructions.forEach { c ->
31
- val direction = when (c) {
32
- ' < ' -> Direction . LEFT
33
- ' > ' -> Direction . RIGHT
34
- ' ^ ' -> Direction . UP
35
- ' v ' -> Direction . DOWN
36
- else -> TODO ( " Unknown direction $c " )
31
+ val direction = Direction .parse (c)
32
+ val boxesToMove = mutableSetOf< Point >()
33
+ var nextPoint = robot + direction.point
34
+ while (nextPoint in boxes) {
35
+ boxesToMove.add(nextPoint)
36
+ nextPoint + = direction.point
37
37
}
38
-
39
- val nextPoint = robot + direction.point
40
- if (nextPoint !in walls && nextPoint !in boxes) {
41
- robot = nextPoint
42
- } else {
43
- val boxesToMove = mutableSetOf<Point >()
44
- var nextBox = nextPoint
45
- while (nextBox in boxes) {
46
- boxesToMove.add(nextBox)
47
- nextBox + = direction.point
48
- }
49
- if (nextBox !in walls) {
50
- boxes.removeAll(boxesToMove)
51
- boxes.addAll(boxesToMove.map { it + direction.point })
52
- robot = nextPoint
53
- }
38
+ if (nextPoint !in walls) {
39
+ boxes.removeAll(boxesToMove)
40
+ boxes.addAll(boxesToMove.map { it + direction.point })
41
+ robot + = direction.point
54
42
}
55
43
}
56
44
@@ -59,11 +47,12 @@ fun solveA(text: String, debug: Debug = Debug.Disabled): Int {
59
47
60
48
61
49
fun solveB (text : String , debug : Debug = Debug .Disabled ): Int {
62
- val (mapText, instructionsText) = text.split(" \n\n " )
63
- val map = mapText.lines()
50
+ val (map, instructions) = text.split(" \n\n " ).let { (first, second) ->
51
+ first.lines() to second.replace(" \n " , " " )
52
+ }
53
+
64
54
val width = map[0 ].length * 2
65
55
val height = map.size
66
- val instructions = instructionsText.replace(" \n " , " " )
67
56
val walls = mutableSetOf<Point >()
68
57
val boxes = mutableSetOf<Pair <Point , Point >>()
69
58
@@ -91,18 +80,14 @@ fun solveB(text: String, debug: Debug = Debug.Disabled): Int {
91
80
}
92
81
93
82
instructions.forEachIndexed { i, c ->
94
- val direction = when (c) {
95
- ' <' -> Direction .LEFT
96
- ' >' -> Direction .RIGHT
97
- ' ^' -> Direction .UP
98
- ' v' -> Direction .DOWN
99
- else -> throw IllegalArgumentException (" Unknown direction $c " )
100
- }
83
+ val direction = Direction .parse(c)
101
84
102
85
val boxesToMove = mutableSetOf<Pair <Point , Point >>()
103
- val pointsToVisit = mutableSetOf (robot + direction.point)
104
- while (pointsToVisit.isNotEmpty() && pointsToVisit.first() !in walls) {
105
- val nextBoxPoint = pointsToVisit.removeFirst()
86
+ val boxPointsToVisit = mutableSetOf (robot + direction.point)
87
+ while (boxPointsToVisit.isNotEmpty() && boxPointsToVisit.first() !in walls) {
88
+ val nextBoxPoint = boxPointsToVisit.removeFirst()
89
+ // For left and right only one of these is possible.
90
+ // But for the sake of simplicity, we just search for both
106
91
val possibleBoxes = setOf (
107
92
Pair (nextBoxPoint + Direction .LEFT .point, nextBoxPoint),
108
93
Pair (nextBoxPoint, nextBoxPoint + Direction .RIGHT .point)
@@ -112,16 +97,16 @@ fun solveB(text: String, debug: Debug = Debug.Disabled): Int {
112
97
boxesToMove.add(box)
113
98
when (direction) {
114
99
Direction .UP , Direction .DOWN -> {
115
- pointsToVisit .add(box.first + direction.point)
116
- pointsToVisit .add(box.second + direction.point)
100
+ boxPointsToVisit .add(box.first + direction.point)
101
+ boxPointsToVisit .add(box.second + direction.point)
117
102
}
118
103
119
- Direction .LEFT -> pointsToVisit .add(box.first + direction.point)
120
- else -> pointsToVisit .add(box.second + direction.point)
104
+ Direction .LEFT -> boxPointsToVisit .add(box.first + direction.point)
105
+ else -> boxPointsToVisit .add(box.second + direction.point)
121
106
}
122
107
}
123
108
}
124
- if (pointsToVisit .none { it in walls }) {
109
+ if (boxPointsToVisit .none { it in walls }) {
125
110
boxes.removeAll(boxesToMove)
126
111
boxes.addAll(boxesToMove.map { (first, second) -> first + direction.point to second + direction.point })
127
112
robot + = direction.point
0 commit comments