package xyz.danielstefani

import java.util.function.Function

lateinit var trees: List<List<Int>>
const val GRID_SIZE = 4

fun main() {
    trees = object {}.javaClass
        .classLoader
        .getResource("Day8Input.in")!!
        .readText()
        .split("\n")
        .map { it.map { it.digitToInt() }.toList() }

    // Part 1
    var visible = 0
    for (row in trees.indices) {
        for (column in trees.indices) {
            val top = isVisible(trees[row][column], row - 1, column, rowFunction = { r -> r - 1 })
            val bottom = isVisible(trees[row][column], row + 1, column, rowFunction = { r -> r + 1 })
            val left = isVisible(trees[row][column], row, column - 1, columnFunction = { c -> c - 1 })
            val right = isVisible(trees[row][column], row, column + 1, columnFunction = { c -> c + 1 })
            if (top || bottom || left || right) visible++
        }
    }
    println(visible)

    // Part 2
    var maxScenicScore = 0
    for (row in trees.indices) {
        for (column in trees.indices) {
            val top = getScenicScore(row - 1, column, rowFunction = { r -> r - 1 })
            val bottom = getScenicScore(row + 1, column, rowFunction = { r -> r + 1 })
            val left = getScenicScore(row, column - 1, columnFunction = { c -> c - 1 })
            val right = getScenicScore(row, column + 1, columnFunction = { c -> c + 1 })
            val score = top * bottom * left * right
            if (score > maxScenicScore) maxScenicScore = score
        }
    }
    println(maxScenicScore)
}

fun isVisible(treeHeight: Int, row: Int, column: Int,
              rowFunction: Function<Int, Int> = Function { r -> r },
              columnFunction: Function<Int, Int> = Function { c -> c }
): Boolean {
    if (column < 0 || column > GRID_SIZE || row < 0 || row > GRID_SIZE) return true
    if (treeHeight <= trees[row][column]) return false
    if (column == 0 || column == GRID_SIZE || row == 0 || row == GRID_SIZE) return true
    return isVisible(treeHeight, rowFunction.apply(row), columnFunction.apply(column), rowFunction, columnFunction)
}

fun getScenicScore(row: Int, column: Int,
              rowFunction: Function<Int, Int> = Function { r -> r },
              columnFunction: Function<Int, Int> = Function { c -> c }
): Int {
    if (column <= 0 || column >= GRID_SIZE || row <= 0 || row >= GRID_SIZE) return 0
    return 1 + getScenicScore(rowFunction.apply(row), columnFunction.apply(column), rowFunction, columnFunction)
}

Compiled from "Day8.kt"
public final class xyz.danielstefani.Day8Kt$main$1 {
  xyz.danielstefani.Day8Kt$main$1();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return
}

Compiled from "Day8.kt"
public final class xyz.danielstefani.Day8Kt {
  public static java.util.List<? extends java.util.List<java.lang.Integer>> trees;

  public static final int GRID_SIZE;

  public static final java.util.List<java.util.List<java.lang.Integer>> getTrees();
    Code:
       0: getstatic     #12                 // Field trees:Ljava/util/List;
       3: dup
       4: ifnull        8
       7: areturn
       8: pop
       9: ldc           #13                 // String trees
      11: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException:(Ljava/lang/String;)V
      14: aconst_null
      15: areturn

  public static final void setTrees(java.util.List<? extends java.util.List<java.lang.Integer>>);
    Code:
       0: aload_0
       1: ldc           #26                 // String <set-?>
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: putstatic     #12                 // Field trees:Ljava/util/List;
      10: return

