import java.io.File
import java.util.Stack

typealias Stacks<E> = List<Stack<E>>
typealias StacksOfChar = Stacks<Char>

fun main() {

    fun part1(input: String) = findCratesOnTopOfAllStacks(
        input,
        StacksOfChar::moveOneStackAtTime
    )

    fun part2(input: String) = findCratesOnTopOfAllStacks(
        input,
        StacksOfChar::moveAllStacksOnce
    )

    // test if implementation meets criteria from the description, like:
//    val testInput = readInputAsString("Day05_test")
//    check(part1(testInput) == "CMZ")
//    check(part2(testInput) == "MCD")
//
//    val input = readInputAsString("Day05")
//    println(part1(input))
//    println(part2(input))
}

fun findCratesOnTopOfAllStacks(
    input: String,
    moveOneOrAllAtATime: StacksOfChar.(Int, Int, Int) -> StacksOfChar
): String {
    val (stackData, proceduresData) = input
        .split("\n\r\n") // separate the information of stacks from that of procedures
    val stackSize = stackData
        .toIntStackSize() // get the last number of the stacks which is in turn the size of stacks
    val listOfStacks = buildList { repeat(stackSize) { add(Stack<Char>()) } }
    stackData
        .lines() // get the cranes at each level of the stacks from the top
        .dropLast(2) // the line with the numbering of the stacks
        .map {
            it
                .chunked(4)
                .map { it[1] }
        } // remove the clutter such as the space and the brackets, take only the character content of the cranes
        .foldRight(listOfStacks) { cranes, stacks ->
            cranes.forEachIndexed { craneStackNum, crane ->
                if (crane.toString().isNotBlank()) {
                    stacks[craneStackNum].push(crane) // push the crates into the list of stacks
                }
            } // build the initial state of the states
            stacks
        }
    proceduresData
        .lines() // get the lines of the procedures
        .map {
            it.split(" ")
        }
        .fold(listOfStacks) { stacks, procedure ->
            stacks
                .moveOneOrAllAtATime(
                    procedure[1].toInt(), // the number of cranes to move
                    procedure[3].toInt() - 1, // the stack to move the cranes from
                    procedure[5].toInt() - 1 // the stack to move the cranes to
                )
        }
    return buildString { listOfStacks.forEach { if (it.isEmpty()) append(" ") else append(it.pop()) } }
}

private fun <E> Stacks<E>.moveOneStackAtTime(crates: Int, fromStack: Int, toStack: Int): Stacks<E> = apply {
    repeat(crates) {
        if (this[fromStack].isNotEmpty()) {
            this[toStack].push(this[fromStack].pop())
        } else this.map { println(it) }
    }
}

private fun <E> Stacks<E>.moveAllStacksOnce(crates: Int, fromStack: Int, toStack: Int): Stacks<E> = apply {
    val tempStack = Stack<E>()
    repeat(crates) {
        if (this[fromStack].isNotEmpty()) {
            tempStack.push(this[fromStack].pop())
        } else this.map { println(it) }
    }
    repeat(crates) {
        if (tempStack.isNotEmpty()) {
            this[toStack].push(tempStack.pop())
        }
    }
}

private fun String.toIntStackSize() = split("\n")
    .last()// get the labels of all the stack
    .split(" ")// get the list of each stack's label
    .last() // get the last stack's label
    .trim() // remove any characters around the label
    .toInt() // return the label as an Int

Compiled from "Day05.kt"
public final class Day05Kt {
  public static final void main();
    Code:
       0: return

