package boj

import java.io.BufferedReader
import java.io.InputStreamReader

class CoffeeShopII constructor(private val numbers: Array<Long>) {

    private val segmentTree: Array<Long> = Array(numbers.size * 4) { 0 }

    init {
        initTree(0, numbers.size - 1)
    }

    private fun initTree(begin: Int, end: Int, root: Int = 1): Long {
        if (begin == end) {
            segmentTree[root] = numbers[begin]
            return numbers[begin]
        }
        val mid = (begin + end) / 2
        segmentTree[root] =
            initTree(begin, mid, root * 2) + initTree(mid + 1, end, root * 2 + 1)
        return segmentTree[root]
    }

    private fun updateTree(begin: Int, end: Int, target: Int, diff: Long, root: Int = 1) {
        if (target in begin..end) {
            segmentTree[root] += diff
            if (begin != end) {
                val mid = (begin + end) / 2
                updateTree(begin, mid, target, diff, root * 2)
                updateTree(mid + 1, end, target, diff, root * 2 + 1)
            }
        }
    }

    fun sum(x: Int, y: Int): Long = rangeSum(0, numbers.size - 1, x, y)

    private fun rangeSum(begin: Int, end: Int, x: Int, y: Int, root: Int = 1): Long {
        if (y < begin || end < x) {
            return 0
        }
        if (x <= begin && end <= y) {
            return segmentTree[root]
        }
        val mid = (begin + end) / 2
        return rangeSum(begin, mid, x, y, root * 2) + rangeSum(mid + 1, end, x, y, root * 2 + 1)
    }

    fun update(pos: Int, n: Long) {
        val diff = getDiff(pos, n)
        numbers[pos] = n
        updateTree(0, numbers.size - 1, pos, diff)
    }

    private fun getDiff(pos: Int, n: Long): Long {
        return n - numbers[pos]
    }
}

fun coffeeShopII(args: Array<String>) {
    val br = BufferedReader(InputStreamReader(System.`in`))

    val (_, q) = br.readLine().trim().split(" ").map(String::toInt)

    val nums = br.readLine().trim().split(" ").map(String::toLong).toTypedArray()
    val solution = CoffeeShopII(nums)

    repeat(q) {
        var (x, y, a, b) = br.readLine().trim().split(" ").map(String::toLong)
        if (x > y) {
            x = y.also { y = x }
        }
        println(solution.sum((x - 1).toInt(), (y - 1).toInt()))
        solution.update((a - 1).toInt(), b)
    }
}

Compiled from "CoffeeShopII.kt"
public final class boj.CoffeeShopIIKt {
  public static final void coffeeShopII(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: new           #17                 // class java/io/BufferedReader
       9: dup
      10: new           #19                 // class java/io/InputStreamReader
      13: dup
      14: getstatic     #25                 // Field java/lang/System.in:Ljava/io/InputStream;
      17: invokespecial #29                 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V
      20: checkcast     #31                 // class java/io/Reader
      23: invokespecial #34                 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V
      26: astore_1
      27: aload_1
      28: invokevirtual #38                 // Method java/io/BufferedReader.readLine:()Ljava/lang/String;
      31: dup
      32: ldc           #40                 // String readLine(...)
      34: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      37: checkcast     #45                 // class java/lang/CharSequence
      40: invokestatic  #51                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      43: invokevirtual #54                 // Method java/lang/Object.toString:()Ljava/lang/String;
      46: checkcast     #45                 // class java/lang/CharSequence
      49: iconst_1
      50: anewarray     #56                 // class java/lang/String
      53: astore_2
      54: aload_2
      55: iconst_0
      56: ldc           #58                 // String
      58: aastore
      59: aload_2
      60: iconst_0
      61: iconst_0
      62: bipush        6
      64: aconst_null
      65: invokestatic  #62                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      68: checkcast     #64                 // class java/lang/Iterable
      71: astore_2
      72: iconst_0
      73: istore_3
      74: aload_2
      75: astore        4
      77: new           #66                 // class java/util/ArrayList
      80: dup
      81: aload_2
      82: bipush        10
      84: invokestatic  #72                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      87: invokespecial #75                 // Method java/util/ArrayList."<init>":(I)V
      90: checkcast     #77                 // class java/util/Collection
      93: astore        5
      95: iconst_0
      96: istore        6
      98: aload         4
     100: invokeinterface #81,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     105: astore        7
     107: aload         7
     109: invokeinterface #87,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     114: ifeq          161
     117: aload         7
     119: invokeinterface #91,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     124: astore        8
     126: aload         5
     128: aload         8
     130: checkcast     #56                 // class java/lang/String
     133: astore        9
     135: astore        29
     137: iconst_0
     138: istore        10
     140: aload         9
     142: invokestatic  #97                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     145: nop
     146: invokestatic  #101                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     149: aload         29
     151: swap
     152: invokeinterface #105,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     157: pop
     158: goto          107
     161: aload         5
     163: checkcast     #107                // class java/util/List
     166: nop
     167: iconst_1
     168: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     173: checkcast     #113                // class java/lang/Number
     176: invokevirtual #117                // Method java/lang/Number.intValue:()I
     179: istore_2
     180: aload_1
     181: invokevirtual #38                 // Method java/io/BufferedReader.readLine:()Ljava/lang/String;
     184: dup
     185: ldc           #40                 // String readLine(...)
     187: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     190: checkcast     #45                 // class java/lang/CharSequence
     193: invokestatic  #51                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     196: invokevirtual #54                 // Method java/lang/Object.toString:()Ljava/lang/String;
     199: checkcast     #45                 // class java/lang/CharSequence
     202: iconst_1
     203: anewarray     #56                 // class java/lang/String
     206: astore        4
     208: aload         4
     210: iconst_0
     211: ldc           #58                 // String
     213: aastore
     214: aload         4
     216: iconst_0
     217: iconst_0
     218: bipush        6
     220: aconst_null
     221: invokestatic  #62                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     224: checkcast     #64                 // class java/lang/Iterable
     227: astore        4
     229: iconst_0
     230: istore        5
     232: aload         4
     234: astore        6
     236: new           #66                 // class java/util/ArrayList
     239: dup
     240: aload         4
     242: bipush        10
     244: invokestatic  #72                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     247: invokespecial #75                 // Method java/util/ArrayList."<init>":(I)V
     250: checkcast     #77                 // class java/util/Collection
     253: astore        7
     255: iconst_0
     256: istore        8
     258: aload         6
     260: invokeinterface #81,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     265: astore        9
     267: aload         9
     269: invokeinterface #87,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     274: ifeq          321
     277: aload         9
     279: invokeinterface #91,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     284: astore        10
     286: aload         7
     288: aload         10
     290: checkcast     #56                 // class java/lang/String
     293: astore        11
     295: astore        29
     297: iconst_0
     298: istore        12
     300: aload         11
     302: invokestatic  #123                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     305: nop
     306: invokestatic  #126                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     309: aload         29
     311: swap
     312: invokeinterface #105,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     317: pop
     318: goto          267
     321: aload         7
     323: checkcast     #107                // class java/util/List
     326: nop
     327: checkcast     #77                 // class java/util/Collection
     330: astore        4
     332: nop
     333: iconst_0
     334: istore        5
     336: aload         4
     338: astore        6
     340: aload         6
     342: iconst_0
     343: anewarray     #119                // class java/lang/Long
     346: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
     351: checkcast     #132                // class "[Ljava/lang/Long;"
     354: astore_3
     355: new           #134                // class boj/CoffeeShopII
     358: dup
     359: aload_3
     360: invokespecial #137                // Method boj/CoffeeShopII."<init>":([Ljava/lang/Long;)V
     363: astore        4
     365: iconst_0
     366: istore        5
     368: iload         5
     370: iload_2
     371: if_icmpge     696
     374: iload         5
     376: istore        6
     378: iconst_0
     379: istore        7
     381: aload_1
     382: invokevirtual #38                 // Method java/io/BufferedReader.readLine:()Ljava/lang/String;
     385: dup
     386: ldc           #40                 // String readLine(...)
     388: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     391: checkcast     #45                 // class java/lang/CharSequence
     394: invokestatic  #51                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     397: invokevirtual #54                 // Method java/lang/Object.toString:()Ljava/lang/String;
     400: checkcast     #45                 // class java/lang/CharSequence
     403: iconst_1
     404: anewarray     #56                 // class java/lang/String
     407: astore        8
     409: aload         8
     411: iconst_0
     412: ldc           #58                 // String
     414: aastore
     415: aload         8
     417: iconst_0
     418: iconst_0
     419: bipush        6
     421: aconst_null
     422: invokestatic  #62                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     425: checkcast     #64                 // class java/lang/Iterable
     428: astore        8
     430: iconst_0
     431: istore        9
     433: aload         8
     435: astore        10
     437: new           #66                 // class java/util/ArrayList
     440: dup
     441: aload         8
     443: bipush        10
     445: invokestatic  #72                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     448: invokespecial #75                 // Method java/util/ArrayList."<init>":(I)V
     451: checkcast     #77                 // class java/util/Collection
     454: astore        11
     456: iconst_0
     457: istore        12
     459: aload         10
     461: invokeinterface #81,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     466: astore        13
     468: aload         13
     470: invokeinterface #87,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     475: ifeq          522
     478: aload         13
     480: invokeinterface #91,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     485: astore        14
     487: aload         11
     489: aload         14
     491: checkcast     #56                 // class java/lang/String
     494: astore        16
     496: astore        17
     498: iconst_0
     499: istore        18
     501: aload         16
     503: invokestatic  #123                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     506: nop
     507: invokestatic  #126                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     510: aload         17
     512: swap
     513: invokeinterface #105,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     518: pop
     519: goto          468
     522: aload         11
     524: checkcast     #107                // class java/util/List
     527: nop
     528: astore        19
     530: new           #139                // class kotlin/jvm/internal/Ref$LongRef
     533: dup
     534: invokespecial #142                // Method kotlin/jvm/internal/Ref$LongRef."<init>":()V
     537: astore        8
     539: aload         8
     541: aload         19
     543: iconst_0
     544: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     549: checkcast     #113                // class java/lang/Number
     552: invokevirtual #146                // Method java/lang/Number.longValue:()J
     555: putfield      #150                // Field kotlin/jvm/internal/Ref$LongRef.element:J
     558: lconst_0
     559: lstore        30
     561: aload         19
     563: iconst_1
     564: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     569: checkcast     #113                // class java/lang/Number
     572: invokevirtual #146                // Method java/lang/Number.longValue:()J
     575: lstore        30
     577: aload         19
     579: iconst_2
     580: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     585: checkcast     #113                // class java/lang/Number
     588: invokevirtual #146                // Method java/lang/Number.longValue:()J
     591: lstore        20
     593: aload         19
     595: iconst_3
     596: invokeinterface #111,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     601: checkcast     #113                // class java/lang/Number
     604: invokevirtual #146                // Method java/lang/Number.longValue:()J
     607: lstore        22
     609: aload         8
     611: getfield      #150                // Field kotlin/jvm/internal/Ref$LongRef.element:J
     614: lload         30
     616: lcmp
     617: ifle          649
     620: aload         8
     622: lload         30
     624: lstore        14
     626: lload         14
     628: lstore        24
     630: astore        17
     632: iconst_0
     633: istore        26
     635: aload         8
     637: getfield      #150                // Field kotlin/jvm/internal/Ref$LongRef.element:J
     640: lstore        30
     642: aload         17
     644: lload         14
     646: putfield      #150                // Field kotlin/jvm/internal/Ref$LongRef.element:J
     649: aload         4
     651: aload         8
     653: getfield      #150                // Field kotlin/jvm/internal/Ref$LongRef.element:J
     656: lconst_1
     657: lsub
     658: l2i
     659: lload         30
     661: lconst_1
     662: lsub
     663: l2i
     664: invokevirtual #154                // Method boj/CoffeeShopII.sum:(II)J
     667: lstore        27
     669: getstatic     #158                // Field java/lang/System.out:Ljava/io/PrintStream;
     672: lload         27
     674: invokevirtual #164                // Method java/io/PrintStream.println:(J)V
     677: aload         4
     679: lload         20
     681: lconst_1
     682: lsub
     683: l2i
     684: lload         22
     686: invokevirtual #168                // Method boj/CoffeeShopII.update:(IJ)V
     689: nop
     690: iinc          5, 1
     693: goto          368
     696: return
}

Compiled from "CoffeeShopII.kt"
public final class boj.CoffeeShopII {
  private final java.lang.Long[] numbers;

