package com.seanshubin.code.structure.tree

sealed interface Tree<KeyType, ValueType> {
    fun setValue(path: List<KeyType>, value: ValueType): Tree<KeyType, ValueType>
    fun getValue(path: List<KeyType>): ValueType?
    fun toLines(
        keyOrder: Comparator<KeyType>,
        keyToString: (KeyType) -> String,
        valueToString: (ValueType) -> String
    ): List<String>

    fun pathValues(path: List<KeyType>): List<Pair<List<KeyType>, ValueType>>

    data class Branch<KeyType, ValueType>(val parts: Map<KeyType, Tree<KeyType, ValueType>>) :
        Tree<KeyType, ValueType> {
        override fun setValue(path: List<KeyType>, value: ValueType): Tree<KeyType, ValueType> {
            if (path.isEmpty()) return Leaf(value)
            val key = path[0]
            val remainingPath = path.drop(1)
            val innerValue = when (val existingInnerValue = parts[key]) {
                is Branch -> existingInnerValue
                else -> empty()
            }
            val newInnerValue = innerValue.setValue(remainingPath, value)
            val newValue = Branch(parts + (key to newInnerValue))
            return newValue
        }

        override fun getValue(path: List<KeyType>): ValueType? {
            if (path.isEmpty()) return null
            val key = path[0]
            val remainingPath = path.drop(1)
            val innerValue = when (val existingInnerValue = parts[key]) {
                is Branch -> existingInnerValue
                is Leaf -> return existingInnerValue.value
                null -> return null
            }
            val finalValue = innerValue.getValue(remainingPath)
            return finalValue
        }

        override fun toLines(
            keyOrder: Comparator<KeyType>,
            keyToString: (KeyType) -> String,
            valueToString: (ValueType) -> String
        ): List<String> {
            val keys = parts.keys.toList().sortedWith(keyOrder)
            val lines = keys.flatMap { key ->
                val value = parts.getValue(key)
                val thisLine = keyToString(key)
                val subLines = value.toLines(keyOrder, keyToString, valueToString).map { "  $it" }
                listOf(thisLine) + subLines
            }
            return lines
        }

        override fun pathValues(path: List<KeyType>): List<Pair<List<KeyType>, ValueType>> {
            return parts.flatMap { (key, value) ->
                val newPath = path + key
                value.pathValues(newPath)
            }
        }
    }

    data class Leaf<KeyType, ValueType>(val value: ValueType) : Tree<KeyType, ValueType> {
        override fun setValue(path: List<KeyType>, value: ValueType): Tree<KeyType, ValueType> {
            return empty<KeyType, ValueType>().setValue(path, value)
        }

        override fun getValue(path: List<KeyType>): ValueType? {
            return if (path.isEmpty()) this.value
            else null
        }

        override fun toLines(
            keyOrder: Comparator<KeyType>,
            keyToString: (KeyType) -> String,
            valueToString: (ValueType) -> String
        ): List<String> = listOf(valueToString(value))

        override fun pathValues(path: List<KeyType>): List<Pair<List<KeyType>, ValueType>> {
            return listOf(path to value)
        }

    }

    companion object {
        fun <KeyType, ValueType> empty(): Branch<KeyType, ValueType> = Branch(emptyMap())
    }
}

Compiled from "Tree.kt"
public final class com.seanshubin.code.structure.tree.Tree$Branch<KeyType, ValueType> implements com.seanshubin.code.structure.tree.Tree<KeyType, ValueType> {
  private final java.util.Map<KeyType, com.seanshubin.code.structure.tree.Tree<KeyType, ValueType>> parts;

  public com.seanshubin.code.structure.tree.Tree$Branch(java.util.Map<KeyType, ? extends com.seanshubin.code.structure.tree.Tree<KeyType, ValueType>>);
    Code:
       0: aload_1
       1: ldc           #13                 // String parts
       3: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #22                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: aload_1
      12: putfield      #25                 // Field parts:Ljava/util/Map;
      15: return

  public final java.util.Map<KeyType, com.seanshubin.code.structure.tree.Tree<KeyType, ValueType>> getParts();
    Code:
       0: aload_0
       1: getfield      #25                 // Field parts:Ljava/util/Map;
       4: areturn

