Created
January 9, 2020 03:28
-
-
Save Miha-x64/67f95d6401bcdcae611f997a86452edd to your computer and use it in GitHub Desktop.
Copy of https://github.com/yuriykulikov/kotlin-playground/blob/master/advent-of-code-2019/src/test/java/Day18ManyWorldsInterpretation.kt rewritten on top of Java Stream API instead of RxJava.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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