  private final java.lang.Long[] segmentTree;

  public boj.CoffeeShopII(java.lang.Long[]);
    Code:
       0: aload_1
       1: ldc           #9                  // String numbers
       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 numbers:[Ljava/lang/Long;
      15: aload_0
      16: iconst_0
      17: istore_2
      18: aload_0
      19: getfield      #21                 // Field numbers:[Ljava/lang/Long;
      22: arraylength
      23: iconst_4
      24: imul
      25: istore_3
      26: iload_3
      27: anewarray     #23                 // class java/lang/Long
      30: astore        4
      32: astore        6
      34: iload_2
      35: iload_3
      36: if_icmpge     57
      39: iload_2
      40: istore        5
      42: aload         4
      44: iload         5
      46: lconst_0
      47: invokestatic  #27                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      50: aastore
      51: iinc          2, 1
      54: goto          34
      57: aload         6
      59: aload         4
      61: putfield      #30                 // Field segmentTree:[Ljava/lang/Long;
      64: nop
      65: aload_0
      66: iconst_0
      67: aload_0
      68: getfield      #21                 // Field numbers:[Ljava/lang/Long;
      71: arraylength
      72: iconst_1
      73: isub
      74: iconst_0
      75: iconst_4
      76: aconst_null
      77: invokestatic  #34                 // Method initTree$default:(Lboj/CoffeeShopII;IIIILjava/lang/Object;)J
      80: pop2
      81: nop
      82: return

  private final long initTree(int, int, int);
    Code:
       0: iload_1
       1: iload_2
       2: if_icmpne     27
       5: aload_0
       6: getfield      #30                 // Field segmentTree:[Ljava/lang/Long;
       9: iload_3
      10: aload_0
      11: getfield      #21                 // Field numbers:[Ljava/lang/Long;
      14: iload_1
      15: aaload
      16: aastore
      17: aload_0
      18: getfield      #21                 // Field numbers:[Ljava/lang/Long;
      21: iload_1
      22: aaload
      23: invokevirtual #43                 // Method java/lang/Long.longValue:()J
      26: lreturn
      27: iload_1
      28: iload_2
      29: iadd
      30: iconst_2
      31: idiv
      32: istore        4
      34: aload_0
      35: getfield      #30                 // Field segmentTree:[Ljava/lang/Long;
      38: iload_3
      39: aload_0
      40: iload_1
      41: iload         4
      43: iload_3
      44: iconst_2
      45: imul
      46: invokespecial #45                 // Method initTree:(III)J
      49: aload_0
      50: iload         4
      52: iconst_1
      53: iadd
      54: iload_2
      55: iload_3
      56: iconst_2
      57: imul
      58: iconst_1
      59: iadd
      60: invokespecial #45                 // Method initTree:(III)J
      63: ladd
      64: invokestatic  #27                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      67: aastore
      68: aload_0
      69: getfield      #30                 // Field segmentTree:[Ljava/lang/Long;
      72: iload_3
      73: aaload
      74: invokevirtual #43                 // Method java/lang/Long.longValue:()J
      77: lreturn

  static long initTree$default(boj.CoffeeShopII, int, int, int, int, java.lang.Object);
    Code:
       0: iload         4
       2: iconst_4
       3: iand
       4: ifeq          9
       7: iconst_1
       8: istore_3
       9: aload_0
      10: iload_1
      11: iload_2
      12: iload_3
      13: invokespecial #45                 // Method initTree:(III)J
      16: lreturn

  private final void updateTree(int, int, int, long, int);
    Code:
       0: iload_1
       1: iload_3
       2: if_icmpgt     18
       5: iload_3
       6: iload_2
       7: if_icmpgt     14
      10: iconst_1
      11: goto          19
      14: iconst_0
      15: goto          19
      18: iconst_0
      19: ifeq          91
      22: aload_0
      23: getfield      #30                 // Field segmentTree:[Ljava/lang/Long;
      26: astore        7
      28: aload         7
      30: iload         6
      32: aload         7
      34: iload         6
      36: aaload
      37: invokevirtual #43                 // Method java/lang/Long.longValue:()J
      40: lload         4
      42: ladd
      43: invokestatic  #27                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      46: aastore
      47: iload_1
      48: iload_2
      49: if_icmpeq     91
      52: iload_1
      53: iload_2
      54: iadd
      55: iconst_2
      56: idiv
      57: istore        7
      59: aload_0
      60: iload_1
      61: iload         7
      63: iload_3
      64: lload         4
      66: iload         6
      68: iconst_2
      69: imul
      70: invokespecial #54                 // Method updateTree:(IIIJI)V
      73: aload_0
      74: iload         7
      76: iconst_1
      77: iadd
      78: iload_2
      79: iload_3
      80: lload         4
      82: iload         6
      84: iconst_2
      85: imul
      86: iconst_1
      87: iadd
      88: invokespecial #54                 // Method updateTree:(IIIJI)V
      91: return

  static void updateTree$default(boj.CoffeeShopII, int, int, int, long, int, int, java.lang.Object);
    Code:
       0: iload         7
       2: bipush        16
       4: iand
       5: ifeq          11
       8: iconst_1
       9: istore        6
      11: aload_0
      12: iload_1
      13: iload_2
      14: iload_3
      15: lload         4
      17: iload         6
      19: invokespecial #54                 // Method updateTree:(IIIJI)V
      22: return

  public final long sum(int, int);
    Code:
       0: aload_0
       1: iconst_0
       2: aload_0
       3: getfield      #21                 // Field numbers:[Ljava/lang/Long;
       6: arraylength
       7: iconst_1
       8: isub
       9: iload_1
      10: iload_2
      11: iconst_0
      12: bipush        16
      14: aconst_null
      15: invokestatic  #65                 // Method rangeSum$default:(Lboj/CoffeeShopII;IIIIIILjava/lang/Object;)J
      18: lreturn

  private final long rangeSum(int, int, int, int, int);
    Code:
       0: iload         4
       2: iload_1
       3: if_icmplt     11
       6: iload_2
       7: iload_3
       8: if_icmpge     13
      11: lconst_0
      12: lreturn
      13: iload_3
      14: iload_1
      15: if_icmpgt     35
      18: iload_2
      19: iload         4
      21: if_icmpgt     35
      24: aload_0
      25: getfield      #30                 // Field segmentTree:[Ljava/lang/Long;
      28: iload         5
      30: aaload
      31: invokevirtual #43                 // Method java/lang/Long.longValue:()J
      34: lreturn
      35: iload_1
      36: iload_2
      37: iadd
      38: iconst_2
      39: idiv
      40: istore        6
      42: aload_0
      43: iload_1
      44: iload         6
      46: iload_3
      47: iload         4
      49: iload         5
      51: iconst_2
      52: imul
      53: invokespecial #71                 // Method rangeSum:(IIIII)J
      56: aload_0
      57: iload         6
      59: iconst_1
      60: iadd
      61: iload_2
      62: iload_3
      63: iload         4
      65: iload         5
      67: iconst_2
      68: imul
      69: iconst_1
      70: iadd
      71: invokespecial #71                 // Method rangeSum:(IIIII)J
      74: ladd
      75: lreturn

  static long rangeSum$default(boj.CoffeeShopII, int, int, int, int, int, int, java.lang.Object);
    Code:
       0: iload         6
       2: bipush        16
       4: iand
       5: ifeq          11
       8: iconst_1
       9: istore        5
      11: aload_0
      12: iload_1
      13: iload_2
      14: iload_3
      15: iload         4
      17: iload         5
      19: invokespecial #71                 // Method rangeSum:(IIIII)J
      22: lreturn

  public final void update(int, long);
    Code:
       0: aload_0
       1: iload_1
       2: lload_2
       3: invokespecial #77                 // Method getDiff:(IJ)J
       6: lstore        4
       8: aload_0
       9: getfield      #21                 // Field numbers:[Ljava/lang/Long;
      12: iload_1
      13: lload_2
      14: invokestatic  #27                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      17: aastore
      18: aload_0
      19: iconst_0
      20: aload_0
      21: getfield      #21                 // Field numbers:[Ljava/lang/Long;
      24: arraylength
      25: iconst_1
      26: isub
      27: iload_1
      28: lload         4
      30: iconst_0
      31: bipush        16
      33: aconst_null
      34: invokestatic  #79                 // Method updateTree$default:(Lboj/CoffeeShopII;IIIJIILjava/lang/Object;)V
      37: return

  private final long getDiff(int, long);
    Code:
       0: lload_2
       1: aload_0
       2: getfield      #21                 // Field numbers:[Ljava/lang/Long;
       5: iload_1
       6: aaload
       7: invokevirtual #43                 // Method java/lang/Long.longValue:()J
      10: lsub
      11: lreturn
}


package ru.spbstu.kparsec.examples.tip.constraint

import java.util.*

sealed class Node {
    abstract operator fun contains(v: Node): Boolean
}
data class Var(val id: String = dict[currentId].also { ++currentId }) : Node() {
    override fun contains(v: Node): Boolean = v == this

