import kotlin.math.max

class Rock(val cells: List<Point>, var shift: Point) {
    fun getCoords(): List<Point> {
        return cells.map { x -> x.sum(shift) }
    }

    fun hasCollision(points: Set<Point>, move: Point): Boolean {
        val newPosition = this.getCoords()
            .map { it.sum(move) }

        val hasBoundsCollision = newPosition.any { p -> p.x == -1 || p.y == -1 || p.x == 7 }
        if (hasBoundsCollision) {
            return true
        }

        val hasCollision = newPosition
            .intersect(points)
            .isNotEmpty()
        if (hasCollision) {
            return true
        }

        return false
    }

    companion object {
        fun create(index: Int, init: Point): Rock {
            return when (val number = index % 5) {
                // ####
                0 -> Rock(
                    listOf(
                        Point(0, 0),
                        Point(1, 0),
                        Point(2, 0),
                        Point(3, 0)
                    ),
                    init
                )
                // +
                1 -> Rock(
                    listOf(
                        Point(1, 0),
                        Point(0, 1),
                        Point(1, 1),
                        Point(2, 1),
                        Point(1, 2)
                    ),
                    init
                )
                // _|
                2 -> Rock(
                    listOf(
                        Point(0, 0),
                        Point(1, 0),
                        Point(2, 0),
                        Point(2, 1),
                        Point(2, 2)
                    ),
                    init
                )
                // |
                3 -> Rock(
                    listOf(
                        Point(0, 0),
                        Point(0, 1),
                        Point(0, 2),
                        Point(0, 3)
                    ),
                    init
                )
                // square
                4 -> Rock(
                    listOf(
                        Point(0, 0),
                        Point(1, 0),
                        Point(0, 1),
                        Point(1, 1)
                    ),
                    init
                )
                else -> throw RuntimeException("Unexpected $number")
            }
        }
    }
}

@Suppress("DuplicatedCode")
fun main() {
    data class State(
        val stoppedRocksCount: Long,
        val ground: Set<Point>,
        val maxY: Int
    )

    fun parse(input: List<String>): List<Direction> {
        return input[0].toCharArray().map { c -> if (c == '<') Direction.Left else Direction.Right }
    }

    fun print(rocks: List<Rock>) {
        val points = rocks.flatMap { r -> r.getCoords() }.toSet()
        val maxY = points.maxOf { c -> c.y }
        for (y in maxY downTo 0) {
            for (x in 0..6) {
                if (points.contains(Point(x, y))) {
                    print('#')
                } else {
                    print('.')
                }
            }
            println()
        }
        println()
        println()
    }

    fun calculateState(
        topLevelMap: MutableMap<Int, Int>,
        stopped: Long,
        maxY: Int
    ): State {
        val minY = topLevelMap.minOf { t -> t.value }
        val newGround = topLevelMap.map { t -> Point(t.key, (t.value - minY)) }.toSet()
        return State(stopped, newGround, maxY)
    }

    fun removeUnreachable(
        topLevelMap: MutableMap<Int, Int>,
        ground: MutableSet<Point>
    ) {
        val minLevel = topLevelMap.values.min()
        ground.removeIf { it.y < minLevel }
    }

    fun actualizeTopLevels(
        coords: List<Point>,
        topLevelMap: MutableMap<Int, Int>
    ) {
        for (coord in coords) {
            val top = topLevelMap[coord.x]
            if (top == null || top < coord.y) {
                topLevelMap[coord.x] = coord.y
            }
        }
    }

    fun play(directions: List<Direction>, rocksLimit: Long, initGround: Set<Point>): List<State> {
        var directionIterator = 0
        var rockIterator = 0
        var shift = Point(2, 3)
        val ground = initGround.toMutableSet()
        var stopped = 0L
        val topLevelMap = mutableMapOf<Int, Int>()
        var activeRock: Rock? = null
        var maxY = 0

        val states = mutableListOf<State>()

        val dy = Point(0, -1)
        while (stopped < rocksLimit) {
            if (activeRock == null) {
                activeRock = Rock.create(rockIterator, shift)
                ++rockIterator
            }
            val direction = directions[directionIterator]
            val dx = if (direction == Direction.Left) Point(-1, 0) else Point(1, 0)

            if (!activeRock.hasCollision(ground, dx)) {
                activeRock.shift = activeRock.shift.sum(dx)
            }

            if (!activeRock.hasCollision(ground, dy)) {
                activeRock.shift = activeRock.shift.sum(dy)
            } else {
                ++stopped
                val coords = activeRock.getCoords()
                actualizeTopLevels(coords, topLevelMap)
                ground.addAll(coords)
                removeUnreachable(topLevelMap, ground)

                maxY = max(maxY, topLevelMap.values.max() + 1)
                shift = Point(shift.x, maxY + 3)

                activeRock = null
            }

            directionIterator = (directionIterator + 1) % directions.size

            if (directionIterator == 0) {
                states.add(calculateState(topLevelMap, stopped, maxY))
                if (states.size > 1) {
                    break
                }
            }
        }

        if (states.size <= 1) {
            states.add(calculateState(topLevelMap, stopped, maxY))
        }

        return states
    }

    fun findMax(directions: List<Direction>, totalRocks: Long): Long {
        val defaultGround = (0..6).map { Point(it, -1) }.toSet()

        val states = play(directions, totalRocks, defaultGround).reversed()
        val lastRocksCount = states[0].stoppedRocksCount
        val maxY = states[0].maxY
        val leftRocks = totalRocks - lastRocksCount
        if (leftRocks == 0L) {
            return maxY.toLong()
        }

        val deltaRocks = lastRocksCount - states[1].stoppedRocksCount
        val deltaY = states[0].maxY - states[1].maxY

        val mult = leftRocks / deltaRocks
        val sliceY = deltaY * mult
        val restRocks = leftRocks % deltaRocks

        val (_, _, maxY1) = play(
            directions,
            restRocks,
            states[0].ground
        )[0]

        return maxY + sliceY + maxY1 - 1
    }

    fun part1(input: List<String>): Long {
        return findMax(parse(input), 2022L)
    }

    fun part2(input: List<String>): Long {
        return findMax(parse(input), 1000000000000L)
    }

// ==================================================================== //

    val day = "17"

    fun test() {
        val testInput = readInput("Day${day}_test")
        assert(part1(testInput), 3068L)
        assert(part2(testInput), 1514285714288L)
    }

    fun run() {
        val input = readInput("Day$day")
        println(part1(input))
        println(part2(input))
    }

    // test()
    run()
}

