vbe_elvis

2021 Day 12

Dec 12th, 2021 (edited)
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 1.87 KB | None | 0 0
  1.     @Test fun `Part 1`() {
  2.         println("Part 1 ${countAllPaths(puzzleCave)}")
  3.     }
  4.  
  5.     @Test fun `Part 2`() {
  6.         println("Part 2 ${countAllPaths(puzzleCave, part2 = true)}")
  7.     }
  8.  
  9.     private fun countAllPaths(tunnels: List<Tunnel>, part2: Boolean = false): Int {
  10.         var paths = listOf(CavePath())
  11.         var count = 0
  12.         while (paths.isNotEmpty()) {
  13.             count += paths.count { it.isAtEnd }
  14.             paths = paths.filter{!it.isAtEnd}.fold( mutableListOf() ) { nextPaths, path ->
  15.                 tunnels.cavesConnectedTo(path.currentLocation)
  16.                     .filter { cave -> cave != "start" && (cave.isBig
  17.                             || (part2 && !path.visitedSmallCaveTwice)
  18.                             || !path.alreadyVisited(cave)) }
  19.                     .forEach { cave -> nextPaths.add(path + cave) }
  20.                 nextPaths
  21.             }
  22.         }
  23.         return count
  24.     }
  25.  
  26.     private fun List<Tunnel>.cavesConnectedTo(cave: String) =
  27.         this.map { it.connectsTo(cave) }.filter { it != "" }
  28.  
  29.     private val String.isBig: Boolean get() = this[0].isUpperCase()
  30.    
  31. class Tunnel(it: String) {
  32.     private val cave0 = it.split("-")[0]
  33.     private val cave1 = it.split("-")[1]
  34.  
  35.     fun connectsTo(cave:String): String = when (cave) {
  36.         cave0 -> cave1
  37.         cave1 -> cave0
  38.         else -> ""
  39.     }
  40. }
  41.  
  42. class CavePath private constructor(val path: List<String>, val visitedSmallCaveTwice:Boolean) {
  43.     constructor(): this (listOf("start"), false)
  44.     val currentLocation = path.last()
  45.     val isAtEnd = currentLocation == "end"
  46.  
  47.     fun alreadyVisited(cave: String) = path.contains(cave)
  48.     operator fun plus(cave: String) =
  49.         CavePath(path + cave, visitedSmallCaveTwice || cave.isSmall && path.contains(cave))
  50.  
  51.     private val String.isSmall: Boolean get() = this[0].isLowerCase() && this != "start"
  52. }
Add Comment
Please, Sign In to add comment