  public static final void main();
    Code:
       0: new           #34                 // class xyz/danielstefani/Day8Kt$main$1
       3: dup
       4: invokespecial #37                 // Method xyz/danielstefani/Day8Kt$main$1."<init>":()V
       7: invokevirtual #41                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
      10: invokevirtual #47                 // Method java/lang/Class.getClassLoader:()Ljava/lang/ClassLoader;
      13: ldc           #49                 // String Day8Input.in
      15: invokevirtual #55                 // Method java/lang/ClassLoader.getResource:(Ljava/lang/String;)Ljava/net/URL;
      18: dup
      19: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      22: astore_0
      23: getstatic     #65                 // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      26: astore_1
      27: aload_0
      28: invokestatic  #71                 // Method kotlin/io/TextStreamsKt.readBytes:(Ljava/net/URL;)[B
      31: astore_2
      32: new           #73                 // class java/lang/String
      35: dup
      36: aload_2
      37: aload_1
      38: invokespecial #76                 // Method java/lang/String."<init>":([BLjava/nio/charset/Charset;)V
      41: checkcast     #78                 // class java/lang/CharSequence
      44: iconst_1
      45: anewarray     #73                 // class java/lang/String
      48: astore_0
      49: aload_0
      50: iconst_0
      51: ldc           #80                 // String \n
      53: aastore
      54: aload_0
      55: iconst_0
      56: iconst_0
      57: bipush        6
      59: aconst_null
      60: invokestatic  #86                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      63: checkcast     #88                 // class java/lang/Iterable
      66: astore_0
      67: nop
      68: iconst_0
      69: istore_1
      70: aload_0
      71: astore_2
      72: new           #90                 // class java/util/ArrayList
      75: dup
      76: aload_0
      77: bipush        10
      79: invokestatic  #96                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      82: invokespecial #99                 // Method java/util/ArrayList."<init>":(I)V
      85: checkcast     #101                // class java/util/Collection
      88: astore_3
      89: iconst_0
      90: istore        4
      92: aload_2
      93: invokeinterface #105,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      98: astore        5
     100: aload         5
     102: invokeinterface #111,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     107: ifeq          252
     110: aload         5
     112: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     117: astore        6
     119: aload_3
     120: aload         6
     122: checkcast     #73                 // class java/lang/String
     125: astore        7
     127: astore        19
     129: iconst_0
     130: istore        8
     132: aload         7
     134: checkcast     #78                 // class java/lang/CharSequence
     137: astore        9
     139: iconst_0
     140: istore        10
     142: aload         9
     144: astore        11
     146: new           #90                 // class java/util/ArrayList
     149: dup
     150: aload         9
     152: invokeinterface #119,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     157: invokespecial #99                 // Method java/util/ArrayList."<init>":(I)V
     160: checkcast     #101                // class java/util/Collection
     163: astore        12
     165: iconst_0
     166: istore        13
     168: iconst_0
     169: istore        14
     171: iload         14
     173: aload         11
     175: invokeinterface #119,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     180: if_icmpge     228
     183: aload         11
     185: iload         14
     187: invokeinterface #123,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     192: istore        15
     194: aload         12
     196: iload         15
     198: istore        16
     200: astore        17
     202: iconst_0
     203: istore        18
     205: iload         16
     207: invokestatic  #129                // Method kotlin/text/CharsKt.digitToInt:(C)I
     210: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     213: aload         17
     215: swap
     216: invokeinterface #139,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     221: pop
     222: iinc          14, 1
     225: goto          171
     228: aload         12
     230: checkcast     #21                 // class java/util/List
     233: nop
     234: checkcast     #88                 // class java/lang/Iterable
     237: invokestatic  #143                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     240: aload         19
     242: swap
     243: invokeinterface #139,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     248: pop
     249: goto          100
     252: aload_3
     253: checkcast     #21                 // class java/util/List
     256: nop
     257: invokestatic  #145                // Method setTrees:(Ljava/util/List;)V
     260: iconst_0
     261: istore_0
     262: iconst_0
     263: istore_1
     264: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     267: checkcast     #101                // class java/util/Collection
     270: invokeinterface #150,  1          // InterfaceMethod java/util/Collection.size:()I
     275: istore_2
     276: iload_1
     277: iload_2
     278: if_icmpge     505
     281: iconst_0
     282: istore_3
     283: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     286: checkcast     #101                // class java/util/Collection
     289: invokeinterface #150,  1          // InterfaceMethod java/util/Collection.size:()I
     294: istore        4
     296: iload_3
     297: iload         4
     299: if_icmpge     499
     302: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     305: iload_1
     306: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     311: checkcast     #21                 // class java/util/List
     314: iload_3
     315: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     320: checkcast     #156                // class java/lang/Number
     323: invokevirtual #159                // Method java/lang/Number.intValue:()I
     326: iload_1
     327: iconst_1
     328: isub
     329: iload_3
     330: invokedynamic #178,  0            // InvokeDynamic #0:apply:()Ljava/util/function/Function;
     335: aconst_null
     336: bipush        16
     338: aconst_null
     339: invokestatic  #182                // Method isVisible$default:(IIILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)Z
     342: istore        5
     344: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     347: iload_1
     348: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     353: checkcast     #21                 // class java/util/List
     356: iload_3
     357: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     362: checkcast     #156                // class java/lang/Number
     365: invokevirtual #159                // Method java/lang/Number.intValue:()I
     368: iload_1
     369: iconst_1
     370: iadd
     371: iload_3
     372: invokedynamic #187,  0            // InvokeDynamic #1:apply:()Ljava/util/function/Function;
     377: aconst_null
     378: bipush        16
     380: aconst_null
     381: invokestatic  #182                // Method isVisible$default:(IIILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)Z
     384: istore        6
     386: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     389: iload_1
     390: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     395: checkcast     #21                 // class java/util/List
     398: iload_3
     399: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     404: checkcast     #156                // class java/lang/Number
     407: invokevirtual #159                // Method java/lang/Number.intValue:()I
     410: iload_1
     411: iload_3
     412: iconst_1
     413: isub
     414: aconst_null
     415: invokedynamic #192,  0            // InvokeDynamic #2:apply:()Ljava/util/function/Function;
     420: bipush        8
     422: aconst_null
     423: invokestatic  #182                // Method isVisible$default:(IIILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)Z
     426: istore        7
     428: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     431: iload_1
     432: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     437: checkcast     #21                 // class java/util/List
     440: iload_3
     441: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     446: checkcast     #156                // class java/lang/Number
     449: invokevirtual #159                // Method java/lang/Number.intValue:()I
     452: iload_1
     453: iload_3
     454: iconst_1
     455: iadd
     456: aconst_null
     457: invokedynamic #197,  0            // InvokeDynamic #3:apply:()Ljava/util/function/Function;
     462: bipush        8
     464: aconst_null
     465: invokestatic  #182                // Method isVisible$default:(IIILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)Z
     468: istore        8
     470: iload         5
     472: ifne          490
     475: iload         6
     477: ifne          490
     480: iload         7
     482: ifne          490
     485: iload         8
     487: ifeq          493
     490: iinc          0, 1
     493: iinc          3, 1
     496: goto          296
     499: iinc          1, 1
     502: goto          276
     505: getstatic     #203                // Field java/lang/System.out:Ljava/io/PrintStream;
     508: iload_0
     509: invokevirtual #208                // Method java/io/PrintStream.println:(I)V
     512: iconst_0
     513: istore_1
     514: iconst_0
     515: istore_2
     516: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     519: checkcast     #101                // class java/util/Collection
     522: invokeinterface #150,  1          // InterfaceMethod java/util/Collection.size:()I
     527: istore_3
     528: iload_2
     529: iload_3
     530: if_icmpge     664
     533: iconst_0
     534: istore        4
     536: invokestatic  #147                // Method getTrees:()Ljava/util/List;
     539: checkcast     #101                // class java/util/Collection
     542: invokeinterface #150,  1          // InterfaceMethod java/util/Collection.size:()I
     547: istore        5
     549: iload         4
     551: iload         5
     553: if_icmpge     658
     556: iload_2
     557: iconst_1
     558: isub
     559: iload         4
     561: invokedynamic #213,  0            // InvokeDynamic #4:apply:()Ljava/util/function/Function;
     566: aconst_null
     567: bipush        8
     569: aconst_null
     570: invokestatic  #217                // Method getScenicScore$default:(IILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)I
     573: istore        6
     575: iload_2
     576: iconst_1
     577: iadd
     578: iload         4
     580: invokedynamic #222,  0            // InvokeDynamic #5:apply:()Ljava/util/function/Function;
     585: aconst_null
     586: bipush        8
     588: aconst_null
     589: invokestatic  #217                // Method getScenicScore$default:(IILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)I
     592: istore        7
     594: iload_2
     595: iload         4
     597: iconst_1
     598: isub
     599: aconst_null
     600: invokedynamic #227,  0            // InvokeDynamic #6:apply:()Ljava/util/function/Function;
     605: iconst_4
     606: aconst_null
     607: invokestatic  #217                // Method getScenicScore$default:(IILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)I
     610: istore        8
     612: iload_2
     613: iload         4
     615: iconst_1
     616: iadd
     617: aconst_null
     618: invokedynamic #232,  0            // InvokeDynamic #7:apply:()Ljava/util/function/Function;
     623: iconst_4
     624: aconst_null
     625: invokestatic  #217                // Method getScenicScore$default:(IILjava/util/function/Function;Ljava/util/function/Function;ILjava/lang/Object;)I
     628: istore        9
     630: iload         6
     632: iload         7
     634: imul
     635: iload         8
     637: imul
     638: iload         9
     640: imul
     641: istore        10
     643: iload         10
     645: iload_1
     646: if_icmple     652
     649: iload         10
     651: istore_1
     652: iinc          4, 1
     655: goto          549
     658: iinc          2, 1
     661: goto          528
     664: getstatic     #203                // Field java/lang/System.out:Ljava/io/PrintStream;
     667: iload_1
     668: invokevirtual #208                // Method java/io/PrintStream.println:(I)V
     671: return