Compiled from "Day17.kt"
public final class Day17Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String 17
       2: astore_0
       3: aload_0
       4: invokestatic  #12                 // Method main$run:(Ljava/lang/String;)V
       7: return

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

  private static final java.util.List<Direction> main$parse(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: iconst_0
       2: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
       7: checkcast     #30                 // class java/lang/String
      10: invokevirtual #34                 // Method java/lang/String.toCharArray:()[C
      13: dup
      14: ldc           #36                 // String toCharArray(...)
      16: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      19: astore_1
      20: nop
      21: iconst_0
      22: istore_2
      23: aload_1
      24: astore_3
      25: new           #44                 // class java/util/ArrayList
      28: dup
      29: aload_1
      30: arraylength
      31: invokespecial #48                 // Method java/util/ArrayList."<init>":(I)V
      34: checkcast     #50                 // class java/util/Collection
      37: astore        4
      39: iconst_0
      40: istore        5
      42: iconst_0
      43: istore        6
      45: aload_3
      46: arraylength
      47: istore        7
      49: iload         6
      51: iload         7
      53: if_icmpge     104
      56: aload_3
      57: iload         6
      59: caload
      60: istore        8
      62: aload         4
      64: iload         8
      66: istore        9
      68: astore        11
      70: iconst_0
      71: istore        10
      73: iload         9
      75: bipush        60
      77: if_icmpne     86
      80: getstatic     #56                 // Field Direction.Left:LDirection;
      83: goto          89
      86: getstatic     #59                 // Field Direction.Right:LDirection;
      89: aload         11
      91: swap
      92: invokeinterface #63,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      97: pop
      98: iinc          6, 1
     101: goto          49
     104: aload         4
     106: checkcast     #24                 // class java/util/List
     109: nop
     110: areturn

  private static final void main$print(java.util.List<Rock>);
    Code:
       0: aload_0
       1: checkcast     #83                 // class java/lang/Iterable
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: astore        4
      10: new           #44                 // class java/util/ArrayList
      13: dup
      14: invokespecial #85                 // Method java/util/ArrayList."<init>":()V
      17: checkcast     #50                 // class java/util/Collection
      20: astore        5
      22: iconst_0
      23: istore        6
      25: aload         4
      27: invokeinterface #89,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      32: astore        7
      34: aload         7
      36: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      41: ifeq          84
      44: aload         7
      46: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      51: astore        8
      53: aload         8
      55: checkcast     #101                // class Rock
      58: astore        9
      60: iconst_0
      61: istore        10
      63: aload         9
      65: invokevirtual #105                // Method Rock.getCoords:()Ljava/util/List;
      68: checkcast     #83                 // class java/lang/Iterable
      71: astore        9
      73: aload         5
      75: aload         9
      77: invokestatic  #111                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
      80: pop
      81: goto          34
      84: aload         5
      86: checkcast     #24                 // class java/util/List
      89: nop
      90: checkcast     #83                 // class java/lang/Iterable
      93: invokestatic  #115                // Method kotlin/collections/CollectionsKt.toSet:(Ljava/lang/Iterable;)Ljava/util/Set;
      96: astore_1
      97: aload_1
      98: checkcast     #83                 // class java/lang/Iterable
     101: invokeinterface #89,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     106: astore        4
     108: aload         4
     110: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     115: ifne          126
     118: new           #117                // class java/util/NoSuchElementException
     121: dup
     122: invokespecial #118                // Method java/util/NoSuchElementException."<init>":()V
     125: athrow
     126: aload         4
     128: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     133: checkcast     #120                // class Point
     136: astore        5
     138: iconst_0
     139: istore        6
     141: aload         5
     143: invokevirtual #124                // Method Point.getY:()I
     146: istore        5
     148: aload         4
     150: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     155: ifeq          194
     158: aload         4
     160: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     165: checkcast     #120                // class Point
     168: astore        6
     170: iconst_0
     171: istore        7
     173: aload         6
     175: invokevirtual #124                // Method Point.getY:()I
     178: istore        6
     180: iload         5
     182: iload         6
     184: if_icmpge     148
     187: iload         6
     189: istore        5
     191: goto          148
     194: iload         5
     196: istore_2
     197: iload_2
     198: istore_3
     199: iconst_m1
     200: iload_3
     201: if_icmpge     278
     204: iconst_0
     205: istore        4
     207: iload         4
     209: bipush        7
     211: if_icmpge     266
     214: aload_1
     215: new           #120                // class Point
     218: dup
     219: iload         4
     221: iload_3
     222: invokespecial #127                // Method Point."<init>":(II)V
     225: invokeinterface #132,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     230: ifeq          248
     233: bipush        35
     235: istore        5
     237: getstatic     #138                // Field java/lang/System.out:Ljava/io/PrintStream;
     240: iload         5
     242: invokevirtual #144                // Method java/io/PrintStream.print:(C)V
     245: goto          260
     248: bipush        46
     250: istore        5
     252: getstatic     #138                // Field java/lang/System.out:Ljava/io/PrintStream;
     255: iload         5
     257: invokevirtual #144                // Method java/io/PrintStream.print:(C)V
     260: iinc          4, 1
     263: goto          207
     266: getstatic     #138                // Field java/lang/System.out:Ljava/io/PrintStream;
     269: invokevirtual #147                // Method java/io/PrintStream.println:()V
     272: iinc          3, -1
     275: goto          199
     278: getstatic     #138                // Field java/lang/System.out:Ljava/io/PrintStream;
     281: invokevirtual #147                // Method java/io/PrintStream.println:()V
     284: getstatic     #138                // Field java/lang/System.out:Ljava/io/PrintStream;
     287: invokevirtual #147                // Method java/io/PrintStream.println:()V
     290: return

  private static final Day17Kt$main$State main$calculateState(java.util.Map<java.lang.Integer, java.lang.Integer>, long, int);
    Code:
       0: aload_0
       1: invokeinterface #175,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
       6: checkcast     #83                 // class java/lang/Iterable
       9: invokeinterface #89,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      14: astore        6
      16: aload         6
      18: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      23: ifne          34
      26: new           #117                // class java/util/NoSuchElementException
      29: dup
      30: invokespecial #118                // Method java/util/NoSuchElementException."<init>":()V
      33: athrow
      34: aload         6
      36: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      41: checkcast     #177                // class java/util/Map$Entry
      44: astore        7
      46: iconst_0
      47: istore        8
      49: aload         7
      51: invokeinterface #180,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      56: checkcast     #182                // class java/lang/Number
      59: invokevirtual #185                // Method java/lang/Number.intValue:()I
      62: istore        7
      64: aload         6
      66: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      71: ifeq          118
      74: aload         6
      76: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      81: checkcast     #177                // class java/util/Map$Entry
      84: astore        8
      86: iconst_0
      87: istore        9
      89: aload         8
      91: invokeinterface #180,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      96: checkcast     #182                // class java/lang/Number
      99: invokevirtual #185                // Method java/lang/Number.intValue:()I
     102: istore        8
     104: iload         7
     106: iload         8
     108: if_icmple     64
     111: iload         8
     113: istore        7
     115: goto          64
     118: iload         7
     120: istore        4
     122: aload_0
     123: astore        6
     125: iconst_0
     126: istore        7
     128: aload         6
     130: astore        8
     132: new           #44                 // class java/util/ArrayList
     135: dup
     136: aload         6
     138: invokeinterface #188,  1          // InterfaceMethod java/util/Map.size:()I
     143: invokespecial #48                 // Method java/util/ArrayList."<init>":(I)V
     146: checkcast     #50                 // class java/util/Collection
     149: astore        9
     151: iconst_0
     152: istore        10
     154: aload         8
     156: invokeinterface #175,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     161: invokeinterface #189,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
     166: astore        11
     168: aload         11
     170: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     175: ifeq          249
     178: aload         11
     180: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     185: checkcast     #177                // class java/util/Map$Entry
     188: astore        12
     190: aload         9
     192: aload         12
     194: astore        13
     196: astore        15
     198: iconst_0
     199: istore        14
     201: new           #120                // class Point
     204: dup
     205: aload         13
     207: invokeinterface #192,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     212: checkcast     #182                // class java/lang/Number
     215: invokevirtual #185                // Method java/lang/Number.intValue:()I
     218: aload         13
     220: invokeinterface #180,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     225: checkcast     #182                // class java/lang/Number
     228: invokevirtual #185                // Method java/lang/Number.intValue:()I
     231: iload         4
     233: isub
     234: invokespecial #127                // Method Point."<init>":(II)V
     237: aload         15
     239: swap
     240: invokeinterface #63,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     245: pop
     246: goto          168
     249: aload         9
     251: checkcast     #24                 // class java/util/List
     254: nop
     255: checkcast     #83                 // class java/lang/Iterable
     258: invokestatic  #115                // Method kotlin/collections/CollectionsKt.toSet:(Ljava/lang/Iterable;)Ljava/util/Set;
     261: astore        5
     263: new           #194                // class Day17Kt$main$State
     266: dup
     267: lload_1
     268: aload         5
     270: iload_3
     271: invokespecial #197                // Method Day17Kt$main$State."<init>":(JLjava/util/Set;I)V
     274: areturn

  private static final boolean main$removeUnreachable$lambda$5(int, Point);
    Code:
       0: aload_1
       1: ldc           #211                // String it
       3: invokestatic  #214                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokevirtual #124                // Method Point.getY:()I
      10: iload_0
      11: if_icmpge     18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: ireturn

  private static final boolean main$removeUnreachable$lambda$6(kotlin.jvm.functions.Function1, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: invokeinterface #223,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
       7: checkcast     #225                // class java/lang/Boolean
      10: invokevirtual #228                // Method java/lang/Boolean.booleanValue:()Z
      13: ireturn

  private static final void main$removeUnreachable(java.util.Map<java.lang.Integer, java.lang.Integer>, java.util.Set<Point>);
    Code:
       0: aload_0
       1: invokeinterface #238,  1          // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
       6: checkcast     #83                 // class java/lang/Iterable
       9: invokestatic  #242                // Method kotlin/collections/CollectionsKt.minOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
      12: checkcast     #182                // class java/lang/Number
      15: invokevirtual #185                // Method java/lang/Number.intValue:()I
      18: istore_2
      19: aload_1
      20: iload_2
      21: invokedynamic #258,  0            // InvokeDynamic #0:invoke:(I)Lkotlin/jvm/functions/Function1;
      26: invokedynamic #266,  0            // InvokeDynamic #1:test:(Lkotlin/jvm/functions/Function1;)Ljava/util/function/Predicate;
      31: invokeinterface #270,  2          // InterfaceMethod java/util/Set.removeIf:(Ljava/util/function/Predicate;)Z
      36: pop
      37: return

  private static final void main$actualizeTopLevels(java.util.List<Point>, java.util.Map<java.lang.Integer, java.lang.Integer>);
    Code:
       0: aload_0
       1: invokeinterface #276,  1          // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
       6: astore_2
       7: aload_2
       8: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      13: ifeq          85
      16: aload_2
      17: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      22: checkcast     #120                // class Point
      25: astore_3
      26: aload_1
      27: aload_3
      28: invokevirtual #279                // Method Point.getX:()I
      31: invokestatic  #285                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      34: invokeinterface #287,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      39: checkcast     #281                // class java/lang/Integer
      42: astore        4
      44: aload         4
      46: ifnull        61
      49: aload         4
      51: invokevirtual #288                // Method java/lang/Integer.intValue:()I
      54: aload_3
      55: invokevirtual #124                // Method Point.getY:()I
      58: if_icmpge     7
      61: aload_1
      62: aload_3
      63: invokevirtual #279                // Method Point.getX:()I
      66: invokestatic  #285                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      69: aload_3
      70: invokevirtual #124                // Method Point.getY:()I
      73: invokestatic  #285                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      76: invokeinterface #292,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      81: pop
      82: goto          7
      85: return

  private static final java.util.List<Day17Kt$main$State> main$play(java.util.List<? extends Direction>, long, java.util.Set<Point>);
    Code:
       0: iconst_0
       1: istore        4
       3: iconst_0
       4: istore        5
       6: new           #120                // class Point
       9: dup
      10: iconst_2
      11: iconst_3
      12: invokespecial #127                // Method Point."<init>":(II)V
      15: astore        6
      17: aload_3
      18: checkcast     #83                 // class java/lang/Iterable
      21: invokestatic  #302                // Method kotlin/collections/CollectionsKt.toMutableSet:(Ljava/lang/Iterable;)Ljava/util/Set;
      24: astore        7
      26: lconst_0
      27: lstore        8
      29: new           #304                // class java/util/LinkedHashMap
      32: dup
      33: invokespecial #305                // Method java/util/LinkedHashMap."<init>":()V
      36: checkcast     #171                // class java/util/Map
      39: astore        10
      41: aconst_null
      42: astore        11
      44: iconst_0
      45: istore        12
      47: new           #44                 // class java/util/ArrayList
      50: dup
      51: invokespecial #85                 // Method java/util/ArrayList."<init>":()V
      54: checkcast     #24                 // class java/util/List
      57: astore        13
      59: new           #120                // class Point
      62: dup
      63: iconst_0
      64: iconst_m1
      65: invokespecial #127                // Method Point."<init>":(II)V
      68: astore        14
      70: lload         8
      72: lload_1
      73: lcmp
      74: ifge          336
      77: aload         11
      79: ifnonnull     97
      82: getstatic     #309                // Field Rock.Companion:LRock$Companion;
      85: iload         5
      87: aload         6
      89: invokevirtual #315                // Method Rock$Companion.create:(ILPoint;)LRock;
      92: astore        11
      94: iinc          5, 1
      97: aload_0
      98: iload         4
     100: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     105: checkcast     #52                 // class Direction
     108: astore        15
     110: aload         15
     112: getstatic     #56                 // Field Direction.Left:LDirection;
     115: if_acmpne     130
     118: new           #120                // class Point
     121: dup
     122: iconst_m1
     123: iconst_0
     124: invokespecial #127                // Method Point."<init>":(II)V
     127: goto          139
     130: new           #120                // class Point
     133: dup
     134: iconst_1
     135: iconst_0
     136: invokespecial #127                // Method Point."<init>":(II)V
     139: astore        16
     141: aload         11
     143: aload         7
     145: aload         16
     147: invokevirtual #319                // Method Rock.hasCollision:(Ljava/util/Set;LPoint;)Z
     150: ifne          168
     153: aload         11
     155: aload         11
     157: invokevirtual #323                // Method Rock.getShift:()LPoint;
     160: aload         16
     162: invokevirtual #327                // Method Point.sum:(LPoint;)LPoint;
     165: invokevirtual #331                // Method Rock.setShift:(LPoint;)V
     168: aload         11
     170: aload         7
     172: aload         14
     174: invokevirtual #319                // Method Rock.hasCollision:(Ljava/util/Set;LPoint;)Z
     177: ifne          198
     180: aload         11
     182: aload         11
     184: invokevirtual #323                // Method Rock.getShift:()LPoint;
     187: aload         14
     189: invokevirtual #327                // Method Point.sum:(LPoint;)LPoint;
     192: invokevirtual #331                // Method Rock.setShift:(LPoint;)V
     195: goto          287
     198: lload         8
     200: lconst_1
     201: ladd
     202: lstore        8
     204: aload         11
     206: invokevirtual #105                // Method Rock.getCoords:()Ljava/util/List;
     209: astore        17
     211: aload         17
     213: aload         10
     215: invokestatic  #333                // Method main$actualizeTopLevels:(Ljava/util/List;Ljava/util/Map;)V
     218: aload         7
     220: aload         17
     222: checkcast     #50                 // class java/util/Collection
     225: invokeinterface #336,  2          // InterfaceMethod java/util/Set.addAll:(Ljava/util/Collection;)Z
     230: pop
     231: aload         10
     233: aload         7
     235: invokestatic  #338                // Method main$removeUnreachable:(Ljava/util/Map;Ljava/util/Set;)V
     238: iload         12
     240: aload         10
     242: invokeinterface #238,  1          // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
     247: checkcast     #83                 // class java/lang/Iterable
     250: invokestatic  #341                // Method kotlin/collections/CollectionsKt.maxOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
     253: checkcast     #182                // class java/lang/Number
     256: invokevirtual #185                // Method java/lang/Number.intValue:()I
     259: iconst_1
     260: iadd
     261: invokestatic  #347                // Method java/lang/Math.max:(II)I
     264: istore        12
     266: new           #120                // class Point
     269: dup
     270: aload         6
     272: invokevirtual #279                // Method Point.getX:()I
     275: iload         12
     277: iconst_3
     278: iadd
     279: invokespecial #127                // Method Point."<init>":(II)V
     282: astore        6
     284: aconst_null
     285: astore        11
     287: iload         4
     289: iconst_1
     290: iadd
     291: aload_0
     292: invokeinterface #348,  1          // InterfaceMethod java/util/List.size:()I
     297: irem
     298: istore        4
     300: iload         4
     302: ifne          70
     305: aload         13
     307: aload         10
     309: lload         8
     311: iload         12
     313: invokestatic  #350                // Method main$calculateState:(Ljava/util/Map;JI)LDay17Kt$main$State;
     316: invokeinterface #351,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     321: pop
     322: aload         13
     324: invokeinterface #348,  1          // InterfaceMethod java/util/List.size:()I
     329: iconst_1
     330: if_icmple     70
     333: goto          336
     336: aload         13
     338: invokeinterface #348,  1          // InterfaceMethod java/util/List.size:()I
     343: iconst_1
     344: if_icmpgt     364
     347: aload         13
     349: aload         10
     351: lload         8
     353: iload         12
     355: invokestatic  #350                // Method main$calculateState:(Ljava/util/Map;JI)LDay17Kt$main$State;
     358: invokeinterface #351,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     363: pop
     364: aload         13
     366: areturn

  private static final long main$findMax(java.util.List<? extends Direction>, long);
    Code:
       0: new           #367                // class kotlin/ranges/IntRange
       3: dup
       4: iconst_0
       5: bipush        6
       7: invokespecial #368                // Method kotlin/ranges/IntRange."<init>":(II)V
      10: checkcast     #83                 // class java/lang/Iterable
      13: astore        4
      15: iconst_0
      16: istore        5
      18: aload         4
      20: astore        6
      22: new           #44                 // class java/util/ArrayList
      25: dup
      26: aload         4
      28: bipush        10
      30: invokestatic  #372                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      33: invokespecial #48                 // Method java/util/ArrayList."<init>":(I)V
      36: checkcast     #50                 // class java/util/Collection
      39: astore        7
      41: iconst_0
      42: istore        8
      44: aload         6
      46: invokeinterface #89,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      51: astore        9
      53: aload         9
      55: invokeinterface #95,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      60: ifeq          106
      63: aload         9
      65: checkcast     #374                // class kotlin/collections/IntIterator
      68: invokevirtual #377                // Method kotlin/collections/IntIterator.nextInt:()I
      71: istore        10
      73: aload         7
      75: iload         10
      77: istore        11
      79: astore        20
      81: iconst_0
      82: istore        12
      84: new           #120                // class Point
      87: dup
      88: iload         11
      90: iconst_m1
      91: invokespecial #127                // Method Point."<init>":(II)V
      94: aload         20
      96: swap
      97: invokeinterface #63,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     102: pop
     103: goto          53
     106: aload         7
     108: checkcast     #24                 // class java/util/List
     111: nop
     112: checkcast     #83                 // class java/lang/Iterable
     115: invokestatic  #115                // Method kotlin/collections/CollectionsKt.toSet:(Ljava/lang/Iterable;)Ljava/util/Set;
     118: astore_3
     119: aload_0
     120: lload_1
     121: aload_3
     122: invokestatic  #379                // Method main$play:(Ljava/util/List;JLjava/util/Set;)Ljava/util/List;
     125: checkcast     #83                 // class java/lang/Iterable
     128: invokestatic  #383                // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
     131: astore        4
     133: aload         4
     135: iconst_0
     136: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     141: checkcast     #194                // class Day17Kt$main$State
     144: invokevirtual #387                // Method Day17Kt$main$State.getStoppedRocksCount:()J
     147: lstore        5
     149: aload         4
     151: iconst_0
     152: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     157: checkcast     #194                // class Day17Kt$main$State
     160: invokevirtual #390                // Method Day17Kt$main$State.getMaxY:()I
     163: istore        7
     165: lload_1
     166: lload         5
     168: lsub
     169: lstore        8
     171: lload         8
     173: lconst_0
     174: lcmp
     175: ifne          182
     178: iload         7
     180: i2l
     181: lreturn
     182: lload         5
     184: aload         4
     186: iconst_1
     187: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     192: checkcast     #194                // class Day17Kt$main$State
     195: invokevirtual #387                // Method Day17Kt$main$State.getStoppedRocksCount:()J
     198: lsub
     199: lstore        10
     201: aload         4
     203: iconst_0
     204: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     209: checkcast     #194                // class Day17Kt$main$State
     212: invokevirtual #390                // Method Day17Kt$main$State.getMaxY:()I
     215: aload         4
     217: iconst_1
     218: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     223: checkcast     #194                // class Day17Kt$main$State
     226: invokevirtual #390                // Method Day17Kt$main$State.getMaxY:()I
     229: isub
     230: istore        12
     232: lload         8
     234: lload         10
     236: ldiv
     237: lstore        13
     239: iload         12
     241: i2l
     242: lload         13
     244: lmul
     245: lstore        15
     247: lload         8
     249: lload         10
     251: lrem
     252: lstore        17
     254: aload_0
     255: lload         17
     257: aload         4
     259: iconst_0
     260: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     265: checkcast     #194                // class Day17Kt$main$State
     268: invokevirtual #393                // Method Day17Kt$main$State.getGround:()Ljava/util/Set;
     271: invokestatic  #379                // Method main$play:(Ljava/util/List;JLjava/util/Set;)Ljava/util/List;
     274: iconst_0
     275: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     280: checkcast     #194                // class Day17Kt$main$State
     283: invokevirtual #396                // Method Day17Kt$main$State.component3:()I
     286: istore        19
     288: iload         7
     290: i2l
     291: lload         15
     293: ladd
     294: iload         19
     296: i2l
     297: ladd
     298: lconst_1
     299: lsub
     300: lreturn

  private static final long main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #412                // Method main$parse:(Ljava/util/List;)Ljava/util/List;
       4: ldc2_w        #413                // long 2022l
       7: invokestatic  #416                // Method main$findMax:(Ljava/util/List;J)J
      10: lreturn

  private static final long main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #412                // Method main$parse:(Ljava/util/List;)Ljava/util/List;
       4: ldc2_w        #418                // long 1000000000000l
       7: invokestatic  #416                // Method main$findMax:(Ljava/util/List;J)J
      10: lreturn

  private static final void main$test(java.lang.String);
    Code:
       0: new           #422                // class java/lang/StringBuilder
       3: dup
       4: invokespecial #423                // Method java/lang/StringBuilder."<init>":()V
       7: ldc_w         #425                // String Day
      10: invokevirtual #429                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      13: aload_0
      14: invokevirtual #429                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      17: ldc_w         #431                // String _test
      20: invokevirtual #429                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      23: invokevirtual #435                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      26: invokestatic  #441                // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      29: astore_1
      30: aload_1
      31: invokestatic  #443                // Method main$part1:(Ljava/util/List;)J
      34: invokestatic  #448                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      37: ldc2_w        #449                // long 3068l
      40: invokestatic  #448                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      43: invokestatic  #454                // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      46: aload_1
      47: invokestatic  #456                // Method main$part2:(Ljava/util/List;)J
      50: invokestatic  #448                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      53: ldc2_w        #457                // long 1514285714288l
      56: invokestatic  #448                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      59: invokestatic  #454                // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      62: return

  private static final void main$run(java.lang.String);
    Code:
       0: new           #422                // class java/lang/StringBuilder
       3: dup
       4: invokespecial #423                // Method java/lang/StringBuilder."<init>":()V
       7: ldc_w         #425                // String Day
      10: invokevirtual #429                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      13: aload_0
      14: invokevirtual #429                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      17: invokevirtual #435                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      20: invokestatic  #441                // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      23: astore_1
      24: aload_1
      25: invokestatic  #443                // Method main$part1:(Ljava/util/List;)J
      28: lstore_2
      29: getstatic     #138                // Field java/lang/System.out:Ljava/io/PrintStream;
      32: lload_2
      33: invokevirtual #462                // Method java/io/PrintStream.println:(J)V
      36: aload_1
      37: invokestatic  #456                // Method main$part2:(Ljava/util/List;)J
      40: lstore_2
      41: getstatic     #138                // Field java/lang/System.out:Ljava/io/PrintStream;
      44: lload_2
      45: invokevirtual #462                // Method java/io/PrintStream.println:(J)V
      48: return
}

Compiled from "Day17.kt"
public final class Day17Kt$main$State {
  private final long stoppedRocksCount;

  private final java.util.Set<Point> ground;

  private final int maxY;

  public Day17Kt$main$State(long, java.util.Set<Point>, int);
    Code:
       0: aload_3
       1: ldc           #9                  // String ground
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #18                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: lload_1
      12: putfield      #22                 // Field stoppedRocksCount:J
      15: aload_0
      16: aload_3
      17: putfield      #25                 // Field ground:Ljava/util/Set;
      20: aload_0
      21: iload         4
      23: putfield      #29                 // Field maxY:I
      26: return

  public final long getStoppedRocksCount();
    Code:
       0: aload_0
       1: getfield      #22                 // Field stoppedRocksCount:J
       4: lreturn

  public final java.util.Set<Point> getGround();
    Code:
       0: aload_0
       1: getfield      #25                 // Field ground:Ljava/util/Set;
       4: areturn

  public final int getMaxY();
    Code:
       0: aload_0
       1: getfield      #29                 // Field maxY:I
       4: ireturn

  public final long component1();
    Code:
       0: aload_0
       1: getfield      #22                 // Field stoppedRocksCount:J
       4: lreturn

  public final java.util.Set<Point> component2();
    Code:
       0: aload_0
       1: getfield      #25                 // Field ground:Ljava/util/Set;
       4: areturn

  public final int component3();
    Code:
       0: aload_0
       1: getfield      #29                 // Field maxY:I
       4: ireturn

  public final Day17Kt$main$State copy(long, java.util.Set<Point>, int);
    Code:
       0: aload_3
       1: ldc           #9                  // String ground
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #2                  // class Day17Kt$main$State
       9: dup
      10: lload_1
      11: aload_3
      12: iload         4
      14: invokespecial #46                 // Method "<init>":(JLjava/util/Set;I)V
      17: areturn

  public static Day17Kt$main$State copy$default(Day17Kt$main$State, long, java.util.Set, int, int, java.lang.Object);
    Code:
       0: iload         5
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #22                 // Field stoppedRocksCount:J
      11: lstore_1
      12: iload         5
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #25                 // Field ground:Ljava/util/Set;
      23: astore_3
      24: iload         5
      26: iconst_4
      27: iand
      28: ifeq          37
      31: aload_0
      32: getfield      #29                 // Field maxY:I
      35: istore        4
      37: aload_0
      38: lload_1
      39: aload_3
      40: iload         4
      42: invokevirtual #50                 // Method copy:(JLjava/util/Set;I)LDay17Kt$main$State;
      45: areturn

  public java.lang.String toString();
    Code:
       0: new           #54                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #55                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #57                 // String State(stoppedRocksCount=
       9: invokevirtual #61                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #22                 // Field stoppedRocksCount:J
      16: invokevirtual #64                 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      19: ldc           #66                 // String , ground=
      21: invokevirtual #61                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #25                 // Field ground:Ljava/util/Set;
      28: invokevirtual #69                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      31: ldc           #71                 // String , maxY=
      33: invokevirtual #61                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      36: aload_0
      37: getfield      #29                 // Field maxY:I
      40: invokevirtual #74                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      43: bipush        41
      45: invokevirtual #77                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      48: invokevirtual #79                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      51: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #22                 // Field stoppedRocksCount:J
       4: invokestatic  #85                 // Method java/lang/Long.hashCode:(J)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #25                 // Field ground:Ljava/util/Set;
      16: invokevirtual #87                 // Method java/lang/Object.hashCode:()I
      19: iadd
      20: istore_1
      21: iload_1
      22: bipush        31
      24: imul
      25: aload_0
      26: getfield      #29                 // Field maxY:I
      29: invokestatic  #92                 // Method java/lang/Integer.hashCode:(I)I
      32: iadd
      33: istore_1
      34: iload_1
      35: 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 Day17Kt$main$State
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class Day17Kt$main$State
      20: astore_2
      21: aload_0
      22: getfield      #22                 // Field stoppedRocksCount:J
      25: aload_2
      26: getfield      #22                 // Field stoppedRocksCount:J
      29: lcmp
      30: ifeq          35
      33: iconst_0
      34: ireturn
      35: aload_0
      36: getfield      #25                 // Field ground:Ljava/util/Set;
      39: aload_2
      40: getfield      #25                 // Field ground:Ljava/util/Set;
      43: invokestatic  #99                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      46: ifne          51
      49: iconst_0
      50: ireturn
      51: aload_0
      52: getfield      #29                 // Field maxY:I
      55: aload_2
      56: getfield      #29                 // Field maxY:I
      59: if_icmpeq     64
      62: iconst_0
      63: ireturn
      64: iconst_1
      65: ireturn
}


import java.math.BigInteger

enum class NodeType { File, Dir }
class Node(val parent: Node?, val children: MutableMap<String, Node>, val alias: String, val size: BigInteger?, val type: NodeType) {
    var totalSize = BigInteger.ZERO

    fun getRoot(): Node {
        var currentNode = this
        while (currentNode.parent != null) {
            currentNode = currentNode.parent!!
        }

        return currentNode
    }

    fun calculateTotalSize(): BigInteger {
        if (type == NodeType.File) {
            totalSize = size!!
            return totalSize
        }

        totalSize = children.values.sumOf { it.calculateTotalSize() }
        return totalSize
    }

    fun sumBy(threshold: BigInteger): BigInteger {
        var result = BigInteger.ZERO

        if (type == NodeType.Dir && totalSize <= threshold) {
            result += totalSize
        }

        return result + children.values.sumOf { it.sumBy(threshold) }
    }

    fun printNode() {
        printNode(0)
    }

    fun printNode(indentLevel: Int) {
        val indent = (0..indentLevel).map { ' ' }.joinToString("")
        val typeMsg = if (type == NodeType.Dir) "dir" else "file, size=$size"
        println("$indent- $alias ($typeMsg)")
        children.values.forEach { it.printNode(indentLevel + 2) }
    }

    fun getDirSizes(): List<BigInteger> {
        val result = mutableListOf(totalSize)
        result.addAll(children.values.flatMap { it.getDirSizes() })
        return result
    }
}

fun main() {
    fun ensureDirExists(node: Node, alias: String) {
        if (node.children[alias] == null) {
            node.children[alias] = Node(node, mutableMapOf(), alias, null, NodeType.Dir)
        }
    }

    fun ensureFileExists(node: Node, alias: String, size: BigInteger) {
        if (node.children[alias] == null) {
            node.children[alias] = Node(node, mutableMapOf(), alias, size, NodeType.File)
        }
    }

    fun parse(input: List<String>): Node {
        val root = Node(null, mutableMapOf(), "/", null, NodeType.Dir)
        var pointer = root
        var lineIdx = 0
        val totalSize = input.size
        while (lineIdx < totalSize) {
            val line = input[lineIdx]

            println("Command: $line")
            if (line == "$ cd /") {
                pointer = pointer.getRoot()
                ++lineIdx
            } else if (line == "$ cd ..") {
                pointer = pointer.parent!!
                ++lineIdx
            } else if (line.startsWith("$ cd")) {
                val dirAlias = line.split(' ')[2]
                ensureDirExists(pointer, dirAlias)
                pointer = pointer.children[dirAlias]!!
                ++lineIdx
            } else if (line == "$ ls") {
                var listIdx = lineIdx + 1
                while (listIdx < totalSize && !input[listIdx].startsWith("$")) {
                    val node = input[listIdx]
                    if (node.startsWith("dir")) {
                        val dirAlias = node.split(' ')[1]
                        ensureDirExists(pointer, dirAlias)
                    } else {
                        val parts = node.split(' ')
                        val size = parts[0].toBigInteger()
                        val fileAlias = parts[1]
                        ensureFileExists(pointer, fileAlias, size)
                    }

                    ++listIdx
                }

                lineIdx = listIdx
            } else {
                println("Unexpected line: $line")
                return root
            }

            println("Root")
            root.printNode()
            println()
        }

        return root
    }

    fun part1(input: List<String>): BigInteger {
        val root = parse(input)
        root.calculateTotalSize()
        return root.sumBy(BigInteger.valueOf(100000))
    }

    fun part2(input: List<String>): BigInteger {
        val root = parse(input)
        root.calculateTotalSize()
        val threshold = root.totalSize - BigInteger.valueOf(40000000)

        return root.getDirSizes().filter { it >= threshold }.min()
    }

    val testInput = readInput("Day07_test")
    assert(part1(testInput), BigInteger.valueOf(95437L))

    val input = readInput("Day07")
    println(part1(input))
    println(part2(input))
}

Compiled from "Day07.kt"
public final class Day07Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Day07_test
       2: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)Ljava/math/BigInteger;
      10: ldc2_w        #19                 // long 95437l
      13: invokestatic  #26                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      16: invokestatic  #30                 // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      19: ldc           #32                 // String Day07
      21: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      24: astore_1
      25: aload_1
      26: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)Ljava/math/BigInteger;
      29: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
      32: swap
      33: invokevirtual #44                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      36: aload_1
      37: invokestatic  #47                 // Method main$part2:(Ljava/util/List;)Ljava/math/BigInteger;
      40: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
      43: swap
      44: invokevirtual #44                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      47: return

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

  private static final void main$ensureDirExists(Node, java.lang.String);
    Code:
       0: aload_0
       1: invokevirtual #63                 // Method Node.getChildren:()Ljava/util/Map;
       4: aload_1
       5: invokeinterface #69,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      10: ifnonnull     47
      13: aload_0
      14: invokevirtual #63                 // Method Node.getChildren:()Ljava/util/Map;
      17: aload_1
      18: new           #59                 // class Node
      21: dup
      22: aload_0
      23: new           #71                 // class java/util/LinkedHashMap
      26: dup
      27: invokespecial #74                 // Method java/util/LinkedHashMap."<init>":()V
      30: checkcast     #65                 // class java/util/Map
      33: aload_1
      34: aconst_null
      35: getstatic     #80                 // Field NodeType.Dir:LNodeType;
      38: invokespecial #83                 // Method Node."<init>":(LNode;Ljava/util/Map;Ljava/lang/String;Ljava/math/BigInteger;LNodeType;)V
      41: invokeinterface #87,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      46: pop
      47: return

  private static final void main$ensureFileExists(Node, java.lang.String, java.math.BigInteger);
    Code:
       0: aload_0
       1: invokevirtual #63                 // Method Node.getChildren:()Ljava/util/Map;
       4: aload_1
       5: invokeinterface #69,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      10: ifnonnull     47
      13: aload_0
      14: invokevirtual #63                 // Method Node.getChildren:()Ljava/util/Map;
      17: aload_1
      18: new           #59                 // class Node
      21: dup
      22: aload_0
      23: new           #71                 // class java/util/LinkedHashMap
      26: dup
      27: invokespecial #74                 // Method java/util/LinkedHashMap."<init>":()V
      30: checkcast     #65                 // class java/util/Map
      33: aload_1
      34: aload_2
      35: getstatic     #96                 // Field NodeType.File:LNodeType;
      38: invokespecial #83                 // Method Node."<init>":(LNode;Ljava/util/Map;Ljava/lang/String;Ljava/math/BigInteger;LNodeType;)V
      41: invokeinterface #87,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      46: pop
      47: return

  private static final Node main$parse(java.util.List<java.lang.String>);
    Code:
       0: new           #59                 // class Node
       3: dup
       4: aconst_null
       5: new           #71                 // class java/util/LinkedHashMap
       8: dup
       9: invokespecial #74                 // Method java/util/LinkedHashMap."<init>":()V
      12: checkcast     #65                 // class java/util/Map
      15: ldc           #103                // String /
      17: aconst_null
      18: getstatic     #80                 // Field NodeType.Dir:LNodeType;
      21: invokespecial #83                 // Method Node."<init>":(LNode;Ljava/util/Map;Ljava/lang/String;Ljava/math/BigInteger;LNodeType;)V
      24: astore_1
      25: aload_1
      26: astore_2
      27: iconst_0
      28: istore_3
      29: aload_0
      30: invokeinterface #108,  1          // InterfaceMethod java/util/List.size:()I
      35: istore        4
      37: iload_3
      38: iload         4
      40: if_icmpge     463
      43: aload_0
      44: iload_3
      45: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      50: checkcast     #113                // class java/lang/String
      53: astore        5
      55: new           #115                // class java/lang/StringBuilder
      58: dup
      59: invokespecial #116                // Method java/lang/StringBuilder."<init>":()V
      62: ldc           #118                // String Command:
      64: invokevirtual #122                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      67: aload         5
      69: invokevirtual #122                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      72: invokevirtual #126                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      75: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
      78: swap
      79: invokevirtual #44                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      82: aload         5
      84: ldc           #128                // String $ cd /
      86: invokestatic  #134                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      89: ifeq          105
      92: aload_2
      93: invokevirtual #138                // Method Node.getRoot:()LNode;
      96: astore_2
      97: iinc          3, 1
     100: iload_3
     101: pop
     102: goto          441
     105: aload         5
     107: ldc           #140                // String $ cd ..
     109: invokestatic  #134                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     112: ifeq          132
     115: aload_2
     116: invokevirtual #143                // Method Node.getParent:()LNode;
     119: dup
     120: invokestatic  #146                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     123: astore_2
     124: iinc          3, 1
     127: iload_3
     128: pop
     129: goto          441
     132: aload         5
     134: ldc           #148                // String $ cd
     136: iconst_0
     137: iconst_2
     138: aconst_null
     139: invokestatic  #154                // Method kotlin/text/StringsKt.startsWith$default:(Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Z
     142: ifeq          215
     145: aload         5
     147: checkcast     #156                // class java/lang/CharSequence
     150: iconst_1
     151: newarray       char
     153: astore        7
     155: aload         7
     157: iconst_0
     158: bipush        32
     160: castore
     161: aload         7
     163: iconst_0
     164: iconst_0
     165: bipush        6
     167: aconst_null
     168: invokestatic  #160                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[CZIILjava/lang/Object;)Ljava/util/List;
     171: iconst_2
     172: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     177: checkcast     #113                // class java/lang/String
     180: astore        6
     182: aload_2
     183: aload         6
     185: invokestatic  #162                // Method main$ensureDirExists:(LNode;Ljava/lang/String;)V
     188: aload_2
     189: invokevirtual #63                 // Method Node.getChildren:()Ljava/util/Map;
     192: aload         6
     194: invokeinterface #69,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     199: dup
     200: invokestatic  #146                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     203: checkcast     #59                 // class Node
     206: astore_2
     207: iinc          3, 1
     210: iload_3
     211: pop
     212: goto          441
     215: aload         5
     217: ldc           #164                // String $ ls
     219: invokestatic  #134                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     222: ifeq          412
     225: iload_3
     226: iconst_1
     227: iadd
     228: istore        6
     230: iload         6
     232: iload         4
     234: if_icmpge     406
     237: aload_0
     238: iload         6
     240: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     245: checkcast     #113                // class java/lang/String
     248: ldc           #166                // String $
     250: iconst_0
     251: iconst_2
     252: aconst_null
     253: invokestatic  #154                // Method kotlin/text/StringsKt.startsWith$default:(Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Z
     256: ifne          406
     259: aload_0
     260: iload         6
     262: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     267: checkcast     #113                // class java/lang/String
     270: astore        7
     272: aload         7
     274: ldc           #168                // String dir
     276: iconst_0
     277: iconst_2
     278: aconst_null
     279: invokestatic  #154                // Method kotlin/text/StringsKt.startsWith$default:(Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Z
     282: ifeq          331
     285: aload         7
     287: checkcast     #156                // class java/lang/CharSequence
     290: iconst_1
     291: newarray       char
     293: astore        9
     295: aload         9
     297: iconst_0
     298: bipush        32
     300: castore
     301: aload         9
     303: iconst_0
     304: iconst_0
     305: bipush        6
     307: aconst_null
     308: invokestatic  #160                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[CZIILjava/lang/Object;)Ljava/util/List;
     311: iconst_1
     312: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     317: checkcast     #113                // class java/lang/String
     320: astore        8
     322: aload_2
     323: aload         8
     325: invokestatic  #162                // Method main$ensureDirExists:(LNode;Ljava/lang/String;)V
     328: goto          400
     331: aload         7
     333: checkcast     #156                // class java/lang/CharSequence
     336: iconst_1
     337: newarray       char
     339: astore        9
     341: aload         9
     343: iconst_0
     344: bipush        32
     346: castore
     347: aload         9
     349: iconst_0
     350: iconst_0
     351: bipush        6
     353: aconst_null
     354: invokestatic  #160                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[CZIILjava/lang/Object;)Ljava/util/List;
     357: astore        8
     359: new           #22                 // class java/math/BigInteger
     362: dup
     363: aload         8
     365: iconst_0
     366: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     371: checkcast     #113                // class java/lang/String
     374: invokespecial #171                // Method java/math/BigInteger."<init>":(Ljava/lang/String;)V
     377: astore        9
     379: aload         8
     381: iconst_1
     382: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     387: checkcast     #113                // class java/lang/String
     390: astore        10
     392: aload_2
     393: aload         10
     395: aload         9
     397: invokestatic  #173                // Method main$ensureFileExists:(LNode;Ljava/lang/String;Ljava/math/BigInteger;)V
     400: iinc          6, 1
     403: goto          230
     406: iload         6
     408: istore_3
     409: goto          441
     412: new           #115                // class java/lang/StringBuilder
     415: dup
     416: invokespecial #116                // Method java/lang/StringBuilder."<init>":()V
     419: ldc           #175                // String Unexpected line:
     421: invokevirtual #122                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     424: aload         5
     426: invokevirtual #122                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     429: invokevirtual #126                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     432: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
     435: swap
     436: invokevirtual #44                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     439: aload_1
     440: areturn
     441: ldc           #177                // String Root
     443: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
     446: swap
     447: invokevirtual #44                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     450: aload_1
     451: invokevirtual #180                // Method Node.printNode:()V
     454: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
     457: invokevirtual #182                // Method java/io/PrintStream.println:()V
     460: goto          37
     463: aload_1
     464: areturn

  private static final java.math.BigInteger main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #195                // Method main$parse:(Ljava/util/List;)LNode;
       4: astore_1
       5: aload_1
       6: invokevirtual #199                // Method Node.calculateTotalSize:()Ljava/math/BigInteger;
       9: pop
      10: aload_1
      11: ldc2_w        #200                // long 100000l
      14: invokestatic  #26                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      17: dup
      18: ldc           #203                // String valueOf(...)
      20: invokestatic  #207                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      23: invokevirtual #211                // Method Node.sumBy:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      26: areturn

  private static final java.math.BigInteger main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #195                // Method main$parse:(Ljava/util/List;)LNode;
       4: astore_1
       5: aload_1
       6: invokevirtual #199                // Method Node.calculateTotalSize:()Ljava/math/BigInteger;
       9: pop
      10: aload_1
      11: invokevirtual #214                // Method Node.getTotalSize:()Ljava/math/BigInteger;
      14: dup
      15: ldc           #216                // String <get-totalSize>(...)
      17: invokestatic  #207                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      20: astore_3
      21: ldc2_w        #217                // long 40000000l
      24: invokestatic  #26                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      27: dup
      28: ldc           #203                // String valueOf(...)
      30: invokestatic  #207                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      33: aload_3
      34: swap
      35: invokevirtual #221                // Method java/math/BigInteger.subtract:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      38: dup
      39: ldc           #223                // String subtract(...)
      41: invokestatic  #207                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      44: astore_2
      45: aload_1
      46: invokevirtual #227                // Method Node.getDirSizes:()Ljava/util/List;
      49: checkcast     #229                // class java/lang/Iterable
      52: astore_3
      53: iconst_0
      54: istore        4
      56: aload_3
      57: astore        5
      59: new           #231                // class java/util/ArrayList
      62: dup
      63: invokespecial #232                // Method java/util/ArrayList."<init>":()V
      66: checkcast     #234                // class java/util/Collection
      69: astore        6
      71: iconst_0
      72: istore        7
      74: aload         5
      76: invokeinterface #238,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      81: astore        8
      83: aload         8
      85: invokeinterface #244,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      90: ifeq          142
      93: aload         8
      95: invokeinterface #248,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     100: astore        9
     102: aload         9
     104: checkcast     #22                 // class java/math/BigInteger
     107: astore        10
     109: iconst_0
     110: istore        11
     112: aload         10
     114: aload_2
     115: invokevirtual #252                // Method java/math/BigInteger.compareTo:(Ljava/math/BigInteger;)I
     118: iflt          125
     121: iconst_1
     122: goto          126
     125: iconst_0
     126: ifeq          83
     129: aload         6
     131: aload         9
     133: invokeinterface #256,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     138: pop
     139: goto          83
     142: aload         6
     144: checkcast     #105                // class java/util/List
     147: nop
     148: checkcast     #229                // class java/lang/Iterable
     151: invokestatic  #262                // Method kotlin/collections/CollectionsKt.minOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
     154: checkcast     #22                 // class java/math/BigInteger
     157: areturn
}


