import kotlin.math.abs
import kotlin.math.sign

object Day09 {
    const val EXPECTED_PART1_CHECK_ANSWER = 13
    const val EXPECTED_PART2_CHECK_ANSWER = 1

    const val TAIL_SIZE_PART_2 = 9
}

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

fun main() {
    data class Location(val x: Int, val y: Int) {
        fun move(direction: MovementDirection) = when (direction) {
            MovementDirection.U -> copy(y = y + 1)
            MovementDirection.D -> copy(y = y - 1)
            MovementDirection.R -> copy(x = x + 1)
            MovementDirection.L -> copy(x = x - 1)
        }

        fun moveAfterPrecursor(precursorPosition: Location): Location {
            val xDiff = precursorPosition.x - x
            val yDiff = precursorPosition.y - y
            if (abs(xDiff) > 1 || abs(yDiff) > 1) {
                return copy(
                    x = x + (xDiff + xDiff.sign) / 2,
                    y = y + (yDiff + yDiff.sign) / 2,
                )
            }
            return this
        }
    }

    fun part1(input: List<String>): Int {
        val tailVisitedPositions = mutableSetOf<Location>()
        var currentHeadPosition = Location(0, 0)
        var currentTailPosition = Location(0, 0)
        tailVisitedPositions.add(currentTailPosition)
        input.forEach { movement ->
            val directionAndSteps = movement.split(" ")
            val (direction, steps) = Pair(MovementDirection.valueOf(directionAndSteps[0]), directionAndSteps[1].toInt())
            repeat(steps) {
                currentHeadPosition = currentHeadPosition.move(direction)

                currentTailPosition = currentTailPosition.moveAfterPrecursor(currentHeadPosition)
                tailVisitedPositions.add(currentTailPosition)
            }
        }
        return tailVisitedPositions.size
    }

    fun part2(input: List<String>): Int {
        val tailVisitedPositions = mutableSetOf<Location>()
        var currentHeadPosition = Location(0, 0)
        val trailPositions = MutableList(Day09.TAIL_SIZE_PART_2) { Location(0, 0) }
        tailVisitedPositions.add(trailPositions.last())
        input.forEach { movement ->
            val directionAndSteps = movement.split(" ")
            val (direction, steps) = Pair(MovementDirection.valueOf(directionAndSteps[0]), directionAndSteps[1].toInt())
            repeat(steps) {
                currentHeadPosition = currentHeadPosition.move(direction)

                trailPositions.forEachIndexed { idx, trailPosition ->
                    val newTrailPosition =
                        trailPosition.moveAfterPrecursor(if (idx == 0) currentHeadPosition else trailPositions[idx - 1])
                    trailPositions[idx] = newTrailPosition
                }
                tailVisitedPositions.add(trailPositions.last())
            }
        }
        return tailVisitedPositions.size
    }

    // test if implementation meets criteria from the description, like:
    val testInput = readInput("Day09_test")
    check(part1(testInput) == Day09.EXPECTED_PART1_CHECK_ANSWER) { "Part 1 failed" }
    check(part2(testInput) == Day09.EXPECTED_PART2_CHECK_ANSWER) { "Part 2 failed" }

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

Compiled from "Day09.kt"
public final class Day09Kt$main$Location {
  private final int x;

  private final int y;

  public Day09Kt$main$Location(int, int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field x:I
       9: aload_0
      10: iload_2
      11: putfield      #16                 // Field y:I
      14: return

  public final int getX();
    Code:
       0: aload_0
       1: getfield      #13                 // Field x:I
       4: ireturn

  public final int getY();
    Code:
       0: aload_0
       1: getfield      #16                 // Field y:I
       4: ireturn

  public final Day09Kt$main$Location move(MovementDirection);
    Code:
       0: aload_1
       1: ldc           #25                 // String direction
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: getstatic     #37                 // Field Day09Kt$main$Location$WhenMappings.$EnumSwitchMapping$0:[I
      10: swap
      11: invokevirtual #42                 // Method MovementDirection.ordinal:()I
      14: iaload
      15: tableswitch   { // 1 to 4
                     1: 44
                     2: 60
                     3: 76
                     4: 92
               default: 108
          }
      44: aload_0
      45: iconst_0
      46: aload_0
      47: getfield      #16                 // Field y:I
      50: iconst_1
      51: iadd
      52: iconst_1
      53: aconst_null
      54: invokestatic  #46                 // Method copy$default:(LDay09Kt$main$Location;IIILjava/lang/Object;)LDay09Kt$main$Location;
      57: goto          116
      60: aload_0
      61: iconst_0
      62: aload_0
      63: getfield      #16                 // Field y:I
      66: iconst_1
      67: isub
      68: iconst_1
      69: aconst_null
      70: invokestatic  #46                 // Method copy$default:(LDay09Kt$main$Location;IIILjava/lang/Object;)LDay09Kt$main$Location;
      73: goto          116
      76: aload_0
      77: aload_0
      78: getfield      #13                 // Field x:I
      81: iconst_1
      82: iadd
      83: iconst_0
      84: iconst_2
      85: aconst_null
      86: invokestatic  #46                 // Method copy$default:(LDay09Kt$main$Location;IIILjava/lang/Object;)LDay09Kt$main$Location;
      89: goto          116
      92: aload_0
      93: aload_0
      94: getfield      #13                 // Field x:I
      97: iconst_1
      98: isub
      99: iconst_0
     100: iconst_2
     101: aconst_null
     102: invokestatic  #46                 // Method copy$default:(LDay09Kt$main$Location;IIILjava/lang/Object;)LDay09Kt$main$Location;
     105: goto          116
     108: new           #48                 // class kotlin/NoWhenBranchMatchedException
     111: dup
     112: invokespecial #49                 // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     115: athrow
     116: areturn

  public final Day09Kt$main$Location moveAfterPrecursor(Day09Kt$main$Location);
    Code:
       0: aload_1
       1: ldc           #54                 // String precursorPosition
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: getfield      #13                 // Field x:I
      10: aload_0
      11: getfield      #13                 // Field x:I
      14: isub
      15: istore_2
      16: aload_1
      17: getfield      #16                 // Field y:I
      20: aload_0
      21: getfield      #16                 // Field y:I
      24: isub
      25: istore_3
      26: iload_2
      27: invokestatic  #60                 // Method java/lang/Math.abs:(I)I
      30: iconst_1
      31: if_icmpgt     42
      34: iload_3
      35: invokestatic  #60                 // Method java/lang/Math.abs:(I)I
      38: iconst_1
      39: if_icmple     73
      42: aload_0
      43: aload_0
      44: getfield      #13                 // Field x:I
      47: iload_2
      48: iload_2
      49: invokestatic  #65                 // Method kotlin/math/MathKt.getSign:(I)I
      52: iadd
      53: iconst_2
      54: idiv
      55: iadd
      56: aload_0
      57: getfield      #16                 // Field y:I
      60: iload_3
      61: iload_3
      62: invokestatic  #65                 // Method kotlin/math/MathKt.getSign:(I)I
      65: iadd
      66: iconst_2
      67: idiv
      68: iadd
      69: invokevirtual #69                 // Method copy:(II)LDay09Kt$main$Location;
      72: areturn
      73: aload_0
      74: areturn

  public final int component1();
    Code:
       0: aload_0
       1: getfield      #13                 // Field x:I
       4: ireturn

  public final int component2();
    Code:
       0: aload_0
       1: getfield      #16                 // Field y:I
       4: ireturn

  public final Day09Kt$main$Location copy(int, int);
    Code:
       0: new           #2                  // class Day09Kt$main$Location
       3: dup
       4: iload_1
       5: iload_2
       6: invokespecial #75                 // Method "<init>":(II)V
       9: areturn

  public static Day09Kt$main$Location copy$default(Day09Kt$main$Location, int, int, int, java.lang.Object);
    Code:
       0: iload_3
       1: iconst_1
       2: iand
       3: ifeq          11
       6: aload_0
       7: getfield      #13                 // Field x:I
      10: istore_1
      11: iload_3
      12: iconst_2
      13: iand
      14: ifeq          22
      17: aload_0
      18: getfield      #16                 // Field y:I
      21: istore_2
      22: aload_0
      23: iload_1
      24: iload_2
      25: invokevirtual #69                 // Method copy:(II)LDay09Kt$main$Location;
      28: areturn

  public java.lang.String toString();
    Code:
       0: new           #79                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #80                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #82                 // String Location(x=
       9: invokevirtual #86                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #13                 // Field x:I
      16: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      19: ldc           #91                 // String , y=
      21: invokevirtual #86                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #16                 // Field y:I
      28: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      31: bipush        41
      33: invokevirtual #94                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      36: invokevirtual #96                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #13                 // Field x:I
       4: invokestatic  #101                // Method java/lang/Integer.hashCode:(I)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #16                 // Field y:I
      16: invokestatic  #101                // Method java/lang/Integer.hashCode:(I)I
      19: iadd
      20: istore_1
      21: iload_1
      22: 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 Day09Kt$main$Location
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class Day09Kt$main$Location
      20: astore_2
      21: aload_0
      22: getfield      #13                 // Field x:I
      25: aload_2
      26: getfield      #13                 // Field x:I
      29: if_icmpeq     34
      32: iconst_0
      33: ireturn
      34: aload_0
      35: getfield      #16                 // Field y:I
      38: aload_2
      39: getfield      #16                 // Field y:I
      42: if_icmpeq     47
      45: iconst_0
      46: ireturn
      47: iconst_1
      48: ireturn
}

Compiled from "Day09.kt"
public final class Day09 {
  public static final Day09 INSTANCE;

  public static final int EXPECTED_PART1_CHECK_ANSWER;

  public static final int EXPECTED_PART2_CHECK_ANSWER;

  public static final int TAIL_SIZE_PART_2;

  private Day09();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #2                  // class Day09
       3: dup
       4: invokespecial #12                 // Method "<init>":()V
       7: putstatic     #15                 // Field INSTANCE:LDay09;
      10: return
}

Compiled from "Day09.kt"
public final class Day09Kt$main$Location$WhenMappings {
  public static final int[] $EnumSwitchMapping$0;

  static {};
    Code:
       0: invokestatic  #14                 // Method MovementDirection.values:()[LMovementDirection;
       3: arraylength
       4: newarray       int
       6: astore_0
       7: nop
       8: aload_0
       9: getstatic     #18                 // Field MovementDirection.U:LMovementDirection;
      12: invokevirtual #22                 // Method MovementDirection.ordinal:()I
      15: iconst_1
      16: iastore
      17: goto          21
      20: astore_1
      21: nop
      22: aload_0
      23: getstatic     #25                 // Field MovementDirection.D:LMovementDirection;
      26: invokevirtual #22                 // Method MovementDirection.ordinal:()I
      29: iconst_2
      30: iastore
      31: goto          35
      34: astore_1
      35: nop
      36: aload_0
      37: getstatic     #28                 // Field MovementDirection.R:LMovementDirection;
      40: invokevirtual #22                 // Method MovementDirection.ordinal:()I
      43: iconst_3
      44: iastore
      45: goto          49
      48: astore_1
      49: nop
      50: aload_0
      51: getstatic     #31                 // Field MovementDirection.L:LMovementDirection;
      54: invokevirtual #22                 // Method MovementDirection.ordinal:()I
      57: iconst_4
      58: iastore
      59: goto          63
      62: astore_1
      63: aload_0
      64: putstatic     #35                 // Field $EnumSwitchMapping$0:[I
      67: return
    Exception table:
       from    to  target type
           7    17    20   Class java/lang/NoSuchFieldError
          21    31    34   Class java/lang/NoSuchFieldError
          35    45    48   Class java/lang/NoSuchFieldError
          49    59    62   Class java/lang/NoSuchFieldError
}

Compiled from "Day09.kt"
public final class Day09Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Day09_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: bipush        13
      12: if_icmpne     19
      15: iconst_1
      16: goto          20
      19: iconst_0
      20: ifne          40
      23: iconst_0
      24: istore_2
      25: ldc           #20                 // String Part 1 failed
      27: astore_2
      28: new           #22                 // class java/lang/IllegalStateException
      31: dup
      32: aload_2
      33: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      36: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      39: athrow
      40: aload_0
      41: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      44: iconst_1
      45: if_icmpne     52
      48: iconst_1
      49: goto          53
      52: iconst_0
      53: ifne          73
      56: iconst_0
      57: istore_2
      58: ldc           #35                 // String Part 2 failed
      60: astore_2
      61: new           #22                 // class java/lang/IllegalStateException
      64: dup
      65: aload_2
      66: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      69: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      72: athrow
      73: ldc           #37                 // String Day09
      75: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      78: astore_1
      79: aload_1
      80: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      83: istore_2
      84: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      87: iload_2
      88: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
      91: aload_1
      92: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      95: istore_2
      96: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      99: iload_2
     100: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
     103: return

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

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: new           #65                 // class java/util/LinkedHashSet
       3: dup
       4: invokespecial #67                 // Method java/util/LinkedHashSet."<init>":()V
       7: checkcast     #69                 // class java/util/Set
      10: astore_1
      11: aconst_null
      12: astore_2
      13: new           #71                 // class Day09Kt$main$Location
      16: dup
      17: iconst_0
      18: iconst_0
      19: invokespecial #74                 // Method Day09Kt$main$Location."<init>":(II)V
      22: astore_2
      23: aconst_null
      24: astore_3
      25: new           #71                 // class Day09Kt$main$Location
      28: dup
      29: iconst_0
      30: iconst_0
      31: invokespecial #74                 // Method Day09Kt$main$Location."<init>":(II)V
      34: astore_3
      35: aload_1
      36: aload_3
      37: invokeinterface #78,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
      42: pop
      43: aload_0
      44: checkcast     #80                 // class java/lang/Iterable
      47: astore        4
      49: iconst_0
      50: istore        5
      52: aload         4
      54: invokeinterface #84,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      59: astore        6
      61: aload         6
      63: invokeinterface #90,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      68: ifeq          232
      71: aload         6
      73: invokeinterface #94,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      78: astore        7
      80: aload         7
      82: checkcast     #96                 // class java/lang/String
      85: astore        8
      87: iconst_0
      88: istore        9
      90: aload         8
      92: checkcast     #98                 // class java/lang/CharSequence
      95: iconst_1
      96: anewarray     #96                 // class java/lang/String
      99: astore        10
     101: aload         10
     103: iconst_0
     104: ldc           #100                // String
     106: aastore
     107: aload         10
     109: iconst_0
     110: iconst_0
     111: bipush        6
     113: aconst_null
     114: invokestatic  #106                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     117: astore        11
     119: new           #108                // class kotlin/Pair
     122: dup
     123: aload         11
     125: iconst_0
     126: invokeinterface #112,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     131: checkcast     #96                 // class java/lang/String
     134: invokestatic  #118                // Method MovementDirection.valueOf:(Ljava/lang/String;)LMovementDirection;
     137: aload         11
     139: iconst_1
     140: invokeinterface #112,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     145: checkcast     #96                 // class java/lang/String
     148: invokestatic  #124                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     151: invokestatic  #127                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     154: invokespecial #130                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     157: astore        10
     159: aload         10
     161: invokevirtual #133                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     164: checkcast     #114                // class MovementDirection
     167: astore        12
     169: aload         10
     171: invokevirtual #136                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     174: checkcast     #138                // class java/lang/Number
     177: invokevirtual #142                // Method java/lang/Number.intValue:()I
     180: istore        13
     182: iconst_0
     183: istore        14
     185: iload         14
     187: iload         13
     189: if_icmpge     227
     192: iload         14
     194: istore        15
     196: iconst_0
     197: istore        16
     199: aload_2
     200: aload         12
     202: invokevirtual #146                // Method Day09Kt$main$Location.move:(LMovementDirection;)LDay09Kt$main$Location;
     205: astore_2
     206: aload_3
     207: aload_2
     208: invokevirtual #150                // Method Day09Kt$main$Location.moveAfterPrecursor:(LDay09Kt$main$Location;)LDay09Kt$main$Location;
     211: astore_3
     212: aload_1
     213: aload_3
     214: invokeinterface #78,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
     219: pop
     220: nop
     221: iinc          14, 1
     224: goto          185
     227: nop
     228: nop
     229: goto          61
     232: nop
     233: aload_1
     234: invokeinterface #153,  1          // InterfaceMethod java/util/Set.size:()I
     239: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: new           #65                 // class java/util/LinkedHashSet
       3: dup
       4: invokespecial #67                 // Method java/util/LinkedHashSet."<init>":()V
       7: checkcast     #69                 // class java/util/Set
      10: astore_1
      11: aconst_null
      12: astore_2
      13: new           #71                 // class Day09Kt$main$Location
      16: dup
      17: iconst_0
      18: iconst_0
      19: invokespecial #74                 // Method Day09Kt$main$Location."<init>":(II)V
      22: astore_2
      23: bipush        9
      25: istore        4
      27: new           #173                // class java/util/ArrayList
      30: dup
      31: iload         4
      33: invokespecial #175                // Method java/util/ArrayList."<init>":(I)V
      36: astore        5
      38: iconst_0
      39: istore        6
      41: iload         6
      43: iload         4
      45: if_icmpge     85
      48: iload         6
      50: istore        7
      52: aload         5
      54: iload         7
      56: istore        8
      58: astore        27
      60: iconst_0
      61: istore        9
      63: new           #71                 // class Day09Kt$main$Location
      66: dup
      67: iconst_0
      68: iconst_0
      69: invokespecial #74                 // Method Day09Kt$main$Location."<init>":(II)V
      72: aload         27
      74: swap
      75: invokevirtual #176                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      78: pop
      79: iinc          6, 1
      82: goto          41
      85: aload         5
      87: checkcast     #57                 // class java/util/List
      90: astore_3
      91: aload_1
      92: aload_3
      93: invokestatic  #182                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
      96: invokeinterface #78,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
     101: pop
     102: aload_0
     103: checkcast     #80                 // class java/lang/Iterable
     106: astore        4
     108: iconst_0
     109: istore        5
     111: aload         4
     113: invokeinterface #84,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     118: astore        6
     120: aload         6
     122: invokeinterface #90,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     127: ifeq          403
     130: aload         6
     132: invokeinterface #94,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     137: astore        7
     139: aload         7
     141: checkcast     #96                 // class java/lang/String
     144: astore        8
     146: iconst_0
     147: istore        9
     149: aload         8
     151: checkcast     #98                 // class java/lang/CharSequence
     154: iconst_1
     155: anewarray     #96                 // class java/lang/String
     158: astore        10
     160: aload         10
     162: iconst_0
     163: ldc           #100                // String
     165: aastore
     166: aload         10
     168: iconst_0
     169: iconst_0
     170: bipush        6
     172: aconst_null
     173: invokestatic  #106                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     176: astore        11
     178: new           #108                // class kotlin/Pair
     181: dup
     182: aload         11
     184: iconst_0
     185: invokeinterface #112,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     190: checkcast     #96                 // class java/lang/String
     193: invokestatic  #118                // Method MovementDirection.valueOf:(Ljava/lang/String;)LMovementDirection;
     196: aload         11
     198: iconst_1
     199: invokeinterface #112,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     204: checkcast     #96                 // class java/lang/String
     207: invokestatic  #124                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     210: invokestatic  #127                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     213: invokespecial #130                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     216: astore        10
     218: aload         10
     220: invokevirtual #133                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     223: checkcast     #114                // class MovementDirection
     226: astore        12
     228: aload         10
     230: invokevirtual #136                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     233: checkcast     #138                // class java/lang/Number
     236: invokevirtual #142                // Method java/lang/Number.intValue:()I
     239: istore        13
     241: iconst_0
     242: istore        14
     244: iload         14
     246: iload         13
     248: if_icmpge     398
     251: iload         14
     253: istore        15
     255: iconst_0
     256: istore        16
     258: aload_2
     259: aload         12
     261: invokevirtual #146                // Method Day09Kt$main$Location.move:(LMovementDirection;)LDay09Kt$main$Location;
     264: astore_2
     265: aload_3
     266: checkcast     #80                 // class java/lang/Iterable
     269: astore        17
     271: iconst_0
     272: istore        18
     274: iconst_0
     275: istore        19
     277: aload         17
     279: invokeinterface #84,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     284: astore        20
     286: aload         20
     288: invokeinterface #90,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     293: ifeq          379
     296: aload         20
     298: invokeinterface #94,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     303: astore        21
     305: iload         19
     307: iinc          19, 1
     310: istore        22
     312: iload         22
     314: ifge          320
     317: invokestatic  #185                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     320: iload         22
     322: aload         21
     324: checkcast     #71                 // class Day09Kt$main$Location
     327: astore        23
     329: istore        24
     331: iconst_0
     332: istore        25
     334: aload         23
     336: iload         24
     338: ifne          345
     341: aload_2
     342: goto          358
     345: aload_3
     346: iload         24
     348: iconst_1
     349: isub
     350: invokeinterface #112,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     355: checkcast     #71                 // class Day09Kt$main$Location
     358: invokevirtual #150                // Method Day09Kt$main$Location.moveAfterPrecursor:(LDay09Kt$main$Location;)LDay09Kt$main$Location;
     361: astore        26
     363: aload_3
     364: iload         24
     366: aload         26
     368: invokeinterface #189,  3          // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
     373: pop
     374: nop
     375: nop
     376: goto          286
     379: nop
     380: aload_1
     381: aload_3
     382: invokestatic  #182                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     385: invokeinterface #78,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
     390: pop
     391: nop
     392: iinc          14, 1
     395: goto          244
     398: nop
     399: nop
     400: goto          120
     403: nop
     404: aload_1
     405: invokeinterface #153,  1          // InterfaceMethod java/util/Set.size:()I
     410: ireturn
}


object Day07 {
    const val EXPECTED_PART1_CHECK_ANSWER = 95437
    const val EXPECTED_PART2_CHECK_ANSWER = 24933642

    const val DIR_SIZE_THRESHOLD = 100_000
    const val FS_TOTAL_SIZE = 70_000_000
    const val FS_NEEDED_FREE_SPACE = 30_000_000
}

sealed class Entry(val name: String)

class File(name: String, val size: Int) : Entry(name)

class Dir(name: String, val parentDir: Dir? = null) : Entry(name) {
    private var content: List<Entry> = emptyList()

    fun add(entry: Entry): Entry {
        content += entry
        return this
    }

    fun dirContent() = content
}

fun main() {

    val fileListingRegex = Regex("(\\d+) (\\S+)")

    fun parseDirTree(input: List<String>): Dir {
        val rootDir = Dir("/")
        var currentDir = rootDir
        input.drop(1).forEach { entry ->
            when {
                entry.startsWith("$ cd ..") -> {
                    if (currentDir.parentDir != null) {
                        currentDir = currentDir.parentDir!!
                    }
                }

                entry.startsWith("$ cd") -> {
                    val newDir = Dir(entry.substring("$ cd ".length), currentDir)
                    currentDir.add(newDir)
                    currentDir = newDir
                }

                entry.matches(fileListingRegex) -> {
                    val match = fileListingRegex.matchEntire(entry)
                    if (match != null) {
                        currentDir.add(File(match.groupValues[2], match.groupValues[1].toInt()))
                    }
                }
            }
        }
        return rootDir
    }

    fun dirSizes(dir: Dir, sizes: MutableList<Int>): Int {
        var totalDirSize = 0
        dir.dirContent().forEach { subEntry ->
            totalDirSize += when (subEntry) {
                is File -> subEntry.size
                is Dir -> dirSizes(subEntry, sizes)
            }
        }
        sizes += totalDirSize
        return totalDirSize
    }

    fun part1(input: List<String>): Int {
        val rootDir = parseDirTree(input)
        val sizesOfDirs = mutableListOf<Int>()
        dirSizes(rootDir, sizesOfDirs)
        return sizesOfDirs.filter { it <= Day07.DIR_SIZE_THRESHOLD }.sum()
    }

    fun part2(input: List<String>): Int {
        val rootDir = parseDirTree(input)
        val sizesOfDirs = mutableListOf<Int>()
        val rootDirSize = dirSizes(rootDir, sizesOfDirs)
        val currentFreeSpace = Day07.FS_TOTAL_SIZE - rootDirSize
        val needToFreeUp = Day07.FS_NEEDED_FREE_SPACE - currentFreeSpace
        return sizesOfDirs.filter { it >= needToFreeUp }.sorted()[0]
    }

    // test if implementation meets criteria from the description, like:
    val testInput = readInput("Day07_test")
    check(part1(testInput) == Day07.EXPECTED_PART1_CHECK_ANSWER) { "Part 1 failed" }
    check(part2(testInput) == Day07.EXPECTED_PART2_CHECK_ANSWER) { "Part 2 failed" }

    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: new           #8                  // class kotlin/text/Regex
       3: dup
       4: ldc           #10                 // String (\\d+) (\\S+)
       6: invokespecial #14                 // Method kotlin/text/Regex."<init>":(Ljava/lang/String;)V
       9: astore_0
      10: ldc           #16                 // String Day07_test
      12: invokestatic  #22                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      15: astore_1
      16: aload_0
      17: aload_1
      18: invokestatic  #26                 // Method main$part1:(Lkotlin/text/Regex;Ljava/util/List;)I
      21: ldc           #27                 // int 95437
      23: if_icmpne     30
      26: iconst_1
      27: goto          31
      30: iconst_0
      31: ifne          51
      34: iconst_0
      35: istore_3
      36: ldc           #29                 // String Part 1 failed
      38: astore_3
      39: new           #31                 // class java/lang/IllegalStateException
      42: dup
      43: aload_3
      44: invokevirtual #35                 // Method java/lang/Object.toString:()Ljava/lang/String;
      47: invokespecial #36                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      50: athrow
      51: aload_0
      52: aload_1
      53: invokestatic  #39                 // Method main$part2:(Lkotlin/text/Regex;Ljava/util/List;)I
      56: ldc           #40                 // int 24933642
      58: if_icmpne     65
      61: iconst_1
      62: goto          66
      65: iconst_0
      66: ifne          86
      69: iconst_0
      70: istore_3
      71: ldc           #42                 // String Part 2 failed
      73: astore_3
      74: new           #31                 // class java/lang/IllegalStateException
      77: dup
      78: aload_3
      79: invokevirtual #35                 // Method java/lang/Object.toString:()Ljava/lang/String;
      82: invokespecial #36                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      85: athrow
      86: ldc           #44                 // String Day07
      88: invokestatic  #22                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      91: astore_2
      92: aload_0
      93: aload_2
      94: invokestatic  #26                 // Method main$part1:(Lkotlin/text/Regex;Ljava/util/List;)I
      97: istore_3
      98: getstatic     #50                 // Field java/lang/System.out:Ljava/io/PrintStream;
     101: iload_3
     102: invokevirtual #56                 // Method java/io/PrintStream.println:(I)V
     105: aload_0
     106: aload_2
     107: invokestatic  #39                 // Method main$part2:(Lkotlin/text/Regex;Ljava/util/List;)I
     110: istore_3
     111: getstatic     #50                 // Field java/lang/System.out:Ljava/io/PrintStream;
     114: iload_3
     115: invokevirtual #56                 // Method java/io/PrintStream.println:(I)V
     118: return

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

  private static final Dir main$parseDirTree(kotlin.text.Regex, java.util.List<java.lang.String>);
    Code:
       0: new           #76                 // class Dir
       3: dup
       4: ldc           #78                 // String /
       6: aconst_null
       7: iconst_2
       8: aconst_null
       9: invokespecial #81                 // Method Dir."<init>":(Ljava/lang/String;LDir;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      12: astore_2
      13: aconst_null
      14: astore_3
      15: aload_2
      16: astore_3
      17: aload_1
      18: checkcast     #83                 // class java/lang/Iterable
      21: iconst_1
      22: invokestatic  #89                 // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      25: checkcast     #83                 // class java/lang/Iterable
      28: astore        4
      30: iconst_0
      31: istore        5
      33: aload         4
      35: invokeinterface #93,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      40: astore        6
      42: aload         6
      44: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      49: ifeq          239
      52: aload         6
      54: invokeinterface #103,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      59: astore        7
      61: aload         7
      63: checkcast     #105                // class java/lang/String
      66: astore        8
      68: iconst_0
      69: istore        9
      71: nop
      72: aload         8
      74: ldc           #107                // String $ cd ..
      76: iconst_0
      77: iconst_2
      78: aconst_null
      79: invokestatic  #113                // Method kotlin/text/StringsKt.startsWith$default:(Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Z
      82: ifeq          104
      85: aload_3
      86: invokevirtual #117                // Method Dir.getParentDir:()LDir;
      89: ifnull        234
      92: aload_3
      93: invokevirtual #117                // Method Dir.getParentDir:()LDir;
      96: dup
      97: invokestatic  #123                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     100: astore_3
     101: goto          234
     104: aload         8
     106: ldc           #125                // String $ cd
     108: iconst_0
     109: iconst_2
     110: aconst_null
     111: invokestatic  #113                // Method kotlin/text/StringsKt.startsWith$default:(Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Z
     114: ifeq          155
     117: new           #76                 // class Dir
     120: dup
     121: aload         8
     123: iconst_5
     124: invokevirtual #129                // Method java/lang/String.substring:(I)Ljava/lang/String;
     127: dup
     128: ldc           #131                // String substring(...)
     130: invokestatic  #135                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     133: aload_3
     134: invokespecial #138                // Method Dir."<init>":(Ljava/lang/String;LDir;)V
     137: astore        10
     139: aload_3
     140: aload         10
     142: checkcast     #140                // class Entry
     145: invokevirtual #144                // Method Dir.add:(LEntry;)LEntry;
     148: pop
     149: aload         10
     151: astore_3
     152: goto          234
     155: aload         8
     157: checkcast     #146                // class java/lang/CharSequence
     160: aload_0
     161: swap
     162: invokevirtual #150                // Method kotlin/text/Regex.matches:(Ljava/lang/CharSequence;)Z
     165: ifeq          234
     168: aload_0
     169: aload         8
     171: checkcast     #146                // class java/lang/CharSequence
     174: invokevirtual #154                // Method kotlin/text/Regex.matchEntire:(Ljava/lang/CharSequence;)Lkotlin/text/MatchResult;
     177: astore        10
     179: aload         10
     181: ifnull        234
     184: aload_3
     185: new           #156                // class File
     188: dup
     189: aload         10
     191: invokeinterface #162,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     196: iconst_2
     197: invokeinterface #166,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     202: checkcast     #105                // class java/lang/String
     205: aload         10
     207: invokeinterface #162,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     212: iconst_1
     213: invokeinterface #166,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     218: checkcast     #105                // class java/lang/String
     221: invokestatic  #172                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     224: invokespecial #175                // Method File."<init>":(Ljava/lang/String;I)V
     227: checkcast     #140                // class Entry
     230: invokevirtual #144                // Method Dir.add:(LEntry;)LEntry;
     233: pop
     234: nop
     235: nop
     236: goto          42
     239: nop
     240: aload_2
     241: areturn

  private static final int main$dirSizes(Dir, java.util.List<java.lang.Integer>);
    Code:
       0: iconst_0
       1: istore_2
       2: aload_0
       3: invokevirtual #195                // Method Dir.dirContent:()Ljava/util/List;
       6: checkcast     #83                 // class java/lang/Iterable
       9: astore_3
      10: iconst_0
      11: istore        4
      13: aload_3
      14: invokeinterface #93,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      19: astore        5
      21: aload         5
      23: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      28: ifeq          109
      31: aload         5
      33: invokeinterface #103,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      38: astore        6
      40: aload         6
      42: checkcast     #140                // class Entry
      45: astore        7
      47: iconst_0
      48: istore        8
      50: iload_2
      51: aload         7
      53: astore        9
      55: aload         9
      57: instanceof    #156                // class File
      60: ifeq          74
      63: aload         7
      65: checkcast     #156                // class File
      68: invokevirtual #199                // Method File.getSize:()I
      71: goto          102
      74: aload         9
      76: instanceof    #76                 // class Dir
      79: ifeq          94
      82: aload         7
      84: checkcast     #76                 // class Dir
      87: aload_1
      88: invokestatic  #201                // Method main$dirSizes:(LDir;Ljava/util/List;)I
      91: goto          102
      94: new           #203                // class kotlin/NoWhenBranchMatchedException
      97: dup
      98: invokespecial #205                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     101: athrow
     102: iadd
     103: istore_2
     104: nop
     105: nop
     106: goto          21
     109: nop
     110: aload_1
     111: checkcast     #207                // class java/util/Collection
     114: iload_2
     115: invokestatic  #211                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     118: invokeinterface #214,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     123: pop
     124: iload_2
     125: ireturn

  private static final int main$part1(kotlin.text.Regex, java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: aload_1
       2: invokestatic  #223                // Method main$parseDirTree:(Lkotlin/text/Regex;Ljava/util/List;)LDir;
       5: astore_2
       6: new           #225                // class java/util/ArrayList
       9: dup
      10: invokespecial #226                // Method java/util/ArrayList."<init>":()V
      13: checkcast     #66                 // class java/util/List
      16: astore_3
      17: aload_2
      18: aload_3
      19: invokestatic  #201                // Method main$dirSizes:(LDir;Ljava/util/List;)I
      22: pop
      23: aload_3
      24: checkcast     #83                 // class java/lang/Iterable
      27: astore        4
      29: iconst_0
      30: istore        5
      32: aload         4
      34: astore        6
      36: new           #225                // class java/util/ArrayList
      39: dup
      40: invokespecial #226                // Method java/util/ArrayList."<init>":()V
      43: checkcast     #207                // class java/util/Collection
      46: astore        7
      48: iconst_0
      49: istore        8
      51: aload         6
      53: invokeinterface #93,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      58: astore        9
      60: aload         9
      62: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      67: ifeq          120
      70: aload         9
      72: invokeinterface #103,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      77: astore        10
      79: aload         10
      81: checkcast     #228                // class java/lang/Number
      84: invokevirtual #231                // Method java/lang/Number.intValue:()I
      87: istore        11
      89: iconst_0
      90: istore        12
      92: iload         11
      94: ldc           #232                // int 100000
      96: if_icmpgt     103
      99: iconst_1
     100: goto          104
     103: iconst_0
     104: ifeq          60
     107: aload         7
     109: aload         10
     111: invokeinterface #214,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     116: pop
     117: goto          60
     120: aload         7
     122: checkcast     #66                 // class java/util/List
     125: nop
     126: checkcast     #83                 // class java/lang/Iterable
     129: invokestatic  #236                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     132: ireturn

  private static final int main$part2(kotlin.text.Regex, java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: aload_1
       2: invokestatic  #223                // Method main$parseDirTree:(Lkotlin/text/Regex;Ljava/util/List;)LDir;
       5: astore_2
       6: new           #225                // class java/util/ArrayList
       9: dup
      10: invokespecial #226                // Method java/util/ArrayList."<init>":()V
      13: checkcast     #66                 // class java/util/List
      16: astore_3
      17: aload_2
      18: aload_3
      19: invokestatic  #201                // Method main$dirSizes:(LDir;Ljava/util/List;)I
      22: istore        4
      24: ldc           #247                // int 70000000
      26: iload         4
      28: isub
      29: istore        5
      31: ldc           #248                // int 30000000
      33: iload         5
      35: isub
      36: istore        6
      38: aload_3
      39: checkcast     #83                 // class java/lang/Iterable
      42: astore        7
      44: iconst_0
      45: istore        8
      47: aload         7
      49: astore        9
      51: new           #225                // class java/util/ArrayList
      54: dup
      55: invokespecial #226                // Method java/util/ArrayList."<init>":()V
      58: checkcast     #207                // class java/util/Collection
      61: astore        10
      63: iconst_0
      64: istore        11
      66: aload         9
      68: invokeinterface #93,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      73: astore        12
      75: aload         12
      77: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      82: ifeq          135
      85: aload         12
      87: invokeinterface #103,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      92: astore        13
      94: aload         13
      96: checkcast     #228                // class java/lang/Number
      99: invokevirtual #231                // Method java/lang/Number.intValue:()I
     102: istore        14
     104: iconst_0
     105: istore        15
     107: iload         14
     109: iload         6
     111: if_icmplt     118
     114: iconst_1
     115: goto          119
     118: iconst_0
     119: ifeq          75
     122: aload         10
     124: aload         13
     126: invokeinterface #214,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     131: pop
     132: goto          75
     135: aload         10
     137: checkcast     #66                 // class java/util/List
     140: nop
     141: checkcast     #83                 // class java/lang/Iterable
     144: invokestatic  #252                // Method kotlin/collections/CollectionsKt.sorted:(Ljava/lang/Iterable;)Ljava/util/List;
     147: iconst_0
     148: invokeinterface #166,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     153: checkcast     #228                // class java/lang/Number
     156: invokevirtual #231                // Method java/lang/Number.intValue:()I
     159: ireturn
}

Compiled from "Day07.kt"
public final class Day07 {
  public static final Day07 INSTANCE;

  public static final int EXPECTED_PART1_CHECK_ANSWER;

  public static final int EXPECTED_PART2_CHECK_ANSWER;

  public static final int DIR_SIZE_THRESHOLD;

  public static final int FS_TOTAL_SIZE;

  public static final int FS_NEEDED_FREE_SPACE;

  private Day07();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #2                  // class Day07
       3: dup
       4: invokespecial #12                 // Method "<init>":()V
       7: putstatic     #15                 // Field INSTANCE:LDay07;
      10: return
}


object Day10 {
    const val EXPECTED_PART1_CHECK_ANSWER = 13140
    const val EXPECTED_PART2_CHECK_ANSWER = 1

    val CYCLE_PROBE_POINTS = listOf(20, 60, 100, 140, 180, 220)
    const val CRT_LINE_WIDTH = 40
}

sealed class CpuInstruction(val cycles: Int)

class Noop : CpuInstruction(1)
class AddX(val arg: Int) : CpuInstruction(2)

class Cpu(val instructions: List<CpuInstruction>) : ClockListener {
    private var instructionPointer: Int = 0
    private var instructionCyclesDone: Int = 0
    private val x: MutableList<Int> = mutableListOf(1)

    fun isDone() = instructionPointer >= instructions.size

    fun xAtCycle(cycle: Int) = x[cycle - 1]

    fun x() = x.last()

    override fun tickStart(cycle: Int) {
        // NOOP
    }

    override fun tickEnd(cycle: Int) {
        instructionCyclesDone++
        val currentXValue = if (x.isEmpty()) 1 else x.last()
        when (val currentInstruction = instructions[instructionPointer]) {
            is Noop -> {
                x.add(currentXValue)
                instructionPointer++
                instructionCyclesDone = 0
            }

            is AddX -> {
                if (currentInstruction.cycles == instructionCyclesDone) {
                    x.addAll(listOf(currentXValue, currentXValue + currentInstruction.arg))
                    instructionPointer++
                    instructionCyclesDone = 0
                }
            }
        }

    }
}

class Crt(private val cpu: Cpu) : ClockListener {
    override fun tickStart(cycle: Int) {
        val crtPos = cycle - 1
        val lineNumber = crtPos / Day10.CRT_LINE_WIDTH
        val positionInLine = crtPos - lineNumber * Day10.CRT_LINE_WIDTH
        print(if (positionInLine in (cpu.x() - 1)..(cpu.x() + 1)) "#" else ".")
        if (crtPos > 0 && cycle % Day10.CRT_LINE_WIDTH == 0) println()
    }

    override fun tickEnd(cycle: Int) {
        // NOOP
    }

}

interface ClockListener {
    fun tickStart(cycle: Int)
    fun tickEnd(cycle: Int)
}

fun main() {
    fun List<String>.parseInstructions(): List<CpuInstruction> =
        map { it.split(" ") }.map {
            when (it[0]) {
                "noop" -> Noop()
                "addx" -> AddX(it[1].toInt())
                else -> error("Unknown operation ${it[0]}")
            }
        }

    fun part1(input: List<String>): Int {
        val cpu = Cpu(input.parseInstructions())
        var cycle = 1
        while (!cpu.isDone()) {
            cpu.tickStart(cycle)
            cpu.tickEnd(cycle)
            cycle++
        }
        return Day10.CYCLE_PROBE_POINTS.sumOf { cpu.xAtCycle(it) * it }
    }

    fun part2(input: List<String>): Int {
        println("\n\n")
        val cpu = Cpu(input.parseInstructions())
        val crt = Crt(cpu)
        var cycle = 1
        while (!cpu.isDone()) {
            cpu.tickStart(cycle)
            crt.tickStart(cycle)
            cpu.tickEnd(cycle)
            crt.tickEnd(cycle)
            cycle++
        }
        return 1
    }

    // test if implementation meets criteria from the description, like:
    val testInput = readInput("Day10_test")
    check(part1(testInput) == Day10.EXPECTED_PART1_CHECK_ANSWER) { "Part 1 failed" }
    check(part2(testInput) == Day10.EXPECTED_PART2_CHECK_ANSWER) { "Part 2 failed" }

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

Compiled from "Day10.kt"
public final class Day10 {
  public static final Day10 INSTANCE;

  public static final int EXPECTED_PART1_CHECK_ANSWER;

  public static final int EXPECTED_PART2_CHECK_ANSWER;

  private static final java.util.List<java.lang.Integer> CYCLE_PROBE_POINTS;

  public static final int CRT_LINE_WIDTH;

  private Day10();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final java.util.List<java.lang.Integer> getCYCLE_PROBE_POINTS();
    Code:
       0: getstatic     #18                 // Field CYCLE_PROBE_POINTS:Ljava/util/List;
       3: areturn

  static {};
    Code:
       0: new           #2                  // class Day10
       3: dup
       4: invokespecial #20                 // Method "<init>":()V
       7: putstatic     #23                 // Field INSTANCE:LDay10;
      10: bipush        6
      12: anewarray     #25                 // class java/lang/Integer
      15: astore_0
      16: aload_0
      17: iconst_0
      18: bipush        20
      20: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      23: aastore
      24: aload_0
      25: iconst_1
      26: bipush        60
      28: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      31: aastore
      32: aload_0
      33: iconst_2
      34: bipush        100
      36: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      39: aastore
      40: aload_0
      41: iconst_3
      42: sipush        140
      45: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      48: aastore
      49: aload_0
      50: iconst_4
      51: sipush        180
      54: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      57: aastore
      58: aload_0
      59: iconst_5
      60: sipush        220
      63: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      66: aastore
      67: aload_0
      68: invokestatic  #35                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      71: putstatic     #18                 // Field CYCLE_PROBE_POINTS:Ljava/util/List;
      74: return
}

Compiled from "Day10.kt"
public final class Day10Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Day10_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        13140
      13: if_icmpne     20
      16: iconst_1
      17: goto          21
      20: iconst_0
      21: ifne          41
      24: iconst_0
      25: istore_2
      26: ldc           #20                 // String Part 1 failed
      28: astore_2
      29: new           #22                 // class java/lang/IllegalStateException
      32: dup
      33: aload_2
      34: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      37: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      40: athrow
      41: aload_0
      42: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      45: iconst_1
      46: if_icmpne     53
      49: iconst_1
      50: goto          54
      53: iconst_0
      54: ifne          74
      57: iconst_0
      58: istore_2
      59: ldc           #35                 // String Part 2 failed
      61: astore_2
      62: new           #22                 // class java/lang/IllegalStateException
      65: dup
      66: aload_2
      67: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      70: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      73: athrow
      74: ldc           #37                 // String Day10
      76: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      79: astore_1
      80: aload_1
      81: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      84: istore_2
      85: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      88: iload_2
      89: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
      92: aload_1
      93: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      96: istore_2
      97: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     100: iload_2
     101: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
     104: return

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

  private static final java.util.List<CpuInstruction> main$parseInstructions(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #67                 // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: astore_3
       9: new           #69                 // class java/util/ArrayList
      12: dup
      13: aload_1
      14: bipush        10
      16: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      19: invokespecial #77                 // Method java/util/ArrayList."<init>":(I)V
      22: checkcast     #79                 // class java/util/Collection
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          110
      48: aload         6
      50: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         4
      59: aload         7
      61: checkcast     #95                 // class java/lang/String
      64: astore        8
      66: astore        11
      68: iconst_0
      69: istore        9
      71: aload         8
      73: checkcast     #97                 // class java/lang/CharSequence
      76: iconst_1
      77: anewarray     #95                 // class java/lang/String
      80: astore        10
      82: aload         10
      84: iconst_0
      85: ldc           #99                 // String
      87: aastore
      88: aload         10
      90: iconst_0
      91: iconst_0
      92: bipush        6
      94: aconst_null
      95: invokestatic  #105                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      98: aload         11
     100: swap
     101: invokeinterface #109,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     106: pop
     107: goto          38
     110: aload         4
     112: checkcast     #57                 // class java/util/List
     115: nop
     116: checkcast     #67                 // class java/lang/Iterable
     119: astore_1
     120: nop
     121: iconst_0
     122: istore_2
     123: aload_1
     124: astore_3
     125: new           #69                 // class java/util/ArrayList
     128: dup
     129: aload_1
     130: bipush        10
     132: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     135: invokespecial #77                 // Method java/util/ArrayList."<init>":(I)V
     138: checkcast     #79                 // class java/util/Collection
     141: astore        4
     143: iconst_0
     144: istore        5
     146: aload_3
     147: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     152: astore        6
     154: aload         6
     156: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     161: ifeq          313
     164: aload         6
     166: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     171: astore        7
     173: aload         4
     175: aload         7
     177: checkcast     #57                 // class java/util/List
     180: astore        8
     182: astore        11
     184: iconst_0
     185: istore        9
     187: aload         8
     189: iconst_0
     190: invokeinterface #113,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     195: checkcast     #95                 // class java/lang/String
     198: astore        10
     200: aload         10
     202: ldc           #115                // String noop
     204: invokestatic  #121                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     207: ifeq          223
     210: new           #123                // class Noop
     213: dup
     214: invokespecial #125                // Method Noop."<init>":()V
     217: checkcast     #127                // class CpuInstruction
     220: goto          300
     223: aload         10
     225: ldc           #129                // String addx
     227: invokestatic  #121                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     230: ifeq          260
     233: new           #131                // class AddX
     236: dup
     237: aload         8
     239: iconst_1
     240: invokeinterface #113,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     245: checkcast     #95                 // class java/lang/String
     248: invokestatic  #137                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     251: invokespecial #138                // Method AddX."<init>":(I)V
     254: checkcast     #127                // class CpuInstruction
     257: goto          300
     260: new           #22                 // class java/lang/IllegalStateException
     263: dup
     264: new           #140                // class java/lang/StringBuilder
     267: dup
     268: invokespecial #141                // Method java/lang/StringBuilder."<init>":()V
     271: ldc           #143                // String Unknown operation
     273: invokevirtual #147                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     276: aload         8
     278: iconst_0
     279: invokeinterface #113,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     284: checkcast     #95                 // class java/lang/String
     287: invokevirtual #147                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     290: invokevirtual #148                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     293: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
     296: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     299: athrow
     300: nop
     301: aload         11
     303: swap
     304: invokeinterface #109,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     309: pop
     310: goto          154
     313: aload         4
     315: checkcast     #57                 // class java/util/List
     318: nop
     319: areturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: new           #165                // class Cpu
       3: dup
       4: aload_0
       5: invokestatic  #167                // Method main$parseInstructions:(Ljava/util/List;)Ljava/util/List;
       8: invokespecial #170                // Method Cpu."<init>":(Ljava/util/List;)V
      11: astore_1
      12: iconst_1
      13: istore_2
      14: aload_1
      15: invokevirtual #173                // Method Cpu.isDone:()Z
      18: ifne          37
      21: aload_1
      22: iload_2
      23: invokevirtual #176                // Method Cpu.tickStart:(I)V
      26: aload_1
      27: iload_2
      28: invokevirtual #179                // Method Cpu.tickEnd:(I)V
      31: iinc          2, 1
      34: goto          14
      37: getstatic     #184                // Field Day10.INSTANCE:LDay10;
      40: invokevirtual #188                // Method Day10.getCYCLE_PROBE_POINTS:()Ljava/util/List;
      43: checkcast     #67                 // class java/lang/Iterable
      46: astore_3
      47: iconst_0
      48: istore        4
      50: aload_3
      51: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      56: astore        5
      58: aload         5
      60: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      65: ifeq          115
      68: aload         5
      70: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      75: astore        6
      77: iload         4
      79: aload         6
      81: checkcast     #190                // class java/lang/Number
      84: invokevirtual #194                // Method java/lang/Number.intValue:()I
      87: istore        7
      89: istore        9
      91: iconst_0
      92: istore        8
      94: aload_1
      95: iload         7
      97: invokevirtual #198                // Method Cpu.xAtCycle:(I)I
     100: iload         7
     102: imul
     103: istore        10
     105: iload         9
     107: iload         10
     109: iadd
     110: istore        4
     112: goto          58
     115: iload         4
     117: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: ldc           #204                // String \n\n
       2: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
       5: swap
       6: invokevirtual #207                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
       9: new           #165                // class Cpu
      12: dup
      13: aload_0
      14: invokestatic  #167                // Method main$parseInstructions:(Ljava/util/List;)Ljava/util/List;
      17: invokespecial #170                // Method Cpu."<init>":(Ljava/util/List;)V
      20: astore_1
      21: new           #209                // class Crt
      24: dup
      25: aload_1
      26: invokespecial #212                // Method Crt."<init>":(LCpu;)V
      29: astore_2
      30: iconst_1
      31: istore_3
      32: aload_1
      33: invokevirtual #173                // Method Cpu.isDone:()Z
      36: ifne          65
      39: aload_1
      40: iload_3
      41: invokevirtual #176                // Method Cpu.tickStart:(I)V
      44: aload_2
      45: iload_3
      46: invokevirtual #213                // Method Crt.tickStart:(I)V
      49: aload_1
      50: iload_3
      51: invokevirtual #179                // Method Cpu.tickEnd:(I)V
      54: aload_2
      55: iload_3
      56: invokevirtual #214                // Method Crt.tickEnd:(I)V
      59: iinc          3, 1
      62: goto          32
      65: iconst_1
      66: ireturn
}


import kotlin.system.measureNanoTime

object Day06 {
    const val EXPECTED_PART1_CHECK_ANSWER = 7
    const val EXPECTED_PART2_CHECK_ANSWER = 19

    const val MARKER_PACKET_LENGTH = 4
    const val MARKER_MESSAGE_LENGTH = 14
}

fun main() {

    fun String.findLengthUntilMarker(markerLength: Int): Int {
        var pointerInData = 0
        var potentialMarker = ""
        do {
            when (val indexOfDuplicate = potentialMarker.indexOf(this[pointerInData])) {
                -1 -> potentialMarker += this[pointerInData]
                else -> potentialMarker = potentialMarker.drop(indexOfDuplicate + 1) + this[pointerInData]
            }
            pointerInData++
        } while (potentialMarker.length < markerLength && pointerInData < this.length)
        return pointerInData
    }

    fun String.findLengthUntilMarkerWindowed(markerLength: Int) =
        windowedSequence(markerLength) { it.toSet().size }.indexOfFirst { it == markerLength } + markerLength

    fun part1(input: List<String>): Int {
        val windowedDuration = measureNanoTime {
            input.first().findLengthUntilMarkerWindowed(Day06.MARKER_PACKET_LENGTH)
        }
        val nonWindowedDuration = measureNanoTime {
            input.first().findLengthUntilMarker(Day06.MARKER_PACKET_LENGTH)
        }

        println("Windowed: $windowedDuration, Non windowed: $nonWindowedDuration")

        return input.first().findLengthUntilMarkerWindowed(Day06.MARKER_PACKET_LENGTH)
    }

    fun part2(input: List<String>): Int {
        val windowedDuration = measureNanoTime {
            input.first().findLengthUntilMarkerWindowed(Day06.MARKER_MESSAGE_LENGTH)
        }
        val nonWindowedDuration = measureNanoTime {
            input.first().findLengthUntilMarker(Day06.MARKER_MESSAGE_LENGTH)
        }

        println("Windowed: $windowedDuration, Non windowed: $nonWindowedDuration")

        return input.first().findLengthUntilMarkerWindowed(Day06.MARKER_MESSAGE_LENGTH)
    }

    // test if implementation meets criteria from the description, like:
    val testInput = readInput("Day06_test")
    check(part1(testInput) == Day06.EXPECTED_PART1_CHECK_ANSWER) { "Part 1 failed" }
    check(part2(testInput) == Day06.EXPECTED_PART2_CHECK_ANSWER) { "Part 2 failed" }

    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
       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: bipush        7
      12: if_icmpne     19
      15: iconst_1
      16: goto          20
      19: iconst_0
      20: ifne          40
      23: iconst_0
      24: istore_2
      25: ldc           #20                 // String Part 1 failed
      27: astore_2
      28: new           #22                 // class java/lang/IllegalStateException
      31: dup
      32: aload_2
      33: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      36: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      39: athrow
      40: aload_0
      41: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      44: bipush        19
      46: if_icmpne     53
      49: iconst_1
      50: goto          54
      53: iconst_0
      54: ifne          74
      57: iconst_0
      58: istore_2
      59: ldc           #35                 // String Part 2 failed
      61: astore_2
      62: new           #22                 // class java/lang/IllegalStateException
      65: dup
      66: aload_2
      67: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      70: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      73: athrow
      74: ldc           #37                 // String Day06
      76: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      79: astore_1
      80: aload_1
      81: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      84: istore_2
      85: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      88: iload_2
      89: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
      92: aload_1
      93: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      96: istore_2
      97: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     100: iload_2
     101: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
     104: return

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

  private static final int main$findLengthUntilMarker(java.lang.String, int);
    Code:
       0: iconst_0
       1: istore_2
       2: ldc           #66                 // String
       4: astore_3
       5: aload_3
       6: checkcast     #68                 // class java/lang/CharSequence
       9: aload_0
      10: iload_2
      11: invokevirtual #74                 // Method java/lang/String.charAt:(I)C
      14: iconst_0
      15: iconst_0
      16: bipush        6
      18: aconst_null
      19: invokestatic  #80                 // Method kotlin/text/StringsKt.indexOf$default:(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
      22: istore        4
      24: iload         4
      26: iconst_m1
      27: if_icmpne     56
      30: new           #82                 // class java/lang/StringBuilder
      33: dup
      34: invokespecial #84                 // Method java/lang/StringBuilder."<init>":()V
      37: aload_3
      38: invokevirtual #88                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      41: aload_0
      42: iload_2
      43: invokevirtual #74                 // Method java/lang/String.charAt:(I)C
      46: invokevirtual #91                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      49: invokevirtual #92                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      52: astore_3
      53: goto          86
      56: new           #82                 // class java/lang/StringBuilder
      59: dup
      60: invokespecial #84                 // Method java/lang/StringBuilder."<init>":()V
      63: aload_3
      64: iload         4
      66: iconst_1
      67: iadd
      68: invokestatic  #96                 // Method kotlin/text/StringsKt.drop:(Ljava/lang/String;I)Ljava/lang/String;
      71: invokevirtual #88                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      74: aload_0
      75: iload_2
      76: invokevirtual #74                 // Method java/lang/String.charAt:(I)C
      79: invokevirtual #91                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      82: invokevirtual #92                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      85: astore_3
      86: iinc          2, 1
      89: aload_3
      90: invokevirtual #100                // Method java/lang/String.length:()I
      93: iload_1
      94: if_icmpge     105
      97: iload_2
      98: aload_0
      99: invokevirtual #100                // Method java/lang/String.length:()I
     102: if_icmplt     5
     105: iload_2
     106: ireturn

  private static final int main$findLengthUntilMarkerWindowed$lambda$0(java.lang.CharSequence);
    Code:
       0: aload_0
       1: ldc           #110                // String it
       3: invokestatic  #116                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #120                // Method kotlin/text/StringsKt.toSet:(Ljava/lang/CharSequence;)Ljava/util/Set;
      10: invokeinterface #125,  1          // InterfaceMethod java/util/Set.size:()I
      15: ireturn

  private static final int main$findLengthUntilMarkerWindowed(java.lang.String, int);
    Code:
       0: aload_0
       1: checkcast     #68                 // class java/lang/CharSequence
       4: iload_1
       5: iconst_0
       6: iconst_0
       7: invokedynamic #145,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
      12: bipush        6
      14: aconst_null
      15: invokestatic  #149                // Method kotlin/text/StringsKt.windowedSequence$default:(Ljava/lang/CharSequence;IIZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/sequences/Sequence;
      18: astore_2
      19: iconst_0
      20: istore_3
      21: iconst_0
      22: istore        4
      24: aload_2
      25: invokeinterface #155,  1          // InterfaceMethod kotlin/sequences/Sequence.iterator:()Ljava/util/Iterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #161,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          97
      42: aload         5
      44: invokeinterface #165,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      49: astore        6
      51: iload         4
      53: ifge          59
      56: invokestatic  #170                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
      59: aload         6
      61: checkcast     #172                // class java/lang/Number
      64: invokevirtual #175                // Method java/lang/Number.intValue:()I
      67: istore        7
      69: iconst_0
      70: istore        8
      72: iload         7
      74: iload_1
      75: if_icmpne     82
      78: iconst_1
      79: goto          83
      82: iconst_0
      83: ifeq          91
      86: iload         4
      88: goto          98
      91: iinc          4, 1
      94: goto          32
      97: iconst_m1
      98: iload_1
      99: iadd
     100: ireturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: iconst_0
       1: istore_3
       2: invokestatic  #188                // Method java/lang/System.nanoTime:()J
       5: lstore        4
       7: iconst_0
       8: istore        6
      10: aload_0
      11: invokestatic  #192                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      14: checkcast     #70                 // class java/lang/String
      17: iconst_4
      18: invokestatic  #194                // Method main$findLengthUntilMarkerWindowed:(Ljava/lang/String;I)I
      21: pop
      22: nop
      23: nop
      24: invokestatic  #188                // Method java/lang/System.nanoTime:()J
      27: lload         4
      29: lsub
      30: lstore_1
      31: iconst_0
      32: istore        5
      34: invokestatic  #188                // Method java/lang/System.nanoTime:()J
      37: lstore        6
      39: iconst_0
      40: istore        8
      42: aload_0
      43: invokestatic  #192                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      46: checkcast     #70                 // class java/lang/String
      49: iconst_4
      50: invokestatic  #196                // Method main$findLengthUntilMarker:(Ljava/lang/String;I)I
      53: pop
      54: nop
      55: nop
      56: invokestatic  #188                // Method java/lang/System.nanoTime:()J
      59: lload         6
      61: lsub
      62: lstore_3
      63: new           #82                 // class java/lang/StringBuilder
      66: dup
      67: invokespecial #84                 // Method java/lang/StringBuilder."<init>":()V
      70: ldc           #198                // String Windowed:
      72: invokevirtual #88                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      75: lload_1
      76: invokevirtual #201                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      79: ldc           #203                // String , Non windowed:
      81: invokevirtual #88                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      84: lload_3
      85: invokevirtual #201                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      88: invokevirtual #92                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      91: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      94: swap
      95: invokevirtual #206                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      98: aload_0
      99: invokestatic  #192                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     102: checkcast     #70                 // class java/lang/String
     105: iconst_4
     106: invokestatic  #194                // Method main$findLengthUntilMarkerWindowed:(Ljava/lang/String;I)I
     109: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: iconst_0
       1: istore_3
       2: invokestatic  #188                // Method java/lang/System.nanoTime:()J
       5: lstore        4
       7: iconst_0
       8: istore        6
      10: aload_0
      11: invokestatic  #192                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      14: checkcast     #70                 // class java/lang/String
      17: bipush        14
      19: invokestatic  #194                // Method main$findLengthUntilMarkerWindowed:(Ljava/lang/String;I)I
      22: pop
      23: nop
      24: nop
      25: invokestatic  #188                // Method java/lang/System.nanoTime:()J
      28: lload         4
      30: lsub
      31: lstore_1
      32: iconst_0
      33: istore        5
      35: invokestatic  #188                // Method java/lang/System.nanoTime:()J
      38: lstore        6
      40: iconst_0
      41: istore        8
      43: aload_0
      44: invokestatic  #192                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      47: checkcast     #70                 // class java/lang/String
      50: bipush        14
      52: invokestatic  #196                // Method main$findLengthUntilMarker:(Ljava/lang/String;I)I
      55: pop
      56: nop
      57: nop
      58: invokestatic  #188                // Method java/lang/System.nanoTime:()J
      61: lload         6
      63: lsub
      64: lstore_3
      65: new           #82                 // class java/lang/StringBuilder
      68: dup
      69: invokespecial #84                 // Method java/lang/StringBuilder."<init>":()V
      72: ldc           #198                // String Windowed:
      74: invokevirtual #88                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      77: lload_1
      78: invokevirtual #201                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      81: ldc           #203                // String , Non windowed:
      83: invokevirtual #88                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      86: lload_3
      87: invokevirtual #201                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      90: invokevirtual #92                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      93: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      96: swap
      97: invokevirtual #206                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     100: aload_0
     101: invokestatic  #192                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     104: checkcast     #70                 // class java/lang/String
     107: bipush        14
     109: invokestatic  #194                // Method main$findLengthUntilMarkerWindowed:(Ljava/lang/String;I)I
     112: ireturn
}

Compiled from "Day06.kt"
public final class Day06 {
  public static final Day06 INSTANCE;

  public static final int EXPECTED_PART1_CHECK_ANSWER;

  public static final int EXPECTED_PART2_CHECK_ANSWER;

  public static final int MARKER_PACKET_LENGTH;

  public static final int MARKER_MESSAGE_LENGTH;

  private Day06();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #2                  // class Day06
       3: dup
       4: invokespecial #12                 // Method "<init>":()V
       7: putstatic     #15                 // Field INSTANCE:LDay06;
      10: return
}