  public static final java.lang.String findCratesOnTopOfAllStacks(java.lang.String, kotlin.jvm.functions.Function4<? super java.util.List<? extends java.util.Stack<java.lang.Character>>, ? super java.lang.Integer, ? super java.lang.Integer, ? super java.lang.Integer, ? extends java.util.List<? extends java.util.Stack<java.lang.Character>>>);
    Code:
       0: aload_0
       1: ldc           #12                 // String input
       3: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #20                 // String moveOneOrAllAtATime
       9: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #22                 // class java/lang/CharSequence
      16: iconst_1
      17: anewarray     #24                 // class java/lang/String
      20: astore_3
      21: aload_3
      22: iconst_0
      23: ldc           #26                 // String \n\r\n
      25: aastore
      26: aload_3
      27: iconst_0
      28: iconst_0
      29: bipush        6
      31: aconst_null
      32: invokestatic  #32                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      35: astore_2
      36: aload_2
      37: iconst_0
      38: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      43: checkcast     #24                 // class java/lang/String
      46: astore_3
      47: aload_2
      48: iconst_1
      49: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      54: checkcast     #24                 // class java/lang/String
      57: astore        4
      59: aload_3
      60: invokestatic  #42                 // Method toIntStackSize:(Ljava/lang/String;)I
      63: istore        5
      65: invokestatic  #48                 // Method kotlin/collections/CollectionsKt.createListBuilder:()Ljava/util/List;
      68: astore        7
      70: aload         7
      72: astore        8
      74: iconst_0
      75: istore        9
      77: iconst_0
      78: istore        10
      80: iload         10
      82: iload         5
      84: if_icmpge     115
      87: iload         10
      89: istore        11
      91: iconst_0
      92: istore        12
      94: aload         8
      96: new           #50                 // class java/util/Stack
      99: dup
     100: invokespecial #53                 // Method java/util/Stack."<init>":()V
     103: invokeinterface #57,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     108: pop
     109: iinc          10, 1
     112: goto          80
     115: nop
     116: aload         7
     118: invokestatic  #61                 // Method kotlin/collections/CollectionsKt.build:(Ljava/util/List;)Ljava/util/List;
     121: astore        6
     123: aload_3
     124: checkcast     #22                 // class java/lang/CharSequence
     127: invokestatic  #65                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
     130: iconst_2
     131: invokestatic  #69                 // Method kotlin/collections/CollectionsKt.dropLast:(Ljava/util/List;I)Ljava/util/List;
     134: checkcast     #71                 // class java/lang/Iterable
     137: astore        7
     139: nop
     140: iconst_0
     141: istore        8
     143: aload         7
     145: astore        9
     147: new           #73                 // class java/util/ArrayList
     150: dup
     151: aload         7
     153: bipush        10
     155: invokestatic  #77                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     158: invokespecial #80                 // Method java/util/ArrayList."<init>":(I)V
     161: checkcast     #82                 // class java/util/Collection
     164: astore        10
     166: iconst_0
     167: istore        11
     169: aload         9
     171: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     176: astore        12
     178: aload         12
     180: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     185: ifeq          337
     188: aload         12
     190: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     195: astore        13
     197: aload         10
     199: aload         13
     201: checkcast     #24                 // class java/lang/String
     204: astore        14
     206: astore        26
     208: iconst_0
     209: istore        15
     211: aload         14
     213: checkcast     #22                 // class java/lang/CharSequence
     216: iconst_4
     217: invokestatic  #100                // Method kotlin/text/StringsKt.chunked:(Ljava/lang/CharSequence;I)Ljava/util/List;
     220: checkcast     #71                 // class java/lang/Iterable
     223: astore        16
     225: nop
     226: iconst_0
     227: istore        17
     229: aload         16
     231: astore        18
     233: new           #73                 // class java/util/ArrayList
     236: dup
     237: aload         16
     239: bipush        10
     241: invokestatic  #77                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     244: invokespecial #80                 // Method java/util/ArrayList."<init>":(I)V
     247: checkcast     #82                 // class java/util/Collection
     250: astore        19
     252: iconst_0
     253: istore        20
     255: aload         18
     257: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     262: astore        21
     264: aload         21
     266: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     271: ifeq          318
     274: aload         21
     276: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     281: astore        22
     283: aload         19
     285: aload         22
     287: checkcast     #24                 // class java/lang/String
     290: astore        23
     292: astore        24
     294: iconst_0
     295: istore        25
     297: aload         23
     299: iconst_1
     300: invokevirtual #104                // Method java/lang/String.charAt:(I)C
     303: invokestatic  #110                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     306: aload         24
     308: swap
     309: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     314: pop
     315: goto          264
     318: aload         19
     320: checkcast     #34                 // class java/util/List
     323: nop
     324: nop
     325: aload         26
     327: swap
     328: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     333: pop
     334: goto          178
     337: aload         10
     339: checkcast     #34                 // class java/util/List
     342: nop
     343: astore        7
     345: nop
     346: iconst_0
     347: istore        8
     349: aload         6
     351: astore        9
     353: aload         7
     355: invokeinterface #114,  1          // InterfaceMethod java/util/List.isEmpty:()Z
     360: ifne          537
     363: aload         7
     365: aload         7
     367: invokeinterface #118,  1          // InterfaceMethod java/util/List.size:()I
     372: invokeinterface #122,  2          // InterfaceMethod java/util/List.listIterator:(I)Ljava/util/ListIterator;
     377: astore        10
     379: aload         10
     381: invokeinterface #127,  1          // InterfaceMethod java/util/ListIterator.hasPrevious:()Z
     386: ifeq          537
     389: aload         10
     391: invokeinterface #130,  1          // InterfaceMethod java/util/ListIterator.previous:()Ljava/lang/Object;
     396: aload         9
     398: astore        11
     400: checkcast     #34                 // class java/util/List
     403: astore        12
     405: iconst_0
     406: istore        13
     408: aload         12
     410: checkcast     #71                 // class java/lang/Iterable
     413: astore        14
     415: iconst_0
     416: istore        15
     418: iconst_0
     419: istore        16
     421: aload         14
     423: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     428: astore        17
     430: aload         17
     432: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     437: ifeq          529
     440: aload         17
     442: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     447: astore        18
     449: iload         16
     451: iinc          16, 1
     454: istore        19
     456: iload         19
     458: ifge          464
     461: invokestatic  #133                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     464: iload         19
     466: aload         18
     468: checkcast     #106                // class java/lang/Character
     471: invokevirtual #137                // Method java/lang/Character.charValue:()C
     474: istore        20
     476: istore        21
     478: iconst_0
     479: istore        22
     481: iload         20
     483: invokestatic  #140                // Method java/lang/String.valueOf:(C)Ljava/lang/String;
     486: checkcast     #22                 // class java/lang/CharSequence
     489: invokestatic  #144                // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
     492: ifne          499
     495: iconst_1
     496: goto          500
     499: iconst_0
     500: ifeq          524
     503: aload         11
     505: iload         21
     507: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     512: checkcast     #50                 // class java/util/Stack
     515: iload         20
     517: invokestatic  #110                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     520: invokevirtual #148                // Method java/util/Stack.push:(Ljava/lang/Object;)Ljava/lang/Object;
     523: pop
     524: nop
     525: nop
     526: goto          430
     529: nop
     530: aload         11
     532: astore        9
     534: goto          379
     537: nop
     538: aload         4
     540: checkcast     #22                 // class java/lang/CharSequence
     543: invokestatic  #65                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
     546: checkcast     #71                 // class java/lang/Iterable
     549: astore        7
     551: nop
     552: iconst_0
     553: istore        8
     555: aload         7
     557: astore        9
     559: new           #73                 // class java/util/ArrayList
     562: dup
     563: aload         7
     565: bipush        10
     567: invokestatic  #77                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     570: invokespecial #80                 // Method java/util/ArrayList."<init>":(I)V
     573: checkcast     #82                 // class java/util/Collection
     576: astore        10
     578: iconst_0
     579: istore        11
     581: aload         9
     583: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     588: astore        12
     590: aload         12
     592: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     597: ifeq          662
     600: aload         12
     602: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     607: astore        13
     609: aload         10
     611: aload         13
     613: checkcast     #24                 // class java/lang/String
     616: astore        14
     618: astore        26
     620: iconst_0
     621: istore        15
     623: aload         14
     625: checkcast     #22                 // class java/lang/CharSequence
     628: iconst_1
     629: anewarray     #24                 // class java/lang/String
     632: astore        16
     634: aload         16
     636: iconst_0
     637: ldc           #150                // String
     639: aastore
     640: aload         16
     642: iconst_0
     643: iconst_0
     644: bipush        6
     646: aconst_null
     647: invokestatic  #32                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     650: aload         26
     652: swap
     653: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     658: pop
     659: goto          590
     662: aload         10
     664: checkcast     #34                 // class java/util/List
     667: nop
     668: checkcast     #71                 // class java/lang/Iterable
     671: astore        7
     673: nop
     674: iconst_0
     675: istore        8
     677: aload         6
     679: astore        9
     681: aload         7
     683: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     688: astore        10
     690: aload         10
     692: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     697: ifeq          795
     700: aload         10
     702: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     707: astore        11
     709: aload         9
     711: aload         11
     713: checkcast     #34                 // class java/util/List
     716: astore        12
     718: astore        13
     720: iconst_0
     721: istore        14
     723: aload_1
     724: aload         13
     726: aload         12
     728: iconst_1
     729: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     734: checkcast     #24                 // class java/lang/String
     737: invokestatic  #155                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     740: invokestatic  #158                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     743: aload         12
     745: iconst_3
     746: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     751: checkcast     #24                 // class java/lang/String
     754: invokestatic  #155                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     757: iconst_1
     758: isub
     759: invokestatic  #158                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     762: aload         12
     764: iconst_5
     765: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     770: checkcast     #24                 // class java/lang/String
     773: invokestatic  #155                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     776: iconst_1
     777: isub
     778: invokestatic  #158                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     781: invokeinterface #164,  5          // InterfaceMethod kotlin/jvm/functions/Function4.invoke:(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     786: checkcast     #34                 // class java/util/List
     789: nop
     790: astore        9
     792: goto          690
     795: nop
     796: new           #166                // class java/lang/StringBuilder
     799: dup
     800: invokespecial #167                // Method java/lang/StringBuilder."<init>":()V
     803: astore        7
     805: aload         7
     807: astore        8
     809: iconst_0
     810: istore        9
     812: aload         6
     814: checkcast     #71                 // class java/lang/Iterable
     817: astore        10
     819: iconst_0
     820: istore        11
     822: aload         10
     824: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     829: astore        12
     831: aload         12
     833: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     838: ifeq          905
     841: aload         12
     843: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     848: astore        13
     850: aload         13
     852: checkcast     #50                 // class java/util/Stack
     855: astore        14
     857: iconst_0
     858: istore        15
     860: aload         14
     862: invokevirtual #168                // Method java/util/Stack.isEmpty:()Z
     865: ifeq          878
     868: aload         8
     870: ldc           #150                // String
     872: invokevirtual #172                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     875: goto          900
     878: aload         8
     880: aload         14
     882: invokevirtual #175                // Method java/util/Stack.pop:()Ljava/lang/Object;
     885: dup
     886: ldc           #177                // String pop(...)
     888: invokestatic  #180                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     891: checkcast     #106                // class java/lang/Character
     894: invokevirtual #137                // Method java/lang/Character.charValue:()C
     897: invokevirtual #183                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     900: pop
     901: nop
     902: goto          831
     905: nop
     906: nop
     907: aload         7
     909: invokevirtual #187                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     912: areturn

  private static final <E> java.util.List<java.util.Stack<E>> moveOneStackAtTime(java.util.List<? extends java.util.Stack<E>>, int, int, int);
    Code:
       0: aload_0
       1: astore        4
       3: aload         4
       5: astore        5
       7: iconst_0
       8: istore        6
      10: iconst_0
      11: istore        7
      13: iload         7
      15: iload_1
      16: if_icmpge     199
      19: iload         7
      21: istore        8
      23: iconst_0
      24: istore        9
      26: aload         5
      28: iload_2
      29: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      34: checkcast     #82                 // class java/util/Collection
      37: invokeinterface #243,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
      42: ifne          49
      45: iconst_1
      46: goto          50
      49: iconst_0
      50: ifeq          84
      53: aload         5
      55: iload_3
      56: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      61: checkcast     #50                 // class java/util/Stack
      64: aload         5
      66: iload_2
      67: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      72: checkcast     #50                 // class java/util/Stack
      75: invokevirtual #175                // Method java/util/Stack.pop:()Ljava/lang/Object;
      78: invokevirtual #148                // Method java/util/Stack.push:(Ljava/lang/Object;)Ljava/lang/Object;
      81: goto          191
      84: aload         5
      86: checkcast     #71                 // class java/lang/Iterable
      89: astore        10
      91: iconst_0
      92: istore        11
      94: aload         10
      96: astore        12
      98: new           #73                 // class java/util/ArrayList
     101: dup
     102: aload         10
     104: bipush        10
     106: invokestatic  #77                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     109: invokespecial #80                 // Method java/util/ArrayList."<init>":(I)V
     112: checkcast     #82                 // class java/util/Collection
     115: astore        13
     117: iconst_0
     118: istore        14
     120: aload         12
     122: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     127: astore        15
     129: aload         15
     131: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     136: ifeq          185
     139: aload         15
     141: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     146: astore        16
     148: aload         13
     150: aload         16
     152: checkcast     #50                 // class java/util/Stack
     155: astore        17
     157: astore        18
     159: iconst_0
     160: istore        19
     162: getstatic     #249                // Field java/lang/System.out:Ljava/io/PrintStream;
     165: aload         17
     167: invokevirtual #255                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     170: nop
     171: aload         18
     173: getstatic     #261                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     176: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     181: pop
     182: goto          129
     185: aload         13
     187: checkcast     #34                 // class java/util/List
     190: nop
     191: pop
     192: nop
     193: iinc          7, 1
     196: goto          13
     199: nop
     200: aload         4
     202: areturn