fun main() {
    fun getStructure(input: List<String>): MutableList<List<Int>> {
        val result = mutableListOf<List<Int>>()
        var bucket = mutableListOf<Int>()
        result.add(bucket)

        input.forEach { line ->
            run {
                if (line.isBlank()) {
                    bucket = mutableListOf()
                    result.add(bucket)
                } else {
                    bucket.add(line.toInt())
                }
            }
        }
        return result
    }

    fun part1(input: List<String>): Int {
        val structure = getStructure(input)

        return structure.maxOf { it.sum() }
    }

    fun part2(input: List<String>): Int {
        val structure = getStructure(input)

        return structure
            .map { it.sum() }
            .sortedByDescending { it }
            .take(3)
            .sumOf { it }
    }

    val testInput = readInput("Day01_test")
    check(part1(testInput) == 24000)

    val input = readInput("Day01")
    println(part1(input))
    println(part2(input))
}

Compiled from "Comparisons.kt"
public final class Day01Kt$main$part2$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public Day01Kt$main$part2$$inlined$sortedByDescending$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_2
       1: checkcast     #23                 // class java/lang/Number
       4: invokevirtual #27                 // Method java/lang/Number.intValue:()I
       7: istore_3
       8: iconst_0
       9: istore        4
      11: iload_3
      12: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_1
      19: checkcast     #23                 // class java/lang/Number
      22: invokevirtual #27                 // Method java/lang/Number.intValue:()I
      25: istore_3
      26: astore        5
      28: iconst_0
      29: istore        4
      31: iload_3
      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 "Day01.kt"