  public com.seanshubin.code.structure.tree.Tree<KeyType, ValueType> setValue(java.util.List<? extends KeyType>, ValueType);
    Code:
       0: aload_1
       1: ldc           #35                 // String path
       3: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokeinterface #41,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      12: ifeq          27
      15: new           #43                 // class com/seanshubin/code/structure/tree/Tree$Leaf
      18: dup
      19: aload_2
      20: invokespecial #46                 // Method com/seanshubin/code/structure/tree/Tree$Leaf."<init>":(Ljava/lang/Object;)V
      23: checkcast     #7                  // class com/seanshubin/code/structure/tree/Tree
      26: areturn
      27: aload_1
      28: iconst_0
      29: invokeinterface #50,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      34: astore_3
      35: aload_1
      36: checkcast     #52                 // class java/lang/Iterable
      39: iconst_1
      40: invokestatic  #58                 // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      43: astore        4
      45: aload_0
      46: getfield      #25                 // Field parts:Ljava/util/Map;
      49: aload_3
      50: invokeinterface #63,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      55: checkcast     #7                  // class com/seanshubin/code/structure/tree/Tree
      58: astore        6
      60: aload         6
      62: instanceof    #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
      65: ifeq          76
      68: aload         6
      70: checkcast     #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
      73: goto          82
      76: getstatic     #67                 // Field com/seanshubin/code/structure/tree/Tree.Companion:Lcom/seanshubin/code/structure/tree/Tree$Companion;
      79: invokevirtual #73                 // Method com/seanshubin/code/structure/tree/Tree$Companion.empty:()Lcom/seanshubin/code/structure/tree/Tree$Branch;
      82: astore        5
      84: aload         5
      86: aload         4
      88: aload_2
      89: invokevirtual #75                 // Method setValue:(Ljava/util/List;Ljava/lang/Object;)Lcom/seanshubin/code/structure/tree/Tree;
      92: astore        6
      94: new           #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
      97: dup
      98: aload_0
      99: getfield      #25                 // Field parts:Ljava/util/Map;
     102: aload_3
     103: aload         6
     105: invokestatic  #81                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     108: invokestatic  #87                 // Method kotlin/collections/MapsKt.plus:(Ljava/util/Map;Lkotlin/Pair;)Ljava/util/Map;
     111: invokespecial #89                 // Method "<init>":(Ljava/util/Map;)V
     114: astore        7
     116: aload         7
     118: checkcast     #7                  // class com/seanshubin/code/structure/tree/Tree
     121: areturn

  public ValueType getValue(java.util.List<? extends KeyType>);
    Code:
       0: aload_1
       1: ldc           #35                 // String path
       3: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokeinterface #41,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      12: ifeq          17
      15: aconst_null
      16: areturn
      17: aload_1
      18: iconst_0
      19: invokeinterface #50,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      24: astore_2
      25: aload_1
      26: checkcast     #52                 // class java/lang/Iterable
      29: iconst_1
      30: invokestatic  #58                 // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      33: astore_3
      34: aload_0
      35: getfield      #25                 // Field parts:Ljava/util/Map;
      38: aload_2
      39: invokeinterface #63,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      44: checkcast     #7                  // class com/seanshubin/code/structure/tree/Tree
      47: astore        5
      49: aload         5
      51: instanceof    #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
      54: ifeq          65
      57: aload         5
      59: checkcast     #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
      62: goto          97
      65: aload         5
      67: instanceof    #43                 // class com/seanshubin/code/structure/tree/Tree$Leaf
      70: ifeq          82
      73: aload         5
      75: checkcast     #43                 // class com/seanshubin/code/structure/tree/Tree$Leaf
      78: invokevirtual #106                // Method com/seanshubin/code/structure/tree/Tree$Leaf.getValue:()Ljava/lang/Object;
      81: areturn
      82: aload         5
      84: ifnonnull     89
      87: aconst_null
      88: areturn
      89: new           #108                // class kotlin/NoWhenBranchMatchedException
      92: dup
      93: invokespecial #109                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
      96: athrow
      97: astore        4
      99: aload         4
     101: aload_3
     102: invokevirtual #111                // Method getValue:(Ljava/util/List;)Ljava/lang/Object;
     105: astore        5
     107: aload         5
     109: areturn