    override fun toString() = id
    companion object {
        val dict = ('a'..'z').map{ it.toString() } + (0..100).map { "t" + it }
        var currentId = 0
    }
}
data class Fun(val name: String, val arguments: List<Node>) : Node() {
    override fun contains(v: Node): Boolean = v == this || arguments.any { it.contains(v) }

    override fun toString() = "$name(${arguments.joinToString()})"
}
data class Equality(val lhv: Node, val rhv: Node) {
    override fun toString() = "$lhv = $rhv"
}

fun collectVariables(n: Node, set: MutableSet<Var>): Unit = when(n) {
    is Var -> set += n
    is Fun -> n.arguments.forEach { collectVariables(it, set) }
}

fun collectVariables(eq: Equality, set: MutableSet<Var>) {
    collectVariables(eq.lhv, set)
    collectVariables(eq.rhv, set)
}

class Solver(input: List<Equality>) {
    data class Exception(val eq: Equality): kotlin.Exception("Unsolvable equation: $eq")

    val que: Queue<Equality> = ArrayDeque(input)
    val subst: MutableMap<Var, Node> = mutableMapOf()

    val Equality.rrhv get() = subst[rhv] ?: rhv
    val Equality.rlhv get() = subst[lhv] ?: lhv

    val unsolvedVariables: MutableSet<Var> = mutableSetOf()

    init {
        input.forEach { collectVariables(it, unsolvedVariables) }
    }

    fun substitute(v: Node): Node = when {
        v is Var && v in subst -> substitute(subst[v]!!)
        else -> v
    }

    fun delete(eq: Equality): Boolean = eq.rlhv != eq.rrhv
    fun decompose(eq: Equality): Boolean {
        val lhv = eq.rlhv
        val rhv = eq.rrhv
        when {
            lhv is Fun && rhv is Fun -> {
                if(lhv.name == rhv.name && lhv.arguments.size == rhv.arguments.size) {
                    lhv.arguments.zip(rhv.arguments) { l, r ->
                        que.add(Equality(substitute(l), substitute(r)))
                    }
                    return false
                } else throw Exception(eq)
            }
            else -> return true
        }
    }
    fun swap(eq: Equality): Boolean {
        val lhv = eq.rlhv
        val rhv = eq.rrhv
        if(rhv is Var && lhv !is Var) {
            que.add(Equality(rhv, lhv))
            return false
        }
        return true
    }
    fun eliminate(eq: Equality): Boolean {
        val lhv = eq.rlhv
        val rhv = eq.rrhv
        if(lhv is Var) {
            if(lhv in rhv) throw Exception(eq)

            unsolvedVariables -= lhv
            subst[lhv] = rhv
            return false
        }
        return true
    }

    fun solve() {
        while(que.isNotEmpty()) {
            val v = que.poll()!!
            when {
                delete(v) && decompose(v) && swap(v) && eliminate(v) -> que.add(v)
            }
        }
    }

    fun expand(witness: Var, n: Node): Node = when(n) {
        witness -> witness
        in unsolvedVariables -> n
        is Var -> expand(witness, substitute(n))
        is Fun -> n.copy(arguments = n.arguments.map { expand(witness, it) })
    }

