Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @Test fun `Part 1`() {
- println("Part 1 ${countAllPaths(puzzleCave)}")
- }
- @Test fun `Part 2`() {
- println("Part 2 ${countAllPaths(puzzleCave, part2 = true)}")
- }
- private fun countAllPaths(tunnels: List<Tunnel>, part2: Boolean = false): Int {
- var paths = listOf(CavePath())
- var count = 0
- while (paths.isNotEmpty()) {
- count += paths.count { it.isAtEnd }
- paths = paths.filter{!it.isAtEnd}.fold( mutableListOf() ) { nextPaths, path ->
- tunnels.cavesConnectedTo(path.currentLocation)
- .filter { cave -> cave != "start" && (cave.isBig
- || (part2 && !path.visitedSmallCaveTwice)
- || !path.alreadyVisited(cave)) }
- .forEach { cave -> nextPaths.add(path + cave) }
- nextPaths
- }
- }
- return count
- }
- private fun List<Tunnel>.cavesConnectedTo(cave: String) =
- this.map { it.connectsTo(cave) }.filter { it != "" }
- private val String.isBig: Boolean get() = this[0].isUpperCase()
- class Tunnel(it: String) {
- private val cave0 = it.split("-")[0]
- private val cave1 = it.split("-")[1]
- fun connectsTo(cave:String): String = when (cave) {
- cave0 -> cave1
- cave1 -> cave0
- else -> ""
- }
- }
- class CavePath private constructor(val path: List<String>, val visitedSmallCaveTwice:Boolean) {
- constructor(): this (listOf("start"), false)
- val currentLocation = path.last()
- val isAtEnd = currentLocation == "end"
- fun alreadyVisited(cave: String) = path.contains(cave)
- operator fun plus(cave: String) =
- CavePath(path + cave, visitedSmallCaveTwice || cave.isSmall && path.contains(cave))
- private val String.isSmall: Boolean get() = this[0].isLowerCase() && this != "start"
- }
Add Comment
Please, Sign In to add comment