Skip to content

Commit 2d8948d

Browse files
author
kjh
committed
2019 Day 15 Initial Solve
1 parent 08352da commit 2d8948d

File tree

3 files changed

+225
-2
lines changed

3 files changed

+225
-2
lines changed

resources/2019/15.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,1002,1034,1,1039,101,0,1036,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1106,0,124,101,0,1034,1039,101,0,1036,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1105,1,124,1001,1034,-1,1039,1008,1036,0,1041,102,1,1035,1040,1001,1038,0,1043,1001,1037,0,1042,1106,0,124,1001,1034,1,1039,1008,1036,0,1041,1002,1035,1,1040,1002,1038,1,1043,101,0,1037,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,33,1032,1006,1032,165,1008,1040,35,1032,1006,1032,165,1102,2,1,1044,1105,1,224,2,1041,1043,1032,1006,1032,179,1101,1,0,1044,1105,1,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,58,1044,1106,0,224,1101,0,0,1044,1106,0,224,1006,1044,247,101,0,1039,1034,101,0,1040,1035,1001,1041,0,1036,1001,1043,0,1038,1001,1042,0,1037,4,1044,1105,1,0,33,14,68,54,69,24,9,59,2,7,68,23,97,53,74,21,32,37,55,83,3,26,85,52,38,10,81,19,82,47,70,27,60,32,98,40,46,75,17,66,11,92,30,84,90,36,71,6,82,95,45,23,75,49,38,71,72,2,72,26,64,93,53,68,90,42,3,64,3,66,21,84,47,15,87,60,18,96,30,14,54,99,48,12,63,62,86,41,56,79,50,99,38,68,16,15,69,53,90,59,28,41,7,94,47,74,68,56,43,70,22,55,72,87,28,50,28,55,98,97,22,64,63,21,28,8,87,91,39,1,93,52,95,96,68,13,24,64,14,65,78,89,34,85,92,35,57,83,70,21,75,43,24,76,74,11,90,55,74,22,63,9,95,64,79,2,78,30,74,75,33,23,47,93,93,56,77,48,72,35,42,82,36,25,20,81,15,56,95,96,33,94,53,46,64,31,46,98,43,40,98,48,6,71,44,83,7,56,64,92,72,24,29,35,37,22,63,21,28,68,75,31,77,28,96,71,35,11,66,55,87,17,64,5,53,95,79,52,95,16,78,80,47,51,90,68,63,1,10,99,79,80,30,97,32,82,27,62,49,1,61,93,71,7,39,93,40,75,50,94,68,22,3,44,5,93,55,53,92,92,16,30,94,17,15,77,55,76,25,97,53,73,96,54,98,39,73,75,5,56,78,81,48,64,73,97,25,71,91,28,56,90,53,75,28,79,63,35,48,81,8,28,95,73,52,30,29,88,4,94,2,36,92,86,87,9,34,92,98,30,99,40,37,87,36,49,34,99,72,38,54,71,1,74,41,20,72,40,90,89,6,1,74,50,63,47,98,79,45,90,78,34,10,78,2,72,94,56,30,86,45,82,74,51,73,88,36,65,30,63,8,17,68,92,13,93,3,77,72,20,90,63,37,86,77,17,95,56,57,61,77,74,19,18,70,34,93,23,96,8,93,1,79,81,66,27,38,2,12,31,81,43,48,93,67,60,17,93,44,99,39,72,35,92,99,42,46,79,60,22,56,75,60,95,23,84,33,67,16,16,36,55,39,83,46,75,80,79,2,63,25,60,20,4,39,97,20,90,4,30,86,9,7,90,80,49,20,98,29,83,51,46,92,27,65,34,57,61,10,94,84,90,3,51,64,5,37,19,51,69,73,39,96,99,24,34,66,21,76,81,33,85,14,67,54,29,94,17,85,8,88,42,6,89,83,9,52,81,90,11,38,95,20,93,81,20,20,86,6,36,69,77,25,15,91,78,32,80,3,22,11,90,89,6,11,73,1,82,46,77,99,26,41,2,75,92,52,13,80,96,44,38,98,47,96,87,28,65,77,17,48,93,93,46,8,82,86,26,84,64,38,53,83,67,97,30,64,39,53,31,63,60,11,86,81,22,84,13,89,75,2,77,5,31,69,3,8,75,60,13,14,90,66,28,66,18,85,70,51,82,94,28,29,99,35,71,75,80,1,93,14,13,91,14,83,24,77,32,8,48,85,96,31,6,54,70,95,32,35,66,80,88,3,96,35,80,54,8,70,30,2,18,59,81,27,31,85,73,35,79,68,30,14,21,67,74,57,60,98,44,46,24,12,60,31,39,68,79,50,3,61,40,75,54,25,85,6,93,56,86,74,98,10,15,66,68,13,44,26,98,40,79,80,14,14,86,30,5,74,66,46,96,17,83,6,98,16,67,91,90,56,97,1,68,14,85,93,69,56,88,40,79,29,91,25,68,69,74,48,66,73,76,17,61,31,62,90,84,46,89,0,0,21,21,1,10,1,0,0,0,0,0,0