    fun result(): List<Equality> {
        return subst.entries.map { (k, v) ->
            Equality(k, expand(k, v))
        }
    }

}

Compiled from "Equalities.kt"
public final class ru.spbstu.kparsec.examples.tip.constraint.EqualitiesKt {
  public static final void collectVariables(ru.spbstu.kparsec.examples.tip.constraint.Node, java.util.Set<ru.spbstu.kparsec.examples.tip.constraint.Var>);
    Code:
       0: aload_0
       1: ldc           #10                 // String n
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #18                 // String set
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: astore_2
      14: aload_2
      15: instanceof    #20                 // class ru/spbstu/kparsec/examples/tip/constraint/Var
      18: ifeq          35
      21: aload_1
      22: checkcast     #22                 // class java/util/Collection
      25: aload_0
      26: invokeinterface #26,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      31: pop
      32: goto          115
      35: aload_2
      36: instanceof    #28                 // class ru/spbstu/kparsec/examples/tip/constraint/Fun
      39: ifeq          107
      42: aload_0
      43: checkcast     #28                 // class ru/spbstu/kparsec/examples/tip/constraint/Fun
      46: invokevirtual #32                 // Method ru/spbstu/kparsec/examples/tip/constraint/Fun.getArguments:()Ljava/util/List;
      49: checkcast     #34                 // class java/lang/Iterable
      52: astore_3
      53: iconst_0
      54: istore        4
      56: aload_3
      57: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      62: astore        5
      64: aload         5
      66: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      71: ifeq          103
      74: aload         5
      76: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      81: astore        6
      83: aload         6
      85: checkcast     #50                 // class ru/spbstu/kparsec/examples/tip/constraint/Node
      88: astore        7
      90: iconst_0
      91: istore        8
      93: aload         7
      95: aload_1
      96: invokestatic  #52                 // Method collectVariables:(Lru/spbstu/kparsec/examples/tip/constraint/Node;Ljava/util/Set;)V
      99: nop
     100: goto          64
     103: nop
     104: goto          115
     107: new           #54                 // class kotlin/NoWhenBranchMatchedException
     110: dup
     111: invokespecial #58                 // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     114: athrow
     115: return

  public static final void collectVariables(ru.spbstu.kparsec.examples.tip.constraint.Equality, java.util.Set<ru.spbstu.kparsec.examples.tip.constraint.Var>);
    Code:
       0: aload_0
       1: ldc           #72                 // String eq
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #18                 // String set
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokevirtual #78                 // Method ru/spbstu/kparsec/examples/tip/constraint/Equality.getLhv:()Lru/spbstu/kparsec/examples/tip/constraint/Node;
      16: aload_1
      17: invokestatic  #52                 // Method collectVariables:(Lru/spbstu/kparsec/examples/tip/constraint/Node;Ljava/util/Set;)V
      20: aload_0
      21: invokevirtual #81                 // Method ru/spbstu/kparsec/examples/tip/constraint/Equality.getRhv:()Lru/spbstu/kparsec/examples/tip/constraint/Node;
      24: aload_1
      25: invokestatic  #52                 // Method collectVariables:(Lru/spbstu/kparsec/examples/tip/constraint/Node;Ljava/util/Set;)V
      28: return
}


package com.hi.dhl.algorithms.offer._13.kotlin

import java.util.*

/**
 * <pre>
 *     author: dhl
 *     desc  :
 * </pre>
 */

class Solution {
    fun movingCount(m: Int, n: Int, k: Int): Int {
        val robot = Array(m, { IntArray(n) })
        return dfs(robot, 0, 0, m, n, k)
    }

    fun dfs(robot: Array<IntArray>, x: Int, y: Int, m: Int, n: Int, k: Int): Int {
        if (x > m - 1 || y > n - 1 || robot[x][y] == -1 || count(x) + count(y) > k) {
            return 0
        }
        robot[x][y] = -1
        return dfs(robot, x + 1, y, m, n, k) + dfs(robot, x, y + 1, m, n, k) + 1
    }

    fun bfs(m: Int, n: Int, k: Int): Int {
        val robot = Array(m, { IntArray(n) })
        val queue = LinkedList<IntArray>()
        var res = 0
        queue.offer(intArrayOf(0, 0))
        while (!queue.isEmpty()) {
            val (x, y) = queue.poll()
            if (x > m - 1 || y > n - 1 || robot[x][y] == -1 || count(x) + count(y) > k) {
                continue;
            }
            robot[x][y] = -1
            res += 1
            queue.offer(intArrayOf(x + 1, y))
            queue.offer(intArrayOf(x, y + 1))
        }
        return res
    }

    fun count(x: Int): Int {
        var sx = x
        var count = 0
        while (sx > 0) {
            count += sx % 10
            sx = sx / 10
        }
        return count
    }
}

fun main() {
    val solution = Solution()
    println(solution.bfs(38, 15, 9))
}

Compiled from "Solution.kt"
public final class com.hi.dhl.algorithms.offer._13.kotlin.Solution {
  public com.hi.dhl.algorithms.offer._13.kotlin.Solution();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final int movingCount(int, int, int);
    Code:
       0: iconst_0
       1: istore        5
       3: iload_1
       4: anewarray     #14                 // class "[I"
       7: astore        6
       9: iload         5
      11: iload_1
      12: if_icmpge     33
      15: iload         5
      17: istore        7
      19: aload         6
      21: iload         7
      23: iload_2
      24: newarray       int
      26: aastore
      27: iinc          5, 1
      30: goto          9
      33: aload         6
      35: astore        4
      37: aload_0
      38: aload         4
      40: iconst_0
      41: iconst_0
      42: iload_1
      43: iload_2
      44: iload_3
      45: invokevirtual #18                 // Method dfs:([[IIIIII)I
      48: ireturn

  public final int dfs(int[][], int, int, int, int, int);
    Code:
       0: aload_1
       1: ldc           #27                 // String robot
       3: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_2
       7: iload         4
       9: iconst_1
      10: isub
      11: if_icmpgt     47
      14: iload_3
      15: iload         5
      17: iconst_1
      18: isub
      19: if_icmpgt     47
      22: aload_1
      23: iload_2
      24: aaload
      25: iload_3
      26: iaload
      27: iconst_m1
      28: if_icmpeq     47
      31: aload_0
      32: iload_2
      33: invokevirtual #37                 // Method count:(I)I
      36: aload_0
      37: iload_3
      38: invokevirtual #37                 // Method count:(I)I
      41: iadd
      42: iload         6
      44: if_icmple     49
      47: iconst_0
      48: ireturn
      49: aload_1
      50: iload_2
      51: aaload
      52: iload_3
      53: iconst_m1
      54: iastore
      55: aload_0
      56: aload_1
      57: iload_2
      58: iconst_1
      59: iadd
      60: iload_3
      61: iload         4
      63: iload         5
      65: iload         6
      67: invokevirtual #18                 // Method dfs:([[IIIIII)I
      70: aload_0
      71: aload_1
      72: iload_2
      73: iload_3
      74: iconst_1
      75: iadd
      76: iload         4
      78: iload         5
      80: iload         6
      82: invokevirtual #18                 // Method dfs:([[IIIIII)I
      85: iadd
      86: iconst_1
      87: iadd
      88: ireturn