  private static final <E> java.util.List<java.util.Stack<E>> moveAllStacksOnce(java.util.List<? extends java.util.Stack<E>>, int, int, int);
    Code:
       0: aload_0
       1: astore        4
       3: aload         4
       5: astore        5
       7: iconst_0
       8: istore        6
      10: new           #50                 // class java/util/Stack
      13: dup
      14: invokespecial #53                 // Method java/util/Stack."<init>":()V
      17: astore        7
      19: iconst_0
      20: istore        8
      22: iload         8
      24: iload_1
      25: if_icmpge     199
      28: iload         8
      30: istore        9
      32: iconst_0
      33: istore        10
      35: aload         5
      37: iload_2
      38: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      43: checkcast     #82                 // class java/util/Collection
      46: invokeinterface #243,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
      51: ifne          58
      54: iconst_1
      55: goto          59
      58: iconst_0
      59: ifeq          84
      62: aload         7
      64: aload         5
      66: iload_2
      67: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      72: checkcast     #50                 // class java/util/Stack
      75: invokevirtual #175                // Method java/util/Stack.pop:()Ljava/lang/Object;
      78: invokevirtual #148                // Method java/util/Stack.push:(Ljava/lang/Object;)Ljava/lang/Object;
      81: goto          191
      84: aload         5
      86: checkcast     #71                 // class java/lang/Iterable
      89: astore        11
      91: iconst_0
      92: istore        12
      94: aload         11
      96: astore        13
      98: new           #73                 // class java/util/ArrayList
     101: dup
     102: aload         11
     104: bipush        10
     106: invokestatic  #77                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     109: invokespecial #80                 // Method java/util/ArrayList."<init>":(I)V
     112: checkcast     #82                 // class java/util/Collection
     115: astore        14
     117: iconst_0
     118: istore        15
     120: aload         13
     122: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     127: astore        16
     129: aload         16
     131: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     136: ifeq          185
     139: aload         16
     141: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     146: astore        17
     148: aload         14
     150: aload         17
     152: checkcast     #50                 // class java/util/Stack
     155: astore        18
     157: astore        19
     159: iconst_0
     160: istore        20
     162: getstatic     #249                // Field java/lang/System.out:Ljava/io/PrintStream;
     165: aload         18
     167: invokevirtual #255                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     170: nop
     171: aload         19
     173: getstatic     #261                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     176: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     181: pop
     182: goto          129
     185: aload         14
     187: checkcast     #34                 // class java/util/List
     190: nop
     191: pop
     192: nop
     193: iinc          8, 1
     196: goto          22
     199: iconst_0
     200: istore        8
     202: iload         8
     204: iload_1
     205: if_icmpge     263
     208: iload         8
     210: istore        9
     212: iconst_0
     213: istore        10
     215: aload         7
     217: checkcast     #82                 // class java/util/Collection
     220: invokeinterface #243,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     225: ifne          232
     228: iconst_1
     229: goto          233
     232: iconst_0
     233: ifeq          256
     236: aload         5
     238: iload_3
     239: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     244: checkcast     #50                 // class java/util/Stack
     247: aload         7
     249: invokevirtual #175                // Method java/util/Stack.pop:()Ljava/lang/Object;
     252: invokevirtual #148                // Method java/util/Stack.push:(Ljava/lang/Object;)Ljava/lang/Object;
     255: pop
     256: nop
     257: iinc          8, 1
     260: goto          202
     263: nop
     264: aload         4
     266: areturn

  private static final int toIntStackSize(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #22                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #24                 // class java/lang/String
       8: astore_1
       9: aload_1
      10: iconst_0
      11: ldc_w         #279                // String \n
      14: aastore
      15: aload_1
      16: iconst_0
      17: iconst_0
      18: bipush        6
      20: aconst_null
      21: invokestatic  #32                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      24: invokestatic  #283                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
      27: checkcast     #22                 // class java/lang/CharSequence
      30: iconst_1
      31: anewarray     #24                 // class java/lang/String
      34: astore_1
      35: aload_1
      36: iconst_0
      37: ldc           #150                // String
      39: aastore
      40: aload_1
      41: iconst_0
      42: iconst_0
      43: bipush        6
      45: aconst_null
      46: invokestatic  #32                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      49: invokestatic  #283                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
      52: checkcast     #24                 // class java/lang/String
      55: checkcast     #22                 // class java/lang/CharSequence
      58: invokestatic  #287                // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      61: invokevirtual #288                // Method java/lang/Object.toString:()Ljava/lang/String;
      64: invokestatic  #155                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      67: ireturn

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

  private static final java.lang.String main$part1(java.lang.String);
    Code:
       0: aload_0
       1: getstatic     #301                // Field Day05Kt$main$part1$1.INSTANCE:LDay05Kt$main$part1$1;
       4: checkcast     #160                // class kotlin/jvm/functions/Function4
       7: invokestatic  #303                // Method findCratesOnTopOfAllStacks:(Ljava/lang/String;Lkotlin/jvm/functions/Function4;)Ljava/lang/String;
      10: areturn

  private static final java.lang.String main$part2(java.lang.String);
    Code:
       0: aload_0
       1: getstatic     #309                // Field Day05Kt$main$part2$1.INSTANCE:LDay05Kt$main$part2$1;
       4: checkcast     #160                // class kotlin/jvm/functions/Function4
       7: invokestatic  #303                // Method findCratesOnTopOfAllStacks:(Ljava/lang/String;Lkotlin/jvm/functions/Function4;)Ljava/lang/String;
      10: areturn

  public static final java.util.List access$moveOneStackAtTime(java.util.List, int, int, int);
    Code:
       0: aload_0
       1: iload_1
       2: iload_2
       3: iload_3
       4: invokestatic  #312                // Method moveOneStackAtTime:(Ljava/util/List;III)Ljava/util/List;
       7: areturn

  public static final java.util.List access$moveAllStacksOnce(java.util.List, int, int, int);
    Code:
       0: aload_0
       1: iload_1
       2: iload_2
       3: iload_3
       4: invokestatic  #316                // Method moveAllStacksOnce:(Ljava/util/List;III)Ljava/util/List;
       7: areturn
}

Compiled from "Day05.kt"
final class Day05Kt$main$part1$1 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function4<java.util.List<? extends java.util.Stack<java.lang.Character>>, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.util.List<? extends java.util.Stack<java.lang.Character>>> {
  public static final Day05Kt$main$part1$1 INSTANCE;

  Day05Kt$main$part1$1();
    Code:
       0: aload_0
       1: iconst_4
       2: ldc           #11                 // class Day05Kt
       4: ldc           #13                 // String moveOneStackAtTime
       6: ldc           #15                 // String moveOneStackAtTime(Ljava/util/List;III)Ljava/util/List;
       8: iconst_1
       9: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      12: return

  public final java.util.List<java.util.Stack<java.lang.Character>> invoke(java.util.List<? extends java.util.Stack<java.lang.Character>>, int, int, int);
    Code:
       0: aload_1
       1: ldc           #25                 // String p0
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: iload_2
       8: iload_3
       9: iload         4
      11: invokestatic  #34                 // Method Day05Kt.access$moveOneStackAtTime:(Ljava/util/List;III)Ljava/util/List;
      14: areturn

