package day12

import java.io.File

data class Cave(
    val name: String
) {
    fun isEnd() = name == "end"
    fun isStart() = name == "start"

    fun isLarge(): Boolean = name[0].isUpperCase()

    fun isSmall() = !isStart() && !isEnd() && name[0].isLowerCase()
}

fun readCavesFromFile(fileName: String): Map<Cave, MutableList<Cave>> {
    return readCavesFromString(File(fileName)
        .readText())
}

fun readCavesFromString(input: String): Map<Cave, MutableList<Cave>> {
    val caveMap = mutableMapOf<Cave, MutableList<Cave>>()

    input.lines()
        .map { line ->
            val (a, b) = line.split("-")
            Pair(a, b)
        }
        .forEach { (a, b) ->
            val caveA = Cave(a)
            val caveB = Cave(b)

            val connectionsA = caveMap.getOrDefault(caveA, mutableListOf())
            connectionsA.add(caveB)
            caveMap[caveA] = connectionsA

            val connectionB = caveMap.getOrDefault(caveB, mutableListOf())
            connectionB.add(caveA)
            caveMap[caveB] = connectionB
        }

    return caveMap
}

fun List<Cave>.visitedOnlyOnce(cave: Cave): Boolean {
    return count { current -> current == cave } == 1
}

fun Map<Cave, MutableList<Cave>>.continuePath(
    cave: Cave,
    path: List<Cave>,
    visited: List<Cave>,
    smallCaveToVisitAgain: Cave? = null
): List<List<Cave>> {
    val newPath = path + cave

    if (cave.isEnd()) {
        return listOf(newPath)
    }

    val connections = (get(cave) ?: throw IllegalStateException("No connection from $cave"))
        .filter { current ->
            val onlyVisitedOnce = visited.visitedOnlyOnce(current)
            val isSpecialSmallCave = current == smallCaveToVisitAgain
            current.isLarge() || current !in visited || (isSpecialSmallCave && onlyVisitedOnce)
        }

    if (connections.isEmpty()) {
        return emptyList()
    }

    val paths = mutableListOf<List<Cave>>()

    for (current in connections) {
        val newPaths = continuePath(
            current,
            newPath,
            visited + cave,
            smallCaveToVisitAgain
        )
        paths.addAll(newPaths)
    }

    return paths
}

fun Map<Cave, MutableList<Cave>>.findPaths(): List<List<Cave>> {
    return continuePath(
        Cave("start"),
        listOf(),
        listOf()
    )
}

fun Map<Cave, MutableList<Cave>>.findPathsSpecial(): List<List<Cave>> {
    val paths = mutableListOf<List<Cave>>()

    keys.filter { cave -> cave.isSmall() }
        .forEach { cave ->
            val currentPaths = continuePath(
                Cave("start"),
                listOf(),
                listOf(),
                cave
            )
            paths.addAll(currentPaths)
        }

    return paths.distinct()
}

fun part1() {
    val caveMap = readCavesFromFile("day12.txt")
    val paths = caveMap.findPaths()
    println("Paths = ${paths.size}")
}

fun part2() {
    val caveMap = readCavesFromFile("day12.txt")
    val paths = caveMap.findPathsSpecial()
    println("Paths = ${paths.size}")
}

fun main() {
    part2()
}