  public java.util.List<java.lang.String> toLines(java.util.Comparator<KeyType>, kotlin.jvm.functions.Function1<? super KeyType, java.lang.String>, kotlin.jvm.functions.Function1<? super ValueType, java.lang.String>);
    Code:
       0: aload_1
       1: ldc           #117                // String keyOrder
       3: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #119                // String keyToString
       9: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #121                // String valueToString
      15: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_0
      19: getfield      #25                 // Field parts:Ljava/util/Map;
      22: invokeinterface #125,  1          // InterfaceMethod java/util/Map.keySet:()Ljava/util/Set;
      27: checkcast     #52                 // class java/lang/Iterable
      30: invokestatic  #129                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
      33: checkcast     #52                 // class java/lang/Iterable
      36: aload_1
      37: invokestatic  #133                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      40: astore        4
      42: aload         4
      44: checkcast     #52                 // class java/lang/Iterable
      47: astore        6
      49: iconst_0
      50: istore        7
      52: aload         6
      54: astore        8
      56: new           #135                // class java/util/ArrayList
      59: dup
      60: invokespecial #136                // Method java/util/ArrayList."<init>":()V
      63: checkcast     #138                // class java/util/Collection
      66: astore        9
      68: iconst_0
      69: istore        10
      71: aload         8
      73: invokeinterface #142,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      78: astore        11
      80: aload         11
      82: invokeinterface #147,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      87: ifeq          291
      90: aload         11
      92: invokeinterface #150,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      97: astore        12
      99: aload         12
     101: astore        13
     103: iconst_0
     104: istore        14
     106: aload_0
     107: getfield      #25                 // Field parts:Ljava/util/Map;
     110: aload         13
     112: invokestatic  #153                // Method kotlin/collections/MapsKt.getValue:(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
     115: checkcast     #7                  // class com/seanshubin/code/structure/tree/Tree
     118: astore        15
     120: aload_2
     121: aload         13
     123: invokeinterface #158,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     128: checkcast     #160                // class java/lang/String
     131: astore        16
     133: aload         15
     135: aload_1
     136: aload_2
     137: aload_3
     138: invokeinterface #162,  4          // InterfaceMethod com/seanshubin/code/structure/tree/Tree.toLines:(Ljava/util/Comparator;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
     143: checkcast     #52                 // class java/lang/Iterable
     146: astore        17
     148: iconst_0
     149: istore        18
     151: aload         17
     153: astore        19
     155: new           #135                // class java/util/ArrayList
     158: dup
     159: aload         17
     161: bipush        10
     163: invokestatic  #166                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     166: invokespecial #169                // Method java/util/ArrayList."<init>":(I)V
     169: checkcast     #138                // class java/util/Collection
     172: astore        20
     174: iconst_0
     175: istore        21
     177: aload         19
     179: invokeinterface #142,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     184: astore        22
     186: aload         22
     188: invokeinterface #147,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     193: ifeq          251
     196: aload         22
     198: invokeinterface #150,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     203: astore        23
     205: aload         20
     207: aload         23
     209: checkcast     #160                // class java/lang/String
     212: astore        24
     214: astore        25
     216: iconst_0
     217: istore        26
     219: new           #171                // class java/lang/StringBuilder
     222: dup
     223: invokespecial #172                // Method java/lang/StringBuilder."<init>":()V
     226: ldc           #174                // String
     228: invokevirtual #178                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     231: aload         24
     233: invokevirtual #178                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     236: invokevirtual #182                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     239: aload         25
     241: swap
     242: invokeinterface #186,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     247: pop
     248: goto          186
     251: aload         20
     253: checkcast     #37                 // class java/util/List
     256: nop
     257: astore        27
     259: aload         16
     261: invokestatic  #190                // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
     264: checkcast     #138                // class java/util/Collection
     267: aload         27
     269: checkcast     #52                 // class java/lang/Iterable
     272: invokestatic  #193                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     275: checkcast     #52                 // class java/lang/Iterable
     278: astore        28
     280: aload         9
     282: aload         28
     284: invokestatic  #197                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     287: pop
     288: goto          80
     291: aload         9
     293: checkcast     #37                 // class java/util/List
     296: nop
     297: astore        5
     299: aload         5
     301: areturn

  public java.util.List<kotlin.Pair<java.util.List<KeyType>, ValueType>> pathValues(java.util.List<? extends KeyType>);
    Code:
       0: aload_1
       1: ldc           #35                 // String path
       3: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: getfield      #25                 // Field parts:Ljava/util/Map;
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: astore        4
      16: new           #135                // class java/util/ArrayList
      19: dup
      20: invokespecial #136                // Method java/util/ArrayList."<init>":()V
      23: checkcast     #138                // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #230,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      38: invokeinterface #233,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      43: astore        7
      45: aload         7
      47: invokeinterface #147,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      52: ifeq          131
      55: aload         7
      57: invokeinterface #150,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      62: checkcast     #235                // class java/util/Map$Entry
      65: astore        8
      67: aload         8
      69: astore        9
      71: iconst_0
      72: istore        10
      74: aload         9
      76: invokeinterface #238,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
      81: astore        11
      83: aload         9
      85: invokeinterface #239,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      90: checkcast     #7                  // class com/seanshubin/code/structure/tree/Tree
      93: astore        12
      95: aload_1
      96: checkcast     #138                // class java/util/Collection
      99: aload         11
     101: invokestatic  #242                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Object;)Ljava/util/List;
     104: astore        13
     106: aload         12
     108: aload         13
     110: invokeinterface #244,  2          // InterfaceMethod com/seanshubin/code/structure/tree/Tree.pathValues:(Ljava/util/List;)Ljava/util/List;
     115: checkcast     #52                 // class java/lang/Iterable
     118: astore        9
     120: aload         5
     122: aload         9
     124: invokestatic  #197                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     127: pop
     128: goto          45
     131: aload         5
     133: checkcast     #37                 // class java/util/List
     136: nop
     137: areturn

  public final java.util.Map<KeyType, com.seanshubin.code.structure.tree.Tree<KeyType, ValueType>> component1();
    Code:
       0: aload_0
       1: getfield      #25                 // Field parts:Ljava/util/Map;
       4: areturn