  public java.lang.Object invoke(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #42                 // class java/util/List
       5: aload_2
       6: checkcast     #44                 // class java/lang/Number
       9: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      12: aload_3
      13: checkcast     #44                 // class java/lang/Number
      16: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      19: aload         4
      21: checkcast     #44                 // class java/lang/Number
      24: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      27: invokevirtual #50                 // Method invoke:(Ljava/util/List;III)Ljava/util/List;
      30: areturn

  static {};
    Code:
       0: new           #2                  // class Day05Kt$main$part1$1
       3: dup
       4: invokespecial #55                 // Method "<init>":()V
       7: putstatic     #58                 // Field INSTANCE:LDay05Kt$main$part1$1;
      10: return
}

Compiled from "Day05.kt"
final class Day05Kt$main$part2$1 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function4<java.util.List<? extends java.util.Stack<java.lang.Character>>, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.util.List<? extends java.util.Stack<java.lang.Character>>> {
  public static final Day05Kt$main$part2$1 INSTANCE;

  Day05Kt$main$part2$1();
    Code:
       0: aload_0
       1: iconst_4
       2: ldc           #11                 // class Day05Kt
       4: ldc           #13                 // String moveAllStacksOnce
       6: ldc           #15                 // String moveAllStacksOnce(Ljava/util/List;III)Ljava/util/List;
       8: iconst_1
       9: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      12: return

  public final java.util.List<java.util.Stack<java.lang.Character>> invoke(java.util.List<? extends java.util.Stack<java.lang.Character>>, int, int, int);
    Code:
       0: aload_1
       1: ldc           #25                 // String p0
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: iload_2
       8: iload_3
       9: iload         4
      11: invokestatic  #34                 // Method Day05Kt.access$moveAllStacksOnce:(Ljava/util/List;III)Ljava/util/List;
      14: areturn

  public java.lang.Object invoke(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #42                 // class java/util/List
       5: aload_2
       6: checkcast     #44                 // class java/lang/Number
       9: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      12: aload_3
      13: checkcast     #44                 // class java/lang/Number
      16: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      19: aload         4
      21: checkcast     #44                 // class java/lang/Number
      24: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      27: invokevirtual #50                 // Method invoke:(Ljava/util/List;III)Ljava/util/List;
      30: areturn

  static {};
    Code:
       0: new           #2                  // class Day05Kt$main$part2$1
       3: dup
       4: invokespecial #55                 // Method "<init>":()V
       7: putstatic     #58                 // Field INSTANCE:LDay05Kt$main$part2$1;
      10: return
}


const val TOTALDISKSPACE = 70000000
const val NEEDEDUNUSEDSPACE = 30000000

fun main() {

    fun part1(input: String): Int = FileSystem().run {
        parseInstructions(input)
        getListOfDirNSizes()
            .map { it.second }
            .filter { it < 100000 }
            .sum()
    }

    fun part2(input: String): Pair<String, Int> = FileSystem().run {
        parseInstructions(input)
        val listOfDirNSizes = getListOfDirNSizes()
        val totalUsedSize = getListOfDirNSizes().maxOf { it.second }
        val totalUnUsedSpace = TOTALDISKSPACE - totalUsedSize
        listOfDirNSizes
            .filter { dirNSize ->
                val (_, size) = dirNSize
                size  >= NEEDEDUNUSEDSPACE - totalUnUsedSpace
            }
            .minBy { it.second }

    }

    // test if implementation meets criteria from the description, like:
    // table test of part1
//    val testInput = readInputAsString("Day07_test")
//    check(part1(testInput) == 95437)
//    check(part2(testInput) == Pair("d", 24933642))
//
//    val input = readInputAsString("Day07")
//    println(part1(input))
//    println(part2(input))
}

sealed class FileType (val name: String, val parent: FileType.Dir?) {

    class Dir(name: String, parent: FileType.Dir?, val children: HashMap<String, FileType> = hashMapOf()) : FileType(name, parent) {
        override fun getTheSize(): Int = children
            .map {
                it.value
            }
            .fold(0) { sizes, children ->
                sizes + children.getTheSize()
            }
    }

    class MyFile(name: String, parent: FileType.Dir, val size: Int) : FileType(name, parent) {
        override fun getTheSize(): Int = size
    }

    abstract fun getTheSize(): Int
}

fun FileType.Dir.getDirNSize(list: MutableList<Pair<String, Int>>) {
    children.map { it.value }
        .forEach {
            if (it is FileType.Dir)
                it.getDirNSize(list)
        }
    val size = getTheSize()
    list.add(
        Pair(name, size)
    )
}

class FileSystem {
    private val rootDir = FileType.Dir("/", null)
    private var current = rootDir

    fun changeDirectory(param: String) {
        current = when(param) {
            ".." -> current.parent ?: rootDir
            "/" -> rootDir
            else -> current
                .children
                .getOrElse(param){
                    val newChild = FileType.Dir(param, current)
                    current.children.put(param, newChild)
                    newChild
                } as FileType.Dir
        }
    }

    fun listing(files: List<String>) {
        files
            .map {
                it.split(" ")
            }
            .fold(current) { cur, file ->
                when {
                    file.first() == "dir" -> cur.children.put(file.last(), FileType.Dir(file.last(), cur))
                    else -> cur.children.put(file.last(), FileType.MyFile(file.last(), cur, file.first().toInt()))
                }
                cur
            }
    }

    fun parseInstructions(instructions: String) {
        instructions
            .split("$")
            .map {
                it.trim()
            }
            .forEach {
                val commandNParamsData = it
                    .lines()
                val command = commandNParamsData
                    .first()
                    .split(" ")
                when (command.first()) {
                    "cd" -> changeDirectory(command.last())
                    "ls" -> listing(commandNParamsData
                        .drop(1) // remove any string that follows the command ls, which is blank in this case
                    )
                    else -> {}
                }
            }
    }

    fun getListOfDirNSizes(): MutableList<Pair<String, Int>> = mutableListOf<Pair<String, Int>>().apply {
        rootDir.getDirNSize(this)
    }

}

Compiled from "Day07.kt"
public final class Day07Kt {
  public static final int TOTALDISKSPACE;

  public static final int NEEDEDUNUSEDSPACE;

  public static final void main();
    Code:
       0: return

  public static final void getDirNSize(FileType$Dir, java.util.List<kotlin.Pair<java.lang.String, java.lang.Integer>>);
    Code:
       0: aload_0
       1: ldc           #12                 // String <this>
       3: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #20                 // String list
       9: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokevirtual #26                 // Method FileType$Dir.getChildren:()Ljava/util/HashMap;
      16: checkcast     #28                 // class java/util/Map
      19: astore_2
      20: iconst_0
      21: istore_3
      22: aload_2
      23: astore        4
      25: new           #30                 // class java/util/ArrayList
      28: dup
      29: aload_2
      30: invokeinterface #34,  1           // InterfaceMethod java/util/Map.size:()I
      35: invokespecial #38                 // Method java/util/ArrayList."<init>":(I)V
      38: checkcast     #40                 // class java/util/Collection
      41: astore        5
      43: iconst_0
      44: istore        6
      46: aload         4
      48: invokeinterface #44,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      53: invokeinterface #50,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      58: astore        7
      60: aload         7
      62: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      67: ifeq          115
      70: aload         7
      72: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      77: checkcast     #62                 // class java/util/Map$Entry
      80: astore        8
      82: aload         5
      84: aload         8
      86: astore        9
      88: astore        11
      90: iconst_0
      91: istore        10
      93: aload         9
      95: invokeinterface #65,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     100: checkcast     #67                 // class FileType
     103: aload         11
     105: swap
     106: invokeinterface #71,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     111: pop
     112: goto          60
     115: aload         5
     117: checkcast     #73                 // class java/util/List
     120: nop
     121: checkcast     #75                 // class java/lang/Iterable
     124: astore_2
     125: nop
     126: iconst_0
     127: istore_3
     128: aload_2
     129: invokeinterface #76,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     134: astore        4
     136: aload         4
     138: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     143: ifeq          187
     146: aload         4
     148: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     153: astore        5
     155: aload         5
     157: checkcast     #67                 // class FileType
     160: astore        6
     162: iconst_0
     163: istore        7
     165: aload         6
     167: instanceof    #22                 // class FileType$Dir
     170: ifeq          182
     173: aload         6
     175: checkcast     #22                 // class FileType$Dir
     178: aload_1
     179: invokestatic  #78                 // Method getDirNSize:(LFileType$Dir;Ljava/util/List;)V
     182: nop
     183: nop
     184: goto          136
     187: nop
     188: aload_0
     189: invokevirtual #81                 // Method FileType$Dir.getTheSize:()I
     192: istore_2
     193: aload_1
     194: new           #83                 // class kotlin/Pair
     197: dup
     198: aload_0
     199: invokevirtual #87                 // Method FileType$Dir.getName:()Ljava/lang/String;
     202: iload_2
     203: invokestatic  #93                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     206: invokespecial #96                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     209: invokeinterface #97,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     214: pop
     215: return

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

  private static final int main$part1(java.lang.String);
    Code:
       0: new           #128                // class FileSystem
       3: dup
       4: invokespecial #130                // Method FileSystem."<init>":()V
       7: astore_1
       8: iconst_0
       9: istore_2
      10: aload_1
      11: aload_0
      12: invokevirtual #134                // Method FileSystem.parseInstructions:(Ljava/lang/String;)V
      15: aload_1
      16: invokevirtual #138                // Method FileSystem.getListOfDirNSizes:()Ljava/util/List;
      19: checkcast     #75                 // class java/lang/Iterable
      22: astore_3
      23: nop
      24: iconst_0
      25: istore        4
      27: aload_3
      28: astore        5
      30: new           #30                 // class java/util/ArrayList
      33: dup
      34: aload_3
      35: bipush        10
      37: invokestatic  #144                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      40: invokespecial #38                 // Method java/util/ArrayList."<init>":(I)V
      43: checkcast     #40                 // class java/util/Collection
      46: astore        6
      48: iconst_0
      49: istore        7
      51: aload         5
      53: invokeinterface #76,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      58: astore        8
      60: aload         8
      62: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      67: ifeq          119
      70: aload         8
      72: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      77: astore        9
      79: aload         6
      81: aload         9
      83: checkcast     #83                 // class kotlin/Pair
      86: astore        10
      88: astore        11
      90: iconst_0
      91: istore        12
      93: aload         10
      95: invokevirtual #147                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      98: checkcast     #149                // class java/lang/Number
     101: invokevirtual #152                // Method java/lang/Number.intValue:()I
     104: invokestatic  #93                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     107: aload         11
     109: swap
     110: invokeinterface #71,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     115: pop
     116: goto          60
     119: aload         6
     121: checkcast     #73                 // class java/util/List
     124: nop
     125: checkcast     #75                 // class java/lang/Iterable
     128: astore_3
     129: nop
     130: iconst_0
     131: istore        4
     133: aload_3
     134: astore        5
     136: new           #30                 // class java/util/ArrayList
     139: dup
     140: invokespecial #153                // Method java/util/ArrayList."<init>":()V
     143: checkcast     #40                 // class java/util/Collection
     146: astore        6
     148: iconst_0
     149: istore        7
     151: aload         5
     153: invokeinterface #76,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     158: astore        8
     160: aload         8
     162: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     167: ifeq          220
     170: aload         8
     172: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     177: astore        9
     179: aload         9
     181: checkcast     #149                // class java/lang/Number
     184: invokevirtual #152                // Method java/lang/Number.intValue:()I
     187: istore        10
     189: iconst_0
     190: istore        12
     192: iload         10
     194: ldc           #154                // int 100000
     196: if_icmpge     203
     199: iconst_1
     200: goto          204
     203: iconst_0
     204: ifeq          160
     207: aload         6
     209: aload         9
     211: invokeinterface #71,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     216: pop
     217: goto          160
     220: aload         6
     222: checkcast     #73                 // class java/util/List
     225: nop
     226: checkcast     #75                 // class java/lang/Iterable
     229: invokestatic  #158                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     232: nop
     233: ireturn

  private static final kotlin.Pair<java.lang.String, java.lang.Integer> main$part2(java.lang.String);
    Code:
       0: new           #128                // class FileSystem
       3: dup
       4: invokespecial #130                // Method FileSystem."<init>":()V
       7: astore_1
       8: iconst_0
       9: istore_2
      10: aload_1
      11: aload_0
      12: invokevirtual #134                // Method FileSystem.parseInstructions:(Ljava/lang/String;)V
      15: aload_1
      16: invokevirtual #138                // Method FileSystem.getListOfDirNSizes:()Ljava/util/List;
      19: astore_3
      20: aload_1
      21: invokevirtual #138                // Method FileSystem.getListOfDirNSizes:()Ljava/util/List;
      24: checkcast     #75                 // class java/lang/Iterable
      27: invokeinterface #76,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      32: astore        4
      34: aload         4
      36: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      41: ifne          52
      44: new           #178                // class java/util/NoSuchElementException
      47: dup
      48: invokespecial #179                // Method java/util/NoSuchElementException."<init>":()V
      51: athrow
      52: aload         4
      54: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      59: checkcast     #83                 // class kotlin/Pair
      62: astore        5
      64: iconst_0
      65: istore        6
      67: aload         5
      69: invokevirtual #147                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      72: checkcast     #149                // class java/lang/Number
      75: invokevirtual #152                // Method java/lang/Number.intValue:()I
      78: istore        5
      80: aload         4
      82: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      87: ifeq          132
      90: aload         4
      92: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      97: checkcast     #83                 // class kotlin/Pair
     100: astore        6
     102: iconst_0
     103: istore        7
     105: aload         6
     107: invokevirtual #147                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     110: checkcast     #149                // class java/lang/Number
     113: invokevirtual #152                // Method java/lang/Number.intValue:()I
     116: istore        6
     118: iload         5
     120: iload         6
     122: if_icmpge     80
     125: iload         6
     127: istore        5
     129: goto          80
     132: iload         5
     134: istore        8
     136: ldc           #180                // int 70000000
     138: iload         8
     140: isub
     141: istore        9
     143: aload_3
     144: checkcast     #75                 // class java/lang/Iterable
     147: astore        4
     149: nop
     150: iconst_0
     151: istore        5
     153: aload         4
     155: astore        6
     157: new           #30                 // class java/util/ArrayList
     160: dup
     161: invokespecial #153                // Method java/util/ArrayList."<init>":()V
     164: checkcast     #40                 // class java/util/Collection
     167: astore        7
     169: iconst_0
     170: istore        10
     172: aload         6
     174: invokeinterface #76,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     179: astore        11
     181: aload         11
     183: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     188: ifeq          254
     191: aload         11
     193: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     198: astore        12
     200: aload         12
     202: checkcast     #83                 // class kotlin/Pair
     205: astore        13
     207: iconst_0
     208: istore        14
     210: aload         13
     212: invokevirtual #183                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     215: checkcast     #149                // class java/lang/Number
     218: invokevirtual #152                // Method java/lang/Number.intValue:()I
     221: istore        15
     223: iload         15
     225: ldc           #184                // int 30000000
     227: iload         9
     229: isub
     230: if_icmplt     237
     233: iconst_1
     234: goto          238
     237: iconst_0
     238: ifeq          181
     241: aload         7
     243: aload         12
     245: invokeinterface #71,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     250: pop
     251: goto          181
     254: aload         7
     256: checkcast     #73                 // class java/util/List
     259: nop
     260: checkcast     #75                 // class java/lang/Iterable
     263: astore        4
     265: nop
     266: iconst_0
     267: istore        5
     269: aload         4
     271: invokeinterface #76,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     276: astore        6
     278: aload         6
     280: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     285: ifne          296
     288: new           #178                // class java/util/NoSuchElementException
     291: dup
     292: invokespecial #179                // Method java/util/NoSuchElementException."<init>":()V
     295: athrow
     296: aload         6
     298: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     303: astore        7
     305: aload         6
     307: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     312: ifne          320
     315: aload         7
     317: goto          402
     320: aload         7
     322: checkcast     #83                 // class kotlin/Pair
     325: astore        10
     327: iconst_0
     328: istore        11
     330: aload         10
     332: invokevirtual #147                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     335: checkcast     #149                // class java/lang/Number
     338: invokevirtual #152                // Method java/lang/Number.intValue:()I
     341: istore        10
     343: aload         6
     345: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     350: astore        11
     352: aload         11
     354: checkcast     #83                 // class kotlin/Pair
     357: astore        12
     359: iconst_0
     360: istore        13
     362: aload         12
     364: invokevirtual #147                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     367: checkcast     #149                // class java/lang/Number
     370: invokevirtual #152                // Method java/lang/Number.intValue:()I
     373: istore        12
     375: iload         10
     377: iload         12
     379: if_icmple     390
     382: aload         11
     384: astore        7
     386: iload         12
     388: istore        10
     390: aload         6
     392: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     397: ifne          343
     400: aload         7
     402: checkcast     #83                 // class kotlin/Pair
     405: nop
     406: nop
     407: areturn
}


fun main() {

    fun part1(signal: String, n: Int = 4): Int = firstNUniqueCharacters(signal = signal, n = n)
    fun part2(signal: String, n: Int = 14): Int = firstNUniqueCharacters(signal = signal, n = n)

    // test if implementation meets criteria from the description, like:
    // table test of part1
//    val testInput01 = readInput("Day06_test_part01")
//    val testInput01Solutions = listOf<Int>(7, 5, 6, 10, 11)
//    testInput01
//        .zip(testInput01Solutions)
//        .map {
//            check(part1(it.first) == it.second)
//        }
//
//    // table test of part2
//    val testInput02 = readInput("Day06_test_part02")
//    val testInput02Solutions = listOf<Int>(19, 23, 23, 29, 26)
//    testInput02
//        .zip(testInput02Solutions)
//        .map {
//            check(part2(it.first) == it.second)
//        }
//
//    val input = readInputAsString("Day06")
//    println(part1(input))
//    println(part2(input))
}

fun firstNUniqueCharacters(signal: String, n: Int): Int {
    val possiblePacketMarkers = signal.windowed(n)
        .map { it.toSet() }
    var lastPositionOfMarker = n
    for (possiblePacketMarker in possiblePacketMarkers) {
        if (possiblePacketMarker.size == n) {
            break
        }
        lastPositionOfMarker++
    }
    return lastPositionOfMarker
}

Compiled from "Day06.kt"
public final class Day06Kt {
  public static final void main();
    Code:
       0: return

  public static final int firstNUniqueCharacters(java.lang.String, int);
    Code:
       0: aload_0
       1: ldc           #11                 // String signal
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #19                 // class java/lang/CharSequence
      10: iload_1
      11: iconst_0
      12: iconst_0
      13: bipush        6
      15: aconst_null
      16: invokestatic  #25                 // Method kotlin/text/StringsKt.windowed$default:(Ljava/lang/CharSequence;IIZILjava/lang/Object;)Ljava/util/List;
      19: checkcast     #27                 // class java/lang/Iterable
      22: astore_3
      23: nop
      24: iconst_0
      25: istore        4
      27: aload_3
      28: astore        5
      30: new           #29                 // class java/util/ArrayList
      33: dup
      34: aload_3
      35: bipush        10
      37: invokestatic  #35                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      40: invokespecial #39                 // Method java/util/ArrayList."<init>":(I)V
      43: checkcast     #41                 // class java/util/Collection
      46: astore        6
      48: iconst_0
      49: istore        7
      51: aload         5
      53: invokeinterface #45,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      58: astore        8
      60: aload         8
      62: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      67: ifeq          113
      70: aload         8
      72: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      77: astore        9
      79: aload         6
      81: aload         9
      83: checkcast     #57                 // class java/lang/String
      86: astore        10
      88: astore        12
      90: iconst_0
      91: istore        11
      93: aload         10
      95: checkcast     #19                 // class java/lang/CharSequence
      98: invokestatic  #61                 // Method kotlin/text/StringsKt.toSet:(Ljava/lang/CharSequence;)Ljava/util/Set;
     101: aload         12
     103: swap
     104: invokeinterface #65,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     109: pop
     110: goto          60
     113: aload         6
     115: checkcast     #67                 // class java/util/List
     118: nop
     119: astore_2
     120: iload_1
     121: istore_3
     122: aload_2
     123: invokeinterface #68,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     128: astore        4
     130: aload         4
     132: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     137: ifeq          172
     140: aload         4
     142: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     147: checkcast     #70                 // class java/util/Set
     150: astore        5
     152: aload         5
     154: invokeinterface #74,  1           // InterfaceMethod java/util/Set.size:()I
     159: iload_1
     160: if_icmpne     166
     163: goto          172
     166: iinc          3, 1
     169: goto          130
     172: iload_3
     173: ireturn

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

  private static final int main$part1(java.lang.String, int);
    Code:
       0: aload_0
       1: iload_1
       2: invokestatic  #101                // Method firstNUniqueCharacters:(Ljava/lang/String;I)I
       5: ireturn

  static int main$part1$default(java.lang.String, int, int, java.lang.Object);
    Code:
       0: iload_2
       1: iconst_2
       2: iand
       3: ifeq          8
       6: iconst_4
       7: istore_1
       8: aload_0
       9: iload_1
      10: invokestatic  #105                // Method main$part1:(Ljava/lang/String;I)I
      13: ireturn

  private static final int main$part2(java.lang.String, int);
    Code:
       0: aload_0
       1: iload_1
       2: invokestatic  #101                // Method firstNUniqueCharacters:(Ljava/lang/String;I)I
       5: ireturn

  static int main$part2$default(java.lang.String, int, int, java.lang.Object);
    Code:
       0: iload_2
       1: iconst_2
       2: iand
       3: ifeq          9
       6: bipush        14
       8: istore_1
       9: aload_0
      10: iload_1
      11: invokestatic  #109                // Method main$part2:(Ljava/lang/String;I)I
      14: ireturn
}


fun main() {
    fun itemPriority(c: Char): Int = when  {
        c.isLowerCase() -> c.code - 96
        c.isUpperCase() -> c.code - 64 + 26
        else -> 0
    }
    fun part1(input: List<String>): Int = input.foldRight(0) { rucksack, prioritySum ->
        rucksack
            .chunked(rucksack.length / 2)
            .map {
                it.toSet()
            }
            .intersection()
            .map(::itemPriority)
            .sum() + prioritySum
    }

    fun part2(input: List<String>): Int = input
            .windowed(3, 3)
            .foldRight(0) { threeRucksacks, prioritySum ->
                threeRucksacks
                    .map { it.toSet() }
                    .intersection()
                    .map(::itemPriority)
                    .sum() + prioritySum
            }

    // test if implementation meets criteria from the description, like:
//    val testInput = readInput("Day03_test")
//    check(part1(testInput) == 157)
//    check(part2(testInput) == 70)
//
//    val input = readInput("Day03")
//    println(part1(input))
//    println(part2(input))
}
//
//fun List<Set<Char>>.intersection() = reduce { element, acc ->
//    element.intersect(acc)
//}
private fun <A> List<Set<A>>.intersection(): Set<A> = reduce { element, acc ->
    element.intersect(acc)
}

Compiled from "Day03.kt"
public final class Day03Kt {
  public static final void main();
    Code:
       0: return

  private static final <A> java.util.Set<A> intersection(java.util.List<? extends java.util.Set<? extends A>>);
    Code:
       0: aload_0
       1: checkcast     #11                 // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: invokeinterface #15,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore_3
      14: aload_3
      15: invokeinterface #21,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      20: ifne          33
      23: new           #23                 // class java/lang/UnsupportedOperationException
      26: dup
      27: ldc           #25                 // String Empty collection can\'t be reduced.
      29: invokespecial #29                 // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
      32: athrow
      33: aload_3
      34: invokeinterface #33,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      39: astore        4
      41: aload_3
      42: invokeinterface #21,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          89
      50: aload         4
      52: aload_3
      53: invokeinterface #33,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      58: checkcast     #35                 // class java/util/Set
      61: astore        5
      63: checkcast     #35                 // class java/util/Set
      66: astore        6
      68: iconst_0
      69: istore        7
      71: aload         6
      73: checkcast     #11                 // class java/lang/Iterable
      76: aload         5
      78: checkcast     #11                 // class java/lang/Iterable
      81: invokestatic  #41                 // Method kotlin/collections/CollectionsKt.intersect:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/Set;
      84: astore        4
      86: goto          41
      89: aload         4
      91: checkcast     #35                 // class java/util/Set
      94: areturn

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

  private static final int main$itemPriority(char);
    Code:
       0: nop
       1: iload_0
       2: invokestatic  #68                 // Method java/lang/Character.isLowerCase:(C)Z
       5: ifeq          15
       8: iload_0
       9: bipush        96
      11: isub
      12: goto          33
      15: iload_0
      16: invokestatic  #71                 // Method java/lang/Character.isUpperCase:(C)Z
      19: ifeq          32
      22: iload_0
      23: bipush        64
      25: isub
      26: bipush        26
      28: iadd
      29: goto          33
      32: iconst_0
      33: ireturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: astore_1
       2: iconst_0
       3: istore_2
       4: iconst_0
       5: istore_3
       6: iload_2
       7: istore        4
       9: aload_1
      10: invokeinterface #81,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      15: ifne          303
      18: aload_1
      19: aload_1
      20: invokeinterface #85,  1           // InterfaceMethod java/util/List.size:()I
      25: invokeinterface #89,  2           // InterfaceMethod java/util/List.listIterator:(I)Ljava/util/ListIterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #94,  1           // InterfaceMethod java/util/ListIterator.hasPrevious:()Z
      39: ifeq          303
      42: aload         5
      44: invokeinterface #97,  1           // InterfaceMethod java/util/ListIterator.previous:()Ljava/lang/Object;
      49: iload         4
      51: istore        6
      53: checkcast     #99                 // class java/lang/String
      56: astore        7
      58: iconst_0
      59: istore        8
      61: aload         7
      63: checkcast     #101                // class java/lang/CharSequence
      66: aload         7
      68: invokevirtual #104                // Method java/lang/String.length:()I
      71: iconst_2
      72: idiv
      73: invokestatic  #110                // Method kotlin/text/StringsKt.chunked:(Ljava/lang/CharSequence;I)Ljava/util/List;
      76: checkcast     #11                 // class java/lang/Iterable
      79: astore        9
      81: nop
      82: iconst_0
      83: istore        10
      85: aload         9
      87: astore        11
      89: new           #112                // class java/util/ArrayList
      92: dup
      93: aload         9
      95: bipush        10
      97: invokestatic  #116                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     100: invokespecial #119                // Method java/util/ArrayList."<init>":(I)V
     103: checkcast     #121                // class java/util/Collection
     106: astore        12
     108: iconst_0
     109: istore        13
     111: aload         11
     113: invokeinterface #15,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     118: astore        14
     120: aload         14
     122: invokeinterface #21,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     127: ifeq          173
     130: aload         14
     132: invokeinterface #33,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     137: astore        15
     139: aload         12
     141: aload         15
     143: checkcast     #99                 // class java/lang/String
     146: astore        16
     148: astore        17
     150: iconst_0
     151: istore        18
     153: aload         16
     155: checkcast     #101                // class java/lang/CharSequence
     158: invokestatic  #125                // Method kotlin/text/StringsKt.toSet:(Ljava/lang/CharSequence;)Ljava/util/Set;
     161: aload         17
     163: swap
     164: invokeinterface #129,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     169: pop
     170: goto          120
     173: aload         12
     175: checkcast     #78                 // class java/util/List
     178: nop
     179: invokestatic  #131                // Method intersection:(Ljava/util/List;)Ljava/util/Set;
     182: checkcast     #11                 // class java/lang/Iterable
     185: astore        9
     187: nop
     188: iconst_0
     189: istore        10
     191: aload         9
     193: astore        11
     195: new           #112                // class java/util/ArrayList
     198: dup
     199: aload         9
     201: bipush        10
     203: invokestatic  #116                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     206: invokespecial #119                // Method java/util/ArrayList."<init>":(I)V
     209: checkcast     #121                // class java/util/Collection
     212: astore        12
     214: iconst_0
     215: istore        13
     217: aload         11
     219: invokeinterface #15,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     224: astore        14
     226: aload         14
     228: invokeinterface #21,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     233: ifeq          282
     236: aload         14
     238: invokeinterface #33,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     243: astore        15
     245: aload         12
     247: aload         15
     249: checkcast     #64                 // class java/lang/Character
     252: invokevirtual #135                // Method java/lang/Character.charValue:()C
     255: istore        16
     257: astore        17
     259: iconst_0
     260: istore        18
     262: iload         16
     264: invokestatic  #137                // Method main$itemPriority:(C)I
     267: invokestatic  #143                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     270: aload         17
     272: swap
     273: invokeinterface #129,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     278: pop
     279: goto          226
     282: aload         12
     284: checkcast     #78                 // class java/util/List
     287: nop
     288: checkcast     #11                 // class java/lang/Iterable
     291: invokestatic  #147                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     294: iload         6
     296: iadd
     297: nop
     298: istore        4
     300: goto          32
     303: iload         4
     305: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #11                 // class java/lang/Iterable
       4: iconst_3
       5: iconst_3
       6: iconst_0
       7: iconst_4
       8: aconst_null
       9: invokestatic  #172                // Method kotlin/collections/CollectionsKt.windowed$default:(Ljava/lang/Iterable;IIZILjava/lang/Object;)Ljava/util/List;
      12: astore_1
      13: iconst_0
      14: istore_2
      15: iconst_0
      16: istore_3
      17: iload_2
      18: istore        4
      20: aload_1
      21: invokeinterface #81,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      26: ifne          301
      29: aload_1
      30: aload_1
      31: invokeinterface #85,  1           // InterfaceMethod java/util/List.size:()I
      36: invokeinterface #89,  2           // InterfaceMethod java/util/List.listIterator:(I)Ljava/util/ListIterator;
      41: astore        5
      43: aload         5
      45: invokeinterface #94,  1           // InterfaceMethod java/util/ListIterator.hasPrevious:()Z
      50: ifeq          301
      53: aload         5
      55: invokeinterface #97,  1           // InterfaceMethod java/util/ListIterator.previous:()Ljava/lang/Object;
      60: iload         4
      62: istore        6
      64: checkcast     #78                 // class java/util/List
      67: astore        7
      69: iconst_0
      70: istore        8
      72: aload         7
      74: checkcast     #11                 // class java/lang/Iterable
      77: astore        9
      79: nop
      80: iconst_0
      81: istore        10
      83: aload         9
      85: astore        11
      87: new           #112                // class java/util/ArrayList
      90: dup
      91: aload         9
      93: bipush        10
      95: invokestatic  #116                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      98: invokespecial #119                // Method java/util/ArrayList."<init>":(I)V
     101: checkcast     #121                // class java/util/Collection
     104: astore        12
     106: iconst_0
     107: istore        13
     109: aload         11
     111: invokeinterface #15,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     116: astore        14
     118: aload         14
     120: invokeinterface #21,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     125: ifeq          171
     128: aload         14
     130: invokeinterface #33,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     135: astore        15
     137: aload         12
     139: aload         15
     141: checkcast     #99                 // class java/lang/String
     144: astore        16
     146: astore        17
     148: iconst_0
     149: istore        18
     151: aload         16
     153: checkcast     #101                // class java/lang/CharSequence
     156: invokestatic  #125                // Method kotlin/text/StringsKt.toSet:(Ljava/lang/CharSequence;)Ljava/util/Set;
     159: aload         17
     161: swap
     162: invokeinterface #129,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     167: pop
     168: goto          118
     171: aload         12
     173: checkcast     #78                 // class java/util/List
     176: nop
     177: invokestatic  #131                // Method intersection:(Ljava/util/List;)Ljava/util/Set;
     180: checkcast     #11                 // class java/lang/Iterable
     183: astore        9
     185: nop
     186: iconst_0
     187: istore        10
     189: aload         9
     191: astore        11
     193: new           #112                // class java/util/ArrayList
     196: dup
     197: aload         9
     199: bipush        10
     201: invokestatic  #116                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     204: invokespecial #119                // Method java/util/ArrayList."<init>":(I)V
     207: checkcast     #121                // class java/util/Collection
     210: astore        12
     212: iconst_0
     213: istore        13
     215: aload         11
     217: invokeinterface #15,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     222: astore        14
     224: aload         14
     226: invokeinterface #21,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     231: ifeq          280
     234: aload         14
     236: invokeinterface #33,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     241: astore        15
     243: aload         12
     245: aload         15
     247: checkcast     #64                 // class java/lang/Character
     250: invokevirtual #135                // Method java/lang/Character.charValue:()C
     253: istore        16
     255: astore        17
     257: iconst_0
     258: istore        18
     260: iload         16
     262: invokestatic  #137                // Method main$itemPriority:(C)I
     265: invokestatic  #143                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     268: aload         17
     270: swap
     271: invokeinterface #129,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     276: pop
     277: goto          224
     280: aload         12
     282: checkcast     #78                 // class java/util/List
     285: nop
     286: checkcast     #11                 // class java/lang/Iterable
     289: invokestatic  #147                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     292: iload         6
     294: iadd
     295: nop
     296: istore        4
     298: goto          43
     301: iload         4
     303: ireturn
}


/*enum class RockPaperScissorsPermutation(val result: Int) {
    `A X`(3 + 1), `A Y`(6 + 2), `A Z`(0 + 3),
    `B X`(0 + 1), `B Y`(3 + 2), `B Z`(6 + 3),
    `C X`(6 + 1), `C Y`(0 + 2), `C Z`(3 + 3)
}*/
val RoPaScPermutations = mapOf<String, Int>(
    "A X" to 3 + 1, "A Y" to 6 + 2, "A Z" to 0 + 3,
    "B X" to 0 + 1, "B Y" to 3 + 2, "B Z" to 6 + 3,
    "C X" to 6 + 1, "C Y" to 0 + 2, "C Z" to 3 + 3
)

val RoPaScPermElfStrategy = mapOf<String, Int>(
    "A X" to 0 + 3, "A Y" to 3 + 1, "A Z" to 6 + 2,
    "B X" to 0 + 1, "B Y" to 3 + 2, "B Z" to 6 + 3,
    "C X" to 0 + 2, "C Y" to 3 + 3, "C Z" to 6 + 1
)

fun main() {
    fun part1(input: List<String>): Int = input.foldRight(0) { singlePlayResult, acc ->
        acc + RoPaScPermutations.getOrDefault(singlePlayResult, 0)
    }

    fun part2(input: List<String>): Int = input.foldRight(0) { singlePlayResult, acc ->
        acc + RoPaScPermElfStrategy.getOrDefault(singlePlayResult, 0)
    }

    // test if implementation meets criteria from the description, like:
//    val testInput = readInput("Day02_test")
//    check(part1(testInput) == 15)
//    check(part2(testInput) == 12)
//
//    val input = readInput("Day02")
//    println(part1(input))
//    println(part2(input))
}

Compiled from "Day02.kt"
public final class Day02Kt {
  private static final java.util.Map<java.lang.String, java.lang.Integer> RoPaScPermutations;

  private static final java.util.Map<java.lang.String, java.lang.Integer> RoPaScPermElfStrategy;

  public static final java.util.Map<java.lang.String, java.lang.Integer> getRoPaScPermutations();
    Code:
       0: getstatic     #12                 // Field RoPaScPermutations:Ljava/util/Map;
       3: areturn

  public static final java.util.Map<java.lang.String, java.lang.Integer> getRoPaScPermElfStrategy();
    Code:
       0: getstatic     #16                 // Field RoPaScPermElfStrategy:Ljava/util/Map;
       3: areturn

  public static final void main();
    Code:
       0: return

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

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: astore_1
       2: iconst_0
       3: istore_2
       4: iconst_0
       5: istore_3
       6: iload_2
       7: istore        4
       9: aload_1
      10: invokeinterface #32,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      15: ifne          89
      18: aload_1
      19: aload_1
      20: invokeinterface #36,  1           // InterfaceMethod java/util/List.size:()I
      25: invokeinterface #40,  2           // InterfaceMethod java/util/List.listIterator:(I)Ljava/util/ListIterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #45,  1           // InterfaceMethod java/util/ListIterator.hasPrevious:()Z
      39: ifeq          89
      42: aload         5
      44: invokeinterface #49,  1           // InterfaceMethod java/util/ListIterator.previous:()Ljava/lang/Object;
      49: iload         4
      51: istore        6
      53: checkcast     #51                 // class java/lang/String
      56: astore        7
      58: iconst_0
      59: istore        8
      61: iload         6
      63: getstatic     #12                 // Field RoPaScPermutations:Ljava/util/Map;
      66: aload         7
      68: iconst_0
      69: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      72: invokeinterface #63,  3           // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      77: checkcast     #65                 // class java/lang/Number
      80: invokevirtual #68                 // Method java/lang/Number.intValue:()I
      83: iadd
      84: istore        4
      86: goto          32
      89: iload         4
      91: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: astore_1
       2: iconst_0
       3: istore_2
       4: iconst_0
       5: istore_3
       6: iload_2
       7: istore        4
       9: aload_1
      10: invokeinterface #32,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      15: ifne          89
      18: aload_1
      19: aload_1
      20: invokeinterface #36,  1           // InterfaceMethod java/util/List.size:()I
      25: invokeinterface #40,  2           // InterfaceMethod java/util/List.listIterator:(I)Ljava/util/ListIterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #45,  1           // InterfaceMethod java/util/ListIterator.hasPrevious:()Z
      39: ifeq          89
      42: aload         5
      44: invokeinterface #49,  1           // InterfaceMethod java/util/ListIterator.previous:()Ljava/lang/Object;
      49: iload         4
      51: istore        6
      53: checkcast     #51                 // class java/lang/String
      56: astore        7
      58: iconst_0
      59: istore        8
      61: iload         6
      63: getstatic     #16                 // Field RoPaScPermElfStrategy:Ljava/util/Map;
      66: aload         7
      68: iconst_0
      69: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      72: invokeinterface #63,  3           // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      77: checkcast     #65                 // class java/lang/Number
      80: invokevirtual #68                 // Method java/lang/Number.intValue:()I
      83: iadd
      84: istore        4
      86: goto          32
      89: iload         4
      91: ireturn

  static {};
    Code:
       0: bipush        9
       2: anewarray     #86                 // class kotlin/Pair
       5: astore_0
       6: aload_0
       7: iconst_0
       8: ldc           #88                 // String A X
      10: iconst_4
      11: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      17: aastore
      18: aload_0
      19: iconst_1
      20: ldc           #96                 // String A Y
      22: bipush        8
      24: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      27: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      30: aastore
      31: aload_0
      32: iconst_2
      33: ldc           #98                 // String A Z
      35: iconst_3
      36: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      39: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      42: aastore
      43: aload_0
      44: iconst_3
      45: ldc           #100                // String B X
      47: iconst_1
      48: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      51: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      54: aastore
      55: aload_0
      56: iconst_4
      57: ldc           #102                // String B Y
      59: iconst_5
      60: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      63: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      66: aastore
      67: aload_0
      68: iconst_5
      69: ldc           #104                // String B Z
      71: bipush        9
      73: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      76: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      79: aastore
      80: aload_0
      81: bipush        6
      83: ldc           #106                // String C X
      85: bipush        7
      87: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      90: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      93: aastore
      94: aload_0
      95: bipush        7
      97: ldc           #108                // String C Y
      99: iconst_2
     100: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     103: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     106: aastore
     107: aload_0
     108: bipush        8
     110: ldc           #110                // String C Z
     112: bipush        6
     114: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     117: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     120: aastore
     121: aload_0
     122: invokestatic  #116                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     125: putstatic     #12                 // Field RoPaScPermutations:Ljava/util/Map;
     128: bipush        9
     130: anewarray     #86                 // class kotlin/Pair
     133: astore_0
     134: aload_0
     135: iconst_0
     136: ldc           #88                 // String A X
     138: iconst_3
     139: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     142: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     145: aastore
     146: aload_0
     147: iconst_1
     148: ldc           #96                 // String A Y
     150: iconst_4
     151: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     154: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     157: aastore
     158: aload_0
     159: iconst_2
     160: ldc           #98                 // String A Z
     162: bipush        8
     164: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     167: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     170: aastore
     171: aload_0
     172: iconst_3
     173: ldc           #100                // String B X
     175: iconst_1
     176: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     179: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     182: aastore
     183: aload_0
     184: iconst_4
     185: ldc           #102                // String B Y
     187: iconst_5
     188: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     191: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     194: aastore
     195: aload_0
     196: iconst_5
     197: ldc           #104                // String B Z
     199: bipush        9
     201: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     204: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     207: aastore
     208: aload_0
     209: bipush        6
     211: ldc           #106                // String C X
     213: iconst_2
     214: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     217: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     220: aastore
     221: aload_0
     222: bipush        7
     224: ldc           #108                // String C Y
     226: bipush        6
     228: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     231: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     234: aastore
     235: aload_0
     236: bipush        8
     238: ldc           #110                // String C Z
     240: bipush        7
     242: invokestatic  #57                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     245: invokestatic  #94                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     248: aastore
     249: aload_0
     250: invokestatic  #116                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     253: putstatic     #16                 // Field RoPaScPermElfStrategy:Ljava/util/Map;
     256: return
}