import java.io.File
import kotlin.collections.ArrayDeque

fun main() {
    fun readMonkeys(input: List<String>) =
        input.map { data ->
            val lines = data.split("\n")
            Monkey(
                ArrayDeque(lines[1].split(": ")[1].split(", ").map { it -> it.toLong() }),
                lines[2].split("=")[1].toFunction(),
                lines[3].split(" ").last().toInt(),
                lines[4].split(" ").last().toInt(),
                lines[5].split(" ").last().toInt()
            )
        }

    fun part1(input: List<String>): Int {
        val monkeys = readMonkeys(input)

        repeat(20) {
            monkeys.forEach { monkey ->
                while (monkey.hasItems()) {
                    val (newItem, target) = monkey.inspectNextPt1()
                    monkeys[target].catch(newItem)
                }
            }
        }

        return monkeys.sortedBy { it.inspectionCount }.takeLast(2).fold(1) { acc, m -> acc * m.inspectionCount}
    }

    fun part2(input: List<String>): Long {
        val monkeys = readMonkeys(input)

        val checkProduct = monkeys.fold(1) { acc, m -> acc * m.testDiv }

        repeat(10000) {
            monkeys.forEach { monkey ->
                while (monkey.hasItems()) {
                    val (newItem, target) = monkey.inspectNextPt2()
                    monkeys[target].catch(newItem % checkProduct)
                }
            }
        }

        val topTwo = monkeys.map { it.inspectionCount }.sorted().takeLast(2)
        return 1L * topTwo[0] * topTwo[1]
    }

    val testInput =
"""Monkey 0:
  Starting items: 79, 98
  Operation: new = old * 19
  Test: divisible by 23
    If true: throw to monkey 2
    If false: throw to monkey 3

Monkey 1:
  Starting items: 54, 65, 75, 74
  Operation: new = old + 6
  Test: divisible by 19
    If true: throw to monkey 2
    If false: throw to monkey 0

Monkey 2:
  Starting items: 79, 60, 97
  Operation: new = old * old
  Test: divisible by 13
    If true: throw to monkey 1
    If false: throw to monkey 3

Monkey 3:
  Starting items: 74
  Operation: new = old + 3
  Test: divisible by 17
    If true: throw to monkey 0
    If false: throw to monkey 1
""".split("\n\n")

    // test if implementation meets criteria from the description, like:
    check(part1(testInput) == 10605)
    check(part2(testInput) == 2713310158L)

    val input = File("./src/resources/Day11.txt").readText().split("\n\n")
    println(part1(input))
    println(part2(input))
}

class Monkey(val items: ArrayDeque<Long>, val op: (Long) -> Long, val testDiv: Int, val ifTrue: Int, val ifFalse: Int) {
    var inspectionCount = 0
        private set

    fun catch(item: Long) {
        items.add(item)
    }

    fun hasItems() = items.any()

    private fun inspectNext(divisor: Int): Pair<Long, Int> {
        inspectionCount++
        val newWorry = op(items.removeFirst()) / divisor
        return newWorry to if (newWorry % testDiv == 0L ) ifTrue else ifFalse
    }

    fun inspectNextPt1(): Pair<Long, Int> = inspectNext(3)
    fun inspectNextPt2(): Pair<Long, Int> = inspectNext(1)
}

fun String.toFunction(): (Long) -> Long {
    if (this.trim() == "old * old")
        return { old -> old * old }

    val tokens = this.trim().split(" ")

    if (tokens[1] == "+")
        return { old: Long -> old + tokens[2].toInt() }

    if (tokens[1] == "*")
        return { old: Long -> old * tokens[2].toInt() }

    return { old: Long -> old * tokens[2].toInt() }
}

Compiled from "Comparisons.kt"
public final class Day11Kt$main$part1$$inlined$sortedBy$1<T> implements java.util.Comparator {
  public Day11Kt$main$part1$$inlined$sortedBy$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_1
       1: checkcast     #23                 // class Monkey
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method Monkey.getInspectionCount:()I
      12: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_2
      19: checkcast     #23                 // class Monkey
      22: astore_3
      23: astore        5
      25: iconst_0
      26: istore        4
      28: aload_3
      29: invokevirtual #27                 // Method Monkey.getInspectionCount:()I
      32: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      35: aload         5
      37: swap
      38: checkcast     #35                 // class java/lang/Comparable
      41: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      44: ireturn
}

