package algorithm.dp

sealed class LCS {

    companion object {

        private fun longestOne(A: String, B: String): String {
            return if (A.length >= B.length) A else B
        }

        fun recursionTopDown(A: String, B: String): String {
            if (A.isEmpty() || B.isEmpty()) return "";
            val aLast = A.last()
            val bLast = B.last()
            val subA = A.dropLast(1)
            val subB = B.dropLast(1)
            return if (aLast == bLast) {
                recursionTopDown(subA, subB) + aLast
            } else {
                longestOne(
                    recursionTopDown(subA, B),
                    recursionTopDown(A, subB)
                )
            }
        }

        fun recursionBottomUp(LCS: String, remainA: String, remainB: String): String {
            if (remainA.isEmpty() || remainB.isEmpty()) return LCS
            val aFirst = remainA.first()
            val bFirst = remainB.first()
            val subA = remainA.drop(1)
            val subB = remainB.drop(1)

            return if (aFirst == bFirst) {
                recursionBottomUp(LCS, subA, subB) + aFirst
            } else {
                longestOne(
                    recursionBottomUp(LCS, subA, remainB),
                    recursionBottomUp(LCS, remainA, subB)
                )
            }
        }

        fun recursionTopDownIndex(A: String, B: String, indexA: Int, indexB: Int): String {
            if (indexA < 0 || indexB < 0) return "";
            val a = A[indexA]
            val b = B[indexB]
            return if (a == b) {
                recursionTopDownIndex(A, B, indexA - 1, indexB - 1) + a
            } else {
                longestOne(
                    recursionTopDownIndex(A, B, indexA - 1, indexB),
                    recursionTopDownIndex(A, B, indexA, indexB - 1),
                )
            }
        }

        fun dp(A: String, B: String): Array<IntArray> {
            val aLength = A.length
            val bLength = B.length
            val dp = Array(aLength + 1) { IntArray(bLength + 1) { 0 } }
            val direction = Array(aLength + 1) { CharArray(bLength + 1) { ' ' } }

            for (row in 0 until aLength) {
                for (col in 0 until bLength) {
                    if (A[row] == B[col]) {
                        dp[row + 1][col + 1] = dp[row][col] + 1
                        direction[row + 1][col + 1] = '\\';
                    } else if (dp[row][col + 1] >= dp[row + 1][col]) {
                        dp[row + 1][col + 1] = dp[row][col + 1]
                        direction[row + 1][col + 1] = '^';
                    } else {
                        dp[row + 1][col + 1] = dp[row + 1][col]
                        direction[row + 1][col + 1] = '<';
                    }
                }
            }

            return dp
        }

        fun printDp(dp: Array<IntArray>, direction: Array<CharArray>) {
            val aLength = dp.size
            val bLength = dp[0].size
            for (row in 0..aLength) {
                for (col in 0..bLength) {
                    print("${dp[row][col]}${direction[row][col]} ")
                }
                println()
            }
        }

        fun backtracking(dp: Array<IntArray>, direction: Array<CharArray>, A: String): String {
            val aLength = dp.size
            val bLength = dp[0].size

            var LCS = ""
            var row: Int = aLength
            var col: Int = bLength
            while (direction[row][col] != ' ') {
                when (direction[row][col]) {
                    '\\' -> {
                        LCS += A.get(row - 1)
                        row -= 1
                        col -= 1
                    }
                    '<' -> col -= 1
                    '^' -> row -= 1
                }
            }
            return LCS
        }

    }

}