  public final com.seanshubin.code.structure.tree.Tree$Branch<KeyType, ValueType> copy(java.util.Map<KeyType, ? extends com.seanshubin.code.structure.tree.Tree<KeyType, ValueType>>);
    Code:
       0: aload_1
       1: ldc           #13                 // String parts
       3: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
       9: dup
      10: aload_1
      11: invokespecial #89                 // Method "<init>":(Ljava/util/Map;)V
      14: areturn

  public static com.seanshubin.code.structure.tree.Tree$Branch copy$default(com.seanshubin.code.structure.tree.Tree$Branch, java.util.Map, int, java.lang.Object);
    Code:
       0: iload_2
       1: iconst_1
       2: iand
       3: ifeq          11
       6: aload_0
       7: getfield      #25                 // Field parts:Ljava/util/Map;
      10: astore_1
      11: aload_0
      12: aload_1
      13: invokevirtual #255                // Method copy:(Ljava/util/Map;)Lcom/seanshubin/code/structure/tree/Tree$Branch;
      16: areturn

  public java.lang.String toString();
    Code:
       0: new           #171                // class java/lang/StringBuilder
       3: dup
       4: invokespecial #172                // Method java/lang/StringBuilder."<init>":()V
       7: ldc_w         #257                // String Branch(parts=
      10: invokevirtual #178                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      13: aload_0
      14: getfield      #25                 // Field parts:Ljava/util/Map;
      17: invokevirtual #260                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      20: bipush        41
      22: invokevirtual #263                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      25: invokevirtual #182                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      28: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #25                 // Field parts:Ljava/util/Map;
       4: invokevirtual #267                // Method java/lang/Object.hashCode:()I
       7: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class com/seanshubin/code/structure/tree/Tree$Branch
      20: astore_2
      21: aload_0
      22: getfield      #25                 // Field parts:Ljava/util/Map;
      25: aload_2
      26: getfield      #25                 // Field parts:Ljava/util/Map;
      29: invokestatic  #272                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      32: ifne          37
      35: iconst_0
      36: ireturn
      37: iconst_1
      38: ireturn
}

Compiled from "Tree.kt"
public interface com.seanshubin.code.structure.tree.Tree<KeyType, ValueType> {
  public static final com.seanshubin.code.structure.tree.Tree$Companion Companion;

  public abstract com.seanshubin.code.structure.tree.Tree<KeyType, ValueType> setValue(java.util.List<? extends KeyType>, ValueType);

  public abstract ValueType getValue(java.util.List<? extends KeyType>);

  public abstract java.util.List<java.lang.String> toLines(java.util.Comparator<KeyType>, kotlin.jvm.functions.Function1<? super KeyType, java.lang.String>, kotlin.jvm.functions.Function1<? super ValueType, java.lang.String>);

  public abstract java.util.List<kotlin.Pair<java.util.List<KeyType>, ValueType>> pathValues(java.util.List<? extends KeyType>);

  static {};
    Code:
       0: getstatic     #27                 // Field com/seanshubin/code/structure/tree/Tree$Companion.$$INSTANCE:Lcom/seanshubin/code/structure/tree/Tree$Companion;
       3: putstatic     #30                 // Field Companion:Lcom/seanshubin/code/structure/tree/Tree$Companion;
       6: return
}

Compiled from "Tree.kt"
public final class com.seanshubin.code.structure.tree.Tree$Companion {
  static final com.seanshubin.code.structure.tree.Tree$Companion $$INSTANCE;

  private com.seanshubin.code.structure.tree.Tree$Companion();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final <KeyType, ValueType> com.seanshubin.code.structure.tree.Tree$Branch<KeyType, ValueType> empty();
    Code:
       0: new           #16                 // class com/seanshubin/code/structure/tree/Tree$Branch
       3: dup
       4: invokestatic  #22                 // Method kotlin/collections/MapsKt.emptyMap:()Ljava/util/Map;
       7: invokespecial #25                 // Method com/seanshubin/code/structure/tree/Tree$Branch."<init>":(Ljava/util/Map;)V
      10: areturn

  static {};
    Code:
       0: new           #2                  // class com/seanshubin/code/structure/tree/Tree$Companion
       3: dup
       4: invokespecial #27                 // Method "<init>":()V
       7: putstatic     #30                 // Field $$INSTANCE:Lcom/seanshubin/code/structure/tree/Tree$Companion;
      10: return
}

Compiled from "Tree.kt"
public final class com.seanshubin.code.structure.tree.Tree$Leaf<KeyType, ValueType> implements com.seanshubin.code.structure.tree.Tree<KeyType, ValueType> {
  private final ValueType value;

  public com.seanshubin.code.structure.tree.Tree$Leaf(ValueType);
    Code:
       0: aload_0
       1: invokespecial #13                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: aload_1
       6: putfield      #17                 // Field value:Ljava/lang/Object;
       9: return

  public final ValueType getValue();
    Code:
       0: aload_0
       1: getfield      #17                 // Field value:Ljava/lang/Object;
       4: areturn