Compiled from "Day11.kt"
public final class Day11Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Monkey 0:\n  Starting items: 79, 98\n  Operation: new = old * 19\n  Test: divisible by 23\n    If true: throw to monkey 2\n    If false: throw to monkey 3\n\nMonkey 1:\n  Starting items: 54, 65, 75, 74\n  Operation: new = old + 6\n  Test: divisible by 19\n    If true: throw to monkey 2\n    If false: throw to monkey 0\n\nMonkey 2:\n  Starting items: 79, 60, 97\n  Operation: new = old * old\n  Test: divisible by 13\n    If true: throw to monkey 1\n    If false: throw to monkey 3\n\nMonkey 3:\n  Starting items: 74\n  Operation: new = old + 3\n  Test: divisible by 17\n    If true: throw to monkey 0\n    If false: throw to monkey 1\n
       2: checkcast     #10                 // class java/lang/CharSequence
       5: iconst_1
       6: anewarray     #12                 // class java/lang/String
       9: astore_1
      10: aload_1
      11: iconst_0
      12: ldc           #14                 // String \n\n
      14: aastore
      15: aload_1
      16: iconst_0
      17: iconst_0
      18: bipush        6
      20: aconst_null
      21: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      24: astore_0
      25: aload_0
      26: invokestatic  #24                 // Method main$part1:(Ljava/util/List;)I
      29: sipush        10605
      32: if_icmpne     39
      35: iconst_1
      36: goto          40
      39: iconst_0
      40: ifne          53
      43: new           #26                 // class java/lang/IllegalStateException
      46: dup
      47: ldc           #28                 // String Check failed.
      49: invokespecial #32                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      52: athrow
      53: aload_0
      54: invokestatic  #36                 // Method main$part2:(Ljava/util/List;)J
      57: ldc2_w        #37                 // long 2713310158l
      60: lcmp
      61: ifne          68
      64: iconst_1
      65: goto          69
      68: iconst_0
      69: ifne          82
      72: new           #26                 // class java/lang/IllegalStateException
      75: dup
      76: ldc           #28                 // String Check failed.
      78: invokespecial #32                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      81: athrow
      82: new           #40                 // class java/io/File
      85: dup
      86: ldc           #42                 // String ./src/resources/Day11.txt
      88: invokespecial #43                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      91: aconst_null
      92: iconst_1
      93: aconst_null
      94: invokestatic  #49                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
      97: checkcast     #10                 // class java/lang/CharSequence
     100: iconst_1
     101: anewarray     #12                 // class java/lang/String
     104: astore_2
     105: aload_2
     106: iconst_0
     107: ldc           #14                 // String \n\n
     109: aastore
     110: aload_2
     111: iconst_0
     112: iconst_0
     113: bipush        6
     115: aconst_null
     116: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     119: astore_1
     120: aload_1
     121: invokestatic  #24                 // Method main$part1:(Ljava/util/List;)I
     124: istore_2
     125: getstatic     #55                 // Field java/lang/System.out:Ljava/io/PrintStream;
     128: iload_2
     129: invokevirtual #61                 // Method java/io/PrintStream.println:(I)V
     132: aload_1
     133: invokestatic  #36                 // Method main$part2:(Ljava/util/List;)J
     136: lstore_2
     137: getstatic     #55                 // Field java/lang/System.out:Ljava/io/PrintStream;
     140: lload_2
     141: invokevirtual #64                 // Method java/io/PrintStream.println:(J)V
     144: return

  public static final kotlin.jvm.functions.Function1<java.lang.Long, java.lang.Long> toFunction(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #77                 // String <this>
       3: invokestatic  #83                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #10                 // class java/lang/CharSequence
      10: invokestatic  #87                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      13: invokevirtual #91                 // Method java/lang/Object.toString:()Ljava/lang/String;
      16: ldc           #93                 // String old * old
      18: invokestatic  #97                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      21: ifeq          30
      24: invokedynamic #117,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
      29: areturn
      30: aload_0
      31: checkcast     #10                 // class java/lang/CharSequence
      34: invokestatic  #87                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      37: invokevirtual #91                 // Method java/lang/Object.toString:()Ljava/lang/String;
      40: checkcast     #10                 // class java/lang/CharSequence
      43: iconst_1
      44: anewarray     #12                 // class java/lang/String
      47: astore_2
      48: aload_2
      49: iconst_0
      50: ldc           #119                // String
      52: aastore
      53: aload_2
      54: iconst_0
      55: iconst_0
      56: bipush        6
      58: aconst_null
      59: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      62: astore_1
      63: aload_1
      64: iconst_1
      65: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      70: ldc           #125                // String +
      72: invokestatic  #97                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      75: ifeq          85
      78: aload_1
      79: invokedynamic #133,  0            // InvokeDynamic #1:invoke:(Ljava/util/List;)Lkotlin/jvm/functions/Function1;
      84: areturn
      85: aload_1
      86: iconst_1
      87: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      92: ldc           #135                // String *
      94: invokestatic  #97                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      97: ifeq          107
     100: aload_1
     101: invokedynamic #140,  0            // InvokeDynamic #2:invoke:(Ljava/util/List;)Lkotlin/jvm/functions/Function1;
     106: areturn
     107: aload_1
     108: invokedynamic #145,  0            // InvokeDynamic #3:invoke:(Ljava/util/List;)Lkotlin/jvm/functions/Function1;
     113: areturn

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

  private static final java.util.List<Monkey> main$readMonkeys(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #157                // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: astore_3
       9: new           #159                // class java/util/ArrayList
      12: dup
      13: aload_1
      14: bipush        10
      16: invokestatic  #165                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      19: invokespecial #167                // Method java/util/ArrayList."<init>":(I)V
      22: checkcast     #169                // class java/util/Collection
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          492
      48: aload         6
      50: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         4
      59: aload         7
      61: checkcast     #12                 // class java/lang/String
      64: astore        8
      66: astore        21
      68: iconst_0
      69: istore        9
      71: aload         8
      73: checkcast     #10                 // class java/lang/CharSequence
      76: iconst_1
      77: anewarray     #12                 // class java/lang/String
      80: astore        10
      82: aload         10
      84: iconst_0
      85: ldc           #185                // String \n
      87: aastore
      88: aload         10
      90: iconst_0
      91: iconst_0
      92: bipush        6
      94: aconst_null
      95: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      98: astore        11
     100: aload         11
     102: iconst_1
     103: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     108: checkcast     #10                 // class java/lang/CharSequence
     111: iconst_1
     112: anewarray     #12                 // class java/lang/String
     115: astore        10
     117: aload         10
     119: iconst_0
     120: ldc           #187                // String :
     122: aastore
     123: aload         10
     125: iconst_0
     126: iconst_0
     127: bipush        6
     129: aconst_null
     130: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     133: iconst_1
     134: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     139: checkcast     #10                 // class java/lang/CharSequence
     142: iconst_1
     143: anewarray     #12                 // class java/lang/String
     146: astore        10
     148: aload         10
     150: iconst_0
     151: ldc           #189                // String ,
     153: aastore
     154: aload         10
     156: iconst_0
     157: iconst_0
     158: bipush        6
     160: aconst_null
     161: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     164: checkcast     #157                // class java/lang/Iterable
     167: astore        10
     169: iconst_0
     170: istore        12
     172: aload         10
     174: astore        13
     176: new           #159                // class java/util/ArrayList
     179: dup
     180: aload         10
     182: bipush        10
     184: invokestatic  #165                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     187: invokespecial #167                // Method java/util/ArrayList."<init>":(I)V
     190: checkcast     #169                // class java/util/Collection
     193: astore        14
     195: iconst_0
     196: istore        15
     198: aload         13
     200: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     205: astore        16
     207: aload         16
     209: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     214: ifeq          261
     217: aload         16
     219: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     224: astore        17
     226: aload         14
     228: aload         17
     230: checkcast     #12                 // class java/lang/String
     233: astore        18
     235: astore        19
     237: iconst_0
     238: istore        20
     240: aload         18
     242: invokestatic  #195                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     245: nop
     246: invokestatic  #199                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     249: aload         19
     251: swap
     252: invokeinterface #203,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     257: pop
     258: goto          207
     261: aload         14
     263: checkcast     #69                 // class java/util/List
     266: nop
     267: checkcast     #169                // class java/util/Collection
     270: astore        22
     272: new           #205                // class kotlin/collections/ArrayDeque
     275: dup
     276: aload         22
     278: invokespecial #208                // Method kotlin/collections/ArrayDeque."<init>":(Ljava/util/Collection;)V
     281: aload         11
     283: iconst_2
     284: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     289: checkcast     #10                 // class java/lang/CharSequence
     292: iconst_1
     293: anewarray     #12                 // class java/lang/String
     296: astore        10
     298: aload         10
     300: iconst_0
     301: ldc           #210                // String =
     303: aastore
     304: aload         10
     306: iconst_0
     307: iconst_0
     308: bipush        6
     310: aconst_null
     311: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     314: iconst_1
     315: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     320: checkcast     #12                 // class java/lang/String
     323: invokestatic  #212                // Method toFunction:(Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
     326: aload         11
     328: iconst_3
     329: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     334: checkcast     #10                 // class java/lang/CharSequence
     337: iconst_1
     338: anewarray     #12                 // class java/lang/String
     341: astore        10
     343: aload         10
     345: iconst_0
     346: ldc           #119                // String
     348: aastore
     349: aload         10
     351: iconst_0
     352: iconst_0
     353: bipush        6
     355: aconst_null
     356: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     359: invokestatic  #216                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     362: checkcast     #12                 // class java/lang/String
     365: invokestatic  #222                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     368: aload         11
     370: iconst_4
     371: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     376: checkcast     #10                 // class java/lang/CharSequence
     379: iconst_1
     380: anewarray     #12                 // class java/lang/String
     383: astore        10
     385: aload         10
     387: iconst_0
     388: ldc           #119                // String
     390: aastore
     391: aload         10
     393: iconst_0
     394: iconst_0
     395: bipush        6
     397: aconst_null
     398: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     401: invokestatic  #216                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     404: checkcast     #12                 // class java/lang/String
     407: invokestatic  #222                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     410: aload         11
     412: iconst_5
     413: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     418: checkcast     #10                 // class java/lang/CharSequence
     421: iconst_1
     422: anewarray     #12                 // class java/lang/String
     425: astore        10
     427: aload         10
     429: iconst_0
     430: ldc           #119                // String
     432: aastore
     433: aload         10
     435: iconst_0
     436: iconst_0
     437: bipush        6
     439: aconst_null
     440: invokestatic  #20                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     443: invokestatic  #216                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     446: checkcast     #12                 // class java/lang/String
     449: invokestatic  #222                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     452: istore        23
     454: istore        24
     456: istore        25
     458: astore        26
     460: astore        27
     462: new           #224                // class Monkey
     465: dup
     466: aload         27
     468: aload         26
     470: iload         25
     472: iload         24
     474: iload         23
     476: invokespecial #227                // Method Monkey."<init>":(Lkotlin/collections/ArrayDeque;Lkotlin/jvm/functions/Function1;III)V
     479: nop
     480: aload         21
     482: swap
     483: invokeinterface #203,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     488: pop
     489: goto          38
     492: aload         4
     494: checkcast     #69                 // class java/util/List
     497: nop
     498: areturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #245                // Method main$readMonkeys:(Ljava/util/List;)Ljava/util/List;
       4: astore_1
       5: bipush        20
       7: istore_2
       8: iconst_0
       9: istore_3
      10: iload_3
      11: iload_2
      12: if_icmpge     141
      15: iload_3
      16: istore        4
      18: iconst_0
      19: istore        5
      21: aload_1
      22: checkcast     #157                // class java/lang/Iterable
      25: astore        6
      27: iconst_0
      28: istore        7
      30: aload         6
      32: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      37: astore        8
      39: aload         8
      41: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      46: ifeq          133
      49: aload         8
      51: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      56: astore        9
      58: aload         9
      60: checkcast     #224                // class Monkey
      63: astore        10
      65: iconst_0
      66: istore        11
      68: aload         10
      70: invokevirtual #248                // Method Monkey.hasItems:()Z
      73: ifeq          128
      76: aload         10
      78: invokevirtual #252                // Method Monkey.inspectNextPt1:()Lkotlin/Pair;
      81: astore        12
      83: aload         12
      85: invokevirtual #257                // Method kotlin/Pair.component1:()Ljava/lang/Object;
      88: checkcast     #259                // class java/lang/Number
      91: invokevirtual #263                // Method java/lang/Number.longValue:()J
      94: lstore        13
      96: aload         12
      98: invokevirtual #266                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     101: checkcast     #259                // class java/lang/Number
     104: invokevirtual #270                // Method java/lang/Number.intValue:()I
     107: istore        15
     109: aload_1
     110: iload         15
     112: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     117: checkcast     #224                // class Monkey
     120: lload         13
     122: invokevirtual #273                // Method Monkey.catch:(J)V
     125: goto          68
     128: nop
     129: nop
     130: goto          39
     133: nop
     134: nop
     135: iinc          3, 1
     138: goto          10
     141: aload_1
     142: checkcast     #157                // class java/lang/Iterable
     145: astore_2
     146: iconst_0
     147: istore_3
     148: aload_2
     149: new           #275                // class Day11Kt$main$part1$$inlined$sortedBy$1
     152: dup
     153: invokespecial #277                // Method Day11Kt$main$part1$$inlined$sortedBy$1."<init>":()V
     156: checkcast     #279                // class java/util/Comparator
     159: invokestatic  #283                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
     162: iconst_2
     163: invokestatic  #287                // Method kotlin/collections/CollectionsKt.takeLast:(Ljava/util/List;I)Ljava/util/List;
     166: checkcast     #157                // class java/lang/Iterable
     169: astore_2
     170: iconst_1
     171: istore_3
     172: iconst_0
     173: istore        4
     175: iload_3
     176: istore        5
     178: aload_2
     179: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     184: astore        6
     186: aload         6
     188: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     193: ifeq          232
     196: aload         6
     198: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     203: astore        7
     205: iload         5
     207: aload         7
     209: checkcast     #224                // class Monkey
     212: astore        8
     214: istore        9
     216: iconst_0
     217: istore        10
     219: iload         9
     221: aload         8
     223: invokevirtual #290                // Method Monkey.getInspectionCount:()I
     226: imul
     227: istore        5
     229: goto          186
     232: iload         5
     234: ireturn

  private static final long main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #245                // Method main$readMonkeys:(Ljava/util/List;)Ljava/util/List;
       4: astore_1
       5: aload_1
       6: checkcast     #157                // class java/lang/Iterable
       9: astore_3
      10: iconst_1
      11: istore        4
      13: iconst_0
      14: istore        5
      16: iload         4
      18: istore        6
      20: aload_3
      21: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      26: astore        7
      28: aload         7
      30: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      35: ifeq          74
      38: aload         7
      40: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      45: astore        8
      47: iload         6
      49: aload         8
      51: checkcast     #224                // class Monkey
      54: astore        9
      56: istore        10
      58: iconst_0
      59: istore        11
      61: iload         10
      63: aload         9
      65: invokevirtual #314                // Method Monkey.getTestDiv:()I
      68: imul
      69: istore        6
      71: goto          28
      74: iload         6
      76: istore_2
      77: sipush        10000
      80: istore_3
      81: iconst_0
      82: istore        4
      84: iload         4
      86: iload_3
      87: if_icmpge     220
      90: iload         4
      92: istore        5
      94: iconst_0
      95: istore        6
      97: aload_1
      98: checkcast     #157                // class java/lang/Iterable
     101: astore        7
     103: iconst_0
     104: istore        8
     106: aload         7
     108: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     113: astore        9
     115: aload         9
     117: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     122: ifeq          212
     125: aload         9
     127: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     132: astore        10
     134: aload         10
     136: checkcast     #224                // class Monkey
     139: astore        11
     141: iconst_0
     142: istore        12
     144: aload         11
     146: invokevirtual #248                // Method Monkey.hasItems:()Z
     149: ifeq          207
     152: aload         11
     154: invokevirtual #317                // Method Monkey.inspectNextPt2:()Lkotlin/Pair;
     157: astore        13
     159: aload         13
     161: invokevirtual #257                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     164: checkcast     #259                // class java/lang/Number
     167: invokevirtual #263                // Method java/lang/Number.longValue:()J
     170: lstore        14
     172: aload         13
     174: invokevirtual #266                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     177: checkcast     #259                // class java/lang/Number
     180: invokevirtual #270                // Method java/lang/Number.intValue:()I
     183: istore        16
     185: aload_1
     186: iload         16
     188: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     193: checkcast     #224                // class Monkey
     196: lload         14
     198: iload_2
     199: i2l
     200: lrem
     201: invokevirtual #273                // Method Monkey.catch:(J)V
     204: goto          144
     207: nop
     208: nop
     209: goto          115
     212: nop
     213: nop
     214: iinc          4, 1
     217: goto          84
     220: aload_1
     221: checkcast     #157                // class java/lang/Iterable
     224: astore        4
     226: iconst_0
     227: istore        5
     229: aload         4
     231: astore        6
     233: new           #159                // class java/util/ArrayList
     236: dup
     237: aload         4
     239: bipush        10
     241: invokestatic  #165                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     244: invokespecial #167                // Method java/util/ArrayList."<init>":(I)V
     247: checkcast     #169                // class java/util/Collection
     250: astore        7
     252: iconst_0
     253: istore        8
     255: aload         6
     257: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     262: astore        9
     264: aload         9
     266: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     271: ifeq          317
     274: aload         9
     276: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     281: astore        10
     283: aload         7
     285: aload         10
     287: checkcast     #224                // class Monkey
     290: astore        11
     292: astore        17
     294: iconst_0
     295: istore        12
     297: aload         11
     299: invokevirtual #290                // Method Monkey.getInspectionCount:()I
     302: invokestatic  #320                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     305: aload         17
     307: swap
     308: invokeinterface #203,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     313: pop
     314: goto          264
     317: aload         7
     319: checkcast     #69                 // class java/util/List
     322: nop
     323: checkcast     #157                // class java/lang/Iterable
     326: invokestatic  #324                // Method kotlin/collections/CollectionsKt.sorted:(Ljava/lang/Iterable;)Ljava/util/List;
     329: iconst_2
     330: invokestatic  #287                // Method kotlin/collections/CollectionsKt.takeLast:(Ljava/util/List;I)Ljava/util/List;
     333: astore_3
     334: lconst_1
     335: aload_3
     336: iconst_0
     337: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     342: checkcast     #259                // class java/lang/Number
     345: invokevirtual #263                // Method java/lang/Number.longValue:()J
     348: lmul
     349: aload_3
     350: iconst_1
     351: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     356: checkcast     #259                // class java/lang/Number
     359: invokevirtual #263                // Method java/lang/Number.longValue:()J
     362: lmul
     363: lreturn

  private static final long toFunction$lambda$10(long);
    Code:
       0: lload_0
       1: lload_0
       2: lmul
       3: lreturn

  private static final long toFunction$lambda$11(java.util.List, long);
    Code:
       0: lload_1
       1: aload_0
       2: iconst_2
       3: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
       8: checkcast     #12                 // class java/lang/String
      11: invokestatic  #222                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      14: i2l
      15: ladd
      16: lreturn

  private static final long toFunction$lambda$12(java.util.List, long);
    Code:
       0: lload_1
       1: aload_0
       2: iconst_2
       3: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
       8: checkcast     #12                 // class java/lang/String
      11: invokestatic  #222                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      14: i2l
      15: lmul
      16: lreturn

  private static final long toFunction$lambda$13(java.util.List, long);
    Code:
       0: lload_1
       1: aload_0
       2: iconst_2
       3: invokeinterface #123,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
       8: checkcast     #12                 // class java/lang/String
      11: invokestatic  #222                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      14: i2l
      15: lmul
      16: lreturn
}


import java.io.File
import kotlin.math.abs
import kotlin.math.round
import kotlin.math.roundToInt

fun main() {
    fun part1(input: List<String>): Int {
        val rope = Rope()

        input.forEach { moveData ->
            val move = moveData.split(" ")
            repeat(move[1].toInt()) {
                rope.move(Direction.valueOf(move[0]))
            }
        }

        return rope.tailPositions.size
    }

    fun part2(input: List<String>): Int {
        val rope = Rope(10)

        input.forEach { moveData ->
            val move = moveData.split(" ")
            repeat(move[1].toInt()) {
                rope.move(Direction.valueOf(move[0]))
            }
        }

        return rope.tailPositions.size
    }

    val testInput = listOf<String>(
        "R 4",
        "U 4",
        "L 3",
        "D 1",
        "R 4",
        "D 1",
        "L 5",
        "R 2",
    )

    val testInput2 = listOf(
        "R 5",
        "U 8",
        "L 8",
        "D 3",
        "R 17",
        "D 10",
        "L 25",
        "U 20",
    )

    // test if implementation meets criteria from the description, like:
    println(part1(testInput))
    check(part1(testInput) == 13)
    println(part2(testInput2))
    check(part2(testInput2) == 36)

    val input = File("./src/resources/Day09.txt").readLines()
    println(part1(input))
    println(part2(input))
}

class Rope(val length: Int = 2) {
    val knots = List(length) { _ -> Knot() }
    val tailPositions = mutableSetOf("0,0")

    private val head = knots[0]

    private fun isTouchingPrevious(index: Int) = abs(knots[index].x-knots[index-1].x) < 2
            && abs(knots[index].y-knots[index-1].y) < 2

    infix fun move(direction: Direction) {
        when (direction) {
            Direction.U -> head.y++
            Direction.D -> head.y--
            Direction.L -> head.x--
            Direction.R -> head.x++
        }

        (1 until knots.size).forEach { i ->
            if (!isTouchingPrevious(i)) {
                if (knots[i-1].x == knots[i].x || knots[i-1].y == knots[i].y) {
                    knots[i].x = (knots[i-1].x + knots[i].x) / 2
                    knots[i].y = (knots[i-1].y + knots[i].y) / 2
                } else {
                    knots[i].x += if (knots[i-1].x > knots[i].x) 1 else -1
                    knots[i].y += if (knots[i-1].y > knots[i].y) 1 else -1
                }
            }
        }
        tailPositions.add("${knots.last().x},${knots.last().y}")

//        println ("H -> ($headX, $headY), T -> ($tailX, $tailY)")
//        (0 .. 5).map { r ->
//            (0 .. 5).joinToString("") { c ->
//                if (headX == c && headY == r) "H" else if (tailX == c && tailY == r) "T" else "."
//            }
//        }.reversed().forEach { println(it) }
//        println()
    }
}

enum class Direction {
    U,D,L,R
}

data class Knot(var x: Int = 0, var y: Int = 0)

Compiled from "Day09.kt"
public final class Day09Kt {
  public static final void main();
    Code:
       0: bipush        8
       2: anewarray     #8                  // class java/lang/String
       5: astore_1
       6: aload_1
       7: iconst_0
       8: ldc           #10                 // String R 4
      10: aastore
      11: aload_1
      12: iconst_1
      13: ldc           #12                 // String U 4
      15: aastore
      16: aload_1
      17: iconst_2
      18: ldc           #14                 // String L 3
      20: aastore
      21: aload_1
      22: iconst_3
      23: ldc           #16                 // String D 1
      25: aastore
      26: aload_1
      27: iconst_4
      28: ldc           #10                 // String R 4
      30: aastore
      31: aload_1
      32: iconst_5
      33: ldc           #16                 // String D 1
      35: aastore
      36: aload_1
      37: bipush        6
      39: ldc           #18                 // String L 5
      41: aastore
      42: aload_1
      43: bipush        7
      45: ldc           #20                 // String R 2
      47: aastore
      48: aload_1
      49: invokestatic  #26                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      52: astore_0
      53: bipush        8
      55: anewarray     #8                  // class java/lang/String
      58: astore_2
      59: aload_2
      60: iconst_0
      61: ldc           #28                 // String R 5
      63: aastore
      64: aload_2
      65: iconst_1
      66: ldc           #30                 // String U 8
      68: aastore
      69: aload_2
      70: iconst_2
      71: ldc           #32                 // String L 8
      73: aastore
      74: aload_2
      75: iconst_3
      76: ldc           #34                 // String D 3
      78: aastore
      79: aload_2
      80: iconst_4
      81: ldc           #36                 // String R 17
      83: aastore
      84: aload_2
      85: iconst_5
      86: ldc           #38                 // String D 10
      88: aastore
      89: aload_2
      90: bipush        6
      92: ldc           #40                 // String L 25
      94: aastore
      95: aload_2
      96: bipush        7
      98: ldc           #42                 // String U 20
     100: aastore
     101: aload_2
     102: invokestatic  #26                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     105: astore_1
     106: aload_0
     107: invokestatic  #46                 // Method main$part1:(Ljava/util/List;)I
     110: istore_2
     111: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
     114: iload_2
     115: invokevirtual #58                 // Method java/io/PrintStream.println:(I)V
     118: aload_0
     119: invokestatic  #46                 // Method main$part1:(Ljava/util/List;)I
     122: bipush        13
     124: if_icmpne     131
     127: iconst_1
     128: goto          132
     131: iconst_0
     132: ifne          145
     135: new           #60                 // class java/lang/IllegalStateException
     138: dup
     139: ldc           #62                 // String Check failed.
     141: invokespecial #66                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     144: athrow
     145: aload_1
     146: invokestatic  #69                 // Method main$part2:(Ljava/util/List;)I
     149: istore_2
     150: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
     153: iload_2
     154: invokevirtual #58                 // Method java/io/PrintStream.println:(I)V
     157: aload_1
     158: invokestatic  #69                 // Method main$part2:(Ljava/util/List;)I
     161: bipush        36
     163: if_icmpne     170
     166: iconst_1
     167: goto          171
     170: iconst_0
     171: ifne          184
     174: new           #60                 // class java/lang/IllegalStateException
     177: dup
     178: ldc           #62                 // String Check failed.
     180: invokespecial #66                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     183: athrow
     184: new           #71                 // class java/io/File
     187: dup
     188: ldc           #73                 // String ./src/resources/Day09.txt
     190: invokespecial #74                 // Method java/io/File."<init>":(Ljava/lang/String;)V
     193: aconst_null
     194: iconst_1
     195: aconst_null
     196: invokestatic  #80                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
     199: astore_2
     200: aload_2
     201: invokestatic  #46                 // Method main$part1:(Ljava/util/List;)I
     204: istore_3
     205: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
     208: iload_3
     209: invokevirtual #58                 // Method java/io/PrintStream.println:(I)V
     212: aload_2
     213: invokestatic  #69                 // Method main$part2:(Ljava/util/List;)I
     216: istore_3
     217: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
     220: iload_3
     221: invokevirtual #58                 // Method java/io/PrintStream.println:(I)V
     224: return

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

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: new           #94                 // class Rope
       3: dup
       4: iconst_0
       5: iconst_1
       6: aconst_null
       7: invokespecial #97                 // Method Rope."<init>":(IILkotlin/jvm/internal/DefaultConstructorMarker;)V
      10: astore_1
      11: aload_0
      12: checkcast     #99                 // class java/lang/Iterable
      15: astore_2
      16: iconst_0
      17: istore_3
      18: aload_2
      19: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      24: astore        4
      26: aload         4
      28: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      33: ifeq          147
      36: aload         4
      38: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      43: astore        5
      45: aload         5
      47: checkcast     #8                  // class java/lang/String
      50: astore        6
      52: iconst_0
      53: istore        7
      55: aload         6
      57: checkcast     #115                // class java/lang/CharSequence
      60: iconst_1
      61: anewarray     #8                  // class java/lang/String
      64: astore        8
      66: aload         8
      68: iconst_0
      69: ldc           #117                // String
      71: aastore
      72: aload         8
      74: iconst_0
      75: iconst_0
      76: bipush        6
      78: aconst_null
      79: invokestatic  #123                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      82: astore        9
      84: aload         9
      86: iconst_1
      87: invokeinterface #127,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      92: checkcast     #8                  // class java/lang/String
      95: invokestatic  #133                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      98: istore        8
     100: iconst_0
     101: istore        10
     103: iload         10
     105: iload         8
     107: if_icmpge     142
     110: iload         10
     112: istore        11
     114: iconst_0
     115: istore        12
     117: aload_1
     118: aload         9
     120: iconst_0
     121: invokeinterface #127,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     126: checkcast     #8                  // class java/lang/String
     129: invokestatic  #139                // Method Direction.valueOf:(Ljava/lang/String;)LDirection;
     132: invokevirtual #143                // Method Rope.move:(LDirection;)V
     135: nop
     136: iinc          10, 1
     139: goto          103
     142: nop
     143: nop
     144: goto          26
     147: nop
     148: aload_1
     149: invokevirtual #147                // Method Rope.getTailPositions:()Ljava/util/Set;
     152: invokeinterface #153,  1          // InterfaceMethod java/util/Set.size:()I
     157: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: new           #94                 // class Rope
       3: dup
       4: bipush        10
       6: invokespecial #168                // Method Rope."<init>":(I)V
       9: astore_1
      10: aload_0
      11: checkcast     #99                 // class java/lang/Iterable
      14: astore_2
      15: iconst_0
      16: istore_3
      17: aload_2
      18: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      23: astore        4
      25: aload         4
      27: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      32: ifeq          146
      35: aload         4
      37: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      42: astore        5
      44: aload         5
      46: checkcast     #8                  // class java/lang/String
      49: astore        6
      51: iconst_0
      52: istore        7
      54: aload         6
      56: checkcast     #115                // class java/lang/CharSequence
      59: iconst_1
      60: anewarray     #8                  // class java/lang/String
      63: astore        8
      65: aload         8
      67: iconst_0
      68: ldc           #117                // String
      70: aastore
      71: aload         8
      73: iconst_0
      74: iconst_0
      75: bipush        6
      77: aconst_null
      78: invokestatic  #123                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      81: astore        9
      83: aload         9
      85: iconst_1
      86: invokeinterface #127,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      91: checkcast     #8                  // class java/lang/String
      94: invokestatic  #133                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      97: istore        8
      99: iconst_0
     100: istore        10
     102: iload         10
     104: iload         8
     106: if_icmpge     141
     109: iload         10
     111: istore        11
     113: iconst_0
     114: istore        12
     116: aload_1
     117: aload         9
     119: iconst_0
     120: invokeinterface #127,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     125: checkcast     #8                  // class java/lang/String
     128: invokestatic  #139                // Method Direction.valueOf:(Ljava/lang/String;)LDirection;
     131: invokevirtual #143                // Method Rope.move:(LDirection;)V
     134: nop
     135: iinc          10, 1
     138: goto          102
     141: nop
     142: nop
     143: goto          25
     146: nop
     147: aload_1
     148: invokevirtual #147                // Method Rope.getTailPositions:()Ljava/util/Set;
     151: invokeinterface #153,  1          // InterfaceMethod java/util/Set.size:()I
     156: ireturn
}


import java.io.File

fun main() {
    fun sightAlongAndMark(trees: List<Tree>) {
        var max = -1
        trees.forEach { t -> if (t.height > max) { t.canSee(); max = t.height }}
    }

    fun getVisibleTrees(trees: List<Tree>): Int {
        var count = 0
        var max = 0
        for (tree in trees.subList(1, trees.size)) {
            count++
            max = maxOf(max, tree.height)
            if (tree.height >= trees[0].height) {
                break
            }
        }
        return count
    }

    fun <T> getColumns(ts: List<List<T>>): List<List<T>> {
        return (0 until ts[0].size).map { i ->
            ts.map { r -> r[i] }.toList()
        }.toList()
    }

    fun getDirectionLists(trees: List<List<Tree>>, row: Int, col: Int): List<List<Tree>> {
        val directions = mutableListOf<List<Tree>>()

        directions.add(trees[row].subList(0, col+1).reversed()) // left
        directions.add(trees[row].subList(col, trees[row].size)) // right

        val column = getColumns(trees)[col]

        directions.add(column.subList(0, row+1).reversed()) // top
        directions.add(column.subList(row, column.size)) // bottom

        return directions.toList()
    }

    fun part1(input: List<String>): Int {
        val forest = input.map { r -> r.map { Tree(it.digitToInt()) }}

        forest.forEach { sightAlongAndMark(it) }
        forest.forEach { sightAlongAndMark(it.reversed()) }

        val columns = getColumns(forest)

        columns.forEach { sightAlongAndMark(it) }
        columns.forEach { sightAlongAndMark(it.reversed()) }

//        forest.forEach { r -> println(r.joinToString("") { t -> "${t}" }) }
        println()

        return forest.flatten().count { it.isVisible }
    }

    fun part2(input: List<String>): Int {
        val forest = input.map { r -> r.map { Tree(it.digitToInt()) }}

        forest.forEachIndexed { i, row -> row.forEachIndexed { j, tree ->
            val lists = getDirectionLists(forest, i, j)
            tree.scenicScore = lists.map {
                getVisibleTrees(it)
            }.fold(1) { acc, it -> it * acc }
        } }

//        forest.forEach { r -> println(r.joinToString(" ") { t -> "${t.scenicScore}" }) }
        println()

        return forest.flatten().maxOf { it.scenicScore }
    }

    val testInput = listOf<String>(
        "30373",
        "25512",
        "65332",
        "33549",
        "35390"
    )

    // test if implementation meets criteria from the description, like:
    check(part1(testInput) == 21)
    check(part2(testInput) == 8)

    val input = File("./src/resources/Day08.txt").readLines()
    println(part1(input))
    println(part2(input))
}

class Tree(val height: Int, var isVisible: Boolean = false) {
    fun canSee() { isVisible = true }
    override fun toString(): String = if (isVisible) "*" else " "
    var scenicScore = -1
}

Compiled from "Day08.kt"
public final class Day08Kt {
  public static final void main();
    Code:
       0: iconst_5
       1: anewarray     #8                  // class java/lang/String
       4: astore_1
       5: aload_1
       6: iconst_0
       7: ldc           #10                 // String 30373
       9: aastore
      10: aload_1
      11: iconst_1
      12: ldc           #12                 // String 25512
      14: aastore
      15: aload_1
      16: iconst_2
      17: ldc           #14                 // String 65332
      19: aastore
      20: aload_1
      21: iconst_3
      22: ldc           #16                 // String 33549
      24: aastore
      25: aload_1
      26: iconst_4
      27: ldc           #18                 // String 35390
      29: aastore
      30: aload_1
      31: invokestatic  #24                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      34: astore_0
      35: aload_0
      36: invokestatic  #28                 // Method main$part1:(Ljava/util/List;)I
      39: bipush        21
      41: if_icmpne     48
      44: iconst_1
      45: goto          49
      48: iconst_0
      49: ifne          62
      52: new           #30                 // class java/lang/IllegalStateException
      55: dup
      56: ldc           #32                 // String Check failed.
      58: invokespecial #36                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      61: athrow
      62: aload_0
      63: invokestatic  #39                 // Method main$part2:(Ljava/util/List;)I
      66: bipush        8
      68: if_icmpne     75
      71: iconst_1
      72: goto          76
      75: iconst_0
      76: ifne          89
      79: new           #30                 // class java/lang/IllegalStateException
      82: dup
      83: ldc           #32                 // String Check failed.
      85: invokespecial #36                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      88: athrow
      89: new           #41                 // class java/io/File
      92: dup
      93: ldc           #43                 // String ./src/resources/Day08.txt
      95: invokespecial #44                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      98: aconst_null
      99: iconst_1
     100: aconst_null
     101: invokestatic  #50                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
     104: astore_1
     105: aload_1
     106: invokestatic  #28                 // Method main$part1:(Ljava/util/List;)I
     109: istore_2
     110: getstatic     #56                 // Field java/lang/System.out:Ljava/io/PrintStream;
     113: iload_2
     114: invokevirtual #62                 // Method java/io/PrintStream.println:(I)V
     117: aload_1
     118: invokestatic  #39                 // Method main$part2:(Ljava/util/List;)I
     121: istore_2
     122: getstatic     #56                 // Field java/lang/System.out:Ljava/io/PrintStream;
     125: iload_2
     126: invokevirtual #62                 // Method java/io/PrintStream.println:(I)V
     129: return

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

  private static final void main$sightAlongAndMark(java.util.List<Tree>);
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_m1
       3: istore_1
       4: aload_0
       5: checkcast     #78                 // class java/lang/Iterable
       8: astore_2
       9: iconst_0
      10: istore_3
      11: aload_2
      12: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      17: astore        4
      19: aload         4
      21: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      26: ifeq          72
      29: aload         4
      31: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      36: astore        5
      38: aload         5
      40: checkcast     #94                 // class Tree
      43: astore        6
      45: iconst_0
      46: istore        7
      48: aload         6
      50: invokevirtual #98                 // Method Tree.getHeight:()I
      53: iload_1
      54: if_icmple     68
      57: aload         6
      59: invokevirtual #101                // Method Tree.canSee:()V
      62: aload         6
      64: invokevirtual #98                 // Method Tree.getHeight:()I
      67: istore_1
      68: nop
      69: goto          19
      72: nop
      73: return

  private static final int main$getVisibleTrees(java.util.List<Tree>);
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_0
       3: istore_2
       4: aload_0
       5: iconst_1
       6: aload_0
       7: invokeinterface #117,  1          // InterfaceMethod java/util/List.size:()I
      12: invokeinterface #121,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
      17: invokeinterface #122,  1          // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      22: astore_3
      23: aload_3
      24: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      29: ifeq          80
      32: aload_3
      33: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      38: checkcast     #94                 // class Tree
      41: astore        4
      43: iinc          1, 1
      46: iload_2
      47: aload         4
      49: invokevirtual #98                 // Method Tree.getHeight:()I
      52: invokestatic  #127                // Method java/lang/Math.max:(II)I
      55: istore_2
      56: aload         4
      58: invokevirtual #98                 // Method Tree.getHeight:()I
      61: aload_0
      62: iconst_0
      63: invokeinterface #131,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      68: checkcast     #94                 // class Tree
      71: invokevirtual #98                 // Method Tree.getHeight:()I
      74: if_icmplt     23
      77: goto          80
      80: iload_1
      81: ireturn

  private static final <T> java.util.List<java.util.List<T>> main$getColumns(java.util.List<? extends java.util.List<? extends T>>);
    Code:
       0: iconst_0
       1: aload_0
       2: iconst_0
       3: invokeinterface #131,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
       8: checkcast     #67                 // class java/util/List
      11: invokeinterface #117,  1          // InterfaceMethod java/util/List.size:()I
      16: invokestatic  #142                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      19: checkcast     #78                 // class java/lang/Iterable
      22: astore_1
      23: iconst_0
      24: istore_2
      25: aload_1
      26: astore_3
      27: new           #144                // class java/util/ArrayList
      30: dup
      31: aload_1
      32: bipush        10
      34: invokestatic  #148                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      37: invokespecial #150                // Method java/util/ArrayList."<init>":(I)V
      40: checkcast     #152                // class java/util/Collection
      43: astore        4
      45: iconst_0
      46: istore        5
      48: aload_3
      49: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      54: astore        6
      56: aload         6
      58: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      63: ifeq          209
      66: aload         6
      68: checkcast     #154                // class kotlin/collections/IntIterator
      71: invokevirtual #157                // Method kotlin/collections/IntIterator.nextInt:()I
      74: istore        7
      76: aload         4
      78: iload         7
      80: istore        8
      82: astore        20
      84: iconst_0
      85: istore        9
      87: aload_0
      88: checkcast     #78                 // class java/lang/Iterable
      91: astore        10
      93: iconst_0
      94: istore        11
      96: aload         10
      98: astore        12
     100: new           #144                // class java/util/ArrayList
     103: dup
     104: aload         10
     106: bipush        10
     108: invokestatic  #148                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     111: invokespecial #150                // Method java/util/ArrayList."<init>":(I)V
     114: checkcast     #152                // class java/util/Collection
     117: astore        13
     119: iconst_0
     120: istore        14
     122: aload         12
     124: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     129: astore        15
     131: aload         15
     133: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     138: ifeq          185
     141: aload         15
     143: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     148: astore        16
     150: aload         13
     152: aload         16
     154: checkcast     #67                 // class java/util/List
     157: astore        17
     159: astore        18
     161: iconst_0
     162: istore        19
     164: aload         17
     166: iload         8
     168: invokeinterface #131,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     173: aload         18
     175: swap
     176: invokeinterface #161,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     181: pop
     182: goto          131
     185: aload         13
     187: checkcast     #67                 // class java/util/List
     190: nop
     191: checkcast     #78                 // class java/lang/Iterable
     194: invokestatic  #165                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     197: aload         20
     199: swap
     200: invokeinterface #161,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     205: pop
     206: goto          56
     209: aload         4
     211: checkcast     #67                 // class java/util/List
     214: nop
     215: checkcast     #78                 // class java/lang/Iterable
     218: invokestatic  #165                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     221: areturn

  private static final java.util.List<java.util.List<Tree>> main$getDirectionLists(java.util.List<? extends java.util.List<Tree>>, int, int);
    Code:
       0: new           #144                // class java/util/ArrayList
       3: dup
       4: invokespecial #182                // Method java/util/ArrayList."<init>":()V
       7: checkcast     #67                 // class java/util/List
      10: astore_3
      11: aload_3
      12: aload_0
      13: iload_1
      14: invokeinterface #131,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      19: checkcast     #67                 // class java/util/List
      22: iconst_0
      23: iload_2
      24: iconst_1
      25: iadd
      26: invokeinterface #121,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
      31: checkcast     #78                 // class java/lang/Iterable
      34: invokestatic  #185                // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
      37: invokeinterface #186,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      42: pop
      43: aload_3
      44: aload_0
      45: iload_1
      46: invokeinterface #131,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      51: checkcast     #67                 // class java/util/List
      54: iload_2
      55: aload_0
      56: iload_1
      57: invokeinterface #131,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      62: checkcast     #67                 // class java/util/List
      65: invokeinterface #117,  1          // InterfaceMethod java/util/List.size:()I
      70: invokeinterface #121,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
      75: invokeinterface #186,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      80: pop
      81: aload_0
      82: invokestatic  #188                // Method main$getColumns:(Ljava/util/List;)Ljava/util/List;
      85: iload_2
      86: invokeinterface #131,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      91: checkcast     #67                 // class java/util/List
      94: astore        4
      96: aload_3
      97: aload         4
      99: iconst_0
     100: iload_1
     101: iconst_1
     102: iadd
     103: invokeinterface #121,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
     108: checkcast     #78                 // class java/lang/Iterable
     111: invokestatic  #185                // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
     114: invokeinterface #186,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     119: pop
     120: aload_3
     121: aload         4
     123: iload_1
     124: aload         4
     126: invokeinterface #117,  1          // InterfaceMethod java/util/List.size:()I
     131: invokeinterface #121,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
     136: invokeinterface #186,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     141: pop
     142: aload_3
     143: checkcast     #78                 // class java/lang/Iterable
     146: invokestatic  #165                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     149: areturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #78                 // class java/lang/Iterable
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: astore        4
      10: new           #144                // class java/util/ArrayList
      13: dup
      14: aload_2
      15: bipush        10
      17: invokestatic  #148                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      20: invokespecial #150                // Method java/util/ArrayList."<init>":(I)V
      23: checkcast     #152                // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          195
      50: aload         7
      52: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         5
      61: aload         8
      63: checkcast     #8                  // class java/lang/String
      66: astore        9
      68: astore        21
      70: iconst_0
      71: istore        10
      73: aload         9
      75: checkcast     #195                // class java/lang/CharSequence
      78: astore        11
      80: iconst_0
      81: istore        12
      83: aload         11
      85: astore        13
      87: new           #144                // class java/util/ArrayList
      90: dup
      91: aload         11
      93: invokeinterface #198,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      98: invokespecial #150                // Method java/util/ArrayList."<init>":(I)V
     101: checkcast     #152                // class java/util/Collection
     104: astore        14
     106: iconst_0
     107: istore        15
     109: iconst_0
     110: istore        16
     112: iload         16
     114: aload         13
     116: invokeinterface #198,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     121: if_icmpge     176
     124: aload         13
     126: iload         16
     128: invokeinterface #202,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     133: istore        17
     135: aload         14
     137: iload         17
     139: istore        18
     141: astore        19
     143: iconst_0
     144: istore        20
     146: new           #94                 // class Tree
     149: dup
     150: iload         18
     152: invokestatic  #208                // Method kotlin/text/CharsKt.digitToInt:(C)I
     155: iconst_0
     156: iconst_2
     157: aconst_null
     158: invokespecial #211                // Method Tree."<init>":(IZILkotlin/jvm/internal/DefaultConstructorMarker;)V
     161: aload         19
     163: swap
     164: invokeinterface #161,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     169: pop
     170: iinc          16, 1
     173: goto          112
     176: aload         14
     178: checkcast     #67                 // class java/util/List
     181: nop
     182: nop
     183: aload         21
     185: swap
     186: invokeinterface #161,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     191: pop
     192: goto          40
     195: aload         5
     197: checkcast     #67                 // class java/util/List
     200: nop
     201: astore_1
     202: aload_1
     203: checkcast     #78                 // class java/lang/Iterable
     206: astore_2
     207: iconst_0
     208: istore_3
     209: aload_2
     210: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     215: astore        4
     217: aload         4
     219: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     224: ifeq          255
     227: aload         4
     229: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     234: astore        5
     236: aload         5
     238: checkcast     #67                 // class java/util/List
     241: astore        6
     243: iconst_0
     244: istore        7
     246: aload         6
     248: invokestatic  #213                // Method main$sightAlongAndMark:(Ljava/util/List;)V
     251: nop
     252: goto          217
     255: nop
     256: aload_1
     257: checkcast     #78                 // class java/lang/Iterable
     260: astore_2
     261: iconst_0
     262: istore_3
     263: aload_2
     264: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     269: astore        4
     271: aload         4
     273: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     278: ifeq          315
     281: aload         4
     283: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     288: astore        5
     290: aload         5
     292: checkcast     #67                 // class java/util/List
     295: astore        6
     297: iconst_0
     298: istore        7
     300: aload         6
     302: checkcast     #78                 // class java/lang/Iterable
     305: invokestatic  #185                // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
     308: invokestatic  #213                // Method main$sightAlongAndMark:(Ljava/util/List;)V
     311: nop
     312: goto          271
     315: nop
     316: aload_1
     317: invokestatic  #188                // Method main$getColumns:(Ljava/util/List;)Ljava/util/List;
     320: astore_2
     321: aload_2
     322: checkcast     #78                 // class java/lang/Iterable
     325: astore_3
     326: iconst_0
     327: istore        4
     329: aload_3
     330: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     335: astore        5
     337: aload         5
     339: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     344: ifeq          375
     347: aload         5
     349: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     354: astore        6
     356: aload         6
     358: checkcast     #67                 // class java/util/List
     361: astore        7
     363: iconst_0
     364: istore        8
     366: aload         7
     368: invokestatic  #213                // Method main$sightAlongAndMark:(Ljava/util/List;)V
     371: nop
     372: goto          337
     375: nop
     376: aload_2
     377: checkcast     #78                 // class java/lang/Iterable
     380: astore_3
     381: iconst_0
     382: istore        4
     384: aload_3
     385: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     390: astore        5
     392: aload         5
     394: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     399: ifeq          436
     402: aload         5
     404: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     409: astore        6
     411: aload         6
     413: checkcast     #67                 // class java/util/List
     416: astore        7
     418: iconst_0
     419: istore        8
     421: aload         7
     423: checkcast     #78                 // class java/lang/Iterable
     426: invokestatic  #185                // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
     429: invokestatic  #213                // Method main$sightAlongAndMark:(Ljava/util/List;)V
     432: nop
     433: goto          392
     436: nop
     437: getstatic     #56                 // Field java/lang/System.out:Ljava/io/PrintStream;
     440: invokevirtual #215                // Method java/io/PrintStream.println:()V
     443: aload_1
     444: checkcast     #78                 // class java/lang/Iterable
     447: invokestatic  #218                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
     450: checkcast     #78                 // class java/lang/Iterable
     453: astore_3
     454: iconst_0
     455: istore        4
     457: aload_3
     458: instanceof    #152                // class java/util/Collection
     461: ifeq          480
     464: aload_3
     465: checkcast     #152                // class java/util/Collection
     468: invokeinterface #221,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     473: ifeq          480
     476: iconst_0
     477: goto          544
     480: iconst_0
     481: istore        5
     483: aload_3
     484: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     489: astore        6
     491: aload         6
     493: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     498: ifeq          542
     501: aload         6
     503: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     508: astore        7
     510: aload         7
     512: checkcast     #94                 // class Tree
     515: astore        8
     517: iconst_0
     518: istore        9
     520: aload         8
     522: invokevirtual #224                // Method Tree.isVisible:()Z
     525: ifeq          491
     528: iinc          5, 1
     531: iload         5
     533: ifge          491
     536: invokestatic  #227                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     539: goto          491
     542: iload         5
     544: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #78                 // class java/lang/Iterable
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: astore        4
      10: new           #144                // class java/util/ArrayList
      13: dup
      14: aload_2
      15: bipush        10
      17: invokestatic  #148                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      20: invokespecial #150                // Method java/util/ArrayList."<init>":(I)V
      23: checkcast     #152                // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          195
      50: aload         7
      52: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         5
      61: aload         8
      63: checkcast     #8                  // class java/lang/String
      66: astore        9
      68: astore        32
      70: iconst_0
      71: istore        10
      73: aload         9
      75: checkcast     #195                // class java/lang/CharSequence
      78: astore        11
      80: iconst_0
      81: istore        12
      83: aload         11
      85: astore        13
      87: new           #144                // class java/util/ArrayList
      90: dup
      91: aload         11
      93: invokeinterface #198,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      98: invokespecial #150                // Method java/util/ArrayList."<init>":(I)V
     101: checkcast     #152                // class java/util/Collection
     104: astore        14
     106: iconst_0
     107: istore        15
     109: iconst_0
     110: istore        16
     112: iload         16
     114: aload         13
     116: invokeinterface #198,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     121: if_icmpge     176
     124: aload         13
     126: iload         16
     128: invokeinterface #202,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     133: istore        17
     135: aload         14
     137: iload         17
     139: istore        18
     141: astore        19
     143: iconst_0
     144: istore        20
     146: new           #94                 // class Tree
     149: dup
     150: iload         18
     152: invokestatic  #208                // Method kotlin/text/CharsKt.digitToInt:(C)I
     155: iconst_0
     156: iconst_2
     157: aconst_null
     158: invokespecial #211                // Method Tree."<init>":(IZILkotlin/jvm/internal/DefaultConstructorMarker;)V
     161: aload         19
     163: swap
     164: invokeinterface #161,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     169: pop
     170: iinc          16, 1
     173: goto          112
     176: aload         14
     178: checkcast     #67                 // class java/util/List
     181: nop
     182: nop
     183: aload         32
     185: swap
     186: invokeinterface #161,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     191: pop
     192: goto          40
     195: aload         5
     197: checkcast     #67                 // class java/util/List
     200: nop
     201: astore_1
     202: aload_1
     203: checkcast     #78                 // class java/lang/Iterable
     206: astore_2
     207: iconst_0
     208: istore_3
     209: iconst_0
     210: istore        4
     212: aload_2
     213: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     218: astore        5
     220: aload         5
     222: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     227: ifeq          568
     230: aload         5
     232: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     237: astore        6
     239: iload         4
     241: iinc          4, 1
     244: istore        7
     246: iload         7
     248: ifge          254
     251: invokestatic  #246                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     254: iload         7
     256: aload         6
     258: checkcast     #67                 // class java/util/List
     261: astore        8
     263: istore        9
     265: iconst_0
     266: istore        10
     268: aload         8
     270: checkcast     #78                 // class java/lang/Iterable
     273: astore        11
     275: iconst_0
     276: istore        12
     278: iconst_0
     279: istore        13
     281: aload         11
     283: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     288: astore        14
     290: aload         14
     292: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     297: ifeq          562
     300: aload         14
     302: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     307: astore        15
     309: iload         13
     311: iinc          13, 1
     314: istore        16
     316: iload         16
     318: ifge          324
     321: invokestatic  #246                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     324: iload         16
     326: aload         15
     328: checkcast     #94                 // class Tree
     331: astore        17
     333: istore        18
     335: iconst_0
     336: istore        19
     338: aload_1
     339: iload         9
     341: iload         18
     343: invokestatic  #248                // Method main$getDirectionLists:(Ljava/util/List;II)Ljava/util/List;
     346: astore        20
     348: aload         17
     350: aload         20
     352: checkcast     #78                 // class java/lang/Iterable
     355: astore        21
     357: astore        22
     359: iconst_0
     360: istore        23
     362: aload         21
     364: astore        24
     366: new           #144                // class java/util/ArrayList
     369: dup
     370: aload         21
     372: bipush        10
     374: invokestatic  #148                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     377: invokespecial #150                // Method java/util/ArrayList."<init>":(I)V
     380: checkcast     #152                // class java/util/Collection
     383: astore        25
     385: iconst_0
     386: istore        26
     388: aload         24
     390: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     395: astore        27
     397: aload         27
     399: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     404: ifeq          450
     407: aload         27
     409: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     414: astore        28
     416: aload         25
     418: aload         28
     420: checkcast     #67                 // class java/util/List
     423: astore        29
     425: astore        30
     427: iconst_0
     428: istore        31
     430: aload         29
     432: invokestatic  #250                // Method main$getVisibleTrees:(Ljava/util/List;)I
     435: invokestatic  #256                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     438: aload         30
     440: swap
     441: invokeinterface #161,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     446: pop
     447: goto          397
     450: aload         25
     452: checkcast     #67                 // class java/util/List
     455: nop
     456: aload         22
     458: swap
     459: checkcast     #78                 // class java/lang/Iterable
     462: astore        21
     464: iconst_1
     465: invokestatic  #256                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     468: astore        23
     470: astore        22
     472: iconst_0
     473: istore        24
     475: aload         23
     477: astore        25
     479: aload         21
     481: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     486: astore        26
     488: aload         26
     490: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     495: ifeq          543
     498: aload         26
     500: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     505: astore        27
     507: aload         25
     509: aload         27
     511: checkcast     #258                // class java/lang/Number
     514: invokevirtual #261                // Method java/lang/Number.intValue:()I
     517: istore        28
     519: checkcast     #258                // class java/lang/Number
     522: invokevirtual #261                // Method java/lang/Number.intValue:()I
     525: istore        29
     527: iconst_0
     528: istore        31
     530: iload         28
     532: iload         29
     534: imul
     535: invokestatic  #256                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     538: astore        25
     540: goto          488
     543: aload         25
     545: aload         22
     547: swap
     548: checkcast     #258                // class java/lang/Number
     551: invokevirtual #261                // Method java/lang/Number.intValue:()I
     554: invokevirtual #264                // Method Tree.setScenicScore:(I)V
     557: nop
     558: nop
     559: goto          290
     562: nop
     563: nop
     564: nop
     565: goto          220
     568: nop
     569: getstatic     #56                 // Field java/lang/System.out:Ljava/io/PrintStream;
     572: invokevirtual #215                // Method java/io/PrintStream.println:()V
     575: aload_1
     576: checkcast     #78                 // class java/lang/Iterable
     579: invokestatic  #218                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
     582: checkcast     #78                 // class java/lang/Iterable
     585: invokeinterface #82,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     590: astore_3
     591: aload_3
     592: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     597: ifne          608
     600: new           #266                // class java/util/NoSuchElementException
     603: dup
     604: invokespecial #267                // Method java/util/NoSuchElementException."<init>":()V
     607: athrow
     608: aload_3
     609: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     614: checkcast     #94                 // class Tree
     617: astore        4
     619: iconst_0
     620: istore        5
     622: aload         4
     624: invokevirtual #270                // Method Tree.getScenicScore:()I
     627: istore        4
     629: aload_3
     630: invokeinterface #88,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     635: ifeq          673
     638: aload_3
     639: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     644: checkcast     #94                 // class Tree
     647: astore        5
     649: iconst_0
     650: istore        6
     652: aload         5
     654: invokevirtual #270                // Method Tree.getScenicScore:()I
     657: istore        5
     659: iload         4
     661: iload         5
     663: if_icmpge     629
     666: iload         5
     668: istore        4
     670: goto          629
     673: iload         4
     675: ireturn
}