Compiled from "Day12.kt"
public final class day12.Day12Kt {
  public static final java.util.Map<day12.Cave, java.util.List<day12.Cave>> readCavesFromFile(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String fileName
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #18                 // class java/io/File
       9: dup
      10: aload_0
      11: invokespecial #22                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      14: aconst_null
      15: iconst_1
      16: aconst_null
      17: invokestatic  #28                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
      20: invokestatic  #31                 // Method readCavesFromString:(Ljava/lang/String;)Ljava/util/Map;
      23: areturn

  public static final java.util.Map<day12.Cave, java.util.List<day12.Cave>> readCavesFromString(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #34                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #36                 // class java/util/LinkedHashMap
       9: dup
      10: invokespecial #39                 // Method java/util/LinkedHashMap."<init>":()V
      13: checkcast     #41                 // class java/util/Map
      16: astore_1
      17: aload_0
      18: checkcast     #43                 // class java/lang/CharSequence
      21: invokestatic  #49                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
      24: checkcast     #51                 // class java/lang/Iterable
      27: astore_2
      28: nop
      29: iconst_0
      30: istore_3
      31: aload_2
      32: astore        4
      34: new           #53                 // class java/util/ArrayList
      37: dup
      38: aload_2
      39: bipush        10
      41: invokestatic  #59                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      44: invokespecial #62                 // Method java/util/ArrayList."<init>":(I)V
      47: checkcast     #64                 // class java/util/Collection
      50: astore        5
      52: iconst_0
      53: istore        6
      55: aload         4
      57: invokeinterface #68,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      62: astore        7
      64: aload         7
      66: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      71: ifeq          175
      74: aload         7
      76: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      81: astore        8
      83: aload         5
      85: aload         8
      87: checkcast     #80                 // class java/lang/String
      90: astore        9
      92: astore        14
      94: iconst_0
      95: istore        10
      97: aload         9
      99: checkcast     #43                 // class java/lang/CharSequence
     102: iconst_1
     103: anewarray     #80                 // class java/lang/String
     106: astore        11
     108: aload         11
     110: iconst_0
     111: ldc           #82                 // String -
     113: aastore
     114: aload         11
     116: iconst_0
     117: iconst_0
     118: bipush        6
     120: aconst_null
     121: invokestatic  #86                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     124: astore        12
     126: aload         12
     128: iconst_0
     129: invokeinterface #92,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     134: checkcast     #80                 // class java/lang/String
     137: astore        11
     139: aload         12
     141: iconst_1
     142: invokeinterface #92,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     147: checkcast     #80                 // class java/lang/String
     150: astore        13
     152: new           #94                 // class kotlin/Pair
     155: dup
     156: aload         11
     158: aload         13
     160: invokespecial #97                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     163: aload         14
     165: swap
     166: invokeinterface #101,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     171: pop
     172: goto          64
     175: aload         5
     177: checkcast     #88                 // class java/util/List
     180: nop
     181: checkcast     #51                 // class java/lang/Iterable
     184: astore_2
     185: nop
     186: iconst_0
     187: istore_3
     188: aload_2
     189: invokeinterface #68,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     194: astore        4
     196: aload         4
     198: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     203: ifeq          360
     206: aload         4
     208: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     213: astore        5
     215: aload         5
     217: checkcast     #94                 // class kotlin/Pair
     220: astore        6
     222: iconst_0
     223: istore        7
     225: aload         6
     227: invokevirtual #104                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     230: checkcast     #80                 // class java/lang/String
     233: astore        8
     235: aload         6
     237: invokevirtual #107                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     240: checkcast     #80                 // class java/lang/String
     243: astore        9
     245: new           #109                // class day12/Cave
     248: dup
     249: aload         8
     251: invokespecial #110                // Method day12/Cave."<init>":(Ljava/lang/String;)V
     254: astore        10
     256: new           #109                // class day12/Cave
     259: dup
     260: aload         9
     262: invokespecial #110                // Method day12/Cave."<init>":(Ljava/lang/String;)V
     265: astore        11
     267: aload_1
     268: aload         10
     270: new           #53                 // class java/util/ArrayList
     273: dup
     274: invokespecial #111                // Method java/util/ArrayList."<init>":()V
     277: checkcast     #88                 // class java/util/List
     280: invokeinterface #115,  3          // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     285: checkcast     #88                 // class java/util/List
     288: astore        12
     290: aload         12
     292: aload         11
     294: invokeinterface #116,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     299: pop
     300: aload_1
     301: aload         10
     303: aload         12
     305: invokeinterface #119,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     310: pop
     311: aload_1
     312: aload         11
     314: new           #53                 // class java/util/ArrayList
     317: dup
     318: invokespecial #111                // Method java/util/ArrayList."<init>":()V
     321: checkcast     #88                 // class java/util/List
     324: invokeinterface #115,  3          // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     329: checkcast     #88                 // class java/util/List
     332: astore        13
     334: aload         13
     336: aload         10
     338: invokeinterface #116,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     343: pop
     344: aload_1
     345: aload         11
     347: aload         13
     349: invokeinterface #119,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     354: pop
     355: nop
     356: nop
     357: goto          196
     360: nop
     361: aload_1
     362: areturn

  public static final boolean visitedOnlyOnce(java.util.List<day12.Cave>, day12.Cave);
    Code:
       0: aload_0
       1: ldc           #150                // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #152                // String cave
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #51                 // class java/lang/Iterable
      16: astore_2
      17: iconst_0
      18: istore_3
      19: aload_2
      20: instanceof    #64                 // class java/util/Collection
      23: ifeq          42
      26: aload_2
      27: checkcast     #64                 // class java/util/Collection
      30: invokeinterface #155,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
      35: ifeq          42
      38: iconst_0
      39: goto          107
      42: iconst_0
      43: istore        4
      45: aload_2
      46: invokeinterface #68,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      51: astore        5
      53: aload         5
      55: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      60: ifeq          105
      63: aload         5
      65: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      70: astore        6
      72: aload         6
      74: checkcast     #109                // class day12/Cave
      77: astore        7
      79: iconst_0
      80: istore        8
      82: aload         7
      84: aload_1
      85: invokestatic  #159                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      88: ifeq          53
      91: iinc          4, 1
      94: iload         4
      96: ifge          53
      99: invokestatic  #162                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     102: goto          53
     105: iload         4
     107: iconst_1
     108: if_icmpne     115
     111: iconst_1
     112: goto          116
     115: iconst_0
     116: ireturn

  public static final java.util.List<java.util.List<day12.Cave>> continuePath(java.util.Map<day12.Cave, ? extends java.util.List<day12.Cave>>, day12.Cave, java.util.List<day12.Cave>, java.util.List<day12.Cave>, day12.Cave);
    Code:
       0: aload_0
       1: ldc           #150                // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #152                // String cave
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: ldc           #174                // String path
      15: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_3
      19: ldc           #176                // String visited
      21: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      24: aload_2
      25: checkcast     #64                 // class java/util/Collection
      28: aload_1
      29: invokestatic  #180                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Object;)Ljava/util/List;
      32: astore        5
      34: aload_1
      35: invokevirtual #183                // Method day12/Cave.isEnd:()Z
      38: ifeq          47
      41: aload         5
      43: invokestatic  #187                // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      46: areturn
      47: aload_0
      48: aload_1
      49: invokeinterface #190,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      54: checkcast     #88                 // class java/util/List
      57: dup
      58: ifnonnull     89
      61: pop
      62: new           #192                // class java/lang/IllegalStateException
      65: dup
      66: new           #194                // class java/lang/StringBuilder
      69: dup
      70: invokespecial #195                // Method java/lang/StringBuilder."<init>":()V
      73: ldc           #197                // String No connection from
      75: invokevirtual #201                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      78: aload_1
      79: invokevirtual #204                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      82: invokevirtual #208                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      85: invokespecial #209                // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      88: athrow
      89: checkcast     #51                 // class java/lang/Iterable
      92: astore        7
      94: nop
      95: iconst_0
      96: istore        8
      98: aload         7
     100: astore        9
     102: new           #53                 // class java/util/ArrayList
     105: dup
     106: invokespecial #111                // Method java/util/ArrayList."<init>":()V
     109: checkcast     #64                 // class java/util/Collection
     112: astore        10
     114: iconst_0
     115: istore        11
     117: aload         9
     119: invokeinterface #68,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     124: astore        12
     126: aload         12
     128: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     133: ifeq          222
     136: aload         12
     138: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     143: astore        13
     145: aload         13
     147: checkcast     #109                // class day12/Cave
     150: astore        14
     152: iconst_0
     153: istore        15
     155: aload_3
     156: aload         14
     158: invokestatic  #211                // Method visitedOnlyOnce:(Ljava/util/List;Lday12/Cave;)Z
     161: istore        16
     163: aload         14
     165: aload         4
     167: invokestatic  #159                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     170: istore        17
     172: aload         14
     174: invokevirtual #214                // Method day12/Cave.isLarge:()Z
     177: ifne          201
     180: aload_3
     181: aload         14
     183: invokeinterface #217,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
     188: ifeq          201
     191: iload         17
     193: ifeq          205
     196: iload         16
     198: ifeq          205
     201: iconst_1
     202: goto          206
     205: iconst_0
     206: ifeq          126
     209: aload         10
     211: aload         13
     213: invokeinterface #101,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     218: pop
     219: goto          126
     222: aload         10
     224: checkcast     #88                 // class java/util/List
     227: nop
     228: astore        6
     230: aload         6
     232: invokeinterface #218,  1          // InterfaceMethod java/util/List.isEmpty:()Z
     237: ifeq          244
     240: invokestatic  #222                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     243: areturn
     244: new           #53                 // class java/util/ArrayList
     247: dup
     248: invokespecial #111                // Method java/util/ArrayList."<init>":()V
     251: checkcast     #88                 // class java/util/List
     254: astore        7
     256: aload         6
     258: invokeinterface #223,  1          // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     263: astore        8
     265: aload         8
     267: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     272: ifeq          323
     275: aload         8
     277: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     282: checkcast     #109                // class day12/Cave
     285: astore        9
     287: aload_0
     288: aload         9
     290: aload         5
     292: aload_3
     293: checkcast     #64                 // class java/util/Collection
     296: aload_1
     297: invokestatic  #180                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Object;)Ljava/util/List;
     300: aload         4
     302: invokestatic  #225                // Method continuePath:(Ljava/util/Map;Lday12/Cave;Ljava/util/List;Ljava/util/List;Lday12/Cave;)Ljava/util/List;
     305: astore        10
     307: aload         7
     309: aload         10
     311: checkcast     #64                 // class java/util/Collection
     314: invokeinterface #229,  2          // InterfaceMethod java/util/List.addAll:(Ljava/util/Collection;)Z
     319: pop
     320: goto          265
     323: aload         7
     325: areturn

  public static java.util.List continuePath$default(java.util.Map, day12.Cave, java.util.List, java.util.List, day12.Cave, int, java.lang.Object);
    Code:
       0: iload         5
       2: bipush        8
       4: iand
       5: ifeq          11
       8: aconst_null
       9: astore        4
      11: aload_0
      12: aload_1
      13: aload_2
      14: aload_3
      15: aload         4
      17: invokestatic  #225                // Method continuePath:(Ljava/util/Map;Lday12/Cave;Ljava/util/List;Ljava/util/List;Lday12/Cave;)Ljava/util/List;
      20: areturn

  public static final java.util.List<java.util.List<day12.Cave>> findPaths(java.util.Map<day12.Cave, ? extends java.util.List<day12.Cave>>);
    Code:
       0: aload_0
       1: ldc           #150                // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: new           #109                // class day12/Cave
      10: dup
      11: ldc           #251                // String start
      13: invokespecial #110                // Method day12/Cave."<init>":(Ljava/lang/String;)V
      16: invokestatic  #222                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      19: invokestatic  #222                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      22: aconst_null
      23: bipush        8
      25: aconst_null
      26: invokestatic  #253                // Method continuePath$default:(Ljava/util/Map;Lday12/Cave;Ljava/util/List;Ljava/util/List;Lday12/Cave;ILjava/lang/Object;)Ljava/util/List;
      29: areturn

  public static final java.util.List<java.util.List<day12.Cave>> findPathsSpecial(java.util.Map<day12.Cave, ? extends java.util.List<day12.Cave>>);
    Code:
       0: aload_0
       1: ldc           #150                // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #53                 // class java/util/ArrayList
       9: dup
      10: invokespecial #111                // Method java/util/ArrayList."<init>":()V
      13: checkcast     #88                 // class java/util/List
      16: astore_1
      17: aload_0
      18: invokeinterface #259,  1          // InterfaceMethod java/util/Map.keySet:()Ljava/util/Set;
      23: checkcast     #51                 // class java/lang/Iterable
      26: astore_2
      27: iconst_0
      28: istore_3
      29: aload_2
      30: astore        4
      32: new           #53                 // class java/util/ArrayList
      35: dup
      36: invokespecial #111                // Method java/util/ArrayList."<init>":()V
      39: checkcast     #64                 // class java/util/Collection
      42: astore        5
      44: iconst_0
      45: istore        6
      47: aload         4
      49: invokeinterface #68,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      54: astore        7
      56: aload         7
      58: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      63: ifeq          106
      66: aload         7
      68: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      73: astore        8
      75: aload         8
      77: checkcast     #109                // class day12/Cave
      80: astore        9
      82: iconst_0
      83: istore        10
      85: aload         9
      87: invokevirtual #262                // Method day12/Cave.isSmall:()Z
      90: ifeq          56
      93: aload         5
      95: aload         8
      97: invokeinterface #101,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     102: pop
     103: goto          56
     106: aload         5
     108: checkcast     #88                 // class java/util/List
     111: nop
     112: checkcast     #51                 // class java/lang/Iterable
     115: astore_2
     116: nop
     117: iconst_0
     118: istore_3
     119: aload_2
     120: invokeinterface #68,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     125: astore        4
     127: aload         4
     129: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     134: ifeq          196
     137: aload         4
     139: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     144: astore        5
     146: aload         5
     148: checkcast     #109                // class day12/Cave
     151: astore        6
     153: iconst_0
     154: istore        7
     156: aload_0
     157: new           #109                // class day12/Cave
     160: dup
     161: ldc           #251                // String start
     163: invokespecial #110                // Method day12/Cave."<init>":(Ljava/lang/String;)V
     166: invokestatic  #222                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     169: invokestatic  #222                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     172: aload         6
     174: invokestatic  #225                // Method continuePath:(Ljava/util/Map;Lday12/Cave;Ljava/util/List;Ljava/util/List;Lday12/Cave;)Ljava/util/List;
     177: astore        8
     179: aload_1
     180: aload         8
     182: checkcast     #64                 // class java/util/Collection
     185: invokeinterface #229,  2          // InterfaceMethod java/util/List.addAll:(Ljava/util/Collection;)Z
     190: pop
     191: nop
     192: nop
     193: goto          127
     196: nop
     197: aload_1
     198: checkcast     #51                 // class java/lang/Iterable
     201: invokestatic  #266                // Method kotlin/collections/CollectionsKt.distinct:(Ljava/lang/Iterable;)Ljava/util/List;
     204: areturn

  public static final void part1();
    Code:
       0: ldc_w         #273                // String day12.txt
       3: invokestatic  #275                // Method readCavesFromFile:(Ljava/lang/String;)Ljava/util/Map;
       6: astore_0
       7: aload_0
       8: invokestatic  #277                // Method findPaths:(Ljava/util/Map;)Ljava/util/List;
      11: astore_1
      12: new           #194                // class java/lang/StringBuilder
      15: dup
      16: invokespecial #195                // Method java/lang/StringBuilder."<init>":()V
      19: ldc_w         #279                // String Paths =
      22: invokevirtual #201                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      25: aload_1
      26: invokeinterface #283,  1          // InterfaceMethod java/util/List.size:()I
      31: invokevirtual #286                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      34: invokevirtual #208                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      37: getstatic     #292                // Field java/lang/System.out:Ljava/io/PrintStream;
      40: swap
      41: invokevirtual #298                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      44: return

  public static final void part2();
    Code:
       0: ldc_w         #273                // String day12.txt
       3: invokestatic  #275                // Method readCavesFromFile:(Ljava/lang/String;)Ljava/util/Map;
       6: astore_0
       7: aload_0
       8: invokestatic  #301                // Method findPathsSpecial:(Ljava/util/Map;)Ljava/util/List;
      11: astore_1
      12: new           #194                // class java/lang/StringBuilder
      15: dup
      16: invokespecial #195                // Method java/lang/StringBuilder."<init>":()V
      19: ldc_w         #279                // String Paths =
      22: invokevirtual #201                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      25: aload_1
      26: invokeinterface #283,  1          // InterfaceMethod java/util/List.size:()I
      31: invokevirtual #286                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      34: invokevirtual #208                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      37: getstatic     #292                // Field java/lang/System.out:Ljava/io/PrintStream;
      40: swap
      41: invokevirtual #298                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      44: return

  public static final void main();
    Code:
       0: invokestatic  #304                // Method part2:()V
       3: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #307                // Method main:()V
       3: return
}