  public com.seanshubin.code.structure.tree.Tree<KeyType, ValueType> setValue(java.util.List<? extends KeyType>, ValueType);
    Code:
       0: aload_1
       1: ldc           #28                 // String path
       3: invokestatic  #34                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #38                 // Field com/seanshubin/code/structure/tree/Tree.Companion:Lcom/seanshubin/code/structure/tree/Tree$Companion;
       9: invokevirtual #44                 // Method com/seanshubin/code/structure/tree/Tree$Companion.empty:()Lcom/seanshubin/code/structure/tree/Tree$Branch;
      12: aload_1
      13: aload_2
      14: invokevirtual #48                 // Method com/seanshubin/code/structure/tree/Tree$Branch.setValue:(Ljava/util/List;Ljava/lang/Object;)Lcom/seanshubin/code/structure/tree/Tree;
      17: areturn

  public ValueType getValue(java.util.List<? extends KeyType>);
    Code:
       0: aload_1
       1: ldc           #28                 // String path
       3: invokestatic  #34                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokeinterface #58,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      12: ifeq          22
      15: aload_0
      16: getfield      #17                 // Field value:Ljava/lang/Object;
      19: goto          23
      22: aconst_null
      23: areturn

  public java.util.List<java.lang.String> toLines(java.util.Comparator<KeyType>, kotlin.jvm.functions.Function1<? super KeyType, java.lang.String>, kotlin.jvm.functions.Function1<? super ValueType, java.lang.String>);
    Code:
       0: aload_1
       1: ldc           #63                 // String keyOrder
       3: invokestatic  #34                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #65                 // String keyToString
       9: invokestatic  #34                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #67                 // String valueToString
      15: invokestatic  #34                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_3
      19: aload_0
      20: getfield      #17                 // Field value:Ljava/lang/Object;
      23: invokeinterface #73,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
      28: invokestatic  #79                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      31: areturn

  public java.util.List<kotlin.Pair<java.util.List<KeyType>, ValueType>> pathValues(java.util.List<? extends KeyType>);
    Code:
       0: aload_1
       1: ldc           #28                 // String path
       3: invokestatic  #34                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: aload_0
       8: getfield      #17                 // Field value:Ljava/lang/Object;
      11: invokestatic  #90                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      14: invokestatic  #79                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      17: areturn

  public final ValueType component1();
    Code:
       0: aload_0
       1: getfield      #17                 // Field value:Ljava/lang/Object;
       4: areturn

  public final com.seanshubin.code.structure.tree.Tree$Leaf<KeyType, ValueType> copy(ValueType);
    Code:
       0: new           #2                  // class com/seanshubin/code/structure/tree/Tree$Leaf
       3: dup
       4: aload_1
       5: invokespecial #96                 // Method "<init>":(Ljava/lang/Object;)V
       8: areturn

  public static com.seanshubin.code.structure.tree.Tree$Leaf copy$default(com.seanshubin.code.structure.tree.Tree$Leaf, java.lang.Object, int, java.lang.Object);
    Code:
       0: iload_2
       1: iconst_1
       2: iand
       3: ifeq          11
       6: aload_0
       7: getfield      #17                 // Field value:Ljava/lang/Object;
      10: astore_1
      11: aload_0
      12: aload_1
      13: invokevirtual #100                // Method copy:(Ljava/lang/Object;)Lcom/seanshubin/code/structure/tree/Tree$Leaf;
      16: areturn

  public java.lang.String toString();
    Code:
       0: new           #104                // class java/lang/StringBuilder
       3: dup
       4: invokespecial #105                // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #107                // String Leaf(value=
       9: invokevirtual #111                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #17                 // Field value:Ljava/lang/Object;
      16: invokevirtual #114                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      19: bipush        41
      21: invokevirtual #117                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      24: invokevirtual #119                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      27: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #17                 // Field value:Ljava/lang/Object;
       4: ifnonnull     11
       7: iconst_0
       8: goto          18
      11: aload_0
      12: getfield      #17                 // Field value:Ljava/lang/Object;
      15: invokevirtual #123                // Method java/lang/Object.hashCode:()I
      18: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class com/seanshubin/code/structure/tree/Tree$Leaf
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class com/seanshubin/code/structure/tree/Tree$Leaf
      20: astore_2
      21: aload_0
      22: getfield      #17                 // Field value:Ljava/lang/Object;
      25: aload_2
      26: getfield      #17                 // Field value:Ljava/lang/Object;
      29: invokestatic  #129                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      32: ifne          37
      35: iconst_0
      36: ireturn
      37: iconst_1
      38: ireturn
}


package day09

import java.io.File

private const val MAX_HEIGHT = 9