public final class Day01Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Day01_test
       2: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      10: sipush        24000
      13: if_icmpne     20
      16: iconst_1
      17: goto          21
      20: iconst_0
      21: ifne          34
      24: new           #20                 // class java/lang/IllegalStateException
      27: dup
      28: ldc           #22                 // String Check failed.
      30: invokespecial #26                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      33: athrow
      34: ldc           #28                 // String Day01
      36: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      39: astore_1
      40: aload_1
      41: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      44: istore_2
      45: getstatic     #34                 // Field java/lang/System.out:Ljava/io/PrintStream;
      48: iload_2
      49: invokevirtual #40                 // Method java/io/PrintStream.println:(I)V
      52: aload_1
      53: invokestatic  #43                 // Method main$part2:(Ljava/util/List;)I
      56: istore_2
      57: getstatic     #34                 // Field java/lang/System.out:Ljava/io/PrintStream;
      60: iload_2
      61: invokevirtual #40                 // Method java/io/PrintStream.println:(I)V
      64: return

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

  private static final java.util.List<java.util.List<java.lang.Integer>> main$getStructure(java.util.List<java.lang.String>);
    Code:
       0: new           #58                 // class java/util/ArrayList
       3: dup
       4: invokespecial #60                 // Method java/util/ArrayList."<init>":()V
       7: checkcast     #48                 // class java/util/List
      10: astore_1
      11: aconst_null
      12: astore_2
      13: new           #58                 // class java/util/ArrayList
      16: dup
      17: invokespecial #60                 // Method java/util/ArrayList."<init>":()V
      20: checkcast     #48                 // class java/util/List
      23: astore_2
      24: aload_1
      25: aload_2
      26: invokeinterface #64,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      31: pop
      32: aload_0
      33: checkcast     #66                 // class java/lang/Iterable
      36: astore_3
      37: iconst_0
      38: istore        4
      40: aload_3
      41: invokeinterface #70,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      46: astore        5
      48: aload         5
      50: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      55: ifeq          134
      58: aload         5
      60: invokeinterface #80,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      65: astore        6
      67: aload         6
      69: checkcast     #82                 // class java/lang/String
      72: astore        7
      74: iconst_0
      75: istore        8
      77: iconst_0
      78: istore        9
      80: aload         7
      82: checkcast     #84                 // class java/lang/CharSequence
      85: invokestatic  #90                 // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
      88: ifeq          112
      91: new           #58                 // class java/util/ArrayList
      94: dup
      95: invokespecial #60                 // Method java/util/ArrayList."<init>":()V
      98: checkcast     #48                 // class java/util/List
     101: astore_2
     102: aload_1
     103: aload_2
     104: invokeinterface #64,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     109: goto          126
     112: aload_2
     113: aload         7
     115: invokestatic  #96                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     118: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     121: invokeinterface #64,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     126: pop
     127: nop
     128: nop
     129: nop
     130: nop
     131: goto          48
     134: nop
     135: aload_1
     136: areturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #115                // Method main$getStructure:(Ljava/util/List;)Ljava/util/List;
       4: astore_1
       5: aload_1
       6: checkcast     #66                 // class java/lang/Iterable
       9: invokeinterface #70,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      14: astore_2
      15: aload_2
      16: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      21: ifne          32
      24: new           #117                // class java/util/NoSuchElementException
      27: dup
      28: invokespecial #118                // Method java/util/NoSuchElementException."<init>":()V
      31: athrow
      32: aload_2
      33: invokeinterface #80,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      38: checkcast     #48                 // class java/util/List
      41: astore_3
      42: iconst_0
      43: istore        4
      45: aload_3
      46: checkcast     #66                 // class java/lang/Iterable
      49: invokestatic  #124                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
      52: istore_3
      53: aload_2
      54: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      59: ifeq          98
      62: aload_2
      63: invokeinterface #80,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      68: checkcast     #48                 // class java/util/List
      71: astore        4
      73: iconst_0
      74: istore        5
      76: aload         4
      78: checkcast     #66                 // class java/lang/Iterable
      81: invokestatic  #124                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
      84: istore        4
      86: iload_3
      87: iload         4
      89: if_icmpge     53
      92: iload         4
      94: istore_3
      95: goto          53
      98: iload_3
      99: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #115                // Method main$getStructure:(Ljava/util/List;)Ljava/util/List;
       4: astore_1
       5: aload_1
       6: checkcast     #66                 // class java/lang/Iterable
       9: astore_2
      10: nop
      11: iconst_0
      12: istore_3
      13: aload_2
      14: astore        4
      16: new           #58                 // class java/util/ArrayList
      19: dup
      20: aload_2
      21: bipush        10
      23: invokestatic  #131                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      26: invokespecial #133                // Method java/util/ArrayList."<init>":(I)V
      29: checkcast     #135                // class java/util/Collection
      32: astore        5
      34: iconst_0
      35: istore        6
      37: aload         4
      39: invokeinterface #70,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      44: astore        7
      46: aload         7
      48: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          102
      56: aload         7
      58: invokeinterface #80,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: astore        8
      65: aload         5
      67: aload         8
      69: checkcast     #48                 // class java/util/List
      72: astore        9
      74: astore        11
      76: iconst_0
      77: istore        10
      79: aload         9
      81: checkcast     #66                 // class java/lang/Iterable
      84: invokestatic  #124                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
      87: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      90: aload         11
      92: swap
      93: invokeinterface #136,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      98: pop
      99: goto          46
     102: aload         5
     104: checkcast     #48                 // class java/util/List
     107: nop
     108: checkcast     #66                 // class java/lang/Iterable
     111: astore_2
     112: nop
     113: iconst_0
     114: istore_3
     115: aload_2
     116: new           #138                // class Day01Kt$main$part2$$inlined$sortedByDescending$1
     119: dup
     120: invokespecial #139                // Method Day01Kt$main$part2$$inlined$sortedByDescending$1."<init>":()V
     123: checkcast     #141                // class java/util/Comparator
     126: invokestatic  #145                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
     129: checkcast     #66                 // class java/lang/Iterable
     132: iconst_3
     133: invokestatic  #149                // Method kotlin/collections/CollectionsKt.take:(Ljava/lang/Iterable;I)Ljava/util/List;
     136: checkcast     #66                 // class java/lang/Iterable
     139: astore_2
     140: iconst_0
     141: istore_3
     142: aload_2
     143: invokeinterface #70,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     148: astore        4
     150: aload         4
     152: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     157: ifeq          198
     160: aload         4
     162: invokeinterface #80,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     167: astore        5
     169: iload_3
     170: aload         5
     172: checkcast     #151                // class java/lang/Number
     175: invokevirtual #155                // Method java/lang/Number.intValue:()I
     178: istore        6
     180: istore        11
     182: iconst_0
     183: istore        7
     185: iload         6
     187: istore        12
     189: iload         11
     191: iload         12
     193: iadd
     194: istore_3
     195: goto          150
     198: iload_3
     199: ireturn
}