Compiled from "LCS.kt"
public final class algorithm.dp.LCS$Companion {
  private algorithm.dp.LCS$Companion();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  private final java.lang.String longestOne(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: invokevirtual #18                 // Method java/lang/String.length:()I
       4: aload_2
       5: invokevirtual #18                 // Method java/lang/String.length:()I
       8: if_icmplt     15
      11: aload_1
      12: goto          16
      15: aload_2
      16: areturn

  public final java.lang.String recursionTopDown(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #24                 // String A
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #31                 // String B
       9: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: checkcast     #33                 // class java/lang/CharSequence
      16: invokeinterface #34,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      21: ifne          28
      24: iconst_1
      25: goto          29
      28: iconst_0
      29: ifne          52
      32: aload_2
      33: checkcast     #33                 // class java/lang/CharSequence
      36: invokeinterface #34,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      41: ifne          48
      44: iconst_1
      45: goto          49
      48: iconst_0
      49: ifeq          55
      52: ldc           #36                 // String
      54: areturn
      55: aload_1
      56: checkcast     #33                 // class java/lang/CharSequence
      59: invokestatic  #42                 // Method kotlin/text/StringsKt.last:(Ljava/lang/CharSequence;)C
      62: istore_3
      63: aload_2
      64: checkcast     #33                 // class java/lang/CharSequence
      67: invokestatic  #42                 // Method kotlin/text/StringsKt.last:(Ljava/lang/CharSequence;)C
      70: istore        4
      72: aload_1
      73: iconst_1
      74: invokestatic  #46                 // Method kotlin/text/StringsKt.dropLast:(Ljava/lang/String;I)Ljava/lang/String;
      77: astore        5
      79: aload_2
      80: iconst_1
      81: invokestatic  #46                 // Method kotlin/text/StringsKt.dropLast:(Ljava/lang/String;I)Ljava/lang/String;
      84: astore        6
      86: iload_3
      87: iload         4
      89: if_icmpne     120
      92: new           #48                 // class java/lang/StringBuilder
      95: dup
      96: invokespecial #49                 // Method java/lang/StringBuilder."<init>":()V
      99: aload_0
     100: aload         5
     102: aload         6
     104: invokevirtual #51                 // Method recursionTopDown:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     107: invokevirtual #55                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     110: iload_3
     111: invokevirtual #58                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     114: invokevirtual #62                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     117: goto          138
     120: aload_0
     121: aload_0
     122: aload         5
     124: aload_2
     125: invokevirtual #51                 // Method recursionTopDown:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     128: aload_0
     129: aload_1
     130: aload         6
     132: invokevirtual #51                 // Method recursionTopDown:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     135: invokespecial #64                 // Method longestOne:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     138: areturn

  public final java.lang.String recursionBottomUp(java.lang.String, java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #73                 // String LCS
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #75                 // String remainA
       9: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #77                 // String remainB
      15: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_2
      19: checkcast     #33                 // class java/lang/CharSequence
      22: invokeinterface #34,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      27: ifne          34
      30: iconst_1
      31: goto          35
      34: iconst_0
      35: ifne          58
      38: aload_3
      39: checkcast     #33                 // class java/lang/CharSequence
      42: invokeinterface #34,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      47: ifne          54
      50: iconst_1
      51: goto          55
      54: iconst_0
      55: ifeq          60
      58: aload_1
      59: areturn
      60: aload_2
      61: checkcast     #33                 // class java/lang/CharSequence
      64: invokestatic  #80                 // Method kotlin/text/StringsKt.first:(Ljava/lang/CharSequence;)C
      67: istore        4
      69: aload_3
      70: checkcast     #33                 // class java/lang/CharSequence
      73: invokestatic  #80                 // Method kotlin/text/StringsKt.first:(Ljava/lang/CharSequence;)C
      76: istore        5
      78: aload_2
      79: iconst_1
      80: invokestatic  #83                 // Method kotlin/text/StringsKt.drop:(Ljava/lang/String;I)Ljava/lang/String;
      83: astore        6
      85: aload_3
      86: iconst_1
      87: invokestatic  #83                 // Method kotlin/text/StringsKt.drop:(Ljava/lang/String;I)Ljava/lang/String;
      90: astore        7
      92: iload         4
      94: iload         5
      96: if_icmpne     129
      99: new           #48                 // class java/lang/StringBuilder
     102: dup
     103: invokespecial #49                 // Method java/lang/StringBuilder."<init>":()V
     106: aload_0
     107: aload_1
     108: aload         6
     110: aload         7
     112: invokevirtual #85                 // Method recursionBottomUp:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     115: invokevirtual #55                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     118: iload         4
     120: invokevirtual #58                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     123: invokevirtual #62                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     126: goto          149
     129: aload_0
     130: aload_0
     131: aload_1
     132: aload         6
     134: aload_3
     135: invokevirtual #85                 // Method recursionBottomUp:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     138: aload_0
     139: aload_1
     140: aload_2
     141: aload         7
     143: invokevirtual #85                 // Method recursionBottomUp:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     146: invokespecial #64                 // Method longestOne:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     149: areturn

  public final java.lang.String recursionTopDownIndex(java.lang.String, java.lang.String, int, int);
    Code:
       0: aload_1
       1: ldc           #24                 // String A
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #31                 // String B
       9: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: iload_3
      13: iflt          21
      16: iload         4
      18: ifge          24
      21: ldc           #36                 // String
      23: areturn
      24: aload_1
      25: iload_3
      26: invokevirtual #93                 // Method java/lang/String.charAt:(I)C
      29: istore        5
      31: aload_2
      32: iload         4
      34: invokevirtual #93                 // Method java/lang/String.charAt:(I)C
      37: istore        6
      39: iload         5
      41: iload         6
      43: if_icmpne     80
      46: new           #48                 // class java/lang/StringBuilder
      49: dup
      50: invokespecial #49                 // Method java/lang/StringBuilder."<init>":()V
      53: aload_0
      54: aload_1
      55: aload_2
      56: iload_3
      57: iconst_1
      58: isub
      59: iload         4
      61: iconst_1
      62: isub
      63: invokevirtual #95                 // Method recursionTopDownIndex:(Ljava/lang/String;Ljava/lang/String;II)Ljava/lang/String;
      66: invokevirtual #55                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      69: iload         5
      71: invokevirtual #58                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      74: invokevirtual #62                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      77: goto          106
      80: aload_0
      81: aload_0
      82: aload_1
      83: aload_2
      84: iload_3
      85: iconst_1
      86: isub
      87: iload         4
      89: invokevirtual #95                 // Method recursionTopDownIndex:(Ljava/lang/String;Ljava/lang/String;II)Ljava/lang/String;
      92: aload_0
      93: aload_1
      94: aload_2
      95: iload_3
      96: iload         4
      98: iconst_1
      99: isub
     100: invokevirtual #95                 // Method recursionTopDownIndex:(Ljava/lang/String;Ljava/lang/String;II)Ljava/lang/String;
     103: invokespecial #64                 // Method longestOne:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
     106: areturn

  public final int[][] dp(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #24                 // String A
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #31                 // String B
       9: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: invokevirtual #18                 // Method java/lang/String.length:()I
      16: istore_3
      17: aload_2
      18: invokevirtual #18                 // Method java/lang/String.length:()I
      21: istore        4
      23: iconst_0
      24: istore        6
      26: iload_3
      27: iconst_1
      28: iadd
      29: istore        7
      31: iload         7
      33: anewarray     #104                // class "[I"
      36: astore        8
      38: iload         6
      40: iload         7
      42: if_icmpge     108
      45: iload         6
      47: istore        9
      49: aload         8
      51: iload         9
      53: iconst_0
      54: istore        10
      56: iload         4
      58: iconst_1
      59: iadd
      60: istore        11
      62: iload         11
      64: newarray       int
      66: astore        12
      68: istore        16
      70: astore        15
      72: iload         10
      74: iload         11
      76: if_icmpge     95
      79: iload         10
      81: istore        13
      83: aload         12
      85: iload         13
      87: iconst_0
      88: iastore
      89: iinc          10, 1
      92: goto          72
      95: aload         15
      97: iload         16
      99: aload         12
     101: aastore
     102: iinc          6, 1
     105: goto          38
     108: aload         8
     110: astore        5
     112: iconst_0
     113: istore        7
     115: iload_3
     116: iconst_1
     117: iadd
     118: istore        8
     120: iload         8
     122: anewarray     #106                // class "[C"
     125: astore        9
     127: iload         7
     129: iload         8
     131: if_icmpge     198
     134: iload         7
     136: istore        10
     138: aload         9
     140: iload         10
     142: iconst_0
     143: istore        11
     145: iload         4
     147: iconst_1
     148: iadd
     149: istore        12
     151: iload         12
     153: newarray       char
     155: astore        13
     157: istore        16
     159: astore        15
     161: iload         11
     163: iload         12
     165: if_icmpge     185
     168: iload         11
     170: istore        14
     172: aload         13
     174: iload         14
     176: bipush        32
     178: castore
     179: iinc          11, 1
     182: goto          161
     185: aload         15
     187: iload         16
     189: aload         13
     191: aastore
     192: iinc          7, 1
     195: goto          127
     198: aload         9
     200: astore        6
     202: iconst_0
     203: istore        7
     205: iload         7
     207: iload_3
     208: if_icmpge     385
     211: iconst_0
     212: istore        8
     214: iload         8
     216: iload         4
     218: if_icmpge     379
     221: aload_1
     222: iload         7
     224: invokevirtual #93                 // Method java/lang/String.charAt:(I)C
     227: aload_2
     228: iload         8
     230: invokevirtual #93                 // Method java/lang/String.charAt:(I)C
     233: if_icmpne     275
     236: aload         5
     238: iload         7
     240: iconst_1
     241: iadd
     242: aaload
     243: iload         8
     245: iconst_1
     246: iadd
     247: aload         5
     249: iload         7
     251: aaload
     252: iload         8
     254: iaload
     255: iconst_1
     256: iadd
     257: iastore
     258: aload         6
     260: iload         7
     262: iconst_1
     263: iadd
     264: aaload
     265: iload         8
     267: iconst_1
     268: iadd
     269: bipush        92
     271: castore
     272: goto          373
     275: aload         5
     277: iload         7
     279: aaload
     280: iload         8
     282: iconst_1
     283: iadd
     284: iaload
     285: aload         5
     287: iload         7
     289: iconst_1
     290: iadd
     291: aaload
     292: iload         8
     294: iaload
     295: if_icmplt     337
     298: aload         5
     300: iload         7
     302: iconst_1
     303: iadd
     304: aaload
     305: iload         8
     307: iconst_1
     308: iadd
     309: aload         5
     311: iload         7
     313: aaload
     314: iload         8
     316: iconst_1
     317: iadd
     318: iaload
     319: iastore
     320: aload         6
     322: iload         7
     324: iconst_1
     325: iadd
     326: aaload
     327: iload         8
     329: iconst_1
     330: iadd
     331: bipush        94
     333: castore
     334: goto          373
     337: aload         5
     339: iload         7
     341: iconst_1
     342: iadd
     343: aaload
     344: iload         8
     346: iconst_1
     347: iadd
     348: aload         5
     350: iload         7
     352: iconst_1
     353: iadd
     354: aaload
     355: iload         8
     357: iaload
     358: iastore
     359: aload         6
     361: iload         7
     363: iconst_1
     364: iadd
     365: aaload
     366: iload         8
     368: iconst_1
     369: iadd
     370: bipush        60
     372: castore
     373: iinc          8, 1
     376: goto          214
     379: iinc          7, 1
     382: goto          205
     385: aload         5
     387: areturn

  public final void printDp(int[][], char[][]);
    Code:
       0: aload_1
       1: ldc           #118                // String dp
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #119                // String direction
       9: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: checkcast     #121                // class "[Ljava/lang/Object;"
      16: arraylength
      17: istore_3
      18: aload_1
      19: iconst_0
      20: aaload
      21: arraylength
      22: istore        4
      24: iconst_0
      25: istore        5
      27: iload         5
      29: iload_3
      30: if_icmpgt     116
      33: iconst_0
      34: istore        6
      36: iload         6
      38: iload         4
      40: if_icmpgt     98
      43: new           #48                 // class java/lang/StringBuilder
      46: dup
      47: invokespecial #49                 // Method java/lang/StringBuilder."<init>":()V
      50: aload_1
      51: iload         5
      53: aaload
      54: iload         6
      56: iaload
      57: invokevirtual #124                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      60: aload_2
      61: iload         5
      63: aaload
      64: iload         6
      66: caload
      67: invokevirtual #58                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      70: bipush        32
      72: invokevirtual #58                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      75: invokevirtual #62                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      78: getstatic     #130                // Field java/lang/System.out:Ljava/io/PrintStream;
      81: swap
      82: invokevirtual #136                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      85: iload         6
      87: iload         4
      89: if_icmpeq     98
      92: iinc          6, 1
      95: goto          43
      98: getstatic     #130                // Field java/lang/System.out:Ljava/io/PrintStream;
     101: invokevirtual #139                // Method java/io/PrintStream.println:()V
     104: iload         5
     106: iload_3
     107: if_icmpeq     116
     110: iinc          5, 1
     113: goto          33
     116: return

  public final java.lang.String backtracking(int[][], char[][], java.lang.String);
    Code:
       0: aload_1
       1: ldc           #118                // String dp
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #119                // String direction
       9: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #24                 // String A
      15: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_1
      19: checkcast     #121                // class "[Ljava/lang/Object;"
      22: arraylength
      23: istore        4
      25: aload_1
      26: iconst_0
      27: aaload
      28: arraylength
      29: istore        5
      31: ldc           #36                 // String
      33: astore        6
      35: iload         4
      37: istore        7
      39: iload         5
      41: istore        8
      43: aload_2
      44: iload         7
      46: aaload
      47: iload         8
      49: caload
      50: bipush        32
      52: if_icmpeq     145
      55: aload_2
      56: iload         7
      58: aaload
      59: iload         8
      61: caload
      62: lookupswitch  { // 3
                    60: 133
                    92: 96
                    94: 139
               default: 142
          }
      96: new           #48                 // class java/lang/StringBuilder
      99: dup
     100: invokespecial #49                 // Method java/lang/StringBuilder."<init>":()V
     103: aload         6
     105: invokevirtual #55                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     108: aload_3
     109: iload         7
     111: iconst_1
     112: isub
     113: invokevirtual #93                 // Method java/lang/String.charAt:(I)C
     116: invokevirtual #58                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     119: invokevirtual #62                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     122: astore        6
     124: iinc          7, -1
     127: iinc          8, -1
     130: goto          43
     133: iinc          8, -1
     136: goto          43
     139: iinc          7, -1
     142: goto          43
     145: aload         6
     147: areturn

  public algorithm.dp.LCS$Companion(kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: aload_0
       1: invokespecial #143                // Method "<init>":()V
       4: return
}

Compiled from "LCS.kt"
public abstract class algorithm.dp.LCS {
  public static final algorithm.dp.LCS$Companion Companion;

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

  public algorithm.dp.LCS(kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: aload_0
       1: invokespecial #12                 // Method "<init>":()V
       4: return

  static {};
    Code:
       0: new           #17                 // class algorithm/dp/LCS$Companion
       3: dup
       4: aconst_null
       5: invokespecial #19                 // Method algorithm/dp/LCS$Companion."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #23                 // Field Companion:Lalgorithm/dp/LCS$Companion;
      11: return
}


package boti996.dsl.proba.models

/**
 * this defines bonus-effect ID-s
 */
enum class BonusEffect(val literal: String) {
    REGENERATION("regeneration"),
    STRENGTH("strength"),
    DEFENSE("defense")
}

/**
 * bonus type: this defines a set of [BonusEffect]-s
 */
enum class BonusType {
    ANOXIA {
        override fun _getBonus(): Map<BonusEffect, Float> = mutableMapOf(
            BonusEffect.REGENERATION to 2.0f,
            BonusEffect.STRENGTH to 4.0f
        )
    },
    EXTRA_STRENGTH {
        override fun _getBonus(): Map<BonusEffect, Float> = mutableMapOf(
            BonusEffect.STRENGTH to 6.0f
        )
    },
    EXTRA_DEFENSE {
        override fun _getBonus(): Map<BonusEffect, Float> = mutableMapOf(
            BonusEffect.DEFENSE to 2.0f
        )
    },
    EXTRA_HEAL {
        override fun _getBonus(): Map<BonusEffect, Float> = mutableMapOf(
            BonusEffect.REGENERATION to 1.5f
        )

    };

    protected abstract fun _getBonus(): Map<BonusEffect, Float>

    /**
     * return a set of [BonusEffect]-s
     * @param multiplier optional, multiplies [BonusEffect]-s
     */
    fun getBonus(multiplier: Float = 1.0f): Map<BonusEffect, Float> {
        val map = _getBonus() as MutableMap
        map.keys.forEach { key -> map[key] = map[key]!!.times(multiplier) }
        return map
    }
}

/**
 * [Bonus] can be set on object to take effect
 */
interface BonusAcceptor {
    fun setBonus(bonus: Bonus)
}

/**
 * wrapper for [BonusType] with a multiplier parameter
 * @param multiplier multiplies [BonusEffect]-s
 */
data class Bonus(val bonus: BonusType, var multiplier: Float = 1.0f) {
    fun getBonus(): Map<BonusEffect, Float> = bonus.getBonus(multiplier)

    override fun equals(other: Any?): Boolean {
        return other is Bonus &&
                bonus == other.bonus &&
                multiplier == other.multiplier
    }

    override fun hashCode(): Int {
        var result = bonus.hashCode()
        result = 31 * result + multiplier.hashCode()
        return result
    }
}

/**
 * object has accessible [Bonus]-s
 */
interface BonusProvider<T : Enum<T>> {
    fun getBonuses(modifierType: T? = null): List<Bonus>
}

Compiled from "Bonus.kt"
public final class boti996.dsl.proba.models.Bonus {
  private final boti996.dsl.proba.models.BonusType bonus;

  private float multiplier;

  public boti996.dsl.proba.models.Bonus(boti996.dsl.proba.models.BonusType, float);
    Code:
       0: aload_1
       1: ldc           #9                  // String bonus
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #18                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: aload_1
      12: putfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
      15: aload_0
      16: fload_2
      17: putfield      #25                 // Field multiplier:F
      20: return

  public boti996.dsl.proba.models.Bonus(boti996.dsl.proba.models.BonusType, float, int, kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: iload_3
       1: iconst_2
       2: iand
       3: ifeq          8
       6: fconst_1
       7: fstore_2
       8: aload_0
       9: aload_1
      10: fload_2
      11: invokespecial #30                 // Method "<init>":(Lboti996/dsl/proba/models/BonusType;F)V
      14: return

  public final boti996.dsl.proba.models.BonusType getBonus();
    Code:
       0: aload_0
       1: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
       4: areturn

  public final float getMultiplier();
    Code:
       0: aload_0
       1: getfield      #25                 // Field multiplier:F
       4: freturn

  public final void setMultiplier(float);
    Code:
       0: aload_0
       1: fload_1
       2: putfield      #25                 // Field multiplier:F
       5: return

  public final java.util.Map<boti996.dsl.proba.models.BonusEffect, java.lang.Float> getBonus();
    Code:
       0: aload_0
       1: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
       4: aload_0
       5: getfield      #25                 // Field multiplier:F
       8: invokevirtual #44                 // Method boti996/dsl/proba/models/BonusType.getBonus:(F)Ljava/util/Map;
      11: areturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_1
       1: instanceof    #2                  // class boti996/dsl/proba/models/Bonus
       4: ifeq          48
       7: aload_0
       8: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
      11: aload_1
      12: checkcast     #2                  // class boti996/dsl/proba/models/Bonus
      15: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
      18: if_acmpne     48
      21: aload_0
      22: getfield      #25                 // Field multiplier:F
      25: aload_1
      26: checkcast     #2                  // class boti996/dsl/proba/models/Bonus
      29: getfield      #25                 // Field multiplier:F
      32: fcmpg
      33: ifne          40
      36: iconst_1
      37: goto          41
      40: iconst_0
      41: ifeq          48
      44: iconst_1
      45: goto          49
      48: iconst_0
      49: ireturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
       4: invokevirtual #53                 // Method boti996/dsl/proba/models/BonusType.hashCode:()I
       7: istore_1
       8: bipush        31
      10: iload_1
      11: imul
      12: aload_0
      13: getfield      #25                 // Field multiplier:F
      16: invokestatic  #58                 // Method java/lang/Float.hashCode:(F)I
      19: iadd
      20: istore_1
      21: iload_1
      22: ireturn

  public final boti996.dsl.proba.models.BonusType component1();
    Code:
       0: aload_0
       1: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
       4: areturn

  public final float component2();
    Code:
       0: aload_0
       1: getfield      #25                 // Field multiplier:F
       4: freturn

  public final boti996.dsl.proba.models.Bonus copy(boti996.dsl.proba.models.BonusType, float);
    Code:
       0: aload_1
       1: ldc           #9                  // String bonus
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #2                  // class boti996/dsl/proba/models/Bonus
       9: dup
      10: aload_1
      11: fload_2
      12: invokespecial #30                 // Method "<init>":(Lboti996/dsl/proba/models/BonusType;F)V
      15: areturn

  public static boti996.dsl.proba.models.Bonus copy$default(boti996.dsl.proba.models.Bonus, boti996.dsl.proba.models.BonusType, float, int, java.lang.Object);
    Code:
       0: iload_3
       1: iconst_1
       2: iand
       3: ifeq          11
       6: aload_0
       7: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
      10: astore_1
      11: iload_3
      12: iconst_2
      13: iand
      14: ifeq          22
      17: aload_0
      18: getfield      #25                 // Field multiplier:F
      21: fstore_2
      22: aload_0
      23: aload_1
      24: fload_2
      25: invokevirtual #68                 // Method copy:(Lboti996/dsl/proba/models/BonusType;F)Lboti996/dsl/proba/models/Bonus;
      28: areturn

  public java.lang.String toString();
    Code:
       0: new           #72                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #73                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #75                 // String Bonus(bonus=
       9: invokevirtual #79                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #21                 // Field bonus:Lboti996/dsl/proba/models/BonusType;
      16: invokevirtual #82                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      19: ldc           #84                 // String , multiplier=
      21: invokevirtual #79                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #25                 // Field multiplier:F
      28: invokevirtual #87                 // Method java/lang/StringBuilder.append:(F)Ljava/lang/StringBuilder;
      31: bipush        41
      33: invokevirtual #90                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      36: invokevirtual #92                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn
}


package behavioural_patterns.interpreter

import java.util.stream.Collectors

interface Element {
    fun eval(): Int
}

class Integer(private val value: Int): Element {
    override fun eval(): Int {
        return value
    }
}

class BinaryOperation: Element {
    lateinit var type: Type
    lateinit var left: Element
    lateinit var right: Element

    override fun eval(): Int {
        return when (type) {
            Type.ADDITION -> left.eval() + right.eval()
            Type.SUBTRACTION -> left.eval() - right.eval()
        }
    }

    enum class Type {
        ADDITION, SUBTRACTION
    }
}

class Token(
    val type: Type,
    val text: String
) {

    override fun toString(): String {
        return "`$text`"
    }

    enum class Type {
        INTEGER, PLUS, MINUS, LEFTPARENTHESIS, RIGHTPARENTHESIS
    }
}

fun lex(input: String): List<Token> {
    val result = ArrayList<Token>()
    var i = 0
    while (i < input.length) {
        when (input[i]) {
            '+' -> result.add(Token(Token.Type.PLUS, "+"))
            '-' -> result.add(Token(Token.Type.MINUS, "-"))
            '(' -> result.add(Token(Token.Type.LEFTPARENTHESIS, "("))
            ')' -> result.add(Token(Token.Type.RIGHTPARENTHESIS, ")"))
            else -> {
                val builder = StringBuilder("${input[i]}")
                for (j in (i + 1) until input.length) {
                    if (input[j].isDigit()) {
                        builder.append(input[j])
                        ++i
                    } else {
                        result.add(Token(Token.Type.INTEGER, builder.toString()))
                        break
                    }
                }
            }
        }

        i++
    }
    return result
}

fun parse(tokens: List<Token>): Element {
    val result = BinaryOperation()
    var hasLeftHandSide = false

    var i = 0
    while (i < tokens.size) {
        val token = tokens[i]
        when (token.type) {
            Token.Type.INTEGER -> {
                val integer = Integer(token.text.toInt())
                if (hasLeftHandSide) result.right = integer
                else {
                    result.left = integer
                    hasLeftHandSide = true
                }
            }
            Token.Type.PLUS -> result.type = BinaryOperation.Type.ADDITION
            Token.Type.MINUS -> result.type = BinaryOperation.Type.SUBTRACTION
            Token.Type.LEFTPARENTHESIS -> {
                var j = i // Location of right parenthesis (assumes no nesting of parentheses)
                while (j < tokens.size) {
                    if (tokens[j].type == Token.Type.RIGHTPARENTHESIS) break
                    j++
                }

                val subExpression = tokens.stream()
                    .skip((i + 1).toLong())
                    .limit((j - i - 1).toLong())
                    .collect(Collectors.toList())

                val element = parse(subExpression)

                if (hasLeftHandSide) result.right = element
                else {
                    result.left = element
                    hasLeftHandSide = true
                }

                i = j
            }
            Token.Type.RIGHTPARENTHESIS -> {
            }
        }

        i++
    }

    return result
}

fun main() {
    val input = "(13+4)-(12+1)"
    val tokens: List<Token> = lex(input)
    println(tokens.stream().map { it.toString() }.collect(Collectors.joining("_")))

    val parsed = parse(tokens)
    println("$input = ${parsed.eval()}")
}

Compiled from "Interpreter.kt"
public final class behavioural_patterns.interpreter.InterpreterKt$WhenMappings {
  public static final int[] $EnumSwitchMapping$0;

  static {};
    Code:
       0: invokestatic  #14                 // Method behavioural_patterns/interpreter/Token$Type.values:()[Lbehavioural_patterns/interpreter/Token$Type;
       3: arraylength
       4: newarray       int
       6: astore_0
       7: nop
       8: aload_0
       9: getstatic     #18                 // Field behavioural_patterns/interpreter/Token$Type.INTEGER:Lbehavioural_patterns/interpreter/Token$Type;
      12: invokevirtual #22                 // Method behavioural_patterns/interpreter/Token$Type.ordinal:()I
      15: iconst_1
      16: iastore
      17: goto          21
      20: astore_1
      21: nop
      22: aload_0
      23: getstatic     #25                 // Field behavioural_patterns/interpreter/Token$Type.PLUS:Lbehavioural_patterns/interpreter/Token$Type;
      26: invokevirtual #22                 // Method behavioural_patterns/interpreter/Token$Type.ordinal:()I
      29: iconst_2
      30: iastore
      31: goto          35
      34: astore_1
      35: nop
      36: aload_0
      37: getstatic     #28                 // Field behavioural_patterns/interpreter/Token$Type.MINUS:Lbehavioural_patterns/interpreter/Token$Type;
      40: invokevirtual #22                 // Method behavioural_patterns/interpreter/Token$Type.ordinal:()I
      43: iconst_3
      44: iastore
      45: goto          49
      48: astore_1
      49: nop
      50: aload_0
      51: getstatic     #31                 // Field behavioural_patterns/interpreter/Token$Type.LEFTPARENTHESIS:Lbehavioural_patterns/interpreter/Token$Type;
      54: invokevirtual #22                 // Method behavioural_patterns/interpreter/Token$Type.ordinal:()I
      57: iconst_4
      58: iastore
      59: goto          63
      62: astore_1
      63: nop
      64: aload_0
      65: getstatic     #34                 // Field behavioural_patterns/interpreter/Token$Type.RIGHTPARENTHESIS:Lbehavioural_patterns/interpreter/Token$Type;
      68: invokevirtual #22                 // Method behavioural_patterns/interpreter/Token$Type.ordinal:()I
      71: iconst_5
      72: iastore
      73: goto          77
      76: astore_1
      77: aload_0
      78: putstatic     #38                 // Field $EnumSwitchMapping$0:[I
      81: return
    Exception table:
       from    to  target type
           7    17    20   Class java/lang/NoSuchFieldError
          21    31    34   Class java/lang/NoSuchFieldError
          35    45    48   Class java/lang/NoSuchFieldError
          49    59    62   Class java/lang/NoSuchFieldError
          63    73    76   Class java/lang/NoSuchFieldError
}

Compiled from "Interpreter.kt"
public final class behavioural_patterns.interpreter.InterpreterKt {
  public static final java.util.List<behavioural_patterns.interpreter.Token> lex(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #18                 // class java/util/ArrayList
       9: dup
      10: invokespecial #22                 // Method java/util/ArrayList."<init>":()V
      13: astore_1
      14: iconst_0
      15: istore_2
      16: iload_2
      17: aload_0
      18: invokevirtual #28                 // Method java/lang/String.length:()I
      21: if_icmpge     251
      24: aload_0
      25: iload_2
      26: invokevirtual #32                 // Method java/lang/String.charAt:(I)C
      29: tableswitch   { // 40 to 45
                    40: 108
                    41: 128
                    42: 148
                    43: 68
                    44: 148
                    45: 88
               default: 148
          }
      68: aload_1
      69: new           #34                 // class behavioural_patterns/interpreter/Token
      72: dup
      73: getstatic     #40                 // Field behavioural_patterns/interpreter/Token$Type.PLUS:Lbehavioural_patterns/interpreter/Token$Type;
      76: ldc           #42                 // String +
      78: invokespecial #45                 // Method behavioural_patterns/interpreter/Token."<init>":(Lbehavioural_patterns/interpreter/Token$Type;Ljava/lang/String;)V
      81: invokevirtual #49                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      84: pop
      85: goto          245
      88: aload_1
      89: new           #34                 // class behavioural_patterns/interpreter/Token
      92: dup
      93: getstatic     #52                 // Field behavioural_patterns/interpreter/Token$Type.MINUS:Lbehavioural_patterns/interpreter/Token$Type;
      96: ldc           #54                 // String -
      98: invokespecial #45                 // Method behavioural_patterns/interpreter/Token."<init>":(Lbehavioural_patterns/interpreter/Token$Type;Ljava/lang/String;)V
     101: invokevirtual #49                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     104: pop
     105: goto          245
     108: aload_1
     109: new           #34                 // class behavioural_patterns/interpreter/Token
     112: dup
     113: getstatic     #57                 // Field behavioural_patterns/interpreter/Token$Type.LEFTPARENTHESIS:Lbehavioural_patterns/interpreter/Token$Type;
     116: ldc           #59                 // String (
     118: invokespecial #45                 // Method behavioural_patterns/interpreter/Token."<init>":(Lbehavioural_patterns/interpreter/Token$Type;Ljava/lang/String;)V
     121: invokevirtual #49                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     124: pop
     125: goto          245
     128: aload_1
     129: new           #34                 // class behavioural_patterns/interpreter/Token
     132: dup
     133: getstatic     #62                 // Field behavioural_patterns/interpreter/Token$Type.RIGHTPARENTHESIS:Lbehavioural_patterns/interpreter/Token$Type;
     136: ldc           #64                 // String )
     138: invokespecial #45                 // Method behavioural_patterns/interpreter/Token."<init>":(Lbehavioural_patterns/interpreter/Token$Type;Ljava/lang/String;)V
     141: invokevirtual #49                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     144: pop
     145: goto          245
     148: new           #66                 // class java/lang/StringBuilder
     151: dup
     152: aload_0
     153: iload_2
     154: invokevirtual #32                 // Method java/lang/String.charAt:(I)C
     157: invokestatic  #70                 // Method java/lang/String.valueOf:(C)Ljava/lang/String;
     160: invokespecial #73                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
     163: astore_3
     164: iload_2
     165: iconst_1
     166: iadd
     167: istore        4
     169: aload_0
     170: invokevirtual #28                 // Method java/lang/String.length:()I
     173: istore        5
     175: iload         4
     177: iload         5
     179: if_icmpge     245
     182: aload_0
     183: iload         4
     185: invokevirtual #32                 // Method java/lang/String.charAt:(I)C
     188: invokestatic  #79                 // Method java/lang/Character.isDigit:(C)Z
     191: ifeq          211
     194: aload_3
     195: aload_0
     196: iload         4
     198: invokevirtual #32                 // Method java/lang/String.charAt:(I)C
     201: invokevirtual #83                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     204: pop
     205: iinc          2, 1
     208: goto          239
     211: aload_1
     212: new           #34                 // class behavioural_patterns/interpreter/Token
     215: dup
     216: getstatic     #86                 // Field behavioural_patterns/interpreter/Token$Type.INTEGER:Lbehavioural_patterns/interpreter/Token$Type;
     219: aload_3
     220: invokevirtual #90                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     223: dup
     224: ldc           #92                 // String toString(...)
     226: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     229: invokespecial #45                 // Method behavioural_patterns/interpreter/Token."<init>":(Lbehavioural_patterns/interpreter/Token$Type;Ljava/lang/String;)V
     232: invokevirtual #49                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     235: pop
     236: goto          245
     239: iinc          4, 1
     242: goto          175
     245: iinc          2, 1
     248: goto          16
     251: aload_1
     252: checkcast     #97                 // class java/util/List
     255: areturn

  public static final behavioural_patterns.interpreter.Element parse(java.util.List<behavioural_patterns.interpreter.Token>);
    Code:
       0: aload_0
       1: ldc           #110                // String tokens
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #112                // class behavioural_patterns/interpreter/BinaryOperation
       9: dup
      10: invokespecial #113                // Method behavioural_patterns/interpreter/BinaryOperation."<init>":()V
      13: astore_1
      14: iconst_0
      15: istore_2
      16: iconst_0
      17: istore_3
      18: iload_3
      19: aload_0
      20: invokeinterface #116,  1          // InterfaceMethod java/util/List.size:()I
      25: if_icmpge     291
      28: aload_0
      29: iload_3
      30: invokeinterface #120,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      35: checkcast     #34                 // class behavioural_patterns/interpreter/Token
      38: astore        4
      40: aload         4
      42: invokevirtual #124                // Method behavioural_patterns/interpreter/Token.getType:()Lbehavioural_patterns/interpreter/Token$Type;
      45: getstatic     #130                // Field behavioural_patterns/interpreter/InterpreterKt$WhenMappings.$EnumSwitchMapping$0:[I
      48: swap
      49: invokevirtual #133                // Method behavioural_patterns/interpreter/Token$Type.ordinal:()I
      52: iaload
      53: tableswitch   { // 1 to 5
                     1: 88
                     2: 135
                     3: 145
                     4: 155
                     5: 274
               default: 277
          }
      88: new           #135                // class behavioural_patterns/interpreter/Integer
      91: dup
      92: aload         4
      94: invokevirtual #138                // Method behavioural_patterns/interpreter/Token.getText:()Ljava/lang/String;
      97: invokestatic  #144                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     100: invokespecial #147                // Method behavioural_patterns/interpreter/Integer."<init>":(I)V
     103: astore        5
     105: iload_2
     106: ifeq          121
     109: aload_1
     110: aload         5
     112: checkcast     #149                // class behavioural_patterns/interpreter/Element
     115: invokevirtual #153                // Method behavioural_patterns/interpreter/BinaryOperation.setRight:(Lbehavioural_patterns/interpreter/Element;)V
     118: goto          285
     121: aload_1
     122: aload         5
     124: checkcast     #149                // class behavioural_patterns/interpreter/Element
     127: invokevirtual #156                // Method behavioural_patterns/interpreter/BinaryOperation.setLeft:(Lbehavioural_patterns/interpreter/Element;)V
     130: iconst_1
     131: istore_2
     132: goto          285
     135: aload_1
     136: getstatic     #162                // Field behavioural_patterns/interpreter/BinaryOperation$Type.ADDITION:Lbehavioural_patterns/interpreter/BinaryOperation$Type;
     139: invokevirtual #166                // Method behavioural_patterns/interpreter/BinaryOperation.setType:(Lbehavioural_patterns/interpreter/BinaryOperation$Type;)V
     142: goto          285
     145: aload_1
     146: getstatic     #169                // Field behavioural_patterns/interpreter/BinaryOperation$Type.SUBTRACTION:Lbehavioural_patterns/interpreter/BinaryOperation$Type;
     149: invokevirtual #166                // Method behavioural_patterns/interpreter/BinaryOperation.setType:(Lbehavioural_patterns/interpreter/BinaryOperation$Type;)V
     152: goto          285
     155: iload_3
     156: istore        5
     158: iload         5
     160: aload_0
     161: invokeinterface #116,  1          // InterfaceMethod java/util/List.size:()I
     166: if_icmpge     195
     169: aload_0
     170: iload         5
     172: invokeinterface #120,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     177: checkcast     #34                 // class behavioural_patterns/interpreter/Token
     180: invokevirtual #124                // Method behavioural_patterns/interpreter/Token.getType:()Lbehavioural_patterns/interpreter/Token$Type;
     183: getstatic     #62                 // Field behavioural_patterns/interpreter/Token$Type.RIGHTPARENTHESIS:Lbehavioural_patterns/interpreter/Token$Type;
     186: if_acmpeq     195
     189: iinc          5, 1
     192: goto          158
     195: aload_0
     196: invokeinterface #173,  1          // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
     201: iload_3
     202: iconst_1
     203: iadd
     204: i2l
     205: invokeinterface #179,  3          // InterfaceMethod java/util/stream/Stream.skip:(J)Ljava/util/stream/Stream;
     210: iload         5
     212: iload_3
     213: isub
     214: iconst_1
     215: isub
     216: i2l
     217: invokeinterface #182,  3          // InterfaceMethod java/util/stream/Stream.limit:(J)Ljava/util/stream/Stream;
     222: invokestatic  #188                // Method java/util/stream/Collectors.toList:()Ljava/util/stream/Collector;
     225: invokeinterface #192,  2          // InterfaceMethod java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
     230: checkcast     #97                 // class java/util/List
     233: astore        6
     235: aload         6
     237: invokestatic  #196                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     240: aload         6
     242: invokestatic  #198                // Method parse:(Ljava/util/List;)Lbehavioural_patterns/interpreter/Element;
     245: astore        7
     247: iload_2
     248: ifeq          260
     251: aload_1
     252: aload         7
     254: invokevirtual #153                // Method behavioural_patterns/interpreter/BinaryOperation.setRight:(Lbehavioural_patterns/interpreter/Element;)V
     257: goto          268
     260: aload_1
     261: aload         7
     263: invokevirtual #156                // Method behavioural_patterns/interpreter/BinaryOperation.setLeft:(Lbehavioural_patterns/interpreter/Element;)V
     266: iconst_1
     267: istore_2
     268: iload         5
     270: istore_3
     271: goto          285
     274: goto          285
     277: new           #200                // class kotlin/NoWhenBranchMatchedException
     280: dup
     281: invokespecial #201                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     284: athrow
     285: iinc          3, 1
     288: goto          18
     291: aload_1
     292: checkcast     #149                // class behavioural_patterns/interpreter/Element
     295: areturn

  public static final void main();
    Code:
       0: ldc           #215                // String (13+4)-(12+1)
       2: astore_0
       3: aload_0
       4: invokestatic  #217                // Method lex:(Ljava/lang/String;)Ljava/util/List;
       7: astore_1
       8: aload_1
       9: invokeinterface #173,  1          // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
      14: invokedynamic #236,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
      19: invokedynamic #247,  0            // InvokeDynamic #1:apply:(Lkotlin/jvm/functions/Function1;)Ljava/util/function/Function;
      24: invokeinterface #251,  2          // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
      29: ldc           #253                // String _
      31: checkcast     #255                // class java/lang/CharSequence
      34: invokestatic  #259                // Method java/util/stream/Collectors.joining:(Ljava/lang/CharSequence;)Ljava/util/stream/Collector;
      37: invokeinterface #192,  2          // InterfaceMethod java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
      42: getstatic     #265                // Field java/lang/System.out:Ljava/io/PrintStream;
      45: swap
      46: invokevirtual #270                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      49: aload_1
      50: invokestatic  #198                // Method parse:(Ljava/util/List;)Lbehavioural_patterns/interpreter/Element;
      53: astore_2
      54: new           #66                 // class java/lang/StringBuilder
      57: dup
      58: invokespecial #271                // Method java/lang/StringBuilder."<init>":()V
      61: aload_0
      62: invokevirtual #274                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      65: ldc_w         #276                // String  =
      68: invokevirtual #274                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      71: aload_2
      72: invokeinterface #279,  1          // InterfaceMethod behavioural_patterns/interpreter/Element.eval:()I
      77: invokevirtual #282                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      80: invokevirtual #90                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      83: getstatic     #265                // Field java/lang/System.out:Ljava/io/PrintStream;
      86: swap
      87: invokevirtual #270                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      90: return

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

  private static final java.lang.String main$lambda$0(behavioural_patterns.interpreter.Token);
    Code:
       0: aload_0
       1: invokevirtual #289                // Method behavioural_patterns/interpreter/Token.toString:()Ljava/lang/String;
       4: areturn

  private static final java.lang.String main$lambda$1(kotlin.jvm.functions.Function1, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: invokeinterface #294,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
       7: checkcast     #24                 // class java/lang/String
      10: areturn
}


package com.company

fun main(args: Array<String>) {
    // please pass sorted array in input always because binary search will always run in sorted array

    val i = readLine()!!.trim().split(" ").map { it -> it.toInt() }.toIntArray()
    val key = readLine()!!.trim().toInt()
    val ans = binarySearch(i, key)
    if(ans >= 0 ) {
        println(ans)
    } else {
        println("Position not found")
    }
}

fun binarySearch(input: IntArray, key: Int) : Int{
    var i = 0
    var j = input.size
    var mid : Int
    while(i < j) {
        mid = (i +j) / 2
        when {
            key == input[mid] -> return mid
            key >input[mid]   -> i = mid+1
            key < input[mid]  -> j = mid-1;
        }
    }
    return -1
}

// sample input 1 :
// 1, 2, 3, 4, 5, 6
// 3
// output : 2

// sample input 2 :
// 4 5 2 3 6
// 3
// output : position not found

// Time Complexity = O(log(n)) for worst case and would be O(1) in best case
// space complexity = O(1)

Compiled from "binary_Search.kt"
public final class com.company.Binary_SearchKt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: invokestatic  #21                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
       9: dup
      10: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      13: checkcast     #27                 // class java/lang/CharSequence
      16: invokestatic  #33                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      19: invokevirtual #36                 // Method java/lang/Object.toString:()Ljava/lang/String;
      22: checkcast     #27                 // class java/lang/CharSequence
      25: iconst_1
      26: anewarray     #38                 // class java/lang/String
      29: astore_2
      30: aload_2
      31: iconst_0
      32: ldc           #40                 // String
      34: aastore
      35: aload_2
      36: iconst_0
      37: iconst_0
      38: bipush        6
      40: aconst_null
      41: invokestatic  #44                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      44: checkcast     #46                 // class java/lang/Iterable
      47: astore_2
      48: iconst_0
      49: istore_3
      50: aload_2
      51: astore        4
      53: new           #48                 // class java/util/ArrayList
      56: dup
      57: aload_2
      58: bipush        10
      60: invokestatic  #54                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      63: invokespecial #58                 // Method java/util/ArrayList."<init>":(I)V
      66: checkcast     #60                 // class java/util/Collection
      69: astore        5
      71: iconst_0
      72: istore        6
      74: aload         4
      76: invokeinterface #64,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      81: astore        7
      83: aload         7
      85: invokeinterface #70,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      90: ifeq          137
      93: aload         7
      95: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     100: astore        8
     102: aload         5
     104: aload         8
     106: checkcast     #38                 // class java/lang/String
     109: astore        9
     111: astore        11
     113: iconst_0
     114: istore        10
     116: aload         9
     118: invokestatic  #80                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     121: nop
     122: invokestatic  #84                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     125: aload         11
     127: swap
     128: invokeinterface #88,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     133: pop
     134: goto          83
     137: aload         5
     139: checkcast     #90                 // class java/util/List
     142: nop
     143: checkcast     #60                 // class java/util/Collection
     146: invokestatic  #94                 // Method kotlin/collections/CollectionsKt.toIntArray:(Ljava/util/Collection;)[I
     149: astore_1
     150: nop
     151: invokestatic  #21                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
     154: dup
     155: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     158: checkcast     #27                 // class java/lang/CharSequence
     161: invokestatic  #33                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     164: invokevirtual #36                 // Method java/lang/Object.toString:()Ljava/lang/String;
     167: invokestatic  #80                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     170: istore_2
     171: aload_1
     172: iload_2
     173: invokestatic  #98                 // Method binarySearch:([II)I
     176: istore_3
     177: iload_3
     178: iflt          191
     181: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
     184: iload_3
     185: invokevirtual #109                // Method java/io/PrintStream.println:(I)V
     188: goto          200
     191: ldc           #111                // String Position not found
     193: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
     196: swap
     197: invokevirtual #113                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     200: return

  public static final int binarySearch(int[], int);
    Code:
       0: aload_0
       1: ldc           #135                // String input
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_2
       8: aload_0
       9: arraylength
      10: istore_3
      11: iconst_0
      12: istore        4
      14: iload_2
      15: iload_3
      16: if_icmpge     70
      19: iload_2
      20: iload_3
      21: iadd
      22: iconst_2
      23: idiv
      24: istore        4
      26: nop
      27: iload_1
      28: aload_0
      29: iload         4
      31: iaload
      32: if_icmpne     38
      35: iload         4
      37: ireturn
      38: iload_1
      39: aload_0
      40: iload         4
      42: iaload
      43: if_icmple     54
      46: iload         4
      48: iconst_1
      49: iadd
      50: istore_2
      51: goto          14
      54: iload_1
      55: aload_0
      56: iload         4
      58: iaload
      59: if_icmpge     14
      62: iload         4
      64: iconst_1
      65: isub
      66: istore_3
      67: goto          14
      70: iconst_m1
      71: ireturn
}


package aoeiuv020

import java.util.*

typealias StringBuilder = java.lang.StringBuilder

/**
 * 最长公共子序列，
 * 输出所有子序列，
 * Created by AoEiuV020 on 2017/05/14.
 */
object DynamicProgramming {
    enum class Last {
        XY, X, Y, E
    }
    fun longestCommonSubsequence(x: String, y: String): List<String> = longestCommonSubsequence(x.toCharArray(), y.toCharArray())
    private fun longestCommonSubsequence(x: CharArray, y: CharArray): List<String> {
        val c = Array(x.size, {
            Array(y.size, {
                Pair(0, Last.XY)
            })
        })
        var i = x.size - 1
        var j = y.size - 1
        _lcs(c, x, y, i, j)
        return collect(c, x, y, i, j).map(StringBuilder::toString).distinct().sorted()
    }
    private fun collect(c: Array<Array<Pair<Int, Last>>>, x: CharArray, y: CharArray, i: Int, j: Int): MutableList<StringBuilder> = if (i < 0 || j < 0) mutableListOf<StringBuilder>(StringBuilder())
    else when (c[i][j].second) {
        Last.X -> collect(c, x, y, i - 1, j)
        Last.Y -> collect(c, x, y, i, j - 1)
        Last.E -> (collect(c, x, y, i - 1, j) + collect(c, x, y, i, j - 1)).toMutableList()
        Last.XY -> {
            collect(c, x, y, i - 1, j - 1).map {
                it.append(x[i])
            }.toMutableList()
        }
    }
    private fun _lcs(c: Array<Array<Pair<Int, Last>>>, x: CharArray, y: CharArray, i: Int, j: Int): Int = when {
        i == -1 || j == -1 -> 0
        x[i] == y[j] -> {
            val xy = _lcs(c, x, y, i - 1, j - 1) + 1
            c[i][j] = Pair(xy, Last.XY)
            c[i][j].first
        }
        else -> {
            val x1 = _lcs(c, x, y, i - 1, j)
            val y1 = _lcs(c, x, y, i, j - 1)
            c[i][j] = if (x1 > y1) {
                Pair(x1, Last.X)
            } else if (x1 < y1) {
                Pair(y1, Last.Y)
            } else {
                Pair(x1, Last.E)
            }
            c[i][j].first
        }
    }
}

Compiled from "DynamicProgramming.kt"
public final class aoeiuv020.DynamicProgramming$Last extends java.lang.Enum<aoeiuv020.DynamicProgramming$Last> {
  public static final aoeiuv020.DynamicProgramming$Last XY;

  public static final aoeiuv020.DynamicProgramming$Last X;

  public static final aoeiuv020.DynamicProgramming$Last Y;

  public static final aoeiuv020.DynamicProgramming$Last E;

  private static final aoeiuv020.DynamicProgramming$Last[] $VALUES;

  private static final kotlin.enums.EnumEntries $ENTRIES;

  private aoeiuv020.DynamicProgramming$Last();
    Code:
       0: aload_0
       1: aload_1
       2: iload_2
       3: invokespecial #10                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
       6: return

  public static aoeiuv020.DynamicProgramming$Last[] values();
    Code:
       0: getstatic     #22                 // Field $VALUES:[Laoeiuv020/DynamicProgramming$Last;
       3: invokevirtual #28                 // Method java/lang/Object.clone:()Ljava/lang/Object;
       6: checkcast     #29                 // class "[Laoeiuv020/DynamicProgramming$Last;"
       9: areturn

  public static aoeiuv020.DynamicProgramming$Last valueOf(java.lang.String);
    Code:
       0: ldc           #2                  // class aoeiuv020/DynamicProgramming$Last
       2: aload_0
       3: invokestatic  #34                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       6: checkcast     #2                  // class aoeiuv020/DynamicProgramming$Last
       9: areturn

  public static kotlin.enums.EnumEntries<aoeiuv020.DynamicProgramming$Last> getEntries();
    Code:
       0: getstatic     #43                 // Field $ENTRIES:Lkotlin/enums/EnumEntries;
       3: areturn

  private static final aoeiuv020.DynamicProgramming$Last[] $values();
    Code:
       0: iconst_4
       1: anewarray     #2                  // class aoeiuv020/DynamicProgramming$Last
       4: astore_0
       5: aload_0
       6: iconst_0
       7: getstatic     #47                 // Field XY:Laoeiuv020/DynamicProgramming$Last;
      10: aastore
      11: aload_0
      12: iconst_1
      13: getstatic     #50                 // Field X:Laoeiuv020/DynamicProgramming$Last;
      16: aastore
      17: aload_0
      18: iconst_2
      19: getstatic     #53                 // Field Y:Laoeiuv020/DynamicProgramming$Last;
      22: aastore
      23: aload_0
      24: iconst_3
      25: getstatic     #56                 // Field E:Laoeiuv020/DynamicProgramming$Last;
      28: aastore
      29: aload_0
      30: areturn

  static {};
    Code:
       0: new           #2                  // class aoeiuv020/DynamicProgramming$Last
       3: dup
       4: ldc           #58                 // String XY
       6: iconst_0
       7: invokespecial #59                 // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #47                 // Field XY:Laoeiuv020/DynamicProgramming$Last;
      13: new           #2                  // class aoeiuv020/DynamicProgramming$Last
      16: dup
      17: ldc           #60                 // String X
      19: iconst_1
      20: invokespecial #59                 // Method "<init>":(Ljava/lang/String;I)V
      23: putstatic     #50                 // Field X:Laoeiuv020/DynamicProgramming$Last;
      26: new           #2                  // class aoeiuv020/DynamicProgramming$Last
      29: dup
      30: ldc           #61                 // String Y
      32: iconst_2
      33: invokespecial #59                 // Method "<init>":(Ljava/lang/String;I)V
      36: putstatic     #53                 // Field Y:Laoeiuv020/DynamicProgramming$Last;
      39: new           #2                  // class aoeiuv020/DynamicProgramming$Last
      42: dup
      43: ldc           #62                 // String E
      45: iconst_3
      46: invokespecial #59                 // Method "<init>":(Ljava/lang/String;I)V
      49: putstatic     #56                 // Field E:Laoeiuv020/DynamicProgramming$Last;
      52: invokestatic  #64                 // Method $values:()[Laoeiuv020/DynamicProgramming$Last;
      55: putstatic     #22                 // Field $VALUES:[Laoeiuv020/DynamicProgramming$Last;
      58: getstatic     #22                 // Field $VALUES:[Laoeiuv020/DynamicProgramming$Last;
      61: checkcast     #66                 // class "[Ljava/lang/Enum;"
      64: invokestatic  #72                 // Method kotlin/enums/EnumEntriesKt.enumEntries:([Ljava/lang/Enum;)Lkotlin/enums/EnumEntries;
      67: putstatic     #43                 // Field $ENTRIES:Lkotlin/enums/EnumEntries;
      70: return
}

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

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

  public final java.util.List<java.lang.String> longestCommonSubsequence(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #16                 // String x
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #24                 // String y
       9: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: aload_1
      14: invokevirtual #30                 // Method java/lang/String.toCharArray:()[C
      17: dup
      18: ldc           #32                 // String toCharArray(...)
      20: invokestatic  #35                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      23: aload_2
      24: invokevirtual #30                 // Method java/lang/String.toCharArray:()[C
      27: dup
      28: ldc           #32                 // String toCharArray(...)
      30: invokestatic  #35                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      33: invokespecial #38                 // Method longestCommonSubsequence:([C[C)Ljava/util/List;
      36: areturn

  private final java.util.List<java.lang.String> longestCommonSubsequence(char[], char[]);
    Code:
       0: iconst_0
       1: istore        4
       3: aload_1
       4: arraylength
       5: istore        5
       7: iload         5
       9: anewarray     #42                 // class "[Lkotlin/Pair;"
      12: astore        6
      14: iload         4
      16: iload         5
      18: if_icmpge     96
      21: iload         4
      23: istore        7
      25: aload         6
      27: iload         7
      29: iconst_0
      30: istore        8
      32: aload_2
      33: arraylength
      34: istore        9
      36: iload         9
      38: anewarray     #44                 // class kotlin/Pair
      41: astore        10
      43: istore        16
      45: astore        15
      47: iload         8
      49: iload         9
      51: if_icmpge     83
      54: iload         8
      56: istore        11
      58: aload         10
      60: iload         11
      62: new           #44                 // class kotlin/Pair
      65: dup
      66: iconst_0
      67: invokestatic  #50                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      70: getstatic     #56                 // Field aoeiuv020/DynamicProgramming$Last.XY:Laoeiuv020/DynamicProgramming$Last;
      73: invokespecial #59                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      76: aastore
      77: iinc          8, 1
      80: goto          47
      83: aload         15
      85: iload         16
      87: aload         10
      89: aastore
      90: iinc          4, 1
      93: goto          14
      96: aload         6
      98: astore_3
      99: aload_1
     100: arraylength
     101: iconst_1
     102: isub
     103: istore        4
     105: aload_2
     106: arraylength
     107: iconst_1
     108: isub
     109: istore        5
     111: aload_0
     112: aload_3
     113: aload_1
     114: aload_2
     115: iload         4
     117: iload         5
     119: invokespecial #63                 // Method _lcs:([[Lkotlin/Pair;[C[CII)I
     122: pop
     123: aload_0
     124: aload_3
     125: aload_1
     126: aload_2
     127: iload         4
     129: iload         5
     131: invokespecial #67                 // Method collect:([[Lkotlin/Pair;[C[CII)Ljava/util/List;
     134: checkcast     #69                 // class java/lang/Iterable
     137: astore        6
     139: iconst_0
     140: istore        7
     142: aload         6
     144: astore        8
     146: new           #71                 // class java/util/ArrayList
     149: dup
     150: aload         6
     152: bipush        10
     154: invokestatic  #77                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     157: invokespecial #80                 // Method java/util/ArrayList."<init>":(I)V
     160: checkcast     #82                 // class java/util/Collection
     163: astore        9
     165: iconst_0
     166: istore        10
     168: aload         8
     170: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     175: astore        11
     177: aload         11
     179: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     184: ifeq          227
     187: aload         11
     189: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     194: astore        12
     196: aload         9
     198: aload         12
     200: checkcast     #98                 // class java/lang/StringBuilder
     203: astore        13
     205: astore        15
     207: iconst_0
     208: istore        14
     210: aload         13
     212: invokevirtual #102                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     215: aload         15
     217: swap
     218: invokeinterface #106,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     223: pop
     224: goto          177
     227: aload         9
     229: checkcast     #108                // class java/util/List
     232: nop
     233: checkcast     #69                 // class java/lang/Iterable
     236: invokestatic  #112                // Method kotlin/collections/CollectionsKt.distinct:(Ljava/lang/Iterable;)Ljava/util/List;
     239: checkcast     #69                 // class java/lang/Iterable
     242: invokestatic  #115                // Method kotlin/collections/CollectionsKt.sorted:(Ljava/lang/Iterable;)Ljava/util/List;
     245: areturn

  private final java.util.List<java.lang.StringBuilder> collect(kotlin.Pair<java.lang.Integer, aoeiuv020.DynamicProgramming$Last>[][], char[], char[], int, int);
    Code:
       0: iload         4
       2: iflt          10
       5: iload         5
       7: ifge          35
      10: iconst_1
      11: anewarray     #98                 // class java/lang/StringBuilder
      14: astore        6
      16: aload         6
      18: iconst_0
      19: new           #98                 // class java/lang/StringBuilder
      22: dup
      23: invokespecial #137                // Method java/lang/StringBuilder."<init>":()V
      26: aastore
      27: aload         6
      29: invokestatic  #141                // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
      32: goto          299
      35: aload_1
      36: iload         4
      38: aaload
      39: iload         5
      41: aaload
      42: invokevirtual #144                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      45: checkcast     #52                 // class aoeiuv020/DynamicProgramming$Last
      48: getstatic     #150                // Field aoeiuv020/DynamicProgramming$WhenMappings.$EnumSwitchMapping$0:[I
      51: swap
      52: invokevirtual #154                // Method aoeiuv020/DynamicProgramming$Last.ordinal:()I
      55: iaload
      56: tableswitch   { // 1 to 4
                     1: 88
                     2: 104
                     3: 120
                     4: 164
               default: 291
          }
      88: aload_0
      89: aload_1
      90: aload_2
      91: aload_3
      92: iload         4
      94: iconst_1
      95: isub
      96: iload         5
      98: invokespecial #67                 // Method collect:([[Lkotlin/Pair;[C[CII)Ljava/util/List;
     101: goto          299
     104: aload_0
     105: aload_1
     106: aload_2
     107: aload_3
     108: iload         4
     110: iload         5
     112: iconst_1
     113: isub
     114: invokespecial #67                 // Method collect:([[Lkotlin/Pair;[C[CII)Ljava/util/List;
     117: goto          299
     120: aload_0
     121: aload_1
     122: aload_2
     123: aload_3
     124: iload         4
     126: iconst_1
     127: isub
     128: iload         5
     130: invokespecial #67                 // Method collect:([[Lkotlin/Pair;[C[CII)Ljava/util/List;
     133: checkcast     #82                 // class java/util/Collection
     136: aload_0
     137: aload_1
     138: aload_2
     139: aload_3
     140: iload         4
     142: iload         5
     144: iconst_1
     145: isub
     146: invokespecial #67                 // Method collect:([[Lkotlin/Pair;[C[CII)Ljava/util/List;
     149: checkcast     #69                 // class java/lang/Iterable
     152: invokestatic  #158                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     155: checkcast     #82                 // class java/util/Collection
     158: invokestatic  #162                // Method kotlin/collections/CollectionsKt.toMutableList:(Ljava/util/Collection;)Ljava/util/List;
     161: goto          299
     164: aload_0
     165: aload_1
     166: aload_2
     167: aload_3
     168: iload         4
     170: iconst_1
     171: isub
     172: iload         5
     174: iconst_1
     175: isub
     176: invokespecial #67                 // Method collect:([[Lkotlin/Pair;[C[CII)Ljava/util/List;
     179: checkcast     #69                 // class java/lang/Iterable
     182: astore        7
     184: iconst_0
     185: istore        8
     187: aload         7
     189: astore        9
     191: new           #71                 // class java/util/ArrayList
     194: dup
     195: aload         7
     197: bipush        10
     199: invokestatic  #77                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     202: invokespecial #80                 // Method java/util/ArrayList."<init>":(I)V
     205: checkcast     #82                 // class java/util/Collection
     208: astore        10
     210: iconst_0
     211: istore        11
     213: aload         9
     215: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     220: astore        12
     222: aload         12
     224: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     229: ifeq          276
     232: aload         12
     234: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     239: astore        13
     241: aload         10
     243: aload         13
     245: checkcast     #98                 // class java/lang/StringBuilder
     248: astore        14
     250: astore        16
     252: iconst_0
     253: istore        15
     255: aload         14
     257: aload_2
     258: iload         4
     260: caload
     261: invokevirtual #166                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     264: aload         16
     266: swap
     267: invokeinterface #106,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     272: pop
     273: goto          222
     276: aload         10
     278: checkcast     #108                // class java/util/List
     281: nop
     282: checkcast     #82                 // class java/util/Collection
     285: invokestatic  #162                // Method kotlin/collections/CollectionsKt.toMutableList:(Ljava/util/Collection;)Ljava/util/List;
     288: goto          299
     291: new           #168                // class kotlin/NoWhenBranchMatchedException
     294: dup
     295: invokespecial #169                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     298: athrow
     299: areturn

  private final int _lcs(kotlin.Pair<java.lang.Integer, aoeiuv020.DynamicProgramming$Last>[][], char[], char[], int, int);
    Code:
       0: nop
       1: iload         4
       3: iconst_m1
       4: if_icmpeq     13
       7: iload         5
       9: iconst_m1
      10: if_icmpne     17
      13: iconst_0
      14: goto          206
      17: aload_2
      18: iload         4
      20: caload
      21: aload_3
      22: iload         5
      24: caload
      25: if_icmpne     88
      28: aload_0
      29: aload_1
      30: aload_2
      31: aload_3
      32: iload         4
      34: iconst_1
      35: isub
      36: iload         5
      38: iconst_1
      39: isub
      40: invokespecial #63                 // Method _lcs:([[Lkotlin/Pair;[C[CII)I
      43: iconst_1
      44: iadd
      45: istore        6
      47: aload_1
      48: iload         4
      50: aaload
      51: iload         5
      53: new           #44                 // class kotlin/Pair
      56: dup
      57: iload         6
      59: invokestatic  #50                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      62: getstatic     #56                 // Field aoeiuv020/DynamicProgramming$Last.XY:Laoeiuv020/DynamicProgramming$Last;
      65: invokespecial #59                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      68: aastore
      69: aload_1
      70: iload         4
      72: aaload
      73: iload         5
      75: aaload
      76: invokevirtual #175                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      79: checkcast     #177                // class java/lang/Number
      82: invokevirtual #180                // Method java/lang/Number.intValue:()I
      85: goto          206
      88: aload_0
      89: aload_1
      90: aload_2
      91: aload_3
      92: iload         4
      94: iconst_1
      95: isub
      96: iload         5
      98: invokespecial #63                 // Method _lcs:([[Lkotlin/Pair;[C[CII)I
     101: istore        6
     103: aload_0
     104: aload_1
     105: aload_2
     106: aload_3
     107: iload         4
     109: iload         5
     111: iconst_1
     112: isub
     113: invokespecial #63                 // Method _lcs:([[Lkotlin/Pair;[C[CII)I
     116: istore        7
     118: aload_1
     119: iload         4
     121: aaload
     122: iload         5
     124: iload         6
     126: iload         7
     128: if_icmple     149
     131: new           #44                 // class kotlin/Pair
     134: dup
     135: iload         6
     137: invokestatic  #50                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     140: getstatic     #183                // Field aoeiuv020/DynamicProgramming$Last.X:Laoeiuv020/DynamicProgramming$Last;
     143: invokespecial #59                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     146: goto          189
     149: iload         6
     151: iload         7
     153: if_icmpge     174
     156: new           #44                 // class kotlin/Pair
     159: dup
     160: iload         7
     162: invokestatic  #50                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     165: getstatic     #186                // Field aoeiuv020/DynamicProgramming$Last.Y:Laoeiuv020/DynamicProgramming$Last;
     168: invokespecial #59                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     171: goto          189
     174: new           #44                 // class kotlin/Pair
     177: dup
     178: iload         6
     180: invokestatic  #50                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     183: getstatic     #189                // Field aoeiuv020/DynamicProgramming$Last.E:Laoeiuv020/DynamicProgramming$Last;
     186: invokespecial #59                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     189: aastore
     190: aload_1
     191: iload         4
     193: aaload
     194: iload         5
     196: aaload
     197: invokevirtual #175                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     200: checkcast     #177                // class java/lang/Number
     203: invokevirtual #180                // Method java/lang/Number.intValue:()I
     206: ireturn

  static {};
    Code:
       0: new           #2                  // class aoeiuv020/DynamicProgramming
       3: dup
       4: invokespecial #194                // Method "<init>":()V
       7: putstatic     #197                // Field INSTANCE:Laoeiuv020/DynamicProgramming;
      10: return
}

Compiled from "DynamicProgramming.kt"
public final class aoeiuv020.DynamicProgrammingKt {
}

Compiled from "DynamicProgramming.kt"
public final class aoeiuv020.DynamicProgramming$WhenMappings {
  public static final int[] $EnumSwitchMapping$0;

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


jerrycychen__algoexpert__c853c59/017. Find Three Largest Numbers/FindThreeLargestNumbers.kt

package com.algoexpert.program

fun findThreeLargestNumbers(array: List<Int>): List<Int> {
    val threeLargest = mutableListOf(Int.MIN_VALUE, Int.MIN_VALUE, Int.MIN_VALUE)
    for (num in array) {
        updateLargest(threeLargest, num)
    }
    return threeLargest
}

fun updateLargest(threeLargest: MutableList<Int>, num: Int) {
    if (num > threeLargest[2]) {
        shiftAndUpdate(threeLargest, num, 2)
    } else if (num > threeLargest[1]) {
        shiftAndUpdate(threeLargest, num, 1)
    } else if (num > threeLargest[0]) {
        shiftAndUpdate(threeLargest, num, 0)
    }
}

fun shiftAndUpdate(threeLargest: MutableList<Int>, num: Int, index: Int) {
    for (i in 0 until index + 1) {
        if (i == index) {
            threeLargest[i] = num
        } else {
            threeLargest[i] = threeLargest[i + 1]
        }
    }
}

Compiled from "FindThreeLargestNumbers.kt"
public final class com.algoexpert.program.FindThreeLargestNumbersKt {
  public static final java.util.List<java.lang.Integer> findThreeLargestNumbers(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #10                 // String array
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_3
       7: anewarray     #18                 // class java/lang/Integer
      10: astore_2
      11: aload_2
      12: iconst_0
      13: ldc           #19                 // int -2147483648
      15: invokestatic  #23                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      18: aastore
      19: aload_2
      20: iconst_1
      21: ldc           #19                 // int -2147483648
      23: invokestatic  #23                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      26: aastore
      27: aload_2
      28: iconst_2
      29: ldc           #19                 // int -2147483648
      31: invokestatic  #23                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      34: aastore
      35: aload_2
      36: invokestatic  #29                 // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
      39: astore_1
      40: aload_0
      41: invokeinterface #35,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      46: astore_2
      47: aload_2
      48: invokeinterface #41,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          77
      56: aload_2
      57: invokeinterface #45,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      62: checkcast     #47                 // class java/lang/Number
      65: invokevirtual #51                 // Method java/lang/Number.intValue:()I
      68: istore_3
      69: aload_1
      70: iload_3
      71: invokestatic  #55                 // Method updateLargest:(Ljava/util/List;I)V
      74: goto          47
      77: aload_1
      78: areturn

  public static final void updateLargest(java.util.List<java.lang.Integer>, int);
    Code:
       0: aload_0
       1: ldc           #61                 // String threeLargest
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: aload_0
       8: iconst_2
       9: invokeinterface #65,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      14: checkcast     #47                 // class java/lang/Number
      17: invokevirtual #51                 // Method java/lang/Number.intValue:()I
      20: if_icmple     32
      23: aload_0
      24: iload_1
      25: iconst_2
      26: invokestatic  #69                 // Method shiftAndUpdate:(Ljava/util/List;II)V
      29: goto          81
      32: iload_1
      33: aload_0
      34: iconst_1
      35: invokeinterface #65,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      40: checkcast     #47                 // class java/lang/Number
      43: invokevirtual #51                 // Method java/lang/Number.intValue:()I
      46: if_icmple     58
      49: aload_0
      50: iload_1
      51: iconst_1
      52: invokestatic  #69                 // Method shiftAndUpdate:(Ljava/util/List;II)V
      55: goto          81
      58: iload_1
      59: aload_0
      60: iconst_0
      61: invokeinterface #65,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      66: checkcast     #47                 // class java/lang/Number
      69: invokevirtual #51                 // Method java/lang/Number.intValue:()I
      72: if_icmple     81
      75: aload_0
      76: iload_1
      77: iconst_0
      78: invokestatic  #69                 // Method shiftAndUpdate:(Ljava/util/List;II)V
      81: return

  public static final void shiftAndUpdate(java.util.List<java.lang.Integer>, int, int);
    Code:
       0: aload_0
       1: ldc           #61                 // String threeLargest
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_3
       8: iload_2
       9: iconst_1
      10: iadd
      11: istore        4
      13: iload_3
      14: iload         4
      16: if_icmpge     62
      19: iload_3
      20: iload_2
      21: if_icmpne     39
      24: aload_0
      25: iload_3
      26: iload_1
      27: invokestatic  #23                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      30: invokeinterface #74,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
      35: pop
      36: goto          56
      39: aload_0
      40: iload_3
      41: aload_0
      42: iload_3
      43: iconst_1
      44: iadd
      45: invokeinterface #65,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      50: invokeinterface #74,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
      55: pop
      56: iinc          3, 1
      59: goto          13
      62: return
}