  public static final boolean isVisible(int, int, int, java.util.function.Function<java.lang.Integer, java.lang.Integer>, java.util.function.Function<java.lang.Integer, java.lang.Integer>);
    Code:
       0: aload_3
       1: ldc_w         #263                // String rowFunction
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload         4
       9: ldc_w         #265                // String columnFunction
      12: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      15: iload_2
      16: iflt          33
      19: iload_2
      20: iconst_4
      21: if_icmpgt     33
      24: iload_1
      25: iflt          33
      28: iload_1
      29: iconst_4
      30: if_icmple     35
      33: iconst_1
      34: ireturn
      35: iload_0
      36: invokestatic  #147                // Method getTrees:()Ljava/util/List;
      39: iload_1
      40: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      45: checkcast     #21                 // class java/util/List
      48: iload_2
      49: invokeinterface #154,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      54: checkcast     #156                // class java/lang/Number
      57: invokevirtual #159                // Method java/lang/Number.intValue:()I
      60: if_icmpgt     65
      63: iconst_0
      64: ireturn
      65: iload_2
      66: ifeq          83
      69: iload_2
      70: iconst_4
      71: if_icmpeq     83
      74: iload_1
      75: ifeq          83
      78: iload_1
      79: iconst_4
      80: if_icmpne     85
      83: iconst_1
      84: ireturn
      85: iload_0
      86: aload_3
      87: iload_1
      88: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      91: invokeinterface #269,  2          // InterfaceMethod java/util/function/Function.apply:(Ljava/lang/Object;)Ljava/lang/Object;
      96: dup
      97: ldc_w         #271                // String apply(...)
     100: invokestatic  #274                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     103: checkcast     #156                // class java/lang/Number
     106: invokevirtual #159                // Method java/lang/Number.intValue:()I
     109: aload         4
     111: iload_2
     112: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     115: invokeinterface #269,  2          // InterfaceMethod java/util/function/Function.apply:(Ljava/lang/Object;)Ljava/lang/Object;
     120: dup
     121: ldc_w         #271                // String apply(...)
     124: invokestatic  #274                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     127: checkcast     #156                // class java/lang/Number
     130: invokevirtual #159                // Method java/lang/Number.intValue:()I
     133: aload_3
     134: aload         4
     136: invokestatic  #276                // Method isVisible:(IIILjava/util/function/Function;Ljava/util/function/Function;)Z
     139: ireturn

  public static boolean isVisible$default(int, int, int, java.util.function.Function, java.util.function.Function, int, java.lang.Object);
    Code:
       0: iload         5
       2: bipush        8
       4: iand
       5: ifeq          14
       8: invokedynamic #283,  0            // InvokeDynamic #8:apply:()Ljava/util/function/Function;
      13: astore_3
      14: iload         5
      16: bipush        16
      18: iand
      19: ifeq          29
      22: invokedynamic #288,  0            // InvokeDynamic #9:apply:()Ljava/util/function/Function;
      27: astore        4
      29: iload_0
      30: iload_1
      31: iload_2
      32: aload_3
      33: aload         4
      35: invokestatic  #276                // Method isVisible:(IIILjava/util/function/Function;Ljava/util/function/Function;)Z
      38: ireturn

  public static final int getScenicScore(int, int, java.util.function.Function<java.lang.Integer, java.lang.Integer>, java.util.function.Function<java.lang.Integer, java.lang.Integer>);
    Code:
       0: aload_2
       1: ldc_w         #263                // String rowFunction
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_3
       8: ldc_w         #265                // String columnFunction
      11: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      14: iload_1
      15: ifle          32
      18: iload_1
      19: iconst_4
      20: if_icmpge     32
      23: iload_0
      24: ifle          32
      27: iload_0
      28: iconst_4
      29: if_icmplt     34
      32: iconst_0
      33: ireturn
      34: iconst_1
      35: aload_2
      36: iload_0
      37: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      40: invokeinterface #269,  2          // InterfaceMethod java/util/function/Function.apply:(Ljava/lang/Object;)Ljava/lang/Object;
      45: dup
      46: ldc_w         #271                // String apply(...)
      49: invokestatic  #274                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      52: checkcast     #156                // class java/lang/Number
      55: invokevirtual #159                // Method java/lang/Number.intValue:()I
      58: aload_3
      59: iload_1
      60: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      63: invokeinterface #269,  2          // InterfaceMethod java/util/function/Function.apply:(Ljava/lang/Object;)Ljava/lang/Object;
      68: dup
      69: ldc_w         #271                // String apply(...)
      72: invokestatic  #274                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      75: checkcast     #156                // class java/lang/Number
      78: invokevirtual #159                // Method java/lang/Number.intValue:()I
      81: aload_2
      82: aload_3
      83: invokestatic  #293                // Method getScenicScore:(IILjava/util/function/Function;Ljava/util/function/Function;)I
      86: iadd
      87: ireturn

  public static int getScenicScore$default(int, int, java.util.function.Function, java.util.function.Function, int, java.lang.Object);
    Code:
       0: iload         4
       2: iconst_4
       3: iand
       4: ifeq          13
       7: invokedynamic #298,  0            // InvokeDynamic #10:apply:()Ljava/util/function/Function;
      12: astore_2
      13: iload         4
      15: bipush        8
      17: iand
      18: ifeq          27
      21: invokedynamic #303,  0            // InvokeDynamic #11:apply:()Ljava/util/function/Function;
      26: astore_3
      27: iload_0
      28: iload_1
      29: aload_2
      30: aload_3
      31: invokestatic  #293                // Method getScenicScore:(IILjava/util/function/Function;Ljava/util/function/Function;)I
      34: ireturn

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

