Skip to content

Instantly share code, notes, and snippets.

@Miha-x64
Created January 9, 2020 03:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Miha-x64/67f95d6401bcdcae611f997a86452edd to your computer and use it in GitHub Desktop.
Save Miha-x64/67f95d6401bcdcae611f997a86452edd to your computer and use it in GitHub Desktop.
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.PersistentSet
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentMap
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
class Day18ManyWorldsInterpretation {
/**
* Nope this does not work for [smallMaze81] and [bigMaze]
*/
@Test
fun silverTest() {
assertThat(Walker(smallMaze8).computeSteps().also { println(it) }.first).isEqualTo(8)
assertThat(Walker(smallMaze81).computeSteps().also { println(it) }.first).isEqualTo(81)
assertThat(Walker(smallMaze86).computeSteps().also { println(it) }.first).isEqualTo(86)
assertThat(Walker(smallMaze132).computeSteps().also { println(it) }.first).isEqualTo(132)
assertThat(Walker(smallMaze136).computeSteps().also { println(it) }.first).isEqualTo(136)
}
@Test
fun silver() {
assertThat(Walker(bigMaze).computeSteps().also { println(it) }.first).isEqualTo(6098)
}
@Test
fun gold() {
val result = intArrayOf(0, 1, 2, 3)
.map { index -> Walker(bigMaze1698, index).computeStepsAsync() }
.let { solutions -> solutions.sumBy { it.first } }
assertThat(result).isEqualTo(1698)
}
class Walker(mapString: String = smallMaze136, private val index: Int? = 0) {
private fun parseMapAndPosition(map: String): PersistentMap<Point, Char> {
return parseMap(map)
.mapValues { (_, v) -> if (v == '.') ' ' else v }
.toPersistentMap()
}
private val map: PersistentMap<Point, Char>
private val start: Point
private val starts: List<Point>
init {
map = parseMapAndPosition(mapString)
starts = map.entries.mapNotNull { (k, v) -> if (v == '@') k else null }
start = starts[index ?: 0]
}
private fun Point.value(): Char = map.getValue(this)
private fun Char.isKey() = isLetter() && isLowerCase()
data class AvailablePoint(val point: Point, val steps: Int)
data class CacheKey(val point: Point, val collected: Set<Char>)
private val cache: MutableMap<CacheKey, Pair<Int, String>> = mutableMapOf()
fun computeSteps(): Pair<Int, String> {
return computeStepsAsync()
}
fun computeStepsAsync(): Pair<Int, String> {
return reachPoints(start, externalKeys(), 0)
}
/** Keys which we cannot collect */
private fun externalKeys(): Set<Char> {
if (index == null) {
return emptySet()
} else {
return generateSequence(starts.minus(start).toSet()) { points: Set<Point> ->
val morePoints = points + points
.flatMap { point -> listOf(point.left(), point.up(), point.right(), point.down()) }
.filter { point -> point.value() != '#' }
.filter { point -> point !in points }
if (morePoints.size != points.size) morePoints else null
}
.last()
.map { it.value() }
.filter { it.isKey() }
.toSet()
}
}
/** return the amount of steps which is required to reach the best next position + best other further steps */
private fun reachPoints(start: Point, collected: Set<Char>, prev: Int): Pair<Int, String> {
return (cache.computeIfAbsent(CacheKey(start, collected)) {
reachOutWithWave(start, collected)
.parallelStream()
.filter { (point, _) -> point.value() !in collected }
.map { (point, steps) ->
val v = reachPoints(point, collected.plus(point.value()), steps)
v.copy(second = v.second + point.value()) // adds the path
}
.min(compareBy { it.first })
.orElseGet { 0 to "*" }
}).let { single -> single.copy(single.first + prev) }
}
private data class Wave(val points: PersistentSet<Point>, val front: List<AvailablePoint>, val iterations: Int)
/** A wave starting at [position] and going in all directions unless it encounters a closed door, a wall, or a new key */
private fun reachOutWithWave(position: Point, collected: Set<Char>): List<AvailablePoint> {
// check(position.value().let { it.isKey() || it == '@' }) { "Position $position=${position.value()} is not a key!" }
val seed = Wave(points = persistentSetOf(position), front = listOf(AvailablePoint(position, 0)), iterations = 0)
return generateSequence(seed) { wave: Wave ->
val keyLocations = wave.front.filter { available -> available.point.value().let { it.isKey() && it !in collected } }
val growth = wave.front
.map { available: AvailablePoint -> available.point }
.filter { point: Point -> !point.value().isKey() || point.value() in collected }
.flatMap { point -> listOf(point.left(), point.up(), point.right(), point.down()) }
.filter { point -> point !in wave.points }
.filter { point ->
with(point.value()) {
when {
this == ' ' -> true
this == '@' -> true
this == '#' -> false
isLowerCase() -> true
isUpperCase() -> toLowerCase() in collected
else -> throw Exception("Cannot deal with ${point.value()}")
}
}
}
.map { point -> AvailablePoint(point, wave.iterations + 1) }
val newFront = growth.plus(keyLocations)
when {
growth.isNotEmpty() -> Wave(wave.points.addAll(newFront.map { it.point }), front = newFront, iterations = wave.iterations + 1)
else -> null
}
}
.last()
.front
// remove non-keys from the front
.filter { availablePoint -> availablePoint.point.value().let { it.isKey() && it !in collected } }
}
}
}
val bigMaze1698 = """
#################################################################################
#...#..j..........#.........#...........#.......#........n......#.....#........m#
#.#.#.#.###########.###.#####.#######O#####.###.#.#########.#.###.#.###.###.###.#
#.#.#.#...............#.Z.......#...#...#...#.#.#.#.......#.#.....#.....#.X.#...#
#.#.#.###########################P#.#.#.#.###.#.###.#####.###.###########.###.###
#.#.#.#.......#.........#......b..#.#.#.#.#.......#...#.#...#.....#.......#.....#
#.#.#.#.###.###.#######.#.#########.###.#.#######.###.#.###.#####.#.#############
#.#.#.#.#...#...#..l#...#.#.......#.#...#.....#.......#.#...#.....#.........#..k#
#.###.#.###.#.#####.#.###.#######.#.#.###.###.#########.#.###.#####.#######.#.#.#
#...#.#...#.#.#...#...#...#.....#.#...#.#...#...#.....#.#.#...#...#...#...#...#.#
#.#.#.#.#.###.#.#U###.###.#.###.#.#####.###.###.#.###.#.#.#.###.#.#####.#.#####F#
#.#.#.#.#...#...#...#.....#.#...#.......#...#g#...#.#.#...#.#...#...#.E.#.....#.#
#.#.#.#.###.#######.#######.###.###Y#.###.###.#####.#.###.###.#####.#.#######.#.#
#.#...#...#...#.....#......a..#...#.#...#.....#.....#...#.....#.......#.....#...#
#.#####D#####.#.#######.#####.###.###.#.#####.#.###.###.#################.#####.#
#.M...#.#...#.#.#c....#...#...#.#...#.#.#...#.#.#.#.#.#.#...............#...#...#
#####.###.#.#.#H#.###.#####.###.###.#.#.#.###.#.#.#.#.#.#.###########.#.###.#.###
#...#.....#.#.#.#...#...#...#.....#.#.#.#...#.#.#.....#.......#.....#.#.#...#.#.#
#.#.#######.#.#.#.#####.#.###.#.###.###.#.#.#.#.#####.#########.###.###.#.###.#.#
#.#.#....x#.#.#...#.....#.#...#.#..i#...#.#.#.#...#...#.........#.....#.#...#...#
#.###K#.#.#.#.#####.#####.#.###.#.###.#####.#.###.#####.###.#########.#.#.#.###.#
#...#.#.#.#.#.....#..r#...#...#.#.#.....#...#.....#.....#...#.......#...#.#.....#
#.#.#.#.###.#.###.#####.#####.#.#.#.###.#.#####.###.#####.#########.#####.#####.#
#.#.#.#.....#.#.........#.....#.#.#...#.#.......#...#...#.#.........#.....#...#.#
###.#.#########.#########.#####.#.#####.#####.###.#.#.#.###.#########.#####.#.#.#
#...#...#.....#.#...........#...#.....#.#..t#.#.#.#.#.#.....#...#.........#.#.#.#
#.#####.#.#.#.#.#####.#####.#########.#.#.#.#.#.#.#.#.#######.###.#########.#.###
#.......#.#.#.#.....#...#.#.....#...#.#.#.#.#...#.#.#.....#.......#...#...#.#...#
#.#########.#.###.#.###.#.#####.#.#.#.#.#.#.#####.#.#####.#########.#.#.#.#.###.#
#.#.....#...#...#.#.#...#...#...#.#...#.#.#.......#.#...#.......#q..#...#...#...#
#.###.#.#.#####.###.###.#.###.###.#####.#.#########.###.#######.#.###########.###
#.....#.#...#.#...#...#.#...#...#...#...#...#...#.#.....#.......#.#...#.....#...#
#######.#.#.#.###.#.#.#.###.###.###.###.#.#.#.#.#.#####.#.#######.#.###.#.#####.#
#.....#.#.#.#.....#.#.#.......#...#.....#.#.#.#.#.#.....#.#...#...#...#.#.....#.#
#.#.###.#.#.###.#####.#####.###.#.#####.#.#.#.#.#.#.#####.#.#.#.#####.#.#####.#.#
#.#.#...#.#...#.#...#.#.....#...#...#...#.#...#.#...#...#...#...#.....#.#.....#.#
###.#.###.###.#.#.#.#.#######.#######.###.#####.#.###.#.#########.#.###.#.###.#.#
#...#.#...#...#.#.#.#...#.....#.....#.#.#.#...#.#.#...#.......#...#.....#...#.#.#
#.###.#####.###.#.#.###.#.#####.###.#.#.#.###.#.###.#######.###.###########.###.#
#...........#.....#.....#.........#....@#@....#...........#...............#w....#
#################################################################################
#.....#.....#.......#.........#........@#@........#.#...................#...#...#
#.###.###.#.#.#####.#.#.#####.#.#####.#.#.#######.#.#.###############.#.#.#.#.#.#
#...#.....#...#.#...#.#...#.#.#.#.#...#.#.......#...#...#...#...#...#.#...#...#.#
###.#####.#####.#.#######.#.#.#.#.#.###.#.#####.###.###.#.###.#.#.#.#.#########.#
#...#...#.#...#.#.....#...#...#...#...#.#.#...#...#.#...#.#...#...#.#.........#.#
#.###.#.###.#.#.#####.#.###.#########.#.#.###.###.###.###.#.#######.###########.#
#.....#.....#.#.....#...#.#.#.......#.#.#.......#.....#...#.#...................#
#############.#####.#####.#.#.#####.#.#.#######.#######.#.#.###.###############.#
#...........#.....#.......#.#...#.#.#.#.#.....#.........#.#...#.#.........#...#.#
#########.#.#####.#.###.###.###.#.#.#.###.#.#.#######T#######.###.#######.#.###.#
#........f#.#...#.#...#.....#...#...#...#.#.#.#.....#.#.......#...#...#...#.#...#
#.#######.###.#.#.#####.#####.###.#####.#.#.#.#.###.#.#.#######.#####.#.###.#.###
#.#.#.....#...#.#.....#.......#...#.....#.#.#.#.#.#...#.#...#.......#.#.#.......#
#.#.#.#####.###.#.###.#########.###.#.###.#.###.#.#####.#.#.#.#####.#.#.#######.#
#.#.#...#...#.#.#...#.#...#...#.#.#.#...#.#...#.#...#...#.#...#...#...#.#.....#.#
#.#.###.#.###.#.###.#.###.#.#.#.#.#.###.#####.#.#.#.#.###.#####.#.#####.#.###.#.#
#.#.....#.#...#...#.#...#...#.#.#...#.#.#.....#.#.#.#.......#...#.#...#....s#.#v#
#.#.#####.#.#.###.###.#.#.###.#.###.#.#.#.#####.###.#####.###.###.#.#.#######.#.#
#.#...#...#.#...#...#.#.#...#.#...#..y#.#.#.........#...#.#...#.....#.........#.#
#.###.#.#######.###.###.#####.###.#####.#.#.#####.###.#.###.#########.###########
#.#...#.........#.#...#.....#...#.#.....#...#...#.#...#...#.#.......#.#.........#
#.#.###########.#.#########.#.###.#.#########.#.#.#.#####.#.#######R###.#######.#
#.#.#.....Q...#...#.........#...#.#.#...#...#.#.#.#.#...#.....#...#.....#...#.C.#
#.###.#.#########.#.###.#######.#.#.#.#.#.#.#.#.#.#.###.#####.#.#.#########.#.###
#...#.#...#...G.#.#...#.#.#.....#.#...#.#.#.#.#.#.#...#...#...#.#.....#.....#.#.#
#.#.#.###.#.###.#.#####.#.#.#.###.#####.#.#.#.#.#.###.#.#.#.#####.###.#.#####.#.#
#.#.#...#.#.#...#.#.....#.#.#.#...#...I.#.#...#.#...#.#.#.#.#.....#.#...#...#...#
#.#S###.#.#.#.#.#.#.#####.#.#.#.###.###.#.#####.#####.#.#.#.###.###.###.#.#.###.#
#.#.....#...#.#.#...#.......#...#...#.#.#.....#.......#.#.#...#.#.#...#.#.#.....#
#.###########.#######.###########.###.#.#.###.#########.#.###.#.#.#.#.#.#.#######
#e#.......#...#.....#.#.......#...#.#...#.#...#...#.#...#.......#...#...#.#.....#
#.#.#######.#.#.#.###.#.###.###.#.#.#.###N#.###.#.#.#.#########.#####.###.#.###.#
#.#.#.......#.#.#.....#...#.#...#.#.....#.#.#...#.#.#.#..p..#...#...#...#h..#.#.#
#.#.#.#########W#########.#.#.###.#####.###.#.###.#.#.#.###.#####.#B#########.#.#
#...#d....#...#.....#...#.#.....#.....#.#...#.#.#.#.#.#...#.#.....#.#.......#...#
###.#####.#.#.#####.#.#.###.#######.#.#.#.###.#.#.#.#.###.#.#.#####.#.#####.#.###
#...#...#...#.....#...#.V.#.#.....#.#.#.#.#...#z#.#...#...#.#...#.#...#.#.L.#.#.#
#.#####.#######.#########.###.###.###.#.#.#.###J#.#####.###.###.#.#####.#.###.#.#
#.............#...............#.....A.#.#.......#........o#.............#....u..#
#################################################################################
""".trimIndent()
val smallMaze8 = """
#########
#b.A.@.a#
#########"""
val smallMaze86 = """
########################
#f.D.E.e.C.b.A.@.a.B.c.#
######################.#
#d.....................#
########################"""
val smallMaze132 = """
########################
#...............b.C.D.f#
#.######################
#.....@.a.B.c.d.A.e.F.g#
########################"""
/**
* Shortest paths are 136 steps; one is: a, f, b, j, g, n, h, d, l, o, e, p, c, i, k, m
*/
val smallMaze136 = """
#################
#i.G..c...e..H.p#
########.########
#j.A..b...f..D.o#
########@########
#k.E..a...g..B.n#
########.########
#l.F..d...h..C.m#
#################"""
/**
* Shortest paths are 136 steps; one is: a, c, f, i, d, g, b, e, h
*/
val smallMaze81 = """
########################
#@..............ac.GI.b#
###d#e#f################
###A#B#C################
###g#h#i################
########################"""
val bigMaze = """
#################################################################################
#...#..j..........#.........#...........#.......#........n......#.....#........m#
#.#.#.#.###########.###.#####.#######O#####.###.#.#########.#.###.#.###.###.###.#
#.#.#.#...............#.Z.......#...#...#...#.#.#.#.......#.#.....#.....#.X.#...#
#.#.#.###########################P#.#.#.#.###.#.###.#####.###.###########.###.###
#.#.#.#.......#.........#......b..#.#.#.#.#.......#...#.#...#.....#.......#.....#
#.#.#.#.###.###.#######.#.#########.###.#.#######.###.#.###.#####.#.#############
#.#.#.#.#...#...#..l#...#.#.......#.#...#.....#.......#.#...#.....#.........#..k#
#.###.#.###.#.#####.#.###.#######.#.#.###.###.#########.#.###.#####.#######.#.#.#
#...#.#...#.#.#...#...#...#.....#.#...#.#...#...#.....#.#.#...#...#...#...#...#.#
#.#.#.#.#.###.#.#U###.###.#.###.#.#####.###.###.#.###.#.#.#.###.#.#####.#.#####F#
#.#.#.#.#...#...#...#.....#.#...#.......#...#g#...#.#.#...#.#...#...#.E.#.....#.#
#.#.#.#.###.#######.#######.###.###Y#.###.###.#####.#.###.###.#####.#.#######.#.#
#.#...#...#...#.....#......a..#...#.#...#.....#.....#...#.....#.......#.....#...#
#.#####D#####.#.#######.#####.###.###.#.#####.#.###.###.#################.#####.#
#.M...#.#...#.#.#c....#...#...#.#...#.#.#...#.#.#.#.#.#.#...............#...#...#
#####.###.#.#.#H#.###.#####.###.###.#.#.#.###.#.#.#.#.#.#.###########.#.###.#.###
#...#.....#.#.#.#...#...#...#.....#.#.#.#...#.#.#.....#.......#.....#.#.#...#.#.#
#.#.#######.#.#.#.#####.#.###.#.###.###.#.#.#.#.#####.#########.###.###.#.###.#.#
#.#.#....x#.#.#...#.....#.#...#.#..i#...#.#.#.#...#...#.........#.....#.#...#...#
#.###K#.#.#.#.#####.#####.#.###.#.###.#####.#.###.#####.###.#########.#.#.#.###.#
#...#.#.#.#.#.....#..r#...#...#.#.#.....#...#.....#.....#...#.......#...#.#.....#
#.#.#.#.###.#.###.#####.#####.#.#.#.###.#.#####.###.#####.#########.#####.#####.#
#.#.#.#.....#.#.........#.....#.#.#...#.#.......#...#...#.#.........#.....#...#.#
###.#.#########.#########.#####.#.#####.#####.###.#.#.#.###.#########.#####.#.#.#
#...#...#.....#.#...........#...#.....#.#..t#.#.#.#.#.#.....#...#.........#.#.#.#
#.#####.#.#.#.#.#####.#####.#########.#.#.#.#.#.#.#.#.#######.###.#########.#.###
#.......#.#.#.#.....#...#.#.....#...#.#.#.#.#...#.#.#.....#.......#...#...#.#...#
#.#########.#.###.#.###.#.#####.#.#.#.#.#.#.#####.#.#####.#########.#.#.#.#.###.#
#.#.....#...#...#.#.#...#...#...#.#...#.#.#.......#.#...#.......#q..#...#...#...#
#.###.#.#.#####.###.###.#.###.###.#####.#.#########.###.#######.#.###########.###
#.....#.#...#.#...#...#.#...#...#...#...#...#...#.#.....#.......#.#...#.....#...#
#######.#.#.#.###.#.#.#.###.###.###.###.#.#.#.#.#.#####.#.#######.#.###.#.#####.#
#.....#.#.#.#.....#.#.#.......#...#.....#.#.#.#.#.#.....#.#...#...#...#.#.....#.#
#.#.###.#.#.###.#####.#####.###.#.#####.#.#.#.#.#.#.#####.#.#.#.#####.#.#####.#.#
#.#.#...#.#...#.#...#.#.....#...#...#...#.#...#.#...#...#...#...#.....#.#.....#.#
###.#.###.###.#.#.#.#.#######.#######.###.#####.#.###.#.#########.#.###.#.###.#.#
#...#.#...#...#.#.#.#...#.....#.....#.#.#.#...#.#.#...#.......#...#.....#...#.#.#
#.###.#####.###.#.#.###.#.#####.###.#.#.#.###.#.###.#######.###.###########.###.#
#...........#.....#.....#.........#...........#...........#...............#w....#
#######################################.@.#######################################
#.....#.....#.......#.........#...................#.#...................#...#...#
#.###.###.#.#.#####.#.#.#####.#.#####.#.#.#######.#.#.###############.#.#.#.#.#.#
#...#.....#...#.#...#.#...#.#.#.#.#...#.#.......#...#...#...#...#...#.#...#...#.#
###.#####.#####.#.#######.#.#.#.#.#.###.#.#####.###.###.#.###.#.#.#.#.#########.#
#...#...#.#...#.#.....#...#...#...#...#.#.#...#...#.#...#.#...#...#.#.........#.#
#.###.#.###.#.#.#####.#.###.#########.#.#.###.###.###.###.#.#######.###########.#
#.....#.....#.#.....#...#.#.#.......#.#.#.......#.....#...#.#...................#
#############.#####.#####.#.#.#####.#.#.#######.#######.#.#.###.###############.#
#...........#.....#.......#.#...#.#.#.#.#.....#.........#.#...#.#.........#...#.#
#########.#.#####.#.###.###.###.#.#.#.###.#.#.#######T#######.###.#######.#.###.#
#........f#.#...#.#...#.....#...#...#...#.#.#.#.....#.#.......#...#...#...#.#...#
#.#######.###.#.#.#####.#####.###.#####.#.#.#.#.###.#.#.#######.#####.#.###.#.###
#.#.#.....#...#.#.....#.......#...#.....#.#.#.#.#.#...#.#...#.......#.#.#.......#
#.#.#.#####.###.#.###.#########.###.#.###.#.###.#.#####.#.#.#.#####.#.#.#######.#
#.#.#...#...#.#.#...#.#...#...#.#.#.#...#.#...#.#...#...#.#...#...#...#.#.....#.#
#.#.###.#.###.#.###.#.###.#.#.#.#.#.###.#####.#.#.#.#.###.#####.#.#####.#.###.#.#
#.#.....#.#...#...#.#...#...#.#.#...#.#.#.....#.#.#.#.......#...#.#...#....s#.#v#
#.#.#####.#.#.###.###.#.#.###.#.###.#.#.#.#####.###.#####.###.###.#.#.#######.#.#
#.#...#...#.#...#...#.#.#...#.#...#..y#.#.#.........#...#.#...#.....#.........#.#
#.###.#.#######.###.###.#####.###.#####.#.#.#####.###.#.###.#########.###########
#.#...#.........#.#...#.....#...#.#.....#...#...#.#...#...#.#.......#.#.........#
#.#.###########.#.#########.#.###.#.#########.#.#.#.#####.#.#######R###.#######.#
#.#.#.....Q...#...#.........#...#.#.#...#...#.#.#.#.#...#.....#...#.....#...#.C.#
#.###.#.#########.#.###.#######.#.#.#.#.#.#.#.#.#.#.###.#####.#.#.#########.#.###
#...#.#...#...G.#.#...#.#.#.....#.#...#.#.#.#.#.#.#...#...#...#.#.....#.....#.#.#
#.#.#.###.#.###.#.#####.#.#.#.###.#####.#.#.#.#.#.###.#.#.#.#####.###.#.#####.#.#
#.#.#...#.#.#...#.#.....#.#.#.#...#...I.#.#...#.#...#.#.#.#.#.....#.#...#...#...#
#.#S###.#.#.#.#.#.#.#####.#.#.#.###.###.#.#####.#####.#.#.#.###.###.###.#.#.###.#
#.#.....#...#.#.#...#.......#...#...#.#.#.....#.......#.#.#...#.#.#...#.#.#.....#
#.###########.#######.###########.###.#.#.###.#########.#.###.#.#.#.#.#.#.#######
#e#.......#...#.....#.#.......#...#.#...#.#...#...#.#...#.......#...#...#.#.....#
#.#.#######.#.#.#.###.#.###.###.#.#.#.###N#.###.#.#.#.#########.#####.###.#.###.#
#.#.#.......#.#.#.....#...#.#...#.#.....#.#.#...#.#.#.#..p..#...#...#...#h..#.#.#
#.#.#.#########W#########.#.#.###.#####.###.#.###.#.#.#.###.#####.#B#########.#.#
#...#d....#...#.....#...#.#.....#.....#.#...#.#.#.#.#.#...#.#.....#.#.......#...#
###.#####.#.#.#####.#.#.###.#######.#.#.#.###.#.#.#.#.###.#.#.#####.#.#####.#.###
#...#...#...#.....#...#.V.#.#.....#.#.#.#.#...#z#.#...#...#.#...#.#...#.#.L.#.#.#
#.#####.#######.#########.###.###.###.#.#.#.###J#.#####.###.###.#.#####.#.###.#.#
#.............#...............#.....A.#.#.......#........o#.............#....u..#
#################################################################################
""".trimIndent()
data class Point(val x: Int, val y: Int, val z: Int = 0) {
operator fun minus(other: Point) = Point(x - other.x, y - other.y)
operator fun plus(other: Point) = Point(x + other.x, y + other.y)
init {
check(z >= 0)
}
}
fun Point.left() = copy(x = x - 1)
fun Point.right() = copy(x = x + 1)
fun Point.up() = copy(y = y + 1)
fun Point.down() = copy(y = y - 1)
fun parseMap(mapString: String): Map<Point, Char> {
return mapString.lines()
.mapIndexed { y, line ->
line.mapIndexed { x, c ->
Point(x, y) to c
}
}.flatten()
.toMap()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment