import java.io.File

fun main() {
    fun part1(input: List<String>): Int {
        return input.map { sack -> sack.bisect() }
            .map { parts -> parts.first.intersect(parts.second).first() }
            .sumOf { it.toScore() }
    }

    fun part2(input: List<String>): Int {
        return input.chunked(3)
            .map { sacks ->
                sacks[0].intersect(sacks[1]).toString().intersect(sacks[2]).firstOrNull()
            }
            .sumOf { it?.toScore() ?: 0 }
    }

    val testInput = listOf<String>(
        "vJrwpWtwJgWrhcsFMMfFFhFp",
        "jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
        "PmmdzqPrVvPwwTWBwg",
        "wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
        "ttgJtRGJQctTZtZT",
        "CrZsJsPPZsGzwwsLwLmpwMDw"
    )

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

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

fun Char.toScore() : Int =
    (if (this.isLowerCase()) this - 'a' else this - 'A' + 26) + 1

fun CharSequence.intersect(list2: CharSequence) : List<Char> {
    return this.filter { list2.contains(it) }.toList()
}

fun String.bisect() : Pair<String, String> =
    Pair(this.substring(0, this.length/2), this.substring(this.length/2, this.length))

Compiled from "Day03.kt"
public final class Day03Kt {
  public static final void main();
    Code:
       0: bipush        6
       2: anewarray     #8                  // class java/lang/String
       5: astore_1
       6: aload_1
       7: iconst_0
       8: ldc           #10                 // String vJrwpWtwJgWrhcsFMMfFFhFp
      10: aastore
      11: aload_1
      12: iconst_1
      13: ldc           #12                 // String jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
      15: aastore
      16: aload_1
      17: iconst_2
      18: ldc           #14                 // String PmmdzqPrVvPwwTWBwg
      20: aastore
      21: aload_1
      22: iconst_3
      23: ldc           #16                 // String wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
      25: aastore
      26: aload_1
      27: iconst_4
      28: ldc           #18                 // String ttgJtRGJQctTZtZT
      30: aastore
      31: aload_1
      32: iconst_5
      33: ldc           #20                 // String CrZsJsPPZsGzwwsLwLmpwMDw
      35: aastore
      36: aload_1
      37: invokestatic  #26                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      40: astore_0
      41: aload_0
      42: invokestatic  #30                 // Method main$part1:(Ljava/util/List;)I
      45: istore_1
      46: getstatic     #36                 // Field java/lang/System.out:Ljava/io/PrintStream;
      49: iload_1
      50: invokevirtual #42                 // Method java/io/PrintStream.println:(I)V
      53: aload_0
      54: invokestatic  #30                 // Method main$part1:(Ljava/util/List;)I
      57: sipush        157
      60: if_icmpne     67
      63: iconst_1
      64: goto          68
      67: iconst_0
      68: ifne          81
      71: new           #44                 // class java/lang/IllegalStateException
      74: dup
      75: ldc           #46                 // String Check failed.
      77: invokespecial #50                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      80: athrow
      81: aload_0
      82: invokestatic  #53                 // Method main$part2:(Ljava/util/List;)I
      85: bipush        70
      87: if_icmpne     94
      90: iconst_1
      91: goto          95
      94: iconst_0
      95: ifne          108
      98: new           #44                 // class java/lang/IllegalStateException
     101: dup
     102: ldc           #46                 // String Check failed.
     104: invokespecial #50                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     107: athrow
     108: new           #55                 // class java/io/File
     111: dup
     112: ldc           #57                 // String ./src/resources/Day03a.txt
     114: invokespecial #58                 // Method java/io/File."<init>":(Ljava/lang/String;)V
     117: aconst_null
     118: iconst_1
     119: aconst_null
     120: invokestatic  #64                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
     123: astore_1
     124: aload_1
     125: invokestatic  #30                 // Method main$part1:(Ljava/util/List;)I
     128: istore_2
     129: getstatic     #36                 // Field java/lang/System.out:Ljava/io/PrintStream;
     132: iload_2
     133: invokevirtual #42                 // Method java/io/PrintStream.println:(I)V
     136: aload_1
     137: invokestatic  #53                 // Method main$part2:(Ljava/util/List;)I
     140: istore_2
     141: getstatic     #36                 // Field java/lang/System.out:Ljava/io/PrintStream;
     144: iload_2
     145: invokevirtual #42                 // Method java/io/PrintStream.println:(I)V
     148: return

  public static final int toScore(char);
    Code:
       0: iload_0
       1: invokestatic  #77                 // Method java/lang/Character.isLowerCase:(C)Z
       4: ifeq          14
       7: iload_0
       8: bipush        97
      10: isub
      11: goto          21
      14: iload_0
      15: bipush        65
      17: isub
      18: bipush        26
      20: iadd
      21: iconst_1
      22: iadd
      23: ireturn

  public static final java.util.List<java.lang.Character> intersect(java.lang.CharSequence, java.lang.CharSequence);
    Code:
       0: aload_0
       1: ldc           #85                 // String <this>
       3: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #93                 // String list2
       9: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: astore_2
      14: iconst_0
      15: istore_3
      16: aload_2
      17: astore        4
      19: new           #95                 // class java/lang/StringBuilder
      22: dup
      23: invokespecial #97                 // Method java/lang/StringBuilder."<init>":()V
      26: checkcast     #99                 // class java/lang/Appendable
      29: astore        5
      31: iconst_0
      32: istore        6
      34: iconst_0
      35: istore        7
      37: aload         4
      39: invokeinterface #105,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      44: istore        8
      46: iload         7
      48: iload         8
      50: if_icmpge     99
      53: aload         4
      55: iload         7
      57: invokeinterface #109,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      62: istore        9
      64: iload         9
      66: istore        10
      68: iconst_0
      69: istore        11
      71: aload_1
      72: iload         10
      74: iconst_0
      75: iconst_2
      76: aconst_null
      77: invokestatic  #115                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
      80: ifeq          93
      83: aload         5
      85: iload         9
      87: invokeinterface #119,  2          // InterfaceMethod java/lang/Appendable.append:(C)Ljava/lang/Appendable;
      92: pop
      93: iinc          7, 1
      96: goto          46
      99: aload         5
     101: checkcast     #101                // class java/lang/CharSequence
     104: nop
     105: invokestatic  #123                // Method kotlin/text/StringsKt.toList:(Ljava/lang/CharSequence;)Ljava/util/List;
     108: areturn

  public static final kotlin.Pair<java.lang.String, java.lang.String> bisect(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #85                 // String <this>
       3: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #141                // class kotlin/Pair
       9: dup
      10: aload_0
      11: iconst_0
      12: aload_0
      13: invokevirtual #142                // Method java/lang/String.length:()I
      16: iconst_2
      17: idiv
      18: invokevirtual #146                // Method java/lang/String.substring:(II)Ljava/lang/String;
      21: dup
      22: ldc           #148                // String substring(...)
      24: invokestatic  #151                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      27: aload_0
      28: aload_0
      29: invokevirtual #142                // Method java/lang/String.length:()I
      32: iconst_2
      33: idiv
      34: aload_0
      35: invokevirtual #142                // Method java/lang/String.length:()I
      38: invokevirtual #146                // Method java/lang/String.substring:(II)Ljava/lang/String;
      41: dup
      42: ldc           #148                // String substring(...)
      44: invokestatic  #151                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      47: invokespecial #154                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      50: areturn

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

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #164                // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: astore_3
       9: new           #166                // class java/util/ArrayList
      12: dup
      13: aload_1
      14: bipush        10
      16: invokestatic  #170                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      19: invokespecial #172                // Method java/util/ArrayList."<init>":(I)V
      22: checkcast     #174                // class java/util/Collection
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #178,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #184,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          88
      48: aload         6
      50: invokeinterface #188,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         4
      59: aload         7
      61: checkcast     #8                  // class java/lang/String
      64: astore        8
      66: astore        10
      68: iconst_0
      69: istore        9
      71: aload         8
      73: invokestatic  #190                // Method bisect:(Ljava/lang/String;)Lkotlin/Pair;
      76: aload         10
      78: swap
      79: invokeinterface #194,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      84: pop
      85: goto          38
      88: aload         4
      90: checkcast     #69                 // class java/util/List
      93: nop
      94: checkcast     #164                // class java/lang/Iterable
      97: astore_1
      98: nop
      99: iconst_0
     100: istore_2
     101: aload_1
     102: astore_3
     103: new           #166                // class java/util/ArrayList
     106: dup
     107: aload_1
     108: bipush        10
     110: invokestatic  #170                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     113: invokespecial #172                // Method java/util/ArrayList."<init>":(I)V
     116: checkcast     #174                // class java/util/Collection
     119: astore        4
     121: iconst_0
     122: istore        5
     124: aload_3
     125: invokeinterface #178,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     130: astore        6
     132: aload         6
     134: invokeinterface #184,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     139: ifeq          208
     142: aload         6
     144: invokeinterface #188,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     149: astore        7
     151: aload         4
     153: aload         7
     155: checkcast     #141                // class kotlin/Pair
     158: astore        8
     160: astore        10
     162: iconst_0
     163: istore        9
     165: aload         8
     167: invokevirtual #197                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     170: checkcast     #101                // class java/lang/CharSequence
     173: aload         8
     175: invokevirtual #200                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     178: checkcast     #101                // class java/lang/CharSequence
     181: invokestatic  #202                // Method intersect:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/List;
     184: invokestatic  #206                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     187: checkcast     #73                 // class java/lang/Character
     190: invokevirtual #210                // Method java/lang/Character.charValue:()C
     193: invokestatic  #214                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     196: aload         10
     198: swap
     199: invokeinterface #194,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     204: pop
     205: goto          132
     208: aload         4
     210: checkcast     #69                 // class java/util/List
     213: nop
     214: checkcast     #164                // class java/lang/Iterable
     217: astore_1
     218: iconst_0
     219: istore_2
     220: aload_1
     221: invokeinterface #178,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     226: astore_3
     227: aload_3
     228: invokeinterface #184,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     233: ifeq          276
     236: aload_3
     237: invokeinterface #188,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     242: astore        4
     244: iload_2
     245: aload         4
     247: checkcast     #73                 // class java/lang/Character
     250: invokevirtual #210                // Method java/lang/Character.charValue:()C
     253: istore        5
     255: istore        10
     257: iconst_0
     258: istore        6
     260: iload         5
     262: invokestatic  #216                // Method toScore:(C)I
     265: istore        11
     267: iload         10
     269: iload         11
     271: iadd
     272: istore_2
     273: goto          227
     276: iload_2
     277: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #164                // class java/lang/Iterable
       4: iconst_3
       5: invokestatic  #234                // Method kotlin/collections/CollectionsKt.chunked:(Ljava/lang/Iterable;I)Ljava/util/List;
       8: checkcast     #164                // class java/lang/Iterable
      11: astore_1
      12: nop
      13: iconst_0
      14: istore_2
      15: aload_1
      16: astore_3
      17: new           #166                // class java/util/ArrayList
      20: dup
      21: aload_1
      22: bipush        10
      24: invokestatic  #170                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      27: invokespecial #172                // Method java/util/ArrayList."<init>":(I)V
      30: checkcast     #174                // class java/util/Collection
      33: astore        4
      35: iconst_0
      36: istore        5
      38: aload_3
      39: invokeinterface #178,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      44: astore        6
      46: aload         6
      48: invokeinterface #184,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          142
      56: aload         6
      58: invokeinterface #188,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: astore        7
      65: aload         4
      67: aload         7
      69: checkcast     #69                 // class java/util/List
      72: astore        8
      74: astore        10
      76: iconst_0
      77: istore        9
      79: aload         8
      81: iconst_0
      82: invokeinterface #238,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      87: checkcast     #101                // class java/lang/CharSequence
      90: aload         8
      92: iconst_1
      93: invokeinterface #238,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      98: checkcast     #101                // class java/lang/CharSequence
     101: invokestatic  #202                // Method intersect:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/List;
     104: invokevirtual #242                // Method java/lang/Object.toString:()Ljava/lang/String;
     107: checkcast     #101                // class java/lang/CharSequence
     110: aload         8
     112: iconst_2
     113: invokeinterface #238,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     118: checkcast     #101                // class java/lang/CharSequence
     121: invokestatic  #202                // Method intersect:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/List;
     124: invokestatic  #245                // Method kotlin/collections/CollectionsKt.firstOrNull:(Ljava/util/List;)Ljava/lang/Object;
     127: checkcast     #73                 // class java/lang/Character
     130: aload         10
     132: swap
     133: invokeinterface #194,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     138: pop
     139: goto          46
     142: aload         4
     144: checkcast     #69                 // class java/util/List
     147: nop
     148: checkcast     #164                // class java/lang/Iterable
     151: astore_1
     152: iconst_0
     153: istore_2
     154: aload_1
     155: invokeinterface #178,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     160: astore_3
     161: aload_3
     162: invokeinterface #184,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     167: ifeq          219
     170: aload_3
     171: invokeinterface #188,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     176: astore        4
     178: iload_2
     179: aload         4
     181: checkcast     #73                 // class java/lang/Character
     184: astore        5
     186: istore        10
     188: iconst_0
     189: istore        6
     191: aload         5
     193: dup
     194: ifnull        206
     197: invokevirtual #210                // Method java/lang/Character.charValue:()C
     200: invokestatic  #216                // Method toScore:(C)I
     203: goto          208
     206: pop
     207: iconst_0
     208: istore        11
     210: iload         10
     212: iload         11
     214: iadd
     215: istore_2
     216: goto          161
     219: iload_2
     220: ireturn
}


import java.io.File

fun main() {
    fun part1(input: List<String>): Int {
        return input.sumOf { getScore(it) }
    }

    fun part2(input: List<String>): Int {
        return input.sumOf { getScore(getGame(it)) }
    }

    val testInput = listOf(
        "A Y",
        "B X",
        "C Z"
    )

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

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

fun getScore(game: String) : Int =
    game[2] - 'W' +
            when {
                game[0] == (game[2] - 23) -> 3
                wins.contains(game) -> 6
                else -> 0
            }

fun getGame(code: String) : String =
    when (code[2]) {
        'Y' -> ties
        'X' -> losses
        'Z' -> wins
        else -> listOf()
    }.first { code[0] == it[0] }

val wins = listOf("A Y", "B Z", "C X")
val losses = listOf("A Z", "B X", "C Y")
val ties = listOf("A X", "B Y", "C Z")

Compiled from "Day02.kt"
public final class Day02Kt {
  private static final java.util.List<java.lang.String> wins;

  private static final java.util.List<java.lang.String> losses;

  private static final java.util.List<java.lang.String> ties;

  public static final void main();
    Code:
       0: iconst_3
       1: anewarray     #8                  // class java/lang/String
       4: astore_1
       5: aload_1
       6: iconst_0
       7: ldc           #10                 // String A Y
       9: aastore
      10: aload_1
      11: iconst_1
      12: ldc           #12                 // String B X
      14: aastore
      15: aload_1
      16: iconst_2
      17: ldc           #14                 // String C Z
      19: aastore
      20: aload_1
      21: invokestatic  #20                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      24: astore_0
      25: aload_0
      26: invokestatic  #24                 // Method main$part1:(Ljava/util/List;)I
      29: bipush        15
      31: if_icmpne     38
      34: iconst_1
      35: goto          39
      38: iconst_0
      39: ifne          52
      42: new           #26                 // class java/lang/IllegalStateException
      45: dup
      46: ldc           #28                 // String Check failed.
      48: invokespecial #32                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      51: athrow
      52: aload_0
      53: invokestatic  #35                 // Method main$part2:(Ljava/util/List;)I
      56: bipush        12
      58: if_icmpne     65
      61: iconst_1
      62: goto          66
      65: iconst_0
      66: ifne          79
      69: new           #26                 // class java/lang/IllegalStateException
      72: dup
      73: ldc           #28                 // String Check failed.
      75: invokespecial #32                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      78: athrow
      79: new           #37                 // class java/io/File
      82: dup
      83: ldc           #39                 // String ./src/resources/Day02a.txt
      85: invokespecial #40                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      88: aconst_null
      89: iconst_1
      90: aconst_null
      91: invokestatic  #46                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      94: astore_1
      95: aload_1
      96: invokestatic  #24                 // Method main$part1:(Ljava/util/List;)I
      99: istore_2
     100: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
     103: iload_2
     104: invokevirtual #58                 // Method java/io/PrintStream.println:(I)V
     107: aload_1
     108: invokestatic  #35                 // Method main$part2:(Ljava/util/List;)I
     111: istore_2
     112: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
     115: iload_2
     116: invokevirtual #58                 // Method java/io/PrintStream.println:(I)V
     119: return

  public static final int getScore(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #70                 // String game
       3: invokestatic  #76                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_2
       8: invokevirtual #80                 // Method java/lang/String.charAt:(I)C
      11: bipush        87
      13: isub
      14: nop
      15: aload_0
      16: iconst_0
      17: invokevirtual #80                 // Method java/lang/String.charAt:(I)C
      20: aload_0
      21: iconst_2
      22: invokevirtual #80                 // Method java/lang/String.charAt:(I)C
      25: bipush        23
      27: isub
      28: i2c
      29: if_icmpne     36
      32: iconst_3
      33: goto          54
      36: getstatic     #83                 // Field wins:Ljava/util/List;
      39: aload_0
      40: invokeinterface #87,  2           // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
      45: ifeq          53
      48: bipush        6
      50: goto          54
      53: iconst_0
      54: iadd
      55: ireturn

  public static final java.lang.String getGame(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #92                 // String code
       3: invokestatic  #76                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_2
       8: invokevirtual #80                 // Method java/lang/String.charAt:(I)C
      11: tableswitch   { // 88 to 90
                    88: 42
                    89: 36
                    90: 48
               default: 54
          }
      36: getstatic     #95                 // Field ties:Ljava/util/List;
      39: goto          57
      42: getstatic     #98                 // Field losses:Ljava/util/List;
      45: goto          57
      48: getstatic     #83                 // Field wins:Ljava/util/List;
      51: goto          57
      54: invokestatic  #102                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      57: checkcast     #104                // class java/lang/Iterable
      60: astore_1
      61: nop
      62: iconst_0
      63: istore_2
      64: aload_1
      65: invokeinterface #108,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      70: astore_3
      71: aload_3
      72: invokeinterface #114,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      77: ifeq          125
      80: aload_3
      81: invokeinterface #118,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      86: astore        4
      88: aload         4
      90: checkcast     #8                  // class java/lang/String
      93: astore        5
      95: iconst_0
      96: istore        6
      98: aload_0
      99: iconst_0
     100: invokevirtual #80                 // Method java/lang/String.charAt:(I)C
     103: aload         5
     105: iconst_0
     106: invokevirtual #80                 // Method java/lang/String.charAt:(I)C
     109: if_icmpne     116
     112: iconst_1
     113: goto          117
     116: iconst_0
     117: ifeq          71
     120: aload         4
     122: goto          135
     125: new           #120                // class java/util/NoSuchElementException
     128: dup
     129: ldc           #122                // String Collection contains no element matching the predicate.
     131: invokespecial #123                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
     134: athrow
     135: checkcast     #8                  // class java/lang/String
     138: areturn

  public static final java.util.List<java.lang.String> getWins();
    Code:
       0: getstatic     #83                 // Field wins:Ljava/util/List;
       3: areturn

  public static final java.util.List<java.lang.String> getLosses();
    Code:
       0: getstatic     #98                 // Field losses:Ljava/util/List;
       3: areturn

  public static final java.util.List<java.lang.String> getTies();
    Code:
       0: getstatic     #95                 // Field ties:Ljava/util/List;
       3: areturn

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

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #104                // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: invokeinterface #108,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore_3
      14: aload_3
      15: invokeinterface #114,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      20: ifeq          60
      23: aload_3
      24: invokeinterface #118,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      29: astore        4
      31: iload_2
      32: aload         4
      34: checkcast     #8                  // class java/lang/String
      37: astore        5
      39: istore        7
      41: iconst_0
      42: istore        6
      44: aload         5
      46: invokestatic  #142                // Method getScore:(Ljava/lang/String;)I
      49: istore        8
      51: iload         7
      53: iload         8
      55: iadd
      56: istore_2
      57: goto          14
      60: iload_2
      61: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #104                // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: invokeinterface #108,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore_3
      14: aload_3
      15: invokeinterface #114,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      20: ifeq          63
      23: aload_3
      24: invokeinterface #118,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      29: astore        4
      31: iload_2
      32: aload         4
      34: checkcast     #8                  // class java/lang/String
      37: astore        5
      39: istore        7
      41: iconst_0
      42: istore        6
      44: aload         5
      46: invokestatic  #145                // Method getGame:(Ljava/lang/String;)Ljava/lang/String;
      49: invokestatic  #142                // Method getScore:(Ljava/lang/String;)I
      52: istore        8
      54: iload         7
      56: iload         8
      58: iadd
      59: istore_2
      60: goto          14
      63: iload_2
      64: ireturn

  static {};
    Code:
       0: iconst_3
       1: anewarray     #8                  // class java/lang/String
       4: astore_0
       5: aload_0
       6: iconst_0
       7: ldc           #10                 // String A Y
       9: aastore
      10: aload_0
      11: iconst_1
      12: ldc           #149                // String B Z
      14: aastore
      15: aload_0
      16: iconst_2
      17: ldc           #151                // String C X
      19: aastore
      20: aload_0
      21: invokestatic  #20                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      24: putstatic     #83                 // Field wins:Ljava/util/List;
      27: iconst_3
      28: anewarray     #8                  // class java/lang/String
      31: astore_0
      32: aload_0
      33: iconst_0
      34: ldc           #153                // String A Z
      36: aastore
      37: aload_0
      38: iconst_1
      39: ldc           #12                 // String B X
      41: aastore
      42: aload_0
      43: iconst_2
      44: ldc           #155                // String C Y
      46: aastore
      47: aload_0
      48: invokestatic  #20                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      51: putstatic     #98                 // Field losses:Ljava/util/List;
      54: iconst_3
      55: anewarray     #8                  // class java/lang/String
      58: astore_0
      59: aload_0
      60: iconst_0
      61: ldc           #157                // String A X
      63: aastore
      64: aload_0
      65: iconst_1
      66: ldc           #159                // String B Y
      68: aastore
      69: aload_0
      70: iconst_2
      71: ldc           #14                 // String C Z
      73: aastore
      74: aload_0
      75: invokestatic  #20                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      78: putstatic     #95                 // Field ties:Ljava/util/List;
      81: return
}


import java.io.File
import kotlin.math.min

fun main() {
    val c0 = '`'
    fun getNodes(input: List<String>): List<List<Node>> =
        input.map { row ->
            row.map { c ->
                val height = when (c) { 'S' -> 0; 'E' -> 'z' - c0; else -> c - c0 }
                Node(height, isStart = c == 'S', isEnd = c == 'E')
            }
        }

    fun buildNeighbors(nodes: List<List<Node>>) {
        nodes.forEachIndexed { y, row ->
            row.forEachIndexed { x, node ->
                listOf(x to y-1, x to y+1, x+1 to y, x-1 to y).forEach {
                    if (it.first in row.indices && it.second in nodes.indices && nodes[it.second][it.first].height <= node.height + 1)
                        node.neighbors.add(nodes[it.second][it.first])
                }
            }
        }
    }

    fun dijkstra(data: MutableList<Node>) {
        while(data.any()) {
            val v = data.removeFirst()
            v.neighbors.forEach {
                if (v.distance + 1 < it.distance) {
                    it.distance = v.distance + 1
                    data.add(it)
                }
                data.sortBy { n -> n.distance }
            }
        }
    }

    fun part1(input: List<String>): Int {
        val nodes = getNodes(input)
        val start = nodes.flatten().first { it.isStart }

        buildNeighbors(nodes)

        start.distance = 0
        val toProcess = mutableListOf(start)

        dijkstra(toProcess)

//        nodes.forEach {row ->
//            row.forEach { print(if (it.distance == Int.MAX_VALUE) "  . " else String.format("%3d", it.distance) + if (it.isEnd) "*" else " ")}
//            println()
//        }
//        println()

        return nodes.flatten().firstOrNull { it.isEnd }?.distance ?: 0
    }

    fun part2(input: List<String>): Int {
        val nodes = getNodes(input)
        val start = nodes.flatten().first { it.isStart }
        val end = nodes.flatten().first { it.isEnd }

        buildNeighbors(nodes)

        start.distance = 0
        val toProcess = mutableListOf(start)

        dijkstra(toProcess)

        val starts = nodes.flatten().filter { it.height == 'a' - c0 && it.distance < Int.MAX_VALUE }.sortedByDescending { it.distance }.toMutableList()

        var shortest = Int.MAX_VALUE

        starts.forEach { newStart ->
            nodes.flatten().forEach { it.distance = Int.MAX_VALUE }
            newStart.distance = 0
            toProcess.add(newStart)

            dijkstra(toProcess)

            shortest = min(shortest, end.distance)
        }

        return shortest
    }

    val testInput = listOf(
        "Sabqponm",
        "abcryxxl",
        "accszExk",
        "acctuvwj",
        "abdefghi"
    )

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

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

data class Node(
    val height: Int,
    var distance: Int = Int.MAX_VALUE,
    val neighbors: MutableList<Node> = mutableListOf(),
    val isStart: Boolean = false,
    val isEnd: Boolean = false)

Compiled from "Day12.kt"
public final class Day12Kt {
  public static final void main();
    Code:
       0: bipush        96
       2: istore_0
       3: iconst_5
       4: anewarray     #8                  // class java/lang/String
       7: astore_2
       8: aload_2
       9: iconst_0
      10: ldc           #10                 // String Sabqponm
      12: aastore
      13: aload_2
      14: iconst_1
      15: ldc           #12                 // String abcryxxl
      17: aastore
      18: aload_2
      19: iconst_2
      20: ldc           #14                 // String accszExk
      22: aastore
      23: aload_2
      24: iconst_3
      25: ldc           #16                 // String acctuvwj
      27: aastore
      28: aload_2
      29: iconst_4
      30: ldc           #18                 // String abdefghi
      32: aastore
      33: aload_2
      34: invokestatic  #24                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      37: astore_1
      38: iload_0
      39: aload_1
      40: invokestatic  #28                 // Method main$part1:(CLjava/util/List;)I
      43: bipush        31
      45: if_icmpne     52
      48: iconst_1
      49: goto          53
      52: iconst_0
      53: ifne          66
      56: new           #30                 // class java/lang/IllegalStateException
      59: dup
      60: ldc           #32                 // String Check failed.
      62: invokespecial #36                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      65: athrow
      66: iload_0
      67: aload_1
      68: invokestatic  #39                 // Method main$part2:(CLjava/util/List;)I
      71: bipush        29
      73: if_icmpne     80
      76: iconst_1
      77: goto          81
      80: iconst_0
      81: ifne          94
      84: new           #30                 // class java/lang/IllegalStateException
      87: dup
      88: ldc           #32                 // String Check failed.
      90: invokespecial #36                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      93: athrow
      94: new           #41                 // class java/io/File
      97: dup
      98: ldc           #43                 // String ./src/resources/Day12.txt
     100: invokespecial #44                 // Method java/io/File."<init>":(Ljava/lang/String;)V
     103: aconst_null
     104: iconst_1
     105: aconst_null
     106: invokestatic  #50                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
     109: astore_2
     110: iload_0
     111: aload_2
     112: invokestatic  #28                 // Method main$part1:(CLjava/util/List;)I
     115: istore_3
     116: getstatic     #56                 // Field java/lang/System.out:Ljava/io/PrintStream;
     119: iload_3
     120: invokevirtual #62                 // Method java/io/PrintStream.println:(I)V
     123: iload_0
     124: aload_2
     125: invokestatic  #39                 // Method main$part2:(CLjava/util/List;)I
     128: istore_3
     129: getstatic     #56                 // Field java/lang/System.out:Ljava/io/PrintStream;
     132: iload_3
     133: invokevirtual #62                 // Method java/io/PrintStream.println:(I)V
     136: return

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

  private static final java.util.List<java.util.List<Node>> main$getNodes(char, java.util.List<java.lang.String>);
    Code:
       0: aload_1
       1: checkcast     #80                 // class java/lang/Iterable
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: astore        4
      10: new           #82                 // class java/util/ArrayList
      13: dup
      14: aload_2
      15: bipush        10
      17: invokestatic  #86                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      20: invokespecial #88                 // Method java/util/ArrayList."<init>":(I)V
      23: checkcast     #90                 // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          265
      50: aload         7
      52: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         5
      61: aload         8
      63: checkcast     #8                  // class java/lang/String
      66: astore        9
      68: astore        22
      70: iconst_0
      71: istore        10
      73: aload         9
      75: checkcast     #106                // class java/lang/CharSequence
      78: astore        11
      80: iconst_0
      81: istore        12
      83: aload         11
      85: astore        13
      87: new           #82                 // class java/util/ArrayList
      90: dup
      91: aload         11
      93: invokeinterface #110,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      98: invokespecial #88                 // Method java/util/ArrayList."<init>":(I)V
     101: checkcast     #90                 // class java/util/Collection
     104: astore        14
     106: iconst_0
     107: istore        15
     109: iconst_0
     110: istore        16
     112: iload         16
     114: aload         13
     116: invokeinterface #110,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     121: if_icmpge     246
     124: aload         13
     126: iload         16
     128: invokeinterface #114,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     133: istore        17
     135: aload         14
     137: iload         17
     139: istore        18
     141: astore        19
     143: iconst_0
     144: istore        20
     146: iload         18
     148: lookupswitch  { // 2
                    69: 180
                    83: 176
               default: 187
          }
     176: iconst_0
     177: goto          191
     180: bipush        122
     182: iload_0
     183: isub
     184: goto          191
     187: iload         18
     189: iload_0
     190: isub
     191: istore        21
     193: new           #116                // class Node
     196: dup
     197: iload         21
     199: iconst_0
     200: aconst_null
     201: iload         18
     203: bipush        83
     205: if_icmpne     212
     208: iconst_1
     209: goto          213
     212: iconst_0
     213: iload         18
     215: bipush        69
     217: if_icmpne     224
     220: iconst_1
     221: goto          225
     224: iconst_0
     225: bipush        6
     227: aconst_null
     228: invokespecial #119                // Method Node."<init>":(IILjava/util/List;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
     231: aload         19
     233: swap
     234: invokeinterface #123,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     239: pop
     240: iinc          16, 1
     243: goto          112
     246: aload         14
     248: checkcast     #69                 // class java/util/List
     251: nop
     252: nop
     253: aload         22
     255: swap
     256: invokeinterface #123,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     261: pop
     262: goto          40
     265: aload         5
     267: checkcast     #69                 // class java/util/List
     270: nop
     271: areturn

  private static final void main$buildNeighbors(java.util.List<? extends java.util.List<Node>>);
    Code:
       0: aload_0
       1: checkcast     #80                 // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: iconst_0
       8: istore_3
       9: aload_1
      10: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      15: astore        4
      17: aload         4
      19: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      24: ifeq          482
      27: aload         4
      29: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      34: astore        5
      36: iload_3
      37: iinc          3, 1
      40: istore        6
      42: iload         6
      44: ifge          50
      47: invokestatic  #146                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
      50: iload         6
      52: aload         5
      54: checkcast     #69                 // class java/util/List
      57: astore        7
      59: istore        8
      61: iconst_0
      62: istore        9
      64: aload         7
      66: checkcast     #80                 // class java/lang/Iterable
      69: astore        10
      71: iconst_0
      72: istore        11
      74: iconst_0
      75: istore        12
      77: aload         10
      79: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      84: astore        13
      86: aload         13
      88: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      93: ifeq          476
      96: aload         13
      98: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     103: astore        14
     105: iload         12
     107: iinc          12, 1
     110: istore        15
     112: iload         15
     114: ifge          120
     117: invokestatic  #146                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     120: iload         15
     122: aload         14
     124: checkcast     #116                // class Node
     127: astore        16
     129: istore        17
     131: iconst_0
     132: istore        18
     134: iconst_4
     135: anewarray     #148                // class kotlin/Pair
     138: astore        19
     140: aload         19
     142: iconst_0
     143: iload         17
     145: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     148: iload         8
     150: iconst_1
     151: isub
     152: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     155: invokestatic  #160                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     158: aastore
     159: aload         19
     161: iconst_1
     162: iload         17
     164: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     167: iload         8
     169: iconst_1
     170: iadd
     171: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     174: invokestatic  #160                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     177: aastore
     178: aload         19
     180: iconst_2
     181: iload         17
     183: iconst_1
     184: iadd
     185: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     188: iload         8
     190: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     193: invokestatic  #160                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     196: aastore
     197: aload         19
     199: iconst_3
     200: iload         17
     202: iconst_1
     203: isub
     204: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     207: iload         8
     209: invokestatic  #154                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     212: invokestatic  #160                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     215: aastore
     216: aload         19
     218: invokestatic  #24                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     221: checkcast     #80                 // class java/lang/Iterable
     224: astore        19
     226: iconst_0
     227: istore        20
     229: aload         19
     231: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     236: astore        21
     238: aload         21
     240: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     245: ifeq          470
     248: aload         21
     250: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     255: astore        22
     257: aload         22
     259: checkcast     #148                // class kotlin/Pair
     262: astore        23
     264: iconst_0
     265: istore        24
     267: aload         7
     269: checkcast     #90                 // class java/util/Collection
     272: invokeinterface #163,  1          // InterfaceMethod java/util/Collection.size:()I
     277: istore        25
     279: aload         23
     281: invokevirtual #166                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     284: checkcast     #168                // class java/lang/Number
     287: invokevirtual #171                // Method java/lang/Number.intValue:()I
     290: istore        26
     292: iconst_0
     293: iload         26
     295: if_icmpgt     313
     298: iload         26
     300: iload         25
     302: if_icmpge     309
     305: iconst_1
     306: goto          314
     309: iconst_0
     310: goto          314
     313: iconst_0
     314: ifeq          465
     317: aload_0
     318: checkcast     #90                 // class java/util/Collection
     321: invokeinterface #163,  1          // InterfaceMethod java/util/Collection.size:()I
     326: istore        25
     328: aload         23
     330: invokevirtual #174                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     333: checkcast     #168                // class java/lang/Number
     336: invokevirtual #171                // Method java/lang/Number.intValue:()I
     339: istore        26
     341: iconst_0
     342: iload         26
     344: if_icmpgt     362
     347: iload         26
     349: iload         25
     351: if_icmpge     358
     354: iconst_1
     355: goto          363
     358: iconst_0
     359: goto          363
     362: iconst_0
     363: ifeq          465
     366: aload_0
     367: aload         23
     369: invokevirtual #174                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     372: checkcast     #168                // class java/lang/Number
     375: invokevirtual #171                // Method java/lang/Number.intValue:()I
     378: invokeinterface #178,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     383: checkcast     #69                 // class java/util/List
     386: aload         23
     388: invokevirtual #166                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     391: checkcast     #168                // class java/lang/Number
     394: invokevirtual #171                // Method java/lang/Number.intValue:()I
     397: invokeinterface #178,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     402: checkcast     #116                // class Node
     405: invokevirtual #181                // Method Node.getHeight:()I
     408: aload         16
     410: invokevirtual #181                // Method Node.getHeight:()I
     413: iconst_1
     414: iadd
     415: if_icmpgt     465
     418: aload         16
     420: invokevirtual #185                // Method Node.getNeighbors:()Ljava/util/List;
     423: aload_0
     424: aload         23
     426: invokevirtual #174                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     429: checkcast     #168                // class java/lang/Number
     432: invokevirtual #171                // Method java/lang/Number.intValue:()I
     435: invokeinterface #178,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     440: checkcast     #69                 // class java/util/List
     443: aload         23
     445: invokevirtual #166                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     448: checkcast     #168                // class java/lang/Number
     451: invokevirtual #171                // Method java/lang/Number.intValue:()I
     454: invokeinterface #178,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     459: invokeinterface #186,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     464: pop
     465: nop
     466: nop
     467: goto          238
     470: nop
     471: nop
     472: nop
     473: goto          86
     476: nop
     477: nop
     478: nop
     479: goto          17
     482: nop
     483: return

  private static final void main$dijkstra(java.util.List<Node>);
    Code:
       0: aload_0
       1: checkcast     #80                 // class java/lang/Iterable
       4: invokestatic  #209                // Method kotlin/collections/CollectionsKt.any:(Ljava/lang/Iterable;)Z
       7: ifeq          149
      10: aload_0
      11: invokeinterface #212,  1          // InterfaceMethod java/util/List.removeFirst:()Ljava/lang/Object;
      16: dup
      17: ldc           #214                // String removeFirst(...)
      19: invokestatic  #220                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      22: checkcast     #116                // class Node
      25: astore_1
      26: aload_1
      27: invokevirtual #185                // Method Node.getNeighbors:()Ljava/util/List;
      30: checkcast     #80                 // class java/lang/Iterable
      33: astore_2
      34: iconst_0
      35: istore_3
      36: aload_2
      37: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      42: astore        4
      44: aload         4
      46: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      51: ifeq          145
      54: aload         4
      56: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      61: astore        5
      63: aload         5
      65: checkcast     #116                // class Node
      68: astore        6
      70: iconst_0
      71: istore        7
      73: aload_1
      74: invokevirtual #223                // Method Node.getDistance:()I
      77: iconst_1
      78: iadd
      79: aload         6
      81: invokevirtual #223                // Method Node.getDistance:()I
      84: if_icmpge     107
      87: aload         6
      89: aload_1
      90: invokevirtual #223                // Method Node.getDistance:()I
      93: iconst_1
      94: iadd
      95: invokevirtual #226                // Method Node.setDistance:(I)V
      98: aload_0
      99: aload         6
     101: invokeinterface #186,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     106: pop
     107: aload_0
     108: astore        8
     110: iconst_0
     111: istore        9
     113: aload         8
     115: invokeinterface #227,  1          // InterfaceMethod java/util/List.size:()I
     120: iconst_1
     121: if_icmple     139
     124: aload         8
     126: new           #229                // class Day12Kt$main$dijkstra$lambda$6$$inlined$sortBy$1
     129: dup
     130: invokespecial #231                // Method Day12Kt$main$dijkstra$lambda$6$$inlined$sortBy$1."<init>":()V
     133: checkcast     #233                // class java/util/Comparator
     136: invokestatic  #237                // Method kotlin/collections/CollectionsKt.sortWith:(Ljava/util/List;Ljava/util/Comparator;)V
     139: nop
     140: nop
     141: nop
     142: goto          44
     145: nop
     146: goto          0
     149: return

  private static final int main$part1(char, java.util.List<java.lang.String>);
    Code:
       0: iload_0
       1: aload_1
       2: invokestatic  #245                // Method main$getNodes:(CLjava/util/List;)Ljava/util/List;
       5: astore_2
       6: aload_2
       7: checkcast     #80                 // class java/lang/Iterable
      10: invokestatic  #249                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
      13: checkcast     #80                 // class java/lang/Iterable
      16: astore        4
      18: iconst_0
      19: istore        5
      21: aload         4
      23: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      28: astore        6
      30: aload         6
      32: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      37: ifeq          72
      40: aload         6
      42: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      47: astore        7
      49: aload         7
      51: checkcast     #116                // class Node
      54: astore        8
      56: iconst_0
      57: istore        9
      59: aload         8
      61: invokevirtual #252                // Method Node.isStart:()Z
      64: ifeq          30
      67: aload         7
      69: goto          83
      72: new           #254                // class java/util/NoSuchElementException
      75: dup
      76: ldc_w         #256                // String Collection contains no element matching the predicate.
      79: invokespecial #257                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
      82: athrow
      83: checkcast     #116                // class Node
      86: astore_3
      87: aload_2
      88: invokestatic  #259                // Method main$buildNeighbors:(Ljava/util/List;)V
      91: aload_3
      92: iconst_0
      93: invokevirtual #226                // Method Node.setDistance:(I)V
      96: iconst_1
      97: anewarray     #116                // class Node
     100: astore        5
     102: aload         5
     104: iconst_0
     105: aload_3
     106: aastore
     107: aload         5
     109: invokestatic  #262                // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
     112: astore        4
     114: aload         4
     116: invokestatic  #264                // Method main$dijkstra:(Ljava/util/List;)V
     119: aload_2
     120: checkcast     #80                 // class java/lang/Iterable
     123: invokestatic  #249                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
     126: checkcast     #80                 // class java/lang/Iterable
     129: astore        6
     131: iconst_0
     132: istore        7
     134: aload         6
     136: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     141: astore        8
     143: aload         8
     145: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     150: ifeq          185
     153: aload         8
     155: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     160: astore        9
     162: aload         9
     164: checkcast     #116                // class Node
     167: astore        10
     169: iconst_0
     170: istore        11
     172: aload         10
     174: invokevirtual #267                // Method Node.isEnd:()Z
     177: ifeq          143
     180: aload         9
     182: goto          186
     185: aconst_null
     186: checkcast     #116                // class Node
     189: dup
     190: ifnull        199
     193: invokevirtual #223                // Method Node.getDistance:()I
     196: goto          201
     199: pop
     200: iconst_0
     201: ireturn

  private static final int main$part2(char, java.util.List<java.lang.String>);
    Code:
       0: iload_0
       1: aload_1
       2: invokestatic  #245                // Method main$getNodes:(CLjava/util/List;)Ljava/util/List;
       5: astore_2
       6: aload_2
       7: checkcast     #80                 // class java/lang/Iterable
      10: invokestatic  #249                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
      13: checkcast     #80                 // class java/lang/Iterable
      16: astore        4
      18: iconst_0
      19: istore        5
      21: aload         4
      23: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      28: astore        6
      30: aload         6
      32: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      37: ifeq          72
      40: aload         6
      42: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      47: astore        7
      49: aload         7
      51: checkcast     #116                // class Node
      54: astore        8
      56: iconst_0
      57: istore        9
      59: aload         8
      61: invokevirtual #252                // Method Node.isStart:()Z
      64: ifeq          30
      67: aload         7
      69: goto          83
      72: new           #254                // class java/util/NoSuchElementException
      75: dup
      76: ldc_w         #256                // String Collection contains no element matching the predicate.
      79: invokespecial #257                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
      82: athrow
      83: checkcast     #116                // class Node
      86: astore_3
      87: aload_2
      88: checkcast     #80                 // class java/lang/Iterable
      91: invokestatic  #249                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
      94: checkcast     #80                 // class java/lang/Iterable
      97: astore        5
      99: iconst_0
     100: istore        6
     102: aload         5
     104: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     109: astore        7
     111: aload         7
     113: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     118: ifeq          153
     121: aload         7
     123: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     128: astore        8
     130: aload         8
     132: checkcast     #116                // class Node
     135: astore        9
     137: iconst_0
     138: istore        10
     140: aload         9
     142: invokevirtual #267                // Method Node.isEnd:()Z
     145: ifeq          111
     148: aload         8
     150: goto          164
     153: new           #254                // class java/util/NoSuchElementException
     156: dup
     157: ldc_w         #256                // String Collection contains no element matching the predicate.
     160: invokespecial #257                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
     163: athrow
     164: checkcast     #116                // class Node
     167: astore        4
     169: aload_2
     170: invokestatic  #259                // Method main$buildNeighbors:(Ljava/util/List;)V
     173: aload_3
     174: iconst_0
     175: invokevirtual #226                // Method Node.setDistance:(I)V
     178: iconst_1
     179: anewarray     #116                // class Node
     182: astore        6
     184: aload         6
     186: iconst_0
     187: aload_3
     188: aastore
     189: aload         6
     191: invokestatic  #262                // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
     194: astore        5
     196: aload         5
     198: invokestatic  #264                // Method main$dijkstra:(Ljava/util/List;)V
     201: aload_2
     202: checkcast     #80                 // class java/lang/Iterable
     205: invokestatic  #249                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
     208: checkcast     #80                 // class java/lang/Iterable
     211: astore        7
     213: iconst_0
     214: istore        8
     216: aload         7
     218: astore        9
     220: new           #82                 // class java/util/ArrayList
     223: dup
     224: invokespecial #278                // Method java/util/ArrayList."<init>":()V
     227: checkcast     #90                 // class java/util/Collection
     230: astore        10
     232: iconst_0
     233: istore        11
     235: aload         9
     237: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     242: astore        12
     244: aload         12
     246: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     251: ifeq          317
     254: aload         12
     256: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     261: astore        13
     263: aload         13
     265: checkcast     #116                // class Node
     268: astore        14
     270: iconst_0
     271: istore        15
     273: aload         14
     275: invokevirtual #181                // Method Node.getHeight:()I
     278: bipush        97
     280: iload_0
     281: isub
     282: if_icmpne     300
     285: aload         14
     287: invokevirtual #223                // Method Node.getDistance:()I
     290: ldc_w         #279                // int 2147483647
     293: if_icmpge     300
     296: iconst_1
     297: goto          301
     300: iconst_0
     301: ifeq          244
     304: aload         10
     306: aload         13
     308: invokeinterface #123,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     313: pop
     314: goto          244
     317: aload         10
     319: checkcast     #69                 // class java/util/List
     322: nop
     323: checkcast     #80                 // class java/lang/Iterable
     326: astore        7
     328: nop
     329: iconst_0
     330: istore        8
     332: aload         7
     334: new           #281                // class Day12Kt$main$part2$$inlined$sortedByDescending$1
     337: dup
     338: invokespecial #282                // Method Day12Kt$main$part2$$inlined$sortedByDescending$1."<init>":()V
     341: checkcast     #233                // class java/util/Comparator
     344: invokestatic  #286                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
     347: checkcast     #90                 // class java/util/Collection
     350: invokestatic  #290                // Method kotlin/collections/CollectionsKt.toMutableList:(Ljava/util/Collection;)Ljava/util/List;
     353: astore        6
     355: iconst_0
     356: istore        7
     358: ldc_w         #279                // int 2147483647
     361: istore        7
     363: aload         6
     365: checkcast     #80                 // class java/lang/Iterable
     368: astore        8
     370: iconst_0
     371: istore        9
     373: aload         8
     375: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     380: astore        10
     382: aload         10
     384: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     389: ifeq          515
     392: aload         10
     394: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     399: astore        11
     401: aload         11
     403: checkcast     #116                // class Node
     406: astore        12
     408: iconst_0
     409: istore        13
     411: aload_2
     412: checkcast     #80                 // class java/lang/Iterable
     415: invokestatic  #249                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
     418: checkcast     #80                 // class java/lang/Iterable
     421: astore        14
     423: iconst_0
     424: istore        15
     426: aload         14
     428: invokeinterface #94,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     433: astore        16
     435: aload         16
     437: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     442: ifeq          476
     445: aload         16
     447: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     452: astore        17
     454: aload         17
     456: checkcast     #116                // class Node
     459: astore        18
     461: iconst_0
     462: istore        19
     464: aload         18
     466: ldc_w         #279                // int 2147483647
     469: invokevirtual #226                // Method Node.setDistance:(I)V
     472: nop
     473: goto          435
     476: nop
     477: aload         12
     479: iconst_0
     480: invokevirtual #226                // Method Node.setDistance:(I)V
     483: aload         5
     485: aload         12
     487: invokeinterface #186,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     492: pop
     493: aload         5
     495: invokestatic  #264                // Method main$dijkstra:(Ljava/util/List;)V
     498: iload         7
     500: aload         4
     502: invokevirtual #223                // Method Node.getDistance:()I
     505: invokestatic  #296                // Method java/lang/Math.min:(II)I
     508: istore        7
     510: nop
     511: nop
     512: goto          382
     515: nop
     516: iload         7
     518: ireturn
}

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

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

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

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