  private static final java.lang.Integer main$lambda$2(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #310                // String r
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: isub
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer main$lambda$3(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #310                // String r
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: iadd
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer main$lambda$4(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #314                // String c
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: isub
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer main$lambda$5(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #314                // String c
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: iadd
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer main$lambda$6(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #310                // String r
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: isub
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer main$lambda$7(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #310                // String r
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: iadd
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer main$lambda$8(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #314                // String c
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: isub
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer main$lambda$9(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #314                // String c
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #311                // Method java/lang/Integer.intValue:()I
      11: iconst_1
      12: iadd
      13: invokestatic  #135                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: areturn

  private static final java.lang.Integer isVisible$lambda$10(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #310                // String r
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: areturn

  private static final java.lang.Integer isVisible$lambda$11(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #314                // String c
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: areturn

  private static final java.lang.Integer getScenicScore$lambda$12(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #310                // String r
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: areturn

  private static final java.lang.Integer getScenicScore$lambda$13(java.lang.Integer);
    Code:
       0: aload_0
       1: ldc_w         #314                // String c
       4: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: areturn
}


package xyz.danielstefani

import java.util.stream.IntStream
import kotlin.streams.asSequence

val priorityMap = mutableMapOf<Int, Int>()

fun main() {
    // Prep
    fillMapWithPriorities(97, 122, 1)
    fillMapWithPriorities(65, 90, 27)

    val splitRucksacks = object {}.javaClass
        .classLoader
        .getResource("Day3Input.in")
        ?.readText()
        ?.split("\n")
        ?.map { twoRucksacks ->
            listOf(twoRucksacks.substring(0, twoRucksacks.length / 2).toCharSet(),
                    twoRucksacks.substring(twoRucksacks.length / 2).toCharSet())
        }

    // Part 1
    val splitRucksacksCommonItemsSum = splitRucksacks?.sumOf {
        priorityMap[it[0].intersect(it[1]).elementAt(0)]!!
    }

    // Part 2
    val groupedBy3CommonItemsSum = splitRucksacks
        ?.map { twoRuckSacks -> twoRuckSacks[0].union(twoRuckSacks[1]) }
        ?.chunked(3)
        ?.sumOf { groupOfThree ->
            priorityMap[groupOfThree.reduce { acc, set -> acc.intersect(set) }.elementAt(0)]!! as Int
        }

    println(splitRucksacksCommonItemsSum)
    println(groupedBy3CommonItemsSum)
}

fun fillMapWithPriorities(lowerInclusive: Int, upperInclusive: Int, foldInit: Int) {
    IntStream.range(lowerInclusive, upperInclusive + 1)
        .asSequence()
        .fold(foldInit) { acc, code ->
            priorityMap[code] = acc
            acc + 1
        }
}

fun String.toCharSet(): Set<Int> {
    return this.chars().collect({ mutableSetOf() }, { s, c -> s.add(c) }, { s1, s2 -> s1.addAll(s2) })
}

Compiled from "Day3.kt"
public final class xyz.danielstefani.Day3Kt {
  private static final java.util.Map<java.lang.Integer, java.lang.Integer> priorityMap;

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

  public static final void main();
    Code:
       0: bipush        97
       2: bipush        122
       4: iconst_1
       5: invokestatic  #18                 // Method fillMapWithPriorities:(III)V
       8: bipush        65
      10: bipush        90
      12: bipush        27
      14: invokestatic  #18                 // Method fillMapWithPriorities:(III)V
      17: new           #20                 // class xyz/danielstefani/Day3Kt$main$splitRucksacks$1
      20: dup
      21: invokespecial #23                 // Method xyz/danielstefani/Day3Kt$main$splitRucksacks$1."<init>":()V
      24: invokevirtual #27                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
      27: invokevirtual #33                 // Method java/lang/Class.getClassLoader:()Ljava/lang/ClassLoader;
      30: ldc           #35                 // String Day3Input.in
      32: invokevirtual #41                 // Method java/lang/ClassLoader.getResource:(Ljava/lang/String;)Ljava/net/URL;
      35: astore_1
      36: aload_1
      37: ifnull        256
      40: aload_1
      41: astore_3
      42: getstatic     #47                 // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      45: astore        4
      47: aload_3
      48: invokestatic  #53                 // Method kotlin/io/TextStreamsKt.readBytes:(Ljava/net/URL;)[B
      51: astore        5
      53: new           #55                 // class java/lang/String
      56: dup
      57: aload         5
      59: aload         4
      61: invokespecial #58                 // Method java/lang/String."<init>":([BLjava/nio/charset/Charset;)V
      64: checkcast     #60                 // class java/lang/CharSequence
      67: iconst_1
      68: anewarray     #55                 // class java/lang/String
      71: astore        4
      73: aload         4
      75: iconst_0
      76: ldc           #62                 // String \n
      78: aastore
      79: aload         4
      81: iconst_0
      82: iconst_0
      83: bipush        6
      85: aconst_null
      86: invokestatic  #68                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      89: astore_3
      90: aload_3
      91: ifnull        256
      94: aload_3
      95: checkcast     #70                 // class java/lang/Iterable
      98: astore        4
     100: nop
     101: iconst_0
     102: istore        5
     104: aload         4
     106: astore        6
     108: new           #72                 // class java/util/ArrayList
     111: dup
     112: aload         4
     114: bipush        10
     116: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     119: invokespecial #81                 // Method java/util/ArrayList."<init>":(I)V
     122: checkcast     #83                 // class java/util/Collection
     125: astore        7
     127: iconst_0
     128: istore        8
     130: aload         6
     132: invokeinterface #87,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     137: astore        9
     139: aload         9
     141: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     146: ifeq          247
     149: aload         9
     151: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     156: astore        10
     158: aload         7
     160: aload         10
     162: checkcast     #55                 // class java/lang/String
     165: astore        11
     167: astore        19
     169: iconst_0
     170: istore        12
     172: iconst_2
     173: anewarray     #99                 // class java/util/Set
     176: astore        13
     178: aload         13
     180: iconst_0
     181: aload         11
     183: iconst_0
     184: aload         11
     186: invokevirtual #103                // Method java/lang/String.length:()I
     189: iconst_2
     190: idiv
     191: invokevirtual #107                // Method java/lang/String.substring:(II)Ljava/lang/String;
     194: dup
     195: ldc           #109                // String substring(...)
     197: invokestatic  #115                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     200: invokestatic  #119                // Method toCharSet:(Ljava/lang/String;)Ljava/util/Set;
     203: aastore
     204: aload         13
     206: iconst_1
     207: aload         11
     209: aload         11
     211: invokevirtual #103                // Method java/lang/String.length:()I
     214: iconst_2
     215: idiv
     216: invokevirtual #122                // Method java/lang/String.substring:(I)Ljava/lang/String;
     219: dup
     220: ldc           #109                // String substring(...)
     222: invokestatic  #115                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     225: invokestatic  #119                // Method toCharSet:(Ljava/lang/String;)Ljava/util/Set;
     228: aastore
     229: aload         13
     231: invokestatic  #126                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     234: nop
     235: aload         19
     237: swap
     238: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     243: pop
     244: goto          139
     247: aload         7
     249: checkcast     #132                // class java/util/List
     252: nop
     253: goto          257
     256: aconst_null
     257: astore_0
     258: aload_0
     259: dup
     260: ifnull        377
     263: checkcast     #70                 // class java/lang/Iterable
     266: astore_2
     267: iconst_0
     268: istore_3
     269: aload_2
     270: invokeinterface #87,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     275: astore        4
     277: aload         4
     279: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     284: ifeq          370
     287: aload         4
     289: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     294: astore        5
     296: iload_3
     297: aload         5
     299: checkcast     #132                // class java/util/List
     302: astore        6
     304: istore        19
     306: iconst_0
     307: istore        7
     309: getstatic     #12                 // Field priorityMap:Ljava/util/Map;
     312: aload         6
     314: iconst_0
     315: invokeinterface #136,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     320: checkcast     #70                 // class java/lang/Iterable
     323: aload         6
     325: iconst_1
     326: invokeinterface #136,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     331: checkcast     #70                 // class java/lang/Iterable
     334: invokestatic  #140                // Method kotlin/collections/CollectionsKt.intersect:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/Set;
     337: checkcast     #70                 // class java/lang/Iterable
     340: iconst_0
     341: invokestatic  #144                // Method kotlin/collections/CollectionsKt.elementAt:(Ljava/lang/Iterable;I)Ljava/lang/Object;
     344: invokeinterface #149,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     349: dup
     350: invokestatic  #153                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     353: checkcast     #155                // class java/lang/Number
     356: invokevirtual #158                // Method java/lang/Number.intValue:()I
     359: istore        20
     361: iload         19
     363: iload         20
     365: iadd
     366: istore_3
     367: goto          277
     370: iload_3
     371: invokestatic  #164                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     374: goto          379
     377: pop
     378: aconst_null
     379: astore_1
     380: aload_0
     381: ifnull        721
     384: aload_0
     385: checkcast     #70                 // class java/lang/Iterable
     388: astore        4
     390: nop
     391: iconst_0
     392: istore        5
     394: aload         4
     396: astore        6
     398: new           #72                 // class java/util/ArrayList
     401: dup
     402: aload         4
     404: bipush        10
     406: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     409: invokespecial #81                 // Method java/util/ArrayList."<init>":(I)V
     412: checkcast     #83                 // class java/util/Collection
     415: astore        7
     417: iconst_0
     418: istore        8
     420: aload         6
     422: invokeinterface #87,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     427: astore        9
     429: aload         9
     431: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     436: ifeq          499
     439: aload         9
     441: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     446: astore        10
     448: aload         7
     450: aload         10
     452: checkcast     #132                // class java/util/List
     455: astore        11
     457: astore        19
     459: iconst_0
     460: istore        12
     462: aload         11
     464: iconst_0
     465: invokeinterface #136,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     470: checkcast     #70                 // class java/lang/Iterable
     473: aload         11
     475: iconst_1
     476: invokeinterface #136,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     481: checkcast     #70                 // class java/lang/Iterable
     484: invokestatic  #167                // Method kotlin/collections/CollectionsKt.union:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/Set;
     487: aload         19
     489: swap
     490: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     495: pop
     496: goto          429
     499: aload         7
     501: checkcast     #132                // class java/util/List
     504: nop
     505: checkcast     #70                 // class java/lang/Iterable
     508: iconst_3
     509: invokestatic  #171                // Method kotlin/collections/CollectionsKt.chunked:(Ljava/lang/Iterable;I)Ljava/util/List;
     512: astore        4
     514: aload         4
     516: ifnull        721
     519: aload         4
     521: checkcast     #70                 // class java/lang/Iterable
     524: astore        5
     526: iconst_0
     527: istore        6
     529: aload         5
     531: invokeinterface #87,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     536: astore        7
     538: aload         7
     540: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     545: ifeq          713
     548: aload         7
     550: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     555: astore        8
     557: iload         6
     559: aload         8
     561: checkcast     #132                // class java/util/List
     564: astore        9
     566: istore        19
     568: iconst_0
     569: istore        10
     571: getstatic     #12                 // Field priorityMap:Ljava/util/Map;
     574: aload         9
     576: checkcast     #70                 // class java/lang/Iterable
     579: astore        11
     581: astore        12
     583: iconst_0
     584: istore        13
     586: aload         11
     588: invokeinterface #87,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     593: astore        14
     595: aload         14
     597: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     602: ifne          615
     605: new           #173                // class java/lang/UnsupportedOperationException
     608: dup
     609: ldc           #175                // String Empty collection can\'t be reduced.
     611: invokespecial #178                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     614: athrow
     615: aload         14
     617: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     622: astore        15
     624: aload         14
     626: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     631: ifeq          674
     634: aload         15
     636: aload         14
     638: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     643: checkcast     #99                 // class java/util/Set
     646: astore        16
     648: checkcast     #99                 // class java/util/Set
     651: astore        17
     653: iconst_0
     654: istore        18
     656: aload         17
     658: checkcast     #70                 // class java/lang/Iterable
     661: aload         16
     663: checkcast     #70                 // class java/lang/Iterable
     666: invokestatic  #140                // Method kotlin/collections/CollectionsKt.intersect:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/Set;
     669: astore        15
     671: goto          624
     674: aload         15
     676: aload         12
     678: swap
     679: checkcast     #70                 // class java/lang/Iterable
     682: iconst_0
     683: invokestatic  #144                // Method kotlin/collections/CollectionsKt.elementAt:(Ljava/lang/Iterable;I)Ljava/lang/Object;
     686: invokeinterface #149,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     691: dup
     692: invokestatic  #153                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     695: checkcast     #160                // class java/lang/Integer
     698: invokevirtual #179                // Method java/lang/Integer.intValue:()I
     701: istore        20
     703: iload         19
     705: iload         20
     707: iadd
     708: istore        6
     710: goto          538
     713: iload         6
     715: invokestatic  #164                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     718: goto          722
     721: aconst_null
     722: astore_2
     723: getstatic     #185                // Field java/lang/System.out:Ljava/io/PrintStream;
     726: aload_1
     727: invokevirtual #190                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     730: getstatic     #185                // Field java/lang/System.out:Ljava/io/PrintStream;
     733: aload_2
     734: invokevirtual #190                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     737: return

  public static final void fillMapWithPriorities(int, int, int);
    Code:
       0: iload_0
       1: iload_1
       2: iconst_1
       3: iadd
       4: invokestatic  #231                // InterfaceMethod java/util/stream/IntStream.range:(II)Ljava/util/stream/IntStream;
       7: dup
       8: ldc           #233                // String range(...)
      10: invokestatic  #115                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      13: invokestatic  #239                // Method kotlin/streams/jdk8/StreamsKt.asSequence:(Ljava/util/stream/IntStream;)Lkotlin/sequences/Sequence;
      16: astore_3
      17: iload_2
      18: istore        4
      20: nop
      21: iconst_0
      22: istore        5
      24: iload         4
      26: istore        6
      28: aload_3
      29: invokeinterface #242,  1          // InterfaceMethod kotlin/sequences/Sequence.iterator:()Ljava/util/Iterator;
      34: astore        7
      36: aload         7
      38: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      43: ifeq          108
      46: aload         7
      48: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      53: astore        8
      55: iload         6
      57: aload         8
      59: checkcast     #155                // class java/lang/Number
      62: invokevirtual #158                // Method java/lang/Number.intValue:()I
      65: istore        9
      67: istore        10
      69: iconst_0
      70: istore        11
      72: iload         9
      74: invokestatic  #164                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      77: astore        12
      79: iload         10
      81: invokestatic  #164                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      84: astore        13
      86: getstatic     #12                 // Field priorityMap:Ljava/util/Map;
      89: aload         12
      91: aload         13
      93: invokeinterface #246,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      98: pop
      99: iload         10
     101: iconst_1
     102: iadd
     103: istore        6
     105: goto          36
     108: nop
     109: return

  public static final java.util.Set<java.lang.Integer> toCharSet(java.lang.String);
    Code:
       0: aload_0
       1: ldc_w         #259                // String <this>
       4: invokestatic  #262                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #266                // Method java/lang/String.chars:()Ljava/util/stream/IntStream;
      11: invokedynamic #283,  0            // InvokeDynamic #0:get:()Ljava/util/function/Supplier;
      16: invokedynamic #295,  0            // InvokeDynamic #1:accept:()Ljava/util/function/ObjIntConsumer;
      21: invokedynamic #306,  0            // InvokeDynamic #2:accept:()Ljava/util/function/BiConsumer;
      26: invokeinterface #310,  4          // InterfaceMethod java/util/stream/IntStream.collect:(Ljava/util/function/Supplier;Ljava/util/function/ObjIntConsumer;Ljava/util/function/BiConsumer;)Ljava/lang/Object;
      31: dup
      32: ldc_w         #312                // String collect(...)
      35: invokestatic  #115                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      38: checkcast     #99                 // class java/util/Set
      41: areturn

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

  private static final java.util.Set toCharSet$lambda$6();
    Code:
       0: new           #320                // class java/util/LinkedHashSet
       3: dup
       4: invokespecial #321                // Method java/util/LinkedHashSet."<init>":()V
       7: checkcast     #99                 // class java/util/Set
      10: areturn

  private static final void toCharSet$lambda$7(java.util.Set, int);
    Code:
       0: aload_0
       1: iload_1
       2: invokestatic  #164                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: invokeinterface #322,  2          // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
      10: pop
      11: return

  private static final void toCharSet$lambda$8(java.util.Set, java.util.Set);
    Code:
       0: aload_0
       1: aload_1
       2: invokestatic  #153                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
       5: aload_1
       6: checkcast     #83                 // class java/util/Collection
       9: invokeinterface #328,  2          // InterfaceMethod java/util/Set.addAll:(Ljava/util/Collection;)Z
      14: pop
      15: return

  static {};
    Code:
       0: new           #333                // class java/util/LinkedHashMap
       3: dup
       4: invokespecial #334                // Method java/util/LinkedHashMap."<init>":()V
       7: checkcast     #146                // class java/util/Map
      10: putstatic     #12                 // Field priorityMap:Ljava/util/Map;
      13: return
}

Compiled from "Day3.kt"
public final class xyz.danielstefani.Day3Kt$main$splitRucksacks$1 {
  xyz.danielstefani.Day3Kt$main$splitRucksacks$1();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return
}


package xyz.danielstefani

import kotlin.math.abs

val shapeToScore = mapOf(
    Pair("A", 1), // Rock
    Pair("B", 2), // Paper
    Pair("C", 3), // Scissors
    Pair("X", 1), // Rock
    Pair("Y", 2), // Paper
    Pair("Z", 3)  // Scissors
)

fun main(args: Array<String>) {
    // Prep
    val rounds = object {}.javaClass
        .classLoader
        .getResource("Day2Input.in")
        ?.readText()
        ?.split("\n")
        ?.map {
            it.split(", ")[0].split(" ")
                .map { letter -> shapeToScore[letter]!! }
        }

    // Part 1
    val scoreFirstAssumption = rounds?.sumOf { extractScoreFromRound(it) }

    // Part 2
    val scoreSecondAssumption = rounds?.map { convertToShapeToPlay(it) }
        ?.sumOf { extractScoreFromRound(it) }

    println(scoreFirstAssumption)
    println(scoreSecondAssumption)
}

fun extractScoreFromRound(elfMyChoices: List<Int>): Int {
    val minChoiceDelta = abs(elfMyChoices[0] - elfMyChoices[1]) <= 1
    val roundOutcome =
        if (elfMyChoices[0] > elfMyChoices[1] && minChoiceDelta) 0
        else if (elfMyChoices[0] < elfMyChoices[1] && !minChoiceDelta) 0
        else if (elfMyChoices[0] == elfMyChoices[1]) 3
        else 6
    return elfMyChoices[1] + roundOutcome
}

fun convertToShapeToPlay(elfEndChoices: List<Int>): List<Int> {
    return when (elfEndChoices[1]) {
        1 -> listOf(
            elfEndChoices[0],
            if (elfEndChoices[0] == 1) 3 else elfEndChoices[0] - 1
        )
        2 -> listOf(elfEndChoices[0], elfEndChoices[0])
        3 -> listOf(
            elfEndChoices[0],
            if (elfEndChoices[0] == 3) 1 else elfEndChoices[0] + 1
        )
        else -> emptyList() // won't happen
    }
}

Compiled from "Day2.kt"
public final class xyz.danielstefani.Day2Kt {
  private static final java.util.Map<java.lang.String, java.lang.Integer> shapeToScore;

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

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #16                 // String args
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #24                 // class xyz/danielstefani/Day2Kt$main$rounds$1
       9: dup
      10: invokespecial #28                 // Method xyz/danielstefani/Day2Kt$main$rounds$1."<init>":()V
      13: invokevirtual #32                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
      16: invokevirtual #38                 // Method java/lang/Class.getClassLoader:()Ljava/lang/ClassLoader;
      19: ldc           #40                 // String Day2Input.in
      21: invokevirtual #46                 // Method java/lang/ClassLoader.getResource:(Ljava/lang/String;)Ljava/net/URL;
      24: astore_2
      25: aload_2
      26: ifnull        364
      29: aload_2
      30: astore        4
      32: getstatic     #52                 // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      35: astore        5
      37: aload         4
      39: invokestatic  #58                 // Method kotlin/io/TextStreamsKt.readBytes:(Ljava/net/URL;)[B
      42: astore        6
      44: new           #60                 // class java/lang/String
      47: dup
      48: aload         6
      50: aload         5
      52: invokespecial #63                 // Method java/lang/String."<init>":([BLjava/nio/charset/Charset;)V
      55: checkcast     #65                 // class java/lang/CharSequence
      58: iconst_1
      59: anewarray     #60                 // class java/lang/String
      62: astore        5
      64: aload         5
      66: iconst_0
      67: ldc           #67                 // String \n
      69: aastore
      70: aload         5
      72: iconst_0
      73: iconst_0
      74: bipush        6
      76: aconst_null
      77: invokestatic  #73                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      80: astore        4
      82: aload         4
      84: ifnull        364
      87: aload         4
      89: checkcast     #75                 // class java/lang/Iterable
      92: astore        5
      94: nop
      95: iconst_0
      96: istore        6
      98: aload         5
     100: astore        7
     102: new           #77                 // class java/util/ArrayList
     105: dup
     106: aload         5
     108: bipush        10
     110: invokestatic  #83                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     113: invokespecial #86                 // Method java/util/ArrayList."<init>":(I)V
     116: checkcast     #88                 // class java/util/Collection
     119: astore        8
     121: iconst_0
     122: istore        9
     124: aload         7
     126: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     131: astore        10
     133: aload         10
     135: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     140: ifeq          355
     143: aload         10
     145: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     150: astore        11
     152: aload         8
     154: aload         11
     156: checkcast     #60                 // class java/lang/String
     159: astore        12
     161: astore        24
     163: iconst_0
     164: istore        13
     166: aload         12
     168: checkcast     #65                 // class java/lang/CharSequence
     171: iconst_1
     172: anewarray     #60                 // class java/lang/String
     175: astore        14
     177: aload         14
     179: iconst_0
     180: ldc           #104                // String ,
     182: aastore
     183: aload         14
     185: iconst_0
     186: iconst_0
     187: bipush        6
     189: aconst_null
     190: invokestatic  #73                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     193: iconst_0
     194: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     199: checkcast     #65                 // class java/lang/CharSequence
     202: iconst_1
     203: anewarray     #60                 // class java/lang/String
     206: astore        14
     208: aload         14
     210: iconst_0
     211: ldc           #112                // String
     213: aastore
     214: aload         14
     216: iconst_0
     217: iconst_0
     218: bipush        6
     220: aconst_null
     221: invokestatic  #73                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     224: checkcast     #75                 // class java/lang/Iterable
     227: astore        14
     229: nop
     230: iconst_0
     231: istore        15
     233: aload         14
     235: astore        16
     237: new           #77                 // class java/util/ArrayList
     240: dup
     241: aload         14
     243: bipush        10
     245: invokestatic  #83                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     248: invokespecial #86                 // Method java/util/ArrayList."<init>":(I)V
     251: checkcast     #88                 // class java/util/Collection
     254: astore        17
     256: iconst_0
     257: istore        18
     259: aload         16
     261: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     266: astore        19
     268: aload         19
     270: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     275: ifeq          336
     278: aload         19
     280: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     285: astore        20
     287: aload         17
     289: aload         20
     291: checkcast     #60                 // class java/lang/String
     294: astore        21
     296: astore        22
     298: iconst_0
     299: istore        23
     301: getstatic     #12                 // Field shapeToScore:Ljava/util/Map;
     304: aload         21
     306: invokeinterface #117,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     311: dup
     312: invokestatic  #121                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     315: checkcast     #123                // class java/lang/Number
     318: invokevirtual #127                // Method java/lang/Number.intValue:()I
     321: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     324: aload         22
     326: swap
     327: invokeinterface #137,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     332: pop
     333: goto          268
     336: aload         17
     338: checkcast     #106                // class java/util/List
     341: nop
     342: nop
     343: aload         24
     345: swap
     346: invokeinterface #137,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     351: pop
     352: goto          133
     355: aload         8
     357: checkcast     #106                // class java/util/List
     360: nop
     361: goto          365
     364: aconst_null
     365: astore_1
     366: aload_1
     367: dup
     368: ifnull        444
     371: checkcast     #75                 // class java/lang/Iterable
     374: astore_3
     375: iconst_0
     376: istore        4
     378: aload_3
     379: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     384: astore        5
     386: aload         5
     388: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     393: ifeq          436
     396: aload         5
     398: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     403: astore        6
     405: iload         4
     407: aload         6
     409: checkcast     #106                // class java/util/List
     412: astore        7
     414: istore        24
     416: iconst_0
     417: istore        8
     419: aload         7
     421: invokestatic  #141                // Method extractScoreFromRound:(Ljava/util/List;)I
     424: istore        25
     426: iload         24
     428: iload         25
     430: iadd
     431: istore        4
     433: goto          386
     436: iload         4
     438: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     441: goto          446
     444: pop
     445: aconst_null
     446: astore_2
     447: aload_1
     448: dup
     449: ifnull        626
     452: checkcast     #75                 // class java/lang/Iterable
     455: astore        5
     457: iconst_0
     458: istore        6
     460: aload         5
     462: astore        7
     464: new           #77                 // class java/util/ArrayList
     467: dup
     468: aload         5
     470: bipush        10
     472: invokestatic  #83                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     475: invokespecial #86                 // Method java/util/ArrayList."<init>":(I)V
     478: checkcast     #88                 // class java/util/Collection
     481: astore        8
     483: iconst_0
     484: istore        9
     486: aload         7
     488: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     493: astore        10
     495: aload         10
     497: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     502: ifeq          545
     505: aload         10
     507: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     512: astore        11
     514: aload         8
     516: aload         11
     518: checkcast     #106                // class java/util/List
     521: astore        12
     523: astore        24
     525: iconst_0
     526: istore        13
     528: aload         12
     530: invokestatic  #145                // Method convertToShapeToPlay:(Ljava/util/List;)Ljava/util/List;
     533: aload         24
     535: swap
     536: invokeinterface #137,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     541: pop
     542: goto          495
     545: aload         8
     547: checkcast     #106                // class java/util/List
     550: nop
     551: checkcast     #75                 // class java/lang/Iterable
     554: astore        5
     556: iconst_0
     557: istore        6
     559: aload         5
     561: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     566: astore        7
     568: aload         7
     570: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     575: ifeq          618
     578: aload         7
     580: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     585: astore        8
     587: iload         6
     589: aload         8
     591: checkcast     #106                // class java/util/List
     594: astore        9
     596: istore        24
     598: iconst_0
     599: istore        10
     601: aload         9
     603: invokestatic  #141                // Method extractScoreFromRound:(Ljava/util/List;)I
     606: istore        25
     608: iload         24
     610: iload         25
     612: iadd
     613: istore        6
     615: goto          568
     618: iload         6
     620: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     623: goto          628
     626: pop
     627: aconst_null
     628: astore_3
     629: getstatic     #151                // Field java/lang/System.out:Ljava/io/PrintStream;
     632: aload_2
     633: invokevirtual #156                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     636: getstatic     #151                // Field java/lang/System.out:Ljava/io/PrintStream;
     639: aload_3
     640: invokevirtual #156                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     643: return

  public static final int extractScoreFromRound(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #186                // String elfMyChoices
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_0
       8: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      13: checkcast     #123                // class java/lang/Number
      16: invokevirtual #127                // Method java/lang/Number.intValue:()I
      19: aload_0
      20: iconst_1
      21: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      26: checkcast     #123                // class java/lang/Number
      29: invokevirtual #127                // Method java/lang/Number.intValue:()I
      32: isub
      33: invokestatic  #192                // Method java/lang/Math.abs:(I)I
      36: iconst_1
      37: if_icmpgt     44
      40: iconst_1
      41: goto          45
      44: iconst_0
      45: istore_1
      46: aload_0
      47: iconst_0
      48: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      53: checkcast     #123                // class java/lang/Number
      56: invokevirtual #127                // Method java/lang/Number.intValue:()I
      59: aload_0
      60: iconst_1
      61: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      66: checkcast     #123                // class java/lang/Number
      69: invokevirtual #127                // Method java/lang/Number.intValue:()I
      72: if_icmple     83
      75: iload_1
      76: ifeq          83
      79: iconst_0
      80: goto          155
      83: aload_0
      84: iconst_0
      85: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      90: checkcast     #123                // class java/lang/Number
      93: invokevirtual #127                // Method java/lang/Number.intValue:()I
      96: aload_0
      97: iconst_1
      98: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     103: checkcast     #123                // class java/lang/Number
     106: invokevirtual #127                // Method java/lang/Number.intValue:()I
     109: if_icmpge     120
     112: iload_1
     113: ifne          120
     116: iconst_0
     117: goto          155
     120: aload_0
     121: iconst_0
     122: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     127: checkcast     #123                // class java/lang/Number
     130: invokevirtual #127                // Method java/lang/Number.intValue:()I
     133: aload_0
     134: iconst_1
     135: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     140: checkcast     #123                // class java/lang/Number
     143: invokevirtual #127                // Method java/lang/Number.intValue:()I
     146: if_icmpne     153
     149: iconst_3
     150: goto          155
     153: bipush        6
     155: istore_2
     156: aload_0
     157: iconst_1
     158: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     163: checkcast     #123                // class java/lang/Number
     166: invokevirtual #127                // Method java/lang/Number.intValue:()I
     169: iload_2
     170: iadd
     171: ireturn

  public static final java.util.List<java.lang.Integer> convertToShapeToPlay(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #198                // String elfEndChoices
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_1
       8: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      13: checkcast     #123                // class java/lang/Number
      16: invokevirtual #127                // Method java/lang/Number.intValue:()I
      19: tableswitch   { // 1 to 3
                     1: 44
                     2: 108
                     3: 140
               default: 204
          }
      44: iconst_2
      45: anewarray     #129                // class java/lang/Integer
      48: astore_1
      49: aload_1
      50: iconst_0
      51: aload_0
      52: iconst_0
      53: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      58: aastore
      59: aload_1
      60: iconst_1
      61: aload_0
      62: iconst_0
      63: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      68: checkcast     #123                // class java/lang/Number
      71: invokevirtual #127                // Method java/lang/Number.intValue:()I
      74: iconst_1
      75: if_icmpne     82
      78: iconst_3
      79: goto          97
      82: aload_0
      83: iconst_0
      84: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      89: checkcast     #123                // class java/lang/Number
      92: invokevirtual #127                // Method java/lang/Number.intValue:()I
      95: iconst_1
      96: isub
      97: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     100: aastore
     101: aload_1
     102: invokestatic  #202                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     105: goto          207
     108: iconst_2
     109: anewarray     #129                // class java/lang/Integer
     112: astore_1
     113: aload_1
     114: iconst_0
     115: aload_0
     116: iconst_0
     117: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     122: aastore
     123: aload_1
     124: iconst_1
     125: aload_0
     126: iconst_0
     127: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     132: aastore
     133: aload_1
     134: invokestatic  #202                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     137: goto          207
     140: iconst_2
     141: anewarray     #129                // class java/lang/Integer
     144: astore_1
     145: aload_1
     146: iconst_0
     147: aload_0
     148: iconst_0
     149: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     154: aastore
     155: aload_1
     156: iconst_1
     157: aload_0
     158: iconst_0
     159: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     164: checkcast     #123                // class java/lang/Number
     167: invokevirtual #127                // Method java/lang/Number.intValue:()I
     170: iconst_3
     171: if_icmpne     178
     174: iconst_1
     175: goto          193
     178: aload_0
     179: iconst_0
     180: invokeinterface #110,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     185: checkcast     #123                // class java/lang/Number
     188: invokevirtual #127                // Method java/lang/Number.intValue:()I
     191: iconst_1
     192: iadd
     193: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     196: aastore
     197: aload_1
     198: invokestatic  #202                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     201: goto          207
     204: invokestatic  #206                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     207: areturn

  static {};
    Code:
       0: bipush        6
       2: anewarray     #211                // class kotlin/Pair
       5: astore_0
       6: aload_0
       7: iconst_0
       8: new           #211                // class kotlin/Pair
      11: dup
      12: ldc           #213                // String A
      14: iconst_1
      15: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      18: invokespecial #216                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      21: aastore
      22: aload_0
      23: iconst_1
      24: new           #211                // class kotlin/Pair
      27: dup
      28: ldc           #218                // String B
      30: iconst_2
      31: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      34: invokespecial #216                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      37: aastore
      38: aload_0
      39: iconst_2
      40: new           #211                // class kotlin/Pair
      43: dup
      44: ldc           #220                // String C
      46: iconst_3
      47: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      50: invokespecial #216                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      53: aastore
      54: aload_0
      55: iconst_3
      56: new           #211                // class kotlin/Pair
      59: dup
      60: ldc           #222                // String X
      62: iconst_1
      63: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      66: invokespecial #216                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      69: aastore
      70: aload_0
      71: iconst_4
      72: new           #211                // class kotlin/Pair
      75: dup
      76: ldc           #224                // String Y
      78: iconst_2
      79: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      82: invokespecial #216                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      85: aastore
      86: aload_0
      87: iconst_5
      88: new           #211                // class kotlin/Pair
      91: dup
      92: ldc           #225                // String Z
      94: iconst_3
      95: invokestatic  #133                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      98: invokespecial #216                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     101: aastore
     102: aload_0
     103: invokestatic  #231                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     106: putstatic     #12                 // Field shapeToScore:Ljava/util/Map;
     109: return
}

Compiled from "Day2.kt"
public final class xyz.danielstefani.Day2Kt$main$rounds$1 {
  xyz.danielstefani.Day2Kt$main$rounds$1();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return
}


package kata

import java.math.BigInteger

/*
You know combinations: for example, if you take 5 cards from a 52 cards deck you have 2,598,960
different combinations.

In mathematics the number of x combinations you can take from a set of n elements is called the
binomial coefficient of n and x, or more often n choose x.
The formula to compute m = n choose x is: m = n! / (x! * (n - x)!) where ! is the factorial operator.

You are a renowned poster designer and painter.
You are asked to provide 6 posters all having the same design each in 2 colors.
Posters must all have a different color combination and you have the choice of 4 colors:
red, blue, yellow, green.
How many colors can you choose for each poster?

The answer is two since 4 choose 2 = 6.
The combinations will be: {red, blue}, {red, yellow}, {red, green}, {blue, yellow}, {blue, green}, {yellow, green}.

Now same question but you have 35 posters to provide and 7 colors available.
How many colors for each poster?
If you take combinations 7 choose 2 you will get 21 with the above formula.
But 21 schemes aren't enough for 35 posters.
If you take 7 choose 5 combinations you will get 21 too.
Fortunately if you take 7 choose 3 or 7 choose 4 combinations you get 35 and so each poster
will have a different combination of 3 colors or 5 colors.
You will take 3 colors because it's less expensive.

Hence the problem is:

knowing m (number of posters to design),
knowing n (total number of available colors),
let us search x (number of colors for each poster so that each poster has a unique combination of
colors and the number of combinations is exactly the same as the number of posters).

In other words we must find x such as n choose x = m (1) for a given m and a given n; m >= 0 and n > 0.
If many x are solutions give as result the smallest x.
It can happen that when m is given at random there are no x satisfying equation (1) then return -1.

Examples:

checkchoose(6, 4) --> 2
checkchoose(4, 4) --> 1
checkchoose(4, 2) --> -1
checkchoose(35, 7) --> 3
checkchoose(36, 7) --> -1

a = 47129212243960
checkchoose(a, 50) --> 20
checkchoose(a + 1, 50) --> -1

clojure: Use big integers in the calculation of n choose k!

*/
fun fact(num: Int): BigInteger {
    var factorial: BigInteger = BigInteger.ONE
    for (i in 1..num) {
        factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
    }
    return factorial
}

fun nChooseX(n: Int, x: Int): BigInteger {
    // m = n! / (x! * (n - x)!)
    return fact(n).div(fact(x).multiply(fact(n - x)))
}

fun checkchoose(m: Long, n: Int): Long {
    for (x in 1..n) {
        val mCurrent = nChooseX(n, x)
        if (mCurrent.longValueExact() == m) {
            return x.toLong()
        }
    }
    return -1
}

Compiled from "ColorChoice.kt"
public final class kata.ColorChoiceKt {
  public static final java.math.BigInteger fact(int);
    Code:
       0: getstatic     #13                 // Field java/math/BigInteger.ONE:Ljava/math/BigInteger;
       3: dup
       4: ldc           #14                 // String ONE
       6: invokestatic  #20                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
       9: astore_1
      10: iconst_1
      11: istore_2
      12: iload_2
      13: iload_0
      14: if_icmpgt     44
      17: aload_1
      18: iload_2
      19: i2l
      20: invokestatic  #24                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      23: invokevirtual #28                 // Method java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      26: dup
      27: ldc           #30                 // String multiply(...)
      29: invokestatic  #20                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      32: astore_1
      33: iload_2
      34: iload_0
      35: if_icmpeq     44
      38: iinc          2, 1
      41: goto          17
      44: aload_1
      45: areturn

  public static final java.math.BigInteger nChooseX(int, int);
    Code:
       0: iload_0
       1: invokestatic  #38                 // Method fact:(I)Ljava/math/BigInteger;
       4: astore_2
       5: iload_1
       6: invokestatic  #38                 // Method fact:(I)Ljava/math/BigInteger;
       9: iload_0
      10: iload_1
      11: isub
      12: invokestatic  #38                 // Method fact:(I)Ljava/math/BigInteger;
      15: invokevirtual #28                 // Method java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      18: dup
      19: ldc           #30                 // String multiply(...)
      21: invokestatic  #20                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      24: aload_2
      25: swap
      26: invokevirtual #41                 // Method java/math/BigInteger.divide:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      29: dup
      30: ldc           #43                 // String divide(...)
      32: invokestatic  #20                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      35: areturn

  public static final long checkchoose(long, int);
    Code:
       0: iconst_1
       1: istore_3
       2: iload_3
       3: iload_2
       4: if_icmpgt     38
       7: iload_2
       8: iload_3
       9: invokestatic  #49                 // Method nChooseX:(II)Ljava/math/BigInteger;
      12: astore        4
      14: aload         4
      16: invokevirtual #53                 // Method java/math/BigInteger.longValueExact:()J
      19: lload_0
      20: lcmp
      21: ifne          27
      24: iload_3
      25: i2l
      26: lreturn
      27: iload_3
      28: iload_2
      29: if_icmpeq     38
      32: iinc          3, 1
      35: goto          7
      38: ldc2_w        #54                 // long -1l
      41: lreturn
}