fun main() {
    val lines = File("src/main/kotlin/day09/input.txt").readLines()
    val mapSize = lines.size
    val heightMap: Array<IntArray> = Array(mapSize) { i -> lines[i].map { it.digitToInt() }.toIntArray() }
    var riskLevel = 0
    val basins = mutableListOf<Set<Point>>()
    for (row in heightMap.indices) {
        for (col in heightMap[row].indices) {
            val currHeight = heightMap[row][col]
            val isLowPoint = (
                    (row == 0 || heightMap[row - 1][col] > currHeight) &&
                            (row == mapSize - 1 || row < mapSize - 1 && heightMap[row + 1][col] > currHeight) &&
                            (col == 0 || heightMap[row][col - 1] > currHeight) &&
                            (col == mapSize - 1 || col < mapSize - 1 && heightMap[row][col + 1] > currHeight)
                    )
            if (isLowPoint) {
                riskLevel += currHeight + 1
                val lowPoint = Point(row, col)
                basins += scanBasinAroundPoint(lowPoint, heightMap, mutableSetOf())
            }
        }
    }
    println(riskLevel)
    println(basins.map { it.size }.sortedDescending().take(3).reduce(Int::times))
}

fun scanBasinAroundPoint(point: Point, heightMap: Array<IntArray>, basinPoints: MutableSet<Point>): Set<Point> {
    val heightMapSize = heightMap.size
    if (
        point.row < 0 || point.row >= heightMapSize
        || point.col < 0 || point.col >= heightMapSize
        || heightMap[point.row][point.col] == MAX_HEIGHT
        || point in basinPoints
    ) return emptySet()
    basinPoints.add(point)
    scanBasinAroundPoint(Point(point.row - 1, point.col), heightMap, basinPoints)
    scanBasinAroundPoint(Point(point.row + 1, point.col), heightMap, basinPoints)
    scanBasinAroundPoint(Point(point.row, point.col - 1), heightMap, basinPoints)
    scanBasinAroundPoint(Point(point.row, point.col + 1), heightMap, basinPoints)
    return basinPoints
}

data class Point(val row: Int, val col: Int)

Compiled from "solution.kt"
public final class day09.SolutionKt {
  private static final int MAX_HEIGHT;

  public static final void main();
    Code:
       0: new           #8                  // class java/io/File
       3: dup
       4: ldc           #10                 // String src/main/kotlin/day09/input.txt
       6: invokespecial #14                 // Method java/io/File."<init>":(Ljava/lang/String;)V
       9: aconst_null
      10: iconst_1
      11: aconst_null
      12: invokestatic  #20                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      15: astore_0
      16: aload_0
      17: invokeinterface #26,  1           // InterfaceMethod java/util/List.size:()I
      22: istore_1
      23: iconst_0
      24: istore_3
      25: iload_1
      26: anewarray     #28                 // class "[I"
      29: astore        4
      31: iload_3
      32: iload_1
      33: if_icmpge     176
      36: iload_3
      37: istore        5
      39: aload         4
      41: iload         5
      43: aload_0
      44: iload         5
      46: invokeinterface #32,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      51: checkcast     #34                 // class java/lang/CharSequence
      54: astore        6
      56: istore        16
      58: astore        15
      60: iconst_0
      61: istore        7
      63: aload         6
      65: astore        8
      67: new           #36                 // class java/util/ArrayList
      70: dup
      71: aload         6
      73: invokeinterface #39,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      78: invokespecial #42                 // Method java/util/ArrayList."<init>":(I)V
      81: checkcast     #44                 // class java/util/Collection
      84: astore        9
      86: iconst_0
      87: istore        10
      89: iconst_0
      90: istore        11
      92: iload         11
      94: aload         8
      96: invokeinterface #39,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     101: if_icmpge     149
     104: aload         8
     106: iload         11
     108: invokeinterface #48,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     113: istore        12
     115: aload         9
     117: iload         12
     119: istore        13
     121: astore        17
     123: iconst_0
     124: istore        14
     126: iload         13
     128: invokestatic  #54                 // Method kotlin/text/CharsKt.digitToInt:(C)I
     131: invokestatic  #60                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     134: aload         17
     136: swap
     137: invokeinterface #64,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     142: pop
     143: iinc          11, 1
     146: goto          92
     149: aload         9
     151: checkcast     #22                 // class java/util/List
     154: nop
     155: astore        17
     157: aload         15
     159: iload         16
     161: aload         17
     163: checkcast     #44                 // class java/util/Collection
     166: invokestatic  #70                 // Method kotlin/collections/CollectionsKt.toIntArray:(Ljava/util/Collection;)[I
     169: aastore
     170: iinc          3, 1
     173: goto          31
     176: aload         4
     178: astore_2
     179: iconst_0
     180: istore_3
     181: new           #36                 // class java/util/ArrayList
     184: dup
     185: invokespecial #72                 // Method java/util/ArrayList."<init>":()V
     188: checkcast     #22                 // class java/util/List
     191: astore        4
     193: iconst_0
     194: istore        5
     196: aload_2
     197: checkcast     #74                 // class "[Ljava/lang/Object;"
     200: arraylength
     201: istore        6
     203: iload         5
     205: iload         6
     207: if_icmpge     405
     210: iconst_0
     211: istore        7
     213: aload_2
     214: iload         5
     216: aaload
     217: arraylength
     218: istore        8
     220: iload         7
     222: iload         8
     224: if_icmpge     399
     227: aload_2
     228: iload         5
     230: aaload
     231: iload         7
     233: iaload
     234: istore        9
     236: iload         5
     238: ifeq          255
     241: aload_2
     242: iload         5
     244: iconst_1
     245: isub
     246: aaload
     247: iload         7
     249: iaload
     250: iload         9
     252: if_icmple     338
     255: iload         5
     257: iload_1
     258: iconst_1
     259: isub
     260: if_icmpeq     285
     263: iload         5
     265: iload_1
     266: iconst_1
     267: isub
     268: if_icmpge     338
     271: aload_2
     272: iload         5
     274: iconst_1
     275: iadd
     276: aaload
     277: iload         7
     279: iaload
     280: iload         9
     282: if_icmple     338
     285: iload         7
     287: ifeq          304
     290: aload_2
     291: iload         5
     293: aaload
     294: iload         7
     296: iconst_1
     297: isub
     298: iaload
     299: iload         9
     301: if_icmple     338
     304: iload         7
     306: iload_1
     307: iconst_1
     308: isub
     309: if_icmpeq     334
     312: iload         7
     314: iload_1
     315: iconst_1
     316: isub
     317: if_icmpge     338
     320: aload_2
     321: iload         5
     323: aaload
     324: iload         7
     326: iconst_1
     327: iadd
     328: iaload
     329: iload         9
     331: if_icmple     338
     334: iconst_1
     335: goto          339
     338: iconst_0
     339: istore        10
     341: iload         10
     343: ifeq          393
     346: iload_3
     347: iload         9
     349: iconst_1
     350: iadd
     351: iadd
     352: istore_3
     353: new           #76                 // class day09/Point
     356: dup
     357: iload         5
     359: iload         7
     361: invokespecial #79                 // Method day09/Point."<init>":(II)V
     364: astore        11
     366: aload         4
     368: checkcast     #44                 // class java/util/Collection
     371: aload         11
     373: aload_2
     374: new           #81                 // class java/util/LinkedHashSet
     377: dup
     378: invokespecial #82                 // Method java/util/LinkedHashSet."<init>":()V
     381: checkcast     #84                 // class java/util/Set
     384: invokestatic  #88                 // Method scanBasinAroundPoint:(Lday09/Point;[[ILjava/util/Set;)Ljava/util/Set;
     387: invokeinterface #64,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     392: pop
     393: iinc          7, 1
     396: goto          220
     399: iinc          5, 1
     402: goto          203
     405: getstatic     #94                 // Field java/lang/System.out:Ljava/io/PrintStream;
     408: iload_3
     409: invokevirtual #99                 // Method java/io/PrintStream.println:(I)V
     412: aload         4
     414: checkcast     #101                // class java/lang/Iterable
     417: astore        5
     419: iconst_0
     420: istore        6
     422: aload         5
     424: astore        7
     426: new           #36                 // class java/util/ArrayList
     429: dup
     430: aload         5
     432: bipush        10
     434: invokestatic  #105                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     437: invokespecial #42                 // Method java/util/ArrayList."<init>":(I)V
     440: checkcast     #44                 // class java/util/Collection
     443: astore        8
     445: iconst_0
     446: istore        9
     448: aload         7
     450: invokeinterface #109,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     455: astore        10
     457: aload         10
     459: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     464: ifeq          512
     467: aload         10
     469: invokeinterface #119,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     474: astore        11
     476: aload         8
     478: aload         11
     480: checkcast     #84                 // class java/util/Set
     483: astore        12
     485: astore        15
     487: iconst_0
     488: istore        13
     490: aload         12
     492: invokeinterface #120,  1          // InterfaceMethod java/util/Set.size:()I
     497: invokestatic  #60                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     500: aload         15
     502: swap
     503: invokeinterface #64,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     508: pop
     509: goto          457
     512: aload         8
     514: checkcast     #22                 // class java/util/List
     517: nop
     518: checkcast     #101                // class java/lang/Iterable
     521: invokestatic  #124                // Method kotlin/collections/CollectionsKt.sortedDescending:(Ljava/lang/Iterable;)Ljava/util/List;
     524: checkcast     #101                // class java/lang/Iterable
     527: iconst_3
     528: invokestatic  #128                // Method kotlin/collections/CollectionsKt.take:(Ljava/lang/Iterable;I)Ljava/util/List;
     531: checkcast     #101                // class java/lang/Iterable
     534: astore        5
     536: iconst_0
     537: istore        6
     539: aload         5
     541: invokeinterface #109,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     546: astore        7
     548: aload         7
     550: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     555: ifne          568
     558: new           #130                // class java/lang/UnsupportedOperationException
     561: dup
     562: ldc           #132                // String Empty collection can\'t be reduced.
     564: invokespecial #133                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     567: athrow
     568: aload         7
     570: invokeinterface #119,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     575: astore        8
     577: aload         7
     579: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     584: ifeq          628
     587: aload         8
     589: aload         7
     591: invokeinterface #119,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     596: checkcast     #135                // class java/lang/Number
     599: invokevirtual #138                // Method java/lang/Number.intValue:()I
     602: istore        9
     604: checkcast     #135                // class java/lang/Number
     607: invokevirtual #138                // Method java/lang/Number.intValue:()I
     610: istore        10
     612: iconst_0
     613: istore        11
     615: iload         10
     617: iload         9
     619: imul
     620: invokestatic  #60                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     623: astore        8
     625: goto          577
     628: aload         8
     630: checkcast     #135                // class java/lang/Number
     633: invokevirtual #138                // Method java/lang/Number.intValue:()I
     636: istore        5
     638: getstatic     #94                 // Field java/lang/System.out:Ljava/io/PrintStream;
     641: iload         5
     643: invokevirtual #99                 // Method java/io/PrintStream.println:(I)V
     646: return