  public final int bfs(int, int, int);
    Code:
       0: iconst_0
       1: istore        5
       3: iload_1
       4: anewarray     #14                 // class "[I"
       7: astore        6
       9: iload         5
      11: iload_1
      12: if_icmpge     33
      15: iload         5
      17: istore        7
      19: aload         6
      21: iload         7
      23: iload_2
      24: newarray       int
      26: aastore
      27: iinc          5, 1
      30: goto          9
      33: aload         6
      35: astore        4
      37: new           #42                 // class java/util/LinkedList
      40: dup
      41: invokespecial #43                 // Method java/util/LinkedList."<init>":()V
      44: astore        5
      46: iconst_0
      47: istore        6
      49: aload         5
      51: iconst_2
      52: newarray       int
      54: astore        7
      56: aload         7
      58: iconst_0
      59: iconst_0
      60: iastore
      61: aload         7
      63: iconst_1
      64: iconst_0
      65: iastore
      66: aload         7
      68: invokevirtual #47                 // Method java/util/LinkedList.offer:(Ljava/lang/Object;)Z
      71: pop
      72: aload         5
      74: invokevirtual #51                 // Method java/util/LinkedList.isEmpty:()Z
      77: ifne          224
      80: aload         5
      82: invokevirtual #55                 // Method java/util/LinkedList.poll:()Ljava/lang/Object;
      85: checkcast     #14                 // class "[I"
      88: astore        7
      90: aload         7
      92: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      95: aload         7
      97: iconst_0
      98: iaload
      99: istore        8
     101: aload         7
     103: iconst_1
     104: iaload
     105: istore        9
     107: iload         8
     109: iload_1
     110: iconst_1
     111: isub
     112: if_icmpgt     152
     115: iload         9
     117: iload_2
     118: iconst_1
     119: isub
     120: if_icmpgt     152
     123: aload         4
     125: iload         8
     127: aaload
     128: iload         9
     130: iaload
     131: iconst_m1
     132: if_icmpeq     152
     135: aload_0
     136: iload         8
     138: invokevirtual #37                 // Method count:(I)I
     141: aload_0
     142: iload         9
     144: invokevirtual #37                 // Method count:(I)I
     147: iadd
     148: iload_3
     149: if_icmple     155
     152: goto          72
     155: aload         4
     157: iload         8
     159: aaload
     160: iload         9
     162: iconst_m1
     163: iastore
     164: iinc          6, 1
     167: aload         5
     169: iconst_2
     170: newarray       int
     172: astore        10
     174: aload         10
     176: iconst_0
     177: iload         8
     179: iconst_1
     180: iadd
     181: iastore
     182: aload         10
     184: iconst_1
     185: iload         9
     187: iastore
     188: aload         10
     190: invokevirtual #47                 // Method java/util/LinkedList.offer:(Ljava/lang/Object;)Z
     193: pop
     194: aload         5
     196: iconst_2
     197: newarray       int
     199: astore        10
     201: aload         10
     203: iconst_0
     204: iload         8
     206: iastore
     207: aload         10
     209: iconst_1
     210: iload         9
     212: iconst_1
     213: iadd
     214: iastore
     215: aload         10
     217: invokevirtual #47                 // Method java/util/LinkedList.offer:(Ljava/lang/Object;)Z
     220: pop
     221: goto          72
     224: iload         6
     226: ireturn

  public final int count(int);
    Code:
       0: iload_1
       1: istore_2
       2: iconst_0
       3: istore_3
       4: iload_2
       5: ifle          23
       8: iload_3
       9: iload_2
      10: bipush        10
      12: irem
      13: iadd
      14: istore_3
      15: iload_2
      16: bipush        10
      18: idiv
      19: istore_2
      20: goto          4
      23: iload_3
      24: ireturn
}

Compiled from "Solution.kt"
public final class com.hi.dhl.algorithms.offer._13.kotlin.SolutionKt {
  public static final void main();
    Code:
       0: new           #8                  // class com/hi/dhl/algorithms/offer/_13/kotlin/Solution
       3: dup
       4: invokespecial #11                 // Method com/hi/dhl/algorithms/offer/_13/kotlin/Solution."<init>":()V
       7: astore_0
       8: aload_0
       9: bipush        38
      11: bipush        15
      13: bipush        9
      15: invokevirtual #15                 // Method com/hi/dhl/algorithms/offer/_13/kotlin/Solution.bfs:(III)I
      18: istore_1
      19: getstatic     #21                 // Field java/lang/System.out:Ljava/io/PrintStream;
      22: iload_1
      23: invokevirtual #27                 // Method java/io/PrintStream.println:(I)V
      26: return

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


package com.hi.dhl.algorithms.offer._17.kotlin

/**
 * <pre>
 *     author: dhl
 *     date  : 2020/8/5
 *     desc  :
 * </pre>
 */

class Solution {

    // 方法一
    fun printNumbers2(n: Int): IntArray {
        var max = 1;
        for (i in 1..n) {
            max = max * 10;
        }
        val result = IntArray(max - 1)
        for (i in 1 until max) {
            result[i - 1] = i
        }
        return result;
    }

    // 方法二
    val defNum = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
    var index = 0;

    fun printNumbers(n: Int): IntArray {
        val num = CharArray(n)
        var max = 1
        // kotlin 中使用 Math.pow 要求参数都是double类型，所以这里自动生成对应的位数
        for (i in 1..n) {
            max = max * 10;
        }
        val result = IntArray(max - 1)
        dfs(num, result, 0) // 开始递归遍历
        return result;
    }

    fun dfs(num: CharArray, result: IntArray, x: Int) {
        if (x == num.size) {
            // 生成的数字前面可能有 0 例如：000,001,002... 等等
            // parstInt 方法去删除高位多余的 0
            val res = parstInt(num);
            // 过滤掉第一个数字 0
            if (res > 0) {
                result[index] = res
                index = index + 1
            }
            return;
        }

        for (c in defNum) {
            num[x] = c
            dfs(num, result, x + 1)
        }
    }

    fun parstInt(num: CharArray): Int {
        var sum = 0
        var isNotZero = false
        for (c in num) {
            // 生成的数字前面可能有 0 例如：000,001,002... 等等
            // 过滤掉高位多余的 0
            if (!isNotZero) {
                if (c == '0') {
                    continue
                } else {
                    isNotZero = true
                }
            }
            sum = sum * 10 + (c - '0')
        }
        return sum;
    }
}

Compiled from "Solution.kt"
public final class com.hi.dhl.algorithms.offer._17.kotlin.Solution {
  private final char[] defNum;

  private int index;

  public com.hi.dhl.algorithms.offer._17.kotlin.Solution();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: bipush        10
       7: newarray       char
       9: astore_1
      10: aload_1
      11: iconst_0
      12: bipush        48
      14: castore
      15: aload_1
      16: iconst_1
      17: bipush        49
      19: castore
      20: aload_1
      21: iconst_2
      22: bipush        50
      24: castore
      25: aload_1
      26: iconst_3
      27: bipush        51
      29: castore
      30: aload_1
      31: iconst_4
      32: bipush        52
      34: castore
      35: aload_1
      36: iconst_5
      37: bipush        53
      39: castore
      40: aload_1
      41: bipush        6
      43: bipush        54
      45: castore
      46: aload_1
      47: bipush        7
      49: bipush        55
      51: castore
      52: aload_1
      53: bipush        8
      55: bipush        56
      57: castore
      58: aload_1
      59: bipush        9
      61: bipush        57
      63: castore
      64: aload_1
      65: putfield      #12                 // Field defNum:[C
      68: return

  public final int[] printNumbers2(int);
    Code:
       0: iconst_1
       1: istore_2
       2: iconst_1
       3: istore_3
       4: iload_3
       5: iload_1
       6: if_icmpgt     25
       9: iload_2
      10: bipush        10
      12: imul
      13: istore_2
      14: iload_3
      15: iload_1
      16: if_icmpeq     25
      19: iinc          3, 1
      22: goto          9
      25: iload_2
      26: iconst_1
      27: isub
      28: newarray       int
      30: astore_3
      31: iconst_1
      32: istore        4
      34: iload_2
      35: istore        5
      37: iload         4
      39: iload         5
      41: if_icmpge     58
      44: aload_3
      45: iload         4
      47: iconst_1
      48: isub
      49: iload         4
      51: iastore
      52: iinc          4, 1
      55: goto          37
      58: aload_3
      59: areturn

  public final char[] getDefNum();
    Code:
       0: aload_0
       1: getfield      #12                 // Field defNum:[C
       4: areturn

  public final int getIndex();
    Code:
       0: aload_0
       1: getfield      #31                 // Field index:I
       4: ireturn

  public final void setIndex(int);
    Code:
       0: aload_0
       1: iload_1
       2: putfield      #31                 // Field index:I
       5: return

  public final int[] printNumbers(int);
    Code:
       0: iload_1
       1: newarray       char
       3: astore_2
       4: iconst_1
       5: istore_3
       6: iconst_1
       7: istore        4
       9: iload         4
      11: iload_1
      12: if_icmpgt     32
      15: iload_3
      16: bipush        10
      18: imul
      19: istore_3
      20: iload         4
      22: iload_1
      23: if_icmpeq     32
      26: iinc          4, 1
      29: goto          15
      32: iload_3
      33: iconst_1
      34: isub
      35: newarray       int
      37: astore        4
      39: aload_0
      40: aload_2
      41: aload         4
      43: iconst_0
      44: invokevirtual #39                 // Method dfs:([C[II)V
      47: aload         4
      49: areturn

  public final void dfs(char[], int[], int);
    Code:
       0: aload_1
       1: ldc           #42                 // String num
       3: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #49                 // String result
       9: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: iload_3
      13: aload_1
      14: arraylength
      15: if_icmpne     49
      18: aload_0
      19: aload_1
      20: invokevirtual #53                 // Method parstInt:([C)I
      23: istore        4
      25: iload         4
      27: ifle          48
      30: aload_2
      31: aload_0
      32: getfield      #31                 // Field index:I
      35: iload         4
      37: iastore
      38: aload_0
      39: aload_0
      40: getfield      #31                 // Field index:I
      43: iconst_1
      44: iadd
      45: putfield      #31                 // Field index:I
      48: return
      49: aload_0
      50: getfield      #12                 // Field defNum:[C
      53: astore        4
      55: iconst_0
      56: istore        5
      58: aload         4
      60: arraylength
      61: istore        6
      63: iload         5
      65: iload         6
      67: if_icmpge     97
      70: aload         4
      72: iload         5
      74: caload
      75: istore        7
      77: aload_1
      78: iload_3
      79: iload         7
      81: castore
      82: aload_0
      83: aload_1
      84: aload_2
      85: iload_3
      86: iconst_1
      87: iadd
      88: invokevirtual #39                 // Method dfs:([C[II)V
      91: iinc          5, 1
      94: goto          63
      97: return

  public final int parstInt(char[]);
    Code:
       0: aload_1
       1: ldc           #42                 // String num
       3: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_2
       8: iconst_0
       9: istore_3
      10: iconst_0
      11: istore        4
      13: aload_1
      14: arraylength
      15: istore        5
      17: iload         4
      19: iload         5
      21: if_icmpge     63
      24: aload_1
      25: iload         4
      27: caload
      28: istore        6
      30: iload_3
      31: ifne          46
      34: iload         6
      36: bipush        48
      38: if_icmpne     44
      41: goto          57
      44: iconst_1
      45: istore_3
      46: iload_2
      47: bipush        10
      49: imul
      50: iload         6
      52: bipush        48
      54: isub
      55: iadd
      56: istore_2
      57: iinc          4, 1
      60: goto          17
      63: iload_2
      64: ireturn
}


package ch.petikoch.examples.tictactoe_fp

import ch.petikoch.examples.tictactoe_fp.Field.*

fun main() {
    var gameState = GameState()                 // "store"
    while (gameState.winner == null && !gameState.board.values.any { it == null }) {
        println(gameState)                      // "view"
        val textInput = readLine()
        val field = convertTextInput(textInput) // "action"
        gameState = play(gameState, field)      // "reduce"
    }
    println(gameState)
}

private fun convertTextInput(textInput: String?): Field {
    return Field.values().find { it.name == textInput }!!
}

fun play(gameState: GameState, field: Field): GameState {
    val newBoard = gameState.board.plus(field to gameState.currentPlayer)
    return GameState(
            currentPlayer = gameState.currentPlayer.other(),
            board = newBoard,
            winner = findWinner(newBoard)
    )
}

private fun findWinner(newBoard: Map<Field, Player?>): Player? {
    return winningConditions.firstOrNull { areSame(newBoard, it) }?.let { newBoard[it.first] }
}

private val winningConditions: List<Triple<Field, Field, Field>> = listOf(
        Triple(TL, TM, TR),
        Triple(ML, MM, MR)
        // ...
)

private fun areSame(board: Map<Field, Player?>,
                    triple: Triple<Field, Field, Field>): Boolean {
    return board[triple.first] == board[triple.second] &&
            board[triple.first] == board[triple.third]
}

data class GameState(
        val currentPlayer: Player = Player.X,
        val board: Map<Field, Player?> = mapOf(),
        val winner: Player? = null
)

enum class Player {
    X, O;

    fun other(): Player = if (this == X) O else X
}

enum class Field {
    TL, TM, TR,
    ML, MM, MR,
    BL, BM, BR
}

Compiled from "TicTacToe.kt"
public final class ch.petikoch.examples.tictactoe_fp.TicTacToeKt {
  private static final java.util.List<kotlin.Triple<ch.petikoch.examples.tictactoe_fp.Field, ch.petikoch.examples.tictactoe_fp.Field, ch.petikoch.examples.tictactoe_fp.Field>> winningConditions;

  public static final void main();
    Code:
       0: new           #8                  // class ch/petikoch/examples/tictactoe_fp/GameState
       3: dup
       4: aconst_null
       5: aconst_null
       6: aconst_null
       7: bipush        7
       9: aconst_null
      10: invokespecial #12                 // Method ch/petikoch/examples/tictactoe_fp/GameState."<init>":(Lch/petikoch/examples/tictactoe_fp/Player;Ljava/util/Map;Lch/petikoch/examples/tictactoe_fp/Player;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      13: astore_0
      14: aload_0
      15: invokevirtual #16                 // Method ch/petikoch/examples/tictactoe_fp/GameState.getWinner:()Lch/petikoch/examples/tictactoe_fp/Player;
      18: ifnonnull     139
      21: aload_0
      22: invokevirtual #20                 // Method ch/petikoch/examples/tictactoe_fp/GameState.getBoard:()Ljava/util/Map;
      25: invokeinterface #26,  1           // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
      30: checkcast     #28                 // class java/lang/Iterable
      33: astore_1
      34: iconst_0
      35: istore_2
      36: aload_1
      37: instanceof    #30                 // class java/util/Collection
      40: ifeq          59
      43: aload_1
      44: checkcast     #30                 // class java/util/Collection
      47: invokeinterface #34,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      52: ifeq          59
      55: iconst_0
      56: goto          111
      59: aload_1
      60: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      65: astore_3
      66: aload_3
      67: invokeinterface #43,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      72: ifeq          110
      75: aload_3
      76: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      81: astore        4
      83: aload         4
      85: checkcast     #49                 // class ch/petikoch/examples/tictactoe_fp/Player
      88: astore        5
      90: iconst_0
      91: istore        6
      93: aload         5
      95: ifnonnull     102
      98: iconst_1
      99: goto          103
     102: iconst_0
     103: ifeq          66
     106: iconst_1
     107: goto          111
     110: iconst_0
     111: ifne          139
     114: getstatic     #55                 // Field java/lang/System.out:Ljava/io/PrintStream;
     117: aload_0
     118: invokevirtual #61                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     121: invokestatic  #67                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
     124: astore_1
     125: aload_1
     126: invokestatic  #71                 // Method convertTextInput:(Ljava/lang/String;)Lch/petikoch/examples/tictactoe_fp/Field;
     129: astore_2
     130: aload_0
     131: aload_2
     132: invokestatic  #75                 // Method play:(Lch/petikoch/examples/tictactoe_fp/GameState;Lch/petikoch/examples/tictactoe_fp/Field;)Lch/petikoch/examples/tictactoe_fp/GameState;
     135: astore_0
     136: goto          14
     139: getstatic     #55                 // Field java/lang/System.out:Ljava/io/PrintStream;
     142: aload_0
     143: invokevirtual #61                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     146: return

  private static final ch.petikoch.examples.tictactoe_fp.Field convertTextInput(java.lang.String);
    Code:
       0: invokestatic  #95                 // Method ch/petikoch/examples/tictactoe_fp/Field.values:()[Lch/petikoch/examples/tictactoe_fp/Field;
       3: astore_1
       4: iconst_0
       5: istore_2
       6: aload_1
       7: arraylength
       8: istore_3
       9: iload_2
      10: iload_3
      11: if_icmpge     49
      14: aload_1
      15: iload_2
      16: aaload
      17: astore        4
      19: aload         4
      21: astore        5
      23: iconst_0
      24: istore        6
      26: aload         5
      28: invokevirtual #98                 // Method ch/petikoch/examples/tictactoe_fp/Field.name:()Ljava/lang/String;
      31: aload_0
      32: invokestatic  #104                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      35: ifeq          43
      38: aload         4
      40: goto          50
      43: iinc          2, 1
      46: goto          9
      49: aconst_null
      50: dup
      51: invokestatic  #107                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      54: areturn

  public static final ch.petikoch.examples.tictactoe_fp.GameState play(ch.petikoch.examples.tictactoe_fp.GameState, ch.petikoch.examples.tictactoe_fp.Field);
    Code:
       0: aload_0
       1: ldc           #112                // String gameState
       3: invokestatic  #116                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #117                // String field
       9: invokestatic  #116                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokevirtual #20                 // Method ch/petikoch/examples/tictactoe_fp/GameState.getBoard:()Ljava/util/Map;
      16: aload_1
      17: aload_0
      18: invokevirtual #120                // Method ch/petikoch/examples/tictactoe_fp/GameState.getCurrentPlayer:()Lch/petikoch/examples/tictactoe_fp/Player;
      21: invokestatic  #126                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      24: invokestatic  #132                // Method kotlin/collections/MapsKt.plus:(Ljava/util/Map;Lkotlin/Pair;)Ljava/util/Map;
      27: astore_2
      28: new           #8                  // class ch/petikoch/examples/tictactoe_fp/GameState
      31: dup
      32: aload_0
      33: invokevirtual #120                // Method ch/petikoch/examples/tictactoe_fp/GameState.getCurrentPlayer:()Lch/petikoch/examples/tictactoe_fp/Player;
      36: invokevirtual #135                // Method ch/petikoch/examples/tictactoe_fp/Player.other:()Lch/petikoch/examples/tictactoe_fp/Player;
      39: aload_2
      40: aload_2
      41: invokestatic  #139                // Method findWinner:(Ljava/util/Map;)Lch/petikoch/examples/tictactoe_fp/Player;
      44: invokespecial #142                // Method ch/petikoch/examples/tictactoe_fp/GameState."<init>":(Lch/petikoch/examples/tictactoe_fp/Player;Ljava/util/Map;Lch/petikoch/examples/tictactoe_fp/Player;)V
      47: areturn

  private static final ch.petikoch.examples.tictactoe_fp.Player findWinner(java.util.Map<ch.petikoch.examples.tictactoe_fp.Field, ? extends ch.petikoch.examples.tictactoe_fp.Player>);
    Code:
       0: getstatic     #149                // Field winningConditions:Ljava/util/List;
       3: checkcast     #28                 // class java/lang/Iterable
       6: astore_1
       7: iconst_0
       8: istore_2
       9: aload_1
      10: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      15: astore_3
      16: aload_3
      17: invokeinterface #43,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      22: ifeq          57
      25: aload_3
      26: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      31: astore        4
      33: aload         4
      35: checkcast     #151                // class kotlin/Triple
      38: astore        5
      40: iconst_0
      41: istore        6
      43: aload_0
      44: aload         5
      46: invokestatic  #155                // Method areSame:(Ljava/util/Map;Lkotlin/Triple;)Z
      49: ifeq          16
      52: aload         4
      54: goto          58
      57: aconst_null
      58: checkcast     #151                // class kotlin/Triple
      61: dup
      62: ifnull        84
      65: astore_2
      66: iconst_0
      67: istore_3
      68: aload_0
      69: aload_2
      70: invokevirtual #158                // Method kotlin/Triple.getFirst:()Ljava/lang/Object;
      73: invokeinterface #162,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      78: checkcast     #49                 // class ch/petikoch/examples/tictactoe_fp/Player
      81: goto          86
      84: pop
      85: aconst_null
      86: areturn

  private static final boolean areSame(java.util.Map<ch.petikoch.examples.tictactoe_fp.Field, ? extends ch.petikoch.examples.tictactoe_fp.Player>, kotlin.Triple<? extends ch.petikoch.examples.tictactoe_fp.Field, ? extends ch.petikoch.examples.tictactoe_fp.Field, ? extends ch.petikoch.examples.tictactoe_fp.Field>);
    Code:
       0: aload_0
       1: aload_1
       2: invokevirtual #158                // Method kotlin/Triple.getFirst:()Ljava/lang/Object;
       5: invokeinterface #162,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      10: aload_0
      11: aload_1
      12: invokevirtual #171                // Method kotlin/Triple.getSecond:()Ljava/lang/Object;
      15: invokeinterface #162,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      20: if_acmpne     50
      23: aload_0
      24: aload_1
      25: invokevirtual #158                // Method kotlin/Triple.getFirst:()Ljava/lang/Object;
      28: invokeinterface #162,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      33: aload_0
      34: aload_1
      35: invokevirtual #174                // Method kotlin/Triple.getThird:()Ljava/lang/Object;
      38: invokeinterface #162,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      43: if_acmpne     50
      46: iconst_1
      47: goto          51
      50: iconst_0
      51: ireturn

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

  static {};
    Code:
       0: iconst_2
       1: anewarray     #151                // class kotlin/Triple
       4: astore_0
       5: aload_0
       6: iconst_0
       7: new           #151                // class kotlin/Triple
      10: dup
      11: getstatic     #185                // Field ch/petikoch/examples/tictactoe_fp/Field.TL:Lch/petikoch/examples/tictactoe_fp/Field;
      14: getstatic     #188                // Field ch/petikoch/examples/tictactoe_fp/Field.TM:Lch/petikoch/examples/tictactoe_fp/Field;
      17: getstatic     #191                // Field ch/petikoch/examples/tictactoe_fp/Field.TR:Lch/petikoch/examples/tictactoe_fp/Field;
      20: invokespecial #194                // Method kotlin/Triple."<init>":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
      23: aastore
      24: aload_0
      25: iconst_1
      26: new           #151                // class kotlin/Triple
      29: dup
      30: getstatic     #197                // Field ch/petikoch/examples/tictactoe_fp/Field.ML:Lch/petikoch/examples/tictactoe_fp/Field;
      33: getstatic     #200                // Field ch/petikoch/examples/tictactoe_fp/Field.MM:Lch/petikoch/examples/tictactoe_fp/Field;
      36: getstatic     #203                // Field ch/petikoch/examples/tictactoe_fp/Field.MR:Lch/petikoch/examples/tictactoe_fp/Field;
      39: invokespecial #194                // Method kotlin/Triple."<init>":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
      42: aastore
      43: aload_0
      44: invokestatic  #209                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      47: putstatic     #149                // Field winningConditions:Ljava/util/List;
      50: return
}


package com.codesample.algo

abstract class Union<T>() {
    /** Make two elements point to same union */
    abstract fun union(fst: T, snd: T)

    /** Return true if two elements are connected or false otherwise. Same elements are always considered connected */
    abstract fun connected(fst: T, snd: T): Boolean
}

fun Union<Int>.printConnected(fst: Int, snd: Int) {
    if (this.connected(fst, snd))
        println("'$fst' and '$snd' are connected") else
        println("'$fst' and '$snd' are NOT connected")
}

/** Union with fast 'connected' operation O(1) and slow 'union' O(n)
 *
 * The entries are connected if and only if they have the same index.
 * Implementation is NOT thread-safe!*/
class QuickFindUnion<T> : Union<T>() {

    /** Next created union index. Incremented each time a new element in added to this union in 'connected' call */
    private var nextUnionIndex = 0

    /** Map element to index of union */
    private val elements: MutableMap<T, Int> = mutableMapOf()

    override fun union(fst: T, snd: T) {

        // Maybe insert new element and return if two elements are the same
        if (fst == snd) {
            oldIndexOrInsertAndIndex(fst)
            return
        }

        val fstIndex = oldIndexOrInsertAndIndex(fst)
        val sndIndex = oldIndexOrInsertAndIndex(snd)

        if (fstIndex == sndIndex) return // both are already in the union
        else {
            // Element in union with index 'fstIndex' will now be in secondIndex. Other elements are not changed
            for (elem in elements) {
                if (elem.value == fstIndex) {
                    elements[elem.key] = sndIndex
                }
            }
        }
    }

    override fun connected(fst: T, snd: T): Boolean {
        // Assume same element in always connected to itself
        if (fst == snd) return true

        val fstIndex = oldIndexOrNull(fst)
        val sndIndex = oldIndexOrNull(snd)
        return fstIndex != null && sndIndex != null && fstIndex == sndIndex
    }

    private fun exist(elem: T) = elements.containsKey(elem)

    /** Get set index of element OR insert element in brand new union */
    private fun oldIndexOrInsertAndIndex(elem: T): Int {
        return if (exist(elem)) elements.getValue(elem)
        else {
            val curIndex = nextUnionIndex
            elements[elem] = curIndex
            nextUnionIndex++
            curIndex
        }
    }