src/main/kotlin/advent2019/Day15.kt

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
package advent2019
2+
3+
import kotlinx.coroutines.channels.Channel
4+
import kotlinx.coroutines.channels.ClosedReceiveChannelException
5+
import kotlinx.coroutines.launch
6+
import kotlinx.coroutines.runBlocking
7+
import kotlinx.coroutines.selects.select
8+
import xyz.usbpc.aoc.Day
9+
import xyz.usbpc.aoc.inputgetter.AdventOfCode
10+
import xyz.usbpc.utils.Queue
11+
12+
class Day15(override val adventOfCode: AdventOfCode) : Day {
13+
override val day = 15
14+
val input = adventOfCode.getInput(2019, day).split(",").map { it.toLong() }
15+
16+
class Tile(val type: Type, var distance: Int = Int.MAX_VALUE) {
17+
var north : Tile? = null
18+
var east : Tile? = null
19+
var south : Tile? = null
20+
var west : Tile? = null
21+
22+
enum class Type {
23+
Wall,
24+
Path,
25+
Goal;
26+
}
27+
28+
fun getConnectingTiles() =
29+
mutableListOf<Tile>().apply {
30+
if (north != null)
31+
add(north!!)
32+
if (east != null)
33+
add(east!!)
34+
if (south != null)
35+
add(south!!)
36+
if (west != null)
37+
add(west!!)
38+
}
39+
40+
fun anyDirNull() = north == null || east == null || south == null || west == null
41+
42+
fun linkNextDirection(tile: Tile) {
43+
when (getNextDirection()) {
44+
CardinalDirection.North -> {
45+
north = tile
46+
tile.south = this
47+
}
48+
CardinalDirection.East -> {
49+
east = tile
50+
tile.west = this
51+
}
52+
CardinalDirection.South -> {
53+
south = tile
54+
tile.north = this
55+
}
56+
CardinalDirection.West -> {
57+
west = tile
58+
tile.east = this
59+
}
60+
}
61+
}
62+
63+
fun getNextDirection() : CardinalDirection {
64+
when {
65+
north == null -> return CardinalDirection.North
66+
east == null -> return CardinalDirection.East
67+
south == null -> return CardinalDirection.South
68+
west == null -> return CardinalDirection.West
69+
}
70+
71+
when (listOf(north!!.distance, east!!.distance, south!!.distance, west!!.distance).withIndex().minBy { it.value }!!.index) {
72+
0 -> return CardinalDirection.North
73+
1 -> return CardinalDirection.East
74+
2 -> return CardinalDirection.South
75+
3 -> return CardinalDirection.West
76+
}
77+
78+
throw IllegalStateException("This can't happen! I'm stuck in a 1x1 square! SEND HELP!!!!!")
79+
}
80+
}
81+
82+
enum class CardinalDirection {
83+
North,
84+
East,
85+
South,
86+
West;
87+
}
88+
89+
fun generateMap() = runBlocking {
90+
val inCh = Channel<Long>()
91+
val outCh = Channel<Long>()
92+
93+
val tileMap = mutableMapOf<Point, Tile>()
94+
95+
var curPos = Point(0, 0)
96+
var curTile = Tile(Tile.Type.Path, 0)
97+
98+
tileMap[curPos] = curTile
99+
100+
val vm = Intcode(input.toMutableList(), inCh, outCh)
101+
102+
val vmRunner = launch { vm.simulate() }
103+
104+
while (tileMap.values.filter { it.type != Tile.Type.Wall }.any{ it.anyDirNull() }) {
105+
val (nextPos, cmd) = when (curTile.getNextDirection()) {
106+
CardinalDirection.North -> Pair(curPos.plus(Point(0, -1)), 1L)
107+
CardinalDirection.South -> Pair(curPos.plus(Point(0, 1)), 2L)
108+
CardinalDirection.West -> Pair(curPos.plus(Point(-1, 0)), 3L)
109+
CardinalDirection.East -> Pair(curPos.plus(Point(1, 0)), 4L)
110+
}
111+
112+
inCh.send(cmd)
113+
val lastResponse = outCh.receive()
114+
115+
if (nextPos !in tileMap) {
116+
val tile = when (lastResponse) {
117+
0L -> Tile(Tile.Type.Wall, Int.MAX_VALUE)
118+
1L -> Tile(Tile.Type.Path, curTile.distance + 1)
119+
2L -> Tile(Tile.Type.Goal, curTile.distance + 1)
120+
else -> throw IllegalStateException("I got a $lastResponse don't know what that is supposed to mean.")
121+
}
122+
tileMap[nextPos] = tile
123+
}
124+
125+
val nextTile = tileMap[nextPos]!!
126+
127+
curTile.linkNextDirection(nextTile)
128+
129+
if (nextTile.type != Tile.Type.Wall) {
130+
curPos = nextPos
131+
curTile = nextTile
132+
}
133+
}
134+
135+
vmRunner.cancel()
136+
vmRunner.join()
137+
138+
val maxY = tileMap.keys.maxBy { it.y }!!.y
139+
val minY = tileMap.keys.minBy { it.y }!!.y
140+
val maxX = tileMap.keys.maxBy { it.x }!!.x
141+
val minX = tileMap.keys.minBy { it.x }!!.x
142+
143+
buildString {
144+
for (y in minY..maxY) {
145+
for (x in minX..maxX) {
146+
when (val cur = Point(x, y)) {
147+
curPos -> {
148+
append('D')
149+
}
150+
in tileMap -> {
151+
when (tileMap[cur]!!.type) {
152+
Tile.Type.Wall -> append('#')
153+
Tile.Type.Path -> append('.')
154+
Tile.Type.Goal -> append('X')
155+
}
156+
}
157+
else -> {
158+
append(' ')
159+
}
160+
}
161+
}
162+
append('\n')
163+
}
164+
}
165+
166+
tileMap[Point(0, 0)]!! to tileMap.values.single { it.type == Tile.Type.Goal }
167+
}
168+
169+
override fun part1() : Any {
170+
val map = generateMap().first
171+
172+
val queue = Queue<Pair<Tile, Int>>()
173+
174+
val visited = mutableSetOf<Tile>()
175+
queue.add(map to 0)
176+
177+
var curTile : Tile
178+
var curDistance : Int
179+
180+
do {
181+
val (tile, distance) = queue.remove()
182+
curTile = tile
183+
curDistance = distance
184+
185+
visited.add(curTile)
186+
187+
curTile.getConnectingTiles()
188+
.filter { it.type != Tile.Type.Wall }
189+
.filter { it !in visited }
190+
.forEach { queue.add(it to curDistance + 1) }
191+
} while (curTile.type != Tile.Type.Goal)
192+
193+
return curDistance
194+
}
195+
196+
override fun part2() : Any {
197+
val end = generateMap().second
198+
199+
val queue = Queue<Pair<Tile, Int>>()
200+
201+
val visited = mutableSetOf<Tile>()
202+
queue.add(end to 0)
203+
204+
var curTile : Tile
205+
var curDistance : Int
206+
207+
do {
208+
val (tile, distance) = queue.remove()
209+
curTile = tile
210+
curDistance = distance
211+
212+
visited.add(curTile)
213+
214+
curTile.getConnectingTiles()
215+
.filter { it.type != Tile.Type.Wall }
216+
.filter { it !in visited }
217+
.forEach { queue.add(it to curDistance + 1) }
218+
} while (queue.isNotEmpty())
219+
220+
return curDistance
221+
}
222+
}

src/main/kotlin/advent2019/Main.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ fun main(args: Array<String>) {
2020
//add(Day11(adventOfCode))
2121
//add(Day12(adventOfCode))
2222
//add(Day13(adventOfCode))
23-
add(Day14(adventOfCode))
24-
//add(Day15(adventOfCode))
23+
//add(Day14(adventOfCode))
24+
add(Day15(adventOfCode))
2525
//add(Day16(adventOfCode))
2626
//add(Day17(adventOfCode))
2727
//add(Day18(adventOfCode))

0 commit comments

Comments
 (0)