  public static final java.util.Set<day09.Point> scanBasinAroundPoint(day09.Point, int[][], java.util.Set<day09.Point>);
    Code:
       0: aload_0
       1: ldc           #181                // String point
       3: invokestatic  #187                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #188                // String heightMap
       9: invokestatic  #187                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: ldc           #190                // String basinPoints
      15: invokestatic  #187                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_1
      19: checkcast     #74                 // class "[Ljava/lang/Object;"
      22: arraylength
      23: istore_3
      24: aload_0
      25: invokevirtual #193                // Method day09/Point.getRow:()I
      28: iflt          80
      31: aload_0
      32: invokevirtual #193                // Method day09/Point.getRow:()I
      35: iload_3
      36: if_icmpge     80
      39: aload_0
      40: invokevirtual #196                // Method day09/Point.getCol:()I
      43: iflt          80
      46: aload_0
      47: invokevirtual #196                // Method day09/Point.getCol:()I
      50: iload_3
      51: if_icmpge     80
      54: aload_1
      55: aload_0
      56: invokevirtual #193                // Method day09/Point.getRow:()I
      59: aaload
      60: aload_0
      61: invokevirtual #196                // Method day09/Point.getCol:()I
      64: iaload
      65: bipush        9
      67: if_icmpeq     80
      70: aload_2
      71: aload_0
      72: invokeinterface #199,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
      77: ifeq          84
      80: invokestatic  #205                // Method kotlin/collections/SetsKt.emptySet:()Ljava/util/Set;
      83: areturn
      84: aload_2
      85: aload_0
      86: invokeinterface #206,  2          // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
      91: pop
      92: new           #76                 // class day09/Point
      95: dup
      96: aload_0
      97: invokevirtual #193                // Method day09/Point.getRow:()I
     100: iconst_1
     101: isub
     102: aload_0
     103: invokevirtual #196                // Method day09/Point.getCol:()I
     106: invokespecial #79                 // Method day09/Point."<init>":(II)V
     109: aload_1
     110: aload_2
     111: invokestatic  #88                 // Method scanBasinAroundPoint:(Lday09/Point;[[ILjava/util/Set;)Ljava/util/Set;
     114: pop
     115: new           #76                 // class day09/Point
     118: dup
     119: aload_0
     120: invokevirtual #193                // Method day09/Point.getRow:()I
     123: iconst_1
     124: iadd
     125: aload_0
     126: invokevirtual #196                // Method day09/Point.getCol:()I
     129: invokespecial #79                 // Method day09/Point."<init>":(II)V
     132: aload_1
     133: aload_2
     134: invokestatic  #88                 // Method scanBasinAroundPoint:(Lday09/Point;[[ILjava/util/Set;)Ljava/util/Set;
     137: pop
     138: new           #76                 // class day09/Point
     141: dup
     142: aload_0
     143: invokevirtual #193                // Method day09/Point.getRow:()I
     146: aload_0
     147: invokevirtual #196                // Method day09/Point.getCol:()I
     150: iconst_1
     151: isub
     152: invokespecial #79                 // Method day09/Point."<init>":(II)V
     155: aload_1
     156: aload_2
     157: invokestatic  #88                 // Method scanBasinAroundPoint:(Lday09/Point;[[ILjava/util/Set;)Ljava/util/Set;
     160: pop
     161: new           #76                 // class day09/Point
     164: dup
     165: aload_0
     166: invokevirtual #193                // Method day09/Point.getRow:()I
     169: aload_0
     170: invokevirtual #196                // Method day09/Point.getCol:()I
     173: iconst_1
     174: iadd
     175: invokespecial #79                 // Method day09/Point."<init>":(II)V
     178: aload_1
     179: aload_2
     180: invokestatic  #88                 // Method scanBasinAroundPoint:(Lday09/Point;[[ILjava/util/Set;)Ljava/util/Set;
     183: pop
     184: aload_2
     185: areturn

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