    private fun oldIndexOrNull(elem: T): Int? = elements[elem]
}

//
//
//
//   Quick Union Union!
//
//

/** Union with fast 'union' operation O(1) and 'slow' 'connected' operation O(n) in worst case,
 * but can be optimized to O(log(n)) [QuickUnionUnionOptimized].
 * The idea is to add elements as children on union operation which will create long-long trees */
class QuickUnionUnion<T> : Union<T>() {

    /** Each element may or may not have a parent. If no parent available -> it's a root of tree */
    private val elementToParent: MutableMap<T, T?> = mutableMapOf()

    override fun union(fst: T, snd: T) {
        insertIfNotExist(fst)
        insertIfNotExist(snd)

        elementToParent[root(fst)] = root(snd)
    }

    override fun connected(fst: T, snd: T): Boolean = root(fst) == root(snd)

    // Can do like this but harder to read
    // private fun insertIfNotExist(elem: T) = elementToParent.computeIfAbsent(elem) { null }
    private fun insertIfNotExist(elem: T) {
        if (!elementToParent.containsKey(elem)) {
            elementToParent[elem] = null
        }
    }

    private fun root(elem: T): T {
        var prev = elem
        var current = elementToParent[prev]

        while (current != null) {
            prev = current
            current = elementToParent[prev]
        }

        return prev
    }

}

//
//
//   Quick Union Union Optimized!
//
//

/** Union with fast 'union' operation O(1) and 'slow' 'connected' operation O(log(n)).
 *
 * There are 2 optimizations:
 * 1. When joining 2 trees -> put smaller one to a root of a larger one (do not let large tree grow further)
 * 2. When finding a root of tree -> rebind all children closer to root */
class QuickUnionUnionOptimized<T> : Union<T>() {

    /** Each element may or may not have a parent. If no parent available -> it's a root of tree */
    private val elementToParent: MutableMap<T, T?> = mutableMapOf()

    override fun union(fst: T, snd: T) {
        insertIfNotExist(fst)
        insertIfNotExist(snd)

        // OPTIMIZATION 1 HERE!
        // Pick smaller of two trees when linking unions
        val rootFst = root(fst)
        val rootSnd = root(snd)
        if (rootFst.size < rootSnd.size) {
            elementToParent[rootFst.root] = rootSnd.root
        } else {
            elementToParent[rootSnd.root] = rootFst.root
        }
    }

    override fun connected(fst: T, snd: T): Boolean = root(fst).root == root(snd).root

    // Can do comment below but seems harder to read
    // private fun insertIfNotExist(elem: T) = elementToParent.computeIfAbsent(elem) { null }
    private fun insertIfNotExist(elem: T) {
        if (!elementToParent.containsKey(elem)) {
            elementToParent[elem] = null
        }
    }

    data class RootAndLength<T>(val root: T, val size: Int)
    private fun root(elem: T): RootAndLength<T> {

        var size = 0
        var prev = elem
        var current = elementToParent[prev]

        while (current != null) {
            val oldPrev = prev
            prev = current
            current = elementToParent[prev]
            size++

            // OPTIMIZATION 2 HERE!
            // Shrink tree on each iteration by rebinding the farthest element 1 step closer to root
            elementToParent[oldPrev] = prev
        }
        return RootAndLength(prev, size)
    }

}

//
//
// main() for testing
//
//

fun main() {

    // pick one of 3 implementations

//    val quickFindUnion = QuickFindUnion<Int>()
//    val quickFindUnion = QuickUnionUnion<Int>()
    val quickFindUnion = QuickUnionUnionOptimized<Int>()

    with(quickFindUnion) {
        union(1, 2)
        union(6, 5)
        union(2, 5)
        union(3, 7)

        this.printConnected(1, 2) // true
        this.printConnected(2, 5) // true
        this.printConnected(5, 6) // true
        this.printConnected(0, 5) // false
        this.printConnected(6, 2) // true
        this.printConnected(7, 3) // true
        this.printConnected(0, 0) // true
        this.printConnected(0, 4) // false
    }
}

Compiled from "unions.kt"
public final class com.codesample.algo.UnionsKt {
  public static final void printConnected(com.codesample.algo.Union<java.lang.Integer>, int, int);
    Code:
       0: aload_0
       1: ldc           #10                 // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iload_1
       8: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      11: iload_2
      12: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      15: invokevirtual #28                 // Method com/codesample/algo/Union.connected:(Ljava/lang/Object;Ljava/lang/Object;)Z
      18: ifeq          64
      21: new           #30                 // class java/lang/StringBuilder
      24: dup
      25: invokespecial #34                 // Method java/lang/StringBuilder."<init>":()V
      28: bipush        39
      30: invokevirtual #38                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      33: iload_1
      34: invokevirtual #41                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      37: ldc           #43                 // String \' and \'
      39: invokevirtual #46                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      42: iload_2
      43: invokevirtual #41                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      46: ldc           #48                 // String \' are connected
      48: invokevirtual #46                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      51: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      54: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
      57: swap
      58: invokevirtual #64                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      61: goto          104
      64: new           #30                 // class java/lang/StringBuilder
      67: dup
      68: invokespecial #34                 // Method java/lang/StringBuilder."<init>":()V
      71: bipush        39
      73: invokevirtual #38                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      76: iload_1
      77: invokevirtual #41                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      80: ldc           #43                 // String \' and \'
      82: invokevirtual #46                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      85: iload_2
      86: invokevirtual #41                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      89: ldc           #66                 // String \' are NOT connected
      91: invokevirtual #46                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      94: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      97: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
     100: swap
     101: invokevirtual #64                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     104: return

  public static final void main();
    Code:
       0: new           #74                 // class com/codesample/algo/QuickUnionUnionOptimized
       3: dup
       4: invokespecial #75                 // Method com/codesample/algo/QuickUnionUnionOptimized."<init>":()V
       7: astore_0
       8: aload_0
       9: astore_1
      10: iconst_0
      11: istore_2
      12: aload_1
      13: iconst_1
      14: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      17: iconst_2
      18: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      21: invokevirtual #79                 // Method com/codesample/algo/QuickUnionUnionOptimized.union:(Ljava/lang/Object;Ljava/lang/Object;)V
      24: aload_1
      25: bipush        6
      27: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      30: iconst_5
      31: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      34: invokevirtual #79                 // Method com/codesample/algo/QuickUnionUnionOptimized.union:(Ljava/lang/Object;Ljava/lang/Object;)V
      37: aload_1
      38: iconst_2
      39: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      42: iconst_5
      43: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      46: invokevirtual #79                 // Method com/codesample/algo/QuickUnionUnionOptimized.union:(Ljava/lang/Object;Ljava/lang/Object;)V
      49: aload_1
      50: iconst_3
      51: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      54: bipush        7
      56: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      59: invokevirtual #79                 // Method com/codesample/algo/QuickUnionUnionOptimized.union:(Ljava/lang/Object;Ljava/lang/Object;)V
      62: aload_1
      63: checkcast     #24                 // class com/codesample/algo/Union
      66: iconst_1
      67: iconst_2
      68: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
      71: aload_1
      72: checkcast     #24                 // class com/codesample/algo/Union
      75: iconst_2
      76: iconst_5
      77: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
      80: aload_1
      81: checkcast     #24                 // class com/codesample/algo/Union
      84: iconst_5
      85: bipush        6
      87: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
      90: aload_1
      91: checkcast     #24                 // class com/codesample/algo/Union
      94: iconst_0
      95: iconst_5
      96: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
      99: aload_1
     100: checkcast     #24                 // class com/codesample/algo/Union
     103: bipush        6
     105: iconst_2
     106: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
     109: aload_1
     110: checkcast     #24                 // class com/codesample/algo/Union
     113: bipush        7
     115: iconst_3
     116: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
     119: aload_1
     120: checkcast     #24                 // class com/codesample/algo/Union
     123: iconst_0
     124: iconst_0
     125: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
     128: aload_1
     129: checkcast     #24                 // class com/codesample/algo/Union
     132: iconst_0
     133: iconst_4
     134: invokestatic  #81                 // Method printConnected:(Lcom/codesample/algo/Union;II)V
     137: nop
     138: nop
     139: return

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