fun main() {
    fun getDiffIndex(input: List<String>, diffCount: Int): Int {
        val line = input[0].toCharArray()

        for (i in 0..line.size - diffCount) {
            if (line.slice(i until i + diffCount).toSet().size == diffCount) {
                return i + diffCount
            }
        }

        return -1
    }

    fun part1(input: List<String>): Int {
        return getDiffIndex(input, 4)
    }

    fun part2(input: List<String>): Int {
        return getDiffIndex(input, 14)
    }

    assert(part1(readInput("Day06_test_1")), 7)
    assert(part1(readInput("Day06_test_2")), 5)
    assert(part1(readInput("Day06_test_3")), 11)

    assert(part2(readInput("Day06_test_1")), 19)
    assert(part2(readInput("Day06_test_2")), 23)
    assert(part2(readInput("Day06_test_3")), 26)

    val input = readInput("Day06")
    println(part1(input))
    println(part2(input))
}

Compiled from "Day06.kt"
public final class Day06Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Day06_test_1
       2: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
       8: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      11: bipush        7
      13: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: invokestatic  #28                 // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      19: ldc           #30                 // String Day06_test_2
      21: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      24: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      27: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      30: iconst_5
      31: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      34: invokestatic  #28                 // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      37: ldc           #32                 // String Day06_test_3
      39: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      42: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      45: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      48: bipush        11
      50: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      53: invokestatic  #28                 // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      56: ldc           #8                  // String Day06_test_1
      58: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      61: invokestatic  #35                 // Method main$part2:(Ljava/util/List;)I
      64: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      67: bipush        19
      69: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      72: invokestatic  #28                 // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      75: ldc           #30                 // String Day06_test_2
      77: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      80: invokestatic  #35                 // Method main$part2:(Ljava/util/List;)I
      83: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      86: bipush        23
      88: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      91: invokestatic  #28                 // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
      94: ldc           #32                 // String Day06_test_3
      96: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      99: invokestatic  #35                 // Method main$part2:(Ljava/util/List;)I
     102: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     105: bipush        26
     107: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     110: invokestatic  #28                 // Method UtilsKt.assert:(Ljava/lang/Object;Ljava/lang/Object;)V
     113: ldc           #37                 // String Day06
     115: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
     118: astore_0
     119: aload_0
     120: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
     123: istore_1
     124: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     127: iload_1
     128: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
     131: aload_0
     132: invokestatic  #35                 // Method main$part2:(Ljava/util/List;)I
     135: istore_1
     136: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     139: iload_1
     140: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
     143: return

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

  private static final int main$getDiffIndex(java.util.List<java.lang.String>, int);
    Code:
       0: aload_0
       1: iconst_0
       2: invokeinterface #65,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
       7: checkcast     #67                 // class java/lang/String
      10: invokevirtual #71                 // Method java/lang/String.toCharArray:()[C
      13: dup
      14: ldc           #73                 // String toCharArray(...)
      16: invokestatic  #79                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      19: astore_2
      20: iconst_0
      21: istore_3
      22: aload_2
      23: arraylength
      24: iload_1
      25: isub
      26: istore        4
      28: iload_3
      29: iload         4
      31: if_icmpgt     76
      34: aload_2
      35: iload_3
      36: iload_3
      37: iload_1
      38: iadd
      39: invokestatic  #85                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      42: invokestatic  #91                 // Method kotlin/collections/ArraysKt.slice:([CLkotlin/ranges/IntRange;)Ljava/util/List;
      45: checkcast     #93                 // class java/lang/Iterable
      48: invokestatic  #99                 // Method kotlin/collections/CollectionsKt.toSet:(Ljava/lang/Iterable;)Ljava/util/Set;
      51: invokeinterface #105,  1          // InterfaceMethod java/util/Set.size:()I
      56: iload_1
      57: if_icmpne     64
      60: iload_3
      61: iload_1
      62: iadd
      63: ireturn
      64: iload_3
      65: iload         4
      67: if_icmpeq     76
      70: iinc          3, 1
      73: goto          34
      76: iconst_m1
      77: ireturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: iconst_4
       2: invokestatic  #114                // Method main$getDiffIndex:(Ljava/util/List;I)I
       5: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: bipush        14
       3: invokestatic  #114                // Method main$getDiffIndex:(Ljava/util/List;I)I
       6: ireturn
}