package com.parsuomash.affogato.core.ktx.collections

/**
 * Returns a [HashMap] containing all elements.
 *
 * Example:
 * ```Kotlin
 * mapOf(1 to 2, 2 to 3).toHashMap() // {1=2, 2=3}
 * ```
 * @since 1.1.0
 */
inline fun <reified K, V> Map<K, V>.toHashMap(): HashMap<K, V> = HashMap(this)

/**
 * Returns a [LinkedHashMap] containing all elements.
 *
 * Example:
 * ```Kotlin
 * mapOf(1 to 2, 2 to 3).toLinkedMap() // {1=2, 2=3}
 * ```
 * @since 1.1.0
 */
inline fun <reified K, V> Map<K, V>.toLinkedMap(): LinkedHashMap<K, V> = LinkedHashMap(this)

/**
 * Returns a map of all elements sorted by value.
 *
 * Example:
 * ```Kotlin
 * mapOf(5 to 1, 10 to 10, 1 to 0).sortedByValue() // {1:0, 5:1, 10:10}
 * mapOf("11" to 1, "1" to 10, "a" to 0).sortedByValue() // {"1":10, "11":1, "a":0}
 * ```
 * @since 1.1.0
 */
inline fun <reified K, V> Map<K, V>.sortedByValue(): Map<K, V> =
  toList().sortedBy { it.second.hashCode() }.toMap()

/**
 * Returns a map of all elements sorted by dec value.
 *
 * Example:
 * ```Kotlin
 * mapOf(5 to 1, 10 to 10, 1 to 0).sortedByValueDescending() // {10:10, 5:1, 1:0}
 * mapOf("11" to 1, "1" to 10, "a" to 0).sortedByValueDescending() // {"a":0, "11":1, "1":10}
 * ```
 * @since 1.1.0
 */
inline fun <reified K, V> Map<K, V>.sortedByValueDescending(): Map<K, V> =
  toList().sortedByDescending { it.second.hashCode() }.toMap()

/**
 * Returns a map of all elements sorted by key.
 *
 * Example:
 * ```Kotlin
 * mapOf(1 to 0, 5 to 1, 10 to 10, 7 to 0).sortedByKey()
 * // {1:0, 7:0, 5:1, 10:10}
 * mapOf(1 to "a", 2 to "0", 3 to "11", 4 to "01", 5 to "1").sortedByKey()
 * // {2:"0", 4:"01", 5:"1", 3:"11", 1:"a"}
 * ```
 * @since 1.1.0
 */
inline fun <reified K, V> Map<K, V>.sortedByKey(): Map<K, V> =
  toList().sortedBy { it.first.hashCode() }.toMap()

/**
 * Returns a map of all elements sorted by dec key.
 *
 * Example:
 * ```Kotlin
 * mapOf(1 to 0, 5 to 1, 10 to 10, 7 to 0).sortedByKeyDescending()
 * // {10:10, 5:1, 1:0, 7:0}
 * mapOf(2 to "0", 3 to "11", 4 to "01", 5 to "1").sortedByKeyDescending()
 * // {3:"11", 5:"1", 4:"01", 2:"0"}
 * ```
 * @since 1.1.0
 */
inline fun <reified K, V> Map<K, V>.sortedByKeyDescending(): Map<K, V> =
  toList().sortedByDescending { it.first.hashCode() }.toMap()

Compiled from "Comparisons.kt"
public final class com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByValueDescending$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByValueDescending$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class kotlin/Pair
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      12: dup
      13: ifnull        22
      16: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      19: goto          24
      22: pop
      23: iconst_0
      24: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      27: nop
      28: checkcast     #39                 // class java/lang/Comparable
      31: aload_1
      32: checkcast     #23                 // class kotlin/Pair
      35: astore_3
      36: astore        5
      38: iconst_0
      39: istore        4
      41: aload_3
      42: invokevirtual #27                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      45: dup
      46: ifnull        55
      49: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      52: goto          57
      55: pop
      56: iconst_0
      57: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      60: nop
      61: aload         5
      63: swap
      64: checkcast     #39                 // class java/lang/Comparable
      67: invokestatic  #45                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      70: ireturn
}

Compiled from "Comparisons.kt"
public final class com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByKeyDescending$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByKeyDescending$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class kotlin/Pair
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      12: dup
      13: ifnull        22
      16: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      19: goto          24
      22: pop
      23: iconst_0
      24: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      27: nop
      28: checkcast     #39                 // class java/lang/Comparable
      31: aload_1
      32: checkcast     #23                 // class kotlin/Pair
      35: astore_3
      36: astore        5
      38: iconst_0
      39: istore        4
      41: aload_3
      42: invokevirtual #27                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      45: dup
      46: ifnull        55
      49: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      52: goto          57
      55: pop
      56: iconst_0
      57: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      60: nop
      61: aload         5
      63: swap
      64: checkcast     #39                 // class java/lang/Comparable
      67: invokestatic  #45                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      70: ireturn
}

Compiled from "Comparisons.kt"
public final class com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByValue$$inlined$sortedBy$1<T> implements java.util.Comparator {
  public com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByValue$$inlined$sortedBy$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_1
       1: checkcast     #23                 // class kotlin/Pair
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      12: dup
      13: ifnull        22
      16: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      19: goto          24
      22: pop
      23: iconst_0
      24: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      27: nop
      28: checkcast     #39                 // class java/lang/Comparable
      31: aload_2
      32: checkcast     #23                 // class kotlin/Pair
      35: astore_3
      36: astore        5
      38: iconst_0
      39: istore        4
      41: aload_3
      42: invokevirtual #27                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      45: dup
      46: ifnull        55
      49: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      52: goto          57
      55: pop
      56: iconst_0
      57: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      60: nop
      61: aload         5
      63: swap
      64: checkcast     #39                 // class java/lang/Comparable
      67: invokestatic  #45                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      70: ireturn
}

Compiled from "Comparisons.kt"
public final class com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByKey$$inlined$sortedBy$1<T> implements java.util.Comparator {
  public com.parsuomash.affogato.core.ktx.collections.MapKt$sortedByKey$$inlined$sortedBy$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_1
       1: checkcast     #23                 // class kotlin/Pair
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      12: dup
      13: ifnull        22
      16: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      19: goto          24
      22: pop
      23: iconst_0
      24: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      27: nop
      28: checkcast     #39                 // class java/lang/Comparable
      31: aload_2
      32: checkcast     #23                 // class kotlin/Pair
      35: astore_3
      36: astore        5
      38: iconst_0
      39: istore        4
      41: aload_3
      42: invokevirtual #27                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      45: dup
      46: ifnull        55
      49: invokevirtual #31                 // Method java/lang/Object.hashCode:()I
      52: goto          57
      55: pop
      56: iconst_0
      57: invokestatic  #37                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      60: nop
      61: aload         5
      63: swap
      64: checkcast     #39                 // class java/lang/Comparable
      67: invokestatic  #45                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      70: ireturn
}

Compiled from "Map.kt"
public final class com.parsuomash.affogato.core.ktx.collections.MapKt {
  public static final <K, V> java.util.HashMap<K, V> toHashMap(java.util.Map<K, ? extends V>);
    Code:
       0: aload_0
       1: ldc           #9                  // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: new           #17                 // class java/util/HashMap
      11: dup
      12: aload_0
      13: invokespecial #21                 // Method java/util/HashMap."<init>":(Ljava/util/Map;)V
      16: areturn

  public static final <K, V> java.util.LinkedHashMap<K, V> toLinkedMap(java.util.Map<K, ? extends V>);
    Code:
       0: aload_0
       1: ldc           #9                  // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: new           #30                 // class java/util/LinkedHashMap
      11: dup
      12: aload_0
      13: invokespecial #31                 // Method java/util/LinkedHashMap."<init>":(Ljava/util/Map;)V
      16: areturn

  public static final <K, V> java.util.Map<K, V> sortedByValue(java.util.Map<K, ? extends V>);
    Code:
       0: aload_0
       1: ldc           #9                  // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: aload_0
       9: invokestatic  #42                 // Method kotlin/collections/MapsKt.toList:(Ljava/util/Map;)Ljava/util/List;
      12: checkcast     #44                 // class java/lang/Iterable
      15: astore_2
      16: iconst_0
      17: istore_3
      18: aload_2
      19: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.needClassReification:()V
      22: new           #50                 // class com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByValue$$inlined$sortedBy$1
      25: dup
      26: invokespecial #52                 // Method com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByValue$$inlined$sortedBy$1."<init>":()V
      29: checkcast     #54                 // class java/util/Comparator
      32: invokestatic  #60                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      35: checkcast     #44                 // class java/lang/Iterable
      38: invokestatic  #64                 // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
      41: areturn

  public static final <K, V> java.util.Map<K, V> sortedByValueDescending(java.util.Map<K, ? extends V>);
    Code:
       0: aload_0
       1: ldc           #9                  // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: aload_0
       9: invokestatic  #42                 // Method kotlin/collections/MapsKt.toList:(Ljava/util/Map;)Ljava/util/List;
      12: checkcast     #44                 // class java/lang/Iterable
      15: astore_2
      16: iconst_0
      17: istore_3
      18: aload_2
      19: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.needClassReification:()V
      22: new           #72                 // class com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByValueDescending$$inlined$sortedByDescending$1
      25: dup
      26: invokespecial #73                 // Method com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByValueDescending$$inlined$sortedByDescending$1."<init>":()V
      29: checkcast     #54                 // class java/util/Comparator
      32: invokestatic  #60                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      35: checkcast     #44                 // class java/lang/Iterable
      38: invokestatic  #64                 // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
      41: areturn

  public static final <K, V> java.util.Map<K, V> sortedByKey(java.util.Map<K, ? extends V>);
    Code:
       0: aload_0
       1: ldc           #9                  // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: aload_0
       9: invokestatic  #42                 // Method kotlin/collections/MapsKt.toList:(Ljava/util/Map;)Ljava/util/List;
      12: checkcast     #44                 // class java/lang/Iterable
      15: astore_2
      16: iconst_0
      17: istore_3
      18: aload_2
      19: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.needClassReification:()V
      22: new           #80                 // class com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByKey$$inlined$sortedBy$1
      25: dup
      26: invokespecial #81                 // Method com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByKey$$inlined$sortedBy$1."<init>":()V
      29: checkcast     #54                 // class java/util/Comparator
      32: invokestatic  #60                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      35: checkcast     #44                 // class java/lang/Iterable
      38: invokestatic  #64                 // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
      41: areturn

  public static final <K, V> java.util.Map<K, V> sortedByKeyDescending(java.util.Map<K, ? extends V>);
    Code:
       0: aload_0
       1: ldc           #9                  // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: aload_0
       9: invokestatic  #42                 // Method kotlin/collections/MapsKt.toList:(Ljava/util/Map;)Ljava/util/List;
      12: checkcast     #44                 // class java/lang/Iterable
      15: astore_2
      16: iconst_0
      17: istore_3
      18: aload_2
      19: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.needClassReification:()V
      22: new           #86                 // class com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByKeyDescending$$inlined$sortedByDescending$1
      25: dup
      26: invokespecial #87                 // Method com/parsuomash/affogato/core/ktx/collections/MapKt$sortedByKeyDescending$$inlined$sortedByDescending$1."<init>":()V
      29: checkcast     #54                 // class java/util/Comparator
      32: invokestatic  #60                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      35: checkcast     #44                 // class java/lang/Iterable
      38: invokestatic  #64                 // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
      41: areturn
}


package io.github.suzp1984.algorithms

class UnionFind(size : Int) {
    val ids : Array<Int>

    init {
        ids = Array(size) { it }
    }

    private fun find(p : Int) : Int {
        if (p < 0 || p > ids.size)
            throw IllegalArgumentException("array out of scope")

        return ids[p]
    }

    fun isConnected(q : Int, p : Int) : Boolean {
        if (q >= 0 && q < ids.size &&
                p >= 0 && p < ids.size) {
            return ids[p] == ids[q]
        }

        throw IllegalArgumentException("array out of scope")
    }

    fun unionElements(p : Int, q : Int) {
        val pId = find(p)
        val qId = find(q)

        if (pId == qId) {
            return
        }

        ids.indices
                .filter { ids[it] == pId }
                .forEach { ids[it] = qId }
    }
}

class UnionFind2(size : Int) {
    private val ids : Array<Int>

    init {
        ids = Array(size) { it }
    }

    private fun find(p : Int) : Int {
        if (p < 0 || p > ids.size)
            throw IllegalArgumentException("array out of scope")

        var i = p
        while (i != ids[i]) i = ids[i]

        return i
    }

    fun isConnected(q : Int, p : Int) : Boolean {
        return find(q) == find(p)
    }

    fun unionElements(p : Int, q : Int) {
        val pId = find(p)
        val qId = find(q)

        if (pId == qId) {
            return
        }

        ids[pId] = qId
    }
}

Compiled from "UnionFind.kt"
public final class io.github.suzp1984.algorithms.UnionFind {
  private final java.lang.Integer[] ids;

  public io.github.suzp1984.algorithms.UnionFind(int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: nop
       5: aload_0
       6: iconst_0
       7: istore_2
       8: iload_1
       9: anewarray     #11                 // class java/lang/Integer
      12: astore_3
      13: astore        5
      15: iload_2
      16: iload_1
      17: if_icmpge     38
      20: iload_2
      21: istore        4
      23: aload_3
      24: iload         4
      26: iload         4
      28: invokestatic  #15                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      31: aastore
      32: iinc          2, 1
      35: goto          15
      38: aload         5
      40: aload_3
      41: putfield      #19                 // Field ids:[Ljava/lang/Integer;
      44: nop
      45: return

  public final java.lang.Integer[] getIds();
    Code:
       0: aload_0
       1: getfield      #19                 // Field ids:[Ljava/lang/Integer;
       4: areturn

  private final int find(int);
    Code:
       0: iload_1
       1: iflt          13
       4: iload_1
       5: aload_0
       6: getfield      #19                 // Field ids:[Ljava/lang/Integer;
       9: arraylength
      10: if_icmple     23
      13: new           #31                 // class java/lang/IllegalArgumentException
      16: dup
      17: ldc           #33                 // String array out of scope
      19: invokespecial #36                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
      22: athrow
      23: aload_0
      24: getfield      #19                 // Field ids:[Ljava/lang/Integer;
      27: iload_1
      28: aaload
      29: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
      32: ireturn

  public final boolean isConnected(int, int);
    Code:
       0: iload_1
       1: iflt          53
       4: iload_1
       5: aload_0
       6: getfield      #19                 // Field ids:[Ljava/lang/Integer;
       9: arraylength
      10: if_icmpge     53
      13: iload_2
      14: iflt          53
      17: iload_2
      18: aload_0
      19: getfield      #19                 // Field ids:[Ljava/lang/Integer;
      22: arraylength
      23: if_icmpge     53
      26: aload_0
      27: getfield      #19                 // Field ids:[Ljava/lang/Integer;
      30: iload_2
      31: aaload
      32: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
      35: aload_0
      36: getfield      #19                 // Field ids:[Ljava/lang/Integer;
      39: iload_1
      40: aaload
      41: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
      44: if_icmpne     51
      47: iconst_1
      48: goto          52
      51: iconst_0
      52: ireturn
      53: new           #31                 // class java/lang/IllegalArgumentException
      56: dup
      57: ldc           #33                 // String array out of scope
      59: invokespecial #36                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
      62: athrow

  public final void unionElements(int, int);
    Code:
       0: aload_0
       1: iload_1
       2: invokespecial #48                 // Method find:(I)I
       5: istore_3
       6: aload_0
       7: iload_2
       8: invokespecial #48                 // Method find:(I)I
      11: istore        4
      13: iload_3
      14: iload         4
      16: if_icmpne     20
      19: return
      20: aload_0
      21: getfield      #19                 // Field ids:[Ljava/lang/Integer;
      24: invokestatic  #54                 // Method kotlin/collections/ArraysKt.getIndices:([Ljava/lang/Object;)Lkotlin/ranges/IntRange;
      27: checkcast     #56                 // class java/lang/Iterable
      30: astore        5
      32: nop
      33: iconst_0
      34: istore        6
      36: aload         5
      38: astore        7
      40: new           #58                 // class java/util/ArrayList
      43: dup
      44: invokespecial #59                 // Method java/util/ArrayList."<init>":()V
      47: checkcast     #61                 // class java/util/Collection
      50: astore        8
      52: iconst_0
      53: istore        9
      55: aload         7
      57: invokeinterface #65,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      62: astore        10
      64: aload         10
      66: invokeinterface #71,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      71: ifeq          131
      74: aload         10
      76: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      81: astore        11
      83: aload         11
      85: checkcast     #77                 // class java/lang/Number
      88: invokevirtual #78                 // Method java/lang/Number.intValue:()I
      91: istore        12
      93: iconst_0
      94: istore        13
      96: aload_0
      97: getfield      #19                 // Field ids:[Ljava/lang/Integer;
     100: iload         12
     102: aaload
     103: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     106: iload_3
     107: if_icmpne     114
     110: iconst_1
     111: goto          115
     114: iconst_0
     115: ifeq          64
     118: aload         8
     120: aload         11
     122: invokeinterface #82,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     127: pop
     128: goto          64
     131: aload         8
     133: checkcast     #84                 // class java/util/List
     136: nop
     137: checkcast     #56                 // class java/lang/Iterable
     140: astore        5
     142: nop
     143: iconst_0
     144: istore        6
     146: aload         5
     148: invokeinterface #65,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     153: astore        7
     155: aload         7
     157: invokeinterface #71,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     162: ifeq          203
     165: aload         7
     167: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     172: astore        8
     174: aload         8
     176: checkcast     #77                 // class java/lang/Number
     179: invokevirtual #78                 // Method java/lang/Number.intValue:()I
     182: istore        9
     184: iconst_0
     185: istore        10
     187: aload_0
     188: getfield      #19                 // Field ids:[Ljava/lang/Integer;
     191: iload         9
     193: iload         4
     195: invokestatic  #15                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     198: aastore
     199: nop
     200: goto          155
     203: nop
     204: return
}


package io.github.suzp1984.algorithms

import java.util.*
import kotlin.math.min

fun <T> Array<T>.swap(i : Int, j : Int) {
    val t = this[i]
    this[i] = this[j]
    this[j] = t
}

fun <T : Comparable<T>> Array<T>.selectionSort() {
    indices.forEach { i ->
        var minIndex = i
        (i + 1 until size)
                .asSequence()
                .filter { this[it] < this[minIndex] }
                .forEach { minIndex = it }

        swap(minIndex, i)
    }
}

fun <T : Comparable<T>> Array<T>.insertionSort() {
    (1 until size).forEach { i ->
        (i downTo 1)
                .asSequence()
                .takeWhile { this[it] < this[it - 1] }
                .forEach { swap(it, it - 1) }
    }
}

fun <T : Comparable<T>> Array<T>.improvedInsertionSort() {
    (1 until size).forEach { i ->
        val t = this[i]

        val seqIndex = (i downTo 1)
                .asSequence()
                .takeWhile { this[it-1] > t }

        seqIndex.forEach { this[it] = this[it-1] }

        val lastIndex = seqIndex.lastOrNull()
        if (lastIndex != null) this[lastIndex - 1] = t
    }
}

fun <T : Comparable<T>> Array<T>.bubbleSort() {
    (0 until size).forEach {
        (1 until size - it).forEach {
            if (this[it] < this[it-1]) {
                swap(it, it-1)
            }
        }
    }
}

private fun <T : Comparable<T>> Array<T>.__merge(l : Int, mid : Int, r : Int) {
    val aux = copyOfRange(l, r + 1)

    var i = l
    var j = mid + 1
    (l until r + 1).forEach {
        when {
            i > mid -> {
                this[it] = aux[j-l]
                j++
            }
            j > r -> {
                this[it] = aux[i-l]
                i++
            }
            aux[i-l] < aux[j-l] -> {
                this[it] = aux[i-l]
                i++
            }
            else -> {
                this[it] = aux[j-l]
                j++
            }
        }
    }
}

fun <T : Comparable<T>> Array<T>.mergeSort() {

    fun <T : Comparable<T>> Array<T>.__mergeSort(l : Int, r : Int) {
        if (l >= r) return

        val mid = l/2 + r/2
        __mergeSort(l, mid)
        __mergeSort(mid+1, r)
        __merge(l, mid, r)
    }

    __mergeSort(0, size-1)
}

fun <T : Comparable<T>> Array<T>.bottomUpMergeSort() {
    var sz = 1
    while (sz <= size) {
        var i = 0
        while (i + sz < size) {
            __merge(i, i + sz - 1, min(i + sz + sz - 1, size - 1))
            i += sz + sz
        }

        sz += sz
    }
}

fun <T : Comparable<T>> Array<T>.quickSort() {

    fun <T : Comparable<T>> Array<T>.__partition(l : Int, r : Int) : Int {
        val t = this[l]
        var j = l
        (l+1 until r+1).forEach {
            if (this[it] < t) {
                swap(++j, it)
            }
        }

        swap(l, j)
        return j
    }

    fun <T : Comparable<T>> Array<T>.__quickSort(l : Int, r : Int) {
        if (l >= r) return

        val p = __partition(l, r)
        __quickSort(l, p - 1)
        __quickSort(p + 1, r)
    }

    __quickSort(0, size-1)
}

fun <T : Comparable<T>> Array<T>.quickSortRandom() {
    fun <T : Comparable<T>> Array<T>.__partition(l : Int, r : Int) : Int {
        swap(l, Random().nextInt(r - l + 1) + l)

        val t = this[l]
        var j = l
        (l+1 until r+1).forEach {
            if (this[it] < t) {
                swap(++j, it)
            }
        }

        swap(l, j)
        return j
    }

    fun <T : Comparable<T>> Array<T>.__quickSort(l : Int, r : Int) {
        if (l >= r) return

        val p = __partition(l, r)
        __quickSort(l, p - 1)
        __quickSort(p + 1, r)
    }

    __quickSort(0, size-1)
}

fun <T : Comparable<T>> Array<T>.quickSortDoublePartition() {
    fun <T : Comparable<T>> Array<T>.__double_partition(l : Int, r : Int) : Int {
        swap(l, Random().nextInt(r - l + 1) + l)

        val t = this[l]
        var i = l + 1
        var j = r
        while (true) {
            while (i <= r && this[i] < t) i++
            while (j >= l + 1 && this[j] > t) j--
            if (i > j) break
            swap(i, j)
            i++
            j--
        }

        swap(l, j)

        return j
    }

    fun <T : Comparable<T>> Array<T>.__quickSort(l : Int, r : Int) {
        if (l >= r) return

        val p = __double_partition(l, r)
        __quickSort(l, p - 1)
        __quickSort(p + 1, r)
    }

    __quickSort(0, size-1)
}

fun <T : Comparable<T>> Array<T>.quickSortTriplePartition() {
    fun <T : Comparable<T>> Array<T>.__triple_partition(l : Int, r : Int) {
        if (l >= r) {
            return
        }

        swap(l, Random().nextInt(r - l + 1) + l)
        val t = this[l]
        var lt = l
        var gt = r + 1;
        var i = l + 1;
        while (i < gt) {
            if (this[i] < t) {
                swap(i, lt + 1)
                lt++
                i++
            } else if (this[i] > t) {
                swap(i, gt - 1)
                gt--
            } else {
                i++
            }
        }

        swap(l, lt)

        __triple_partition(l, lt - 1)
        __triple_partition(gt, r)
    }

    __triple_partition(0, size - 1)
}

Compiled from "ElementSort.kt"
public final class io.github.suzp1984.algorithms.ElementSortKt {
  public static final <T> void swap(T[], 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: aaload
       9: astore_3
      10: aload_0
      11: iload_1
      12: aload_0
      13: iload_2
      14: aaload
      15: aastore
      16: aload_0
      17: iload_2
      18: aload_3
      19: aastore
      20: return

  public static final <T extends java.lang.Comparable<? super T>> void selectionSort(T[]);
    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: invokestatic  #32                 // Method kotlin/collections/ArraysKt.getIndices:([Ljava/lang/Object;)Lkotlin/ranges/IntRange;
      10: checkcast     #34                 // class java/lang/Iterable
      13: astore_1
      14: iconst_0
      15: istore_2
      16: aload_1
      17: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      22: astore_3
      23: aload_3
      24: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      29: ifeq          165
      32: aload_3
      33: checkcast     #46                 // class kotlin/collections/IntIterator
      36: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      39: istore        4
      41: iload         4
      43: istore        5
      45: iconst_0
      46: istore        6
      48: new           #52                 // class kotlin/jvm/internal/Ref$IntRef
      51: dup
      52: invokespecial #56                 // Method kotlin/jvm/internal/Ref$IntRef."<init>":()V
      55: astore        7
      57: aload         7
      59: iload         5
      61: putfield      #59                 // Field kotlin/jvm/internal/Ref$IntRef.element:I
      64: iload         5
      66: iconst_1
      67: iadd
      68: aload_0
      69: arraylength
      70: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      73: checkcast     #34                 // class java/lang/Iterable
      76: invokestatic  #71                 // Method kotlin/collections/CollectionsKt.asSequence:(Ljava/lang/Iterable;)Lkotlin/sequences/Sequence;
      79: aload_0
      80: aload         7
      82: invokedynamic #91,  0             // InvokeDynamic #0:invoke:([Ljava/lang/Comparable;Lkotlin/jvm/internal/Ref$IntRef;)Lkotlin/jvm/functions/Function1;
      87: invokestatic  #97                 // Method kotlin/sequences/SequencesKt.filter:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      90: astore        8
      92: nop
      93: iconst_0
      94: istore        9
      96: aload         8
      98: invokeinterface #100,  1          // InterfaceMethod kotlin/sequences/Sequence.iterator:()Ljava/util/Iterator;
     103: astore        10
     105: aload         10
     107: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     112: ifeq          148
     115: aload         10
     117: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     122: astore        11
     124: aload         11
     126: checkcast     #106                // class java/lang/Number
     129: invokevirtual #109                // Method java/lang/Number.intValue:()I
     132: istore        12
     134: iconst_0
     135: istore        13
     137: aload         7
     139: iload         12
     141: putfield      #59                 // Field kotlin/jvm/internal/Ref$IntRef.element:I
     144: nop
     145: goto          105
     148: nop
     149: aload_0
     150: aload         7
     152: getfield      #59                 // Field kotlin/jvm/internal/Ref$IntRef.element:I
     155: iload         5
     157: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     160: nop
     161: nop
     162: goto          23
     165: nop
     166: return

  public static final <T extends java.lang.Comparable<? super T>> void insertionSort(T[]);
    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: iconst_1
       7: aload_0
       8: arraylength
       9: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      12: checkcast     #34                 // class java/lang/Iterable
      15: astore_1
      16: iconst_0
      17: istore_2
      18: aload_1
      19: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      24: astore_3
      25: aload_3
      26: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      31: ifeq          138
      34: aload_3
      35: checkcast     #46                 // class kotlin/collections/IntIterator
      38: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      41: istore        4
      43: iload         4
      45: istore        5
      47: iconst_0
      48: istore        6
      50: iload         5
      52: iconst_1
      53: invokestatic  #129                // Method kotlin/ranges/RangesKt.downTo:(II)Lkotlin/ranges/IntProgression;
      56: checkcast     #34                 // class java/lang/Iterable
      59: invokestatic  #71                 // Method kotlin/collections/CollectionsKt.asSequence:(Ljava/lang/Iterable;)Lkotlin/sequences/Sequence;
      62: aload_0
      63: invokedynamic #137,  0            // InvokeDynamic #1:invoke:([Ljava/lang/Comparable;)Lkotlin/jvm/functions/Function1;
      68: invokestatic  #140                // Method kotlin/sequences/SequencesKt.takeWhile:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      71: astore        7
      73: nop
      74: iconst_0
      75: istore        8
      77: aload         7
      79: invokeinterface #100,  1          // InterfaceMethod kotlin/sequences/Sequence.iterator:()Ljava/util/Iterator;
      84: astore        9
      86: aload         9
      88: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      93: ifeq          132
      96: aload         9
      98: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     103: astore        10
     105: aload         10
     107: checkcast     #106                // class java/lang/Number
     110: invokevirtual #109                // Method java/lang/Number.intValue:()I
     113: istore        11
     115: iconst_0
     116: istore        12
     118: aload_0
     119: iload         11
     121: iload         11
     123: iconst_1
     124: isub
     125: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     128: nop
     129: goto          86
     132: nop
     133: nop
     134: nop
     135: goto          25
     138: nop
     139: return

  public static final <T extends java.lang.Comparable<? super T>> void improvedInsertionSort(T[]);
    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: iconst_1
       7: aload_0
       8: arraylength
       9: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      12: checkcast     #34                 // class java/lang/Iterable
      15: astore_1
      16: iconst_0
      17: istore_2
      18: aload_1
      19: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      24: astore_3
      25: aload_3
      26: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      31: ifeq          175
      34: aload_3
      35: checkcast     #46                 // class kotlin/collections/IntIterator
      38: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      41: istore        4
      43: iload         4
      45: istore        5
      47: iconst_0
      48: istore        6
      50: aload_0
      51: iload         5
      53: aaload
      54: astore        7
      56: iload         5
      58: iconst_1
      59: invokestatic  #129                // Method kotlin/ranges/RangesKt.downTo:(II)Lkotlin/ranges/IntProgression;
      62: checkcast     #34                 // class java/lang/Iterable
      65: invokestatic  #71                 // Method kotlin/collections/CollectionsKt.asSequence:(Ljava/lang/Iterable;)Lkotlin/sequences/Sequence;
      68: aload_0
      69: aload         7
      71: invokedynamic #152,  0            // InvokeDynamic #2:invoke:([Ljava/lang/Comparable;Ljava/lang/Comparable;)Lkotlin/jvm/functions/Function1;
      76: invokestatic  #140                // Method kotlin/sequences/SequencesKt.takeWhile:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      79: astore        8
      81: aload         8
      83: astore        9
      85: iconst_0
      86: istore        10
      88: aload         9
      90: invokeinterface #100,  1          // InterfaceMethod kotlin/sequences/Sequence.iterator:()Ljava/util/Iterator;
      95: astore        11
      97: aload         11
      99: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     104: ifeq          143
     107: aload         11
     109: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     114: astore        12
     116: aload         12
     118: checkcast     #106                // class java/lang/Number
     121: invokevirtual #109                // Method java/lang/Number.intValue:()I
     124: istore        13
     126: iconst_0
     127: istore        14
     129: aload_0
     130: iload         13
     132: aload_0
     133: iload         13
     135: iconst_1
     136: isub
     137: aaload
     138: aastore
     139: nop
     140: goto          97
     143: nop
     144: aload         8
     146: invokestatic  #156                // Method kotlin/sequences/SequencesKt.lastOrNull:(Lkotlin/sequences/Sequence;)Ljava/lang/Object;
     149: checkcast     #158                // class java/lang/Integer
     152: astore        9
     154: aload         9
     156: ifnull        170
     159: aload_0
     160: aload         9
     162: invokevirtual #159                // Method java/lang/Integer.intValue:()I
     165: iconst_1
     166: isub
     167: aload         7
     169: aastore
     170: nop
     171: nop
     172: goto          25
     175: nop
     176: return

  public static final <T extends java.lang.Comparable<? super T>> void bubbleSort(T[]);
    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: iconst_0
       7: aload_0
       8: arraylength
       9: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      12: checkcast     #34                 // class java/lang/Iterable
      15: astore_1
      16: iconst_0
      17: istore_2
      18: aload_1
      19: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      24: astore_3
      25: aload_3
      26: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      31: ifeq          142
      34: aload_3
      35: checkcast     #46                 // class kotlin/collections/IntIterator
      38: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      41: istore        4
      43: iload         4
      45: istore        5
      47: iconst_0
      48: istore        6
      50: iconst_1
      51: aload_0
      52: arraylength
      53: iload         5
      55: isub
      56: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      59: checkcast     #34                 // class java/lang/Iterable
      62: astore        7
      64: iconst_0
      65: istore        8
      67: aload         7
      69: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      74: astore        9
      76: aload         9
      78: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      83: ifeq          136
      86: aload         9
      88: checkcast     #46                 // class kotlin/collections/IntIterator
      91: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      94: istore        10
      96: iload         10
      98: istore        11
     100: iconst_0
     101: istore        12
     103: aload_0
     104: iload         11
     106: aaload
     107: aload_0
     108: iload         11
     110: iconst_1
     111: isub
     112: aaload
     113: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     118: ifge          131
     121: aload_0
     122: iload         11
     124: iload         11
     126: iconst_1
     127: isub
     128: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     131: nop
     132: nop
     133: goto          76
     136: nop
     137: nop
     138: nop
     139: goto          25
     142: nop
     143: return

  private static final <T extends java.lang.Comparable<? super T>> void __merge(T[], int, int, int);
    Code:
       0: aload_0
       1: iload_1
       2: iload_3
       3: iconst_1
       4: iadd
       5: invokestatic  #183                // Method kotlin/collections/ArraysKt.copyOfRange:([Ljava/lang/Object;II)[Ljava/lang/Object;
       8: checkcast     #124                // class "[Ljava/lang/Comparable;"
      11: astore        4
      13: iconst_0
      14: istore        5
      16: iload_1
      17: istore        5
      19: iconst_0
      20: istore        6
      22: iload_2
      23: iconst_1
      24: iadd
      25: istore        6
      27: iload_1
      28: iload_3
      29: iconst_1
      30: iadd
      31: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      34: checkcast     #34                 // class java/lang/Iterable
      37: astore        7
      39: iconst_0
      40: istore        8
      42: aload         7
      44: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      49: astore        9
      51: aload         9
      53: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      58: ifeq          211
      61: aload         9
      63: checkcast     #46                 // class kotlin/collections/IntIterator
      66: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      69: istore        10
      71: iload         10
      73: istore        11
      75: iconst_0
      76: istore        12
      78: nop
      79: iload         5
      81: iload_2
      82: if_icmple     109
      85: aload_0
      86: iload         11
      88: aload         4
      90: iload         6
      92: iload_1
      93: isub
      94: aaload
      95: aastore
      96: iload         6
      98: istore        13
     100: iload         13
     102: iconst_1
     103: iadd
     104: istore        6
     106: goto          206
     109: iload         6
     111: iload_3
     112: if_icmple     139
     115: aload_0
     116: iload         11
     118: aload         4
     120: iload         5
     122: iload_1
     123: isub
     124: aaload
     125: aastore
     126: iload         5
     128: istore        13
     130: iload         13
     132: iconst_1
     133: iadd
     134: istore        5
     136: goto          206
     139: aload         4
     141: iload         5
     143: iload_1
     144: isub
     145: aaload
     146: aload         4
     148: iload         6
     150: iload_1
     151: isub
     152: aaload
     153: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     158: ifge          185
     161: aload_0
     162: iload         11
     164: aload         4
     166: iload         5
     168: iload_1
     169: isub
     170: aaload
     171: aastore
     172: iload         5
     174: istore        13
     176: iload         13
     178: iconst_1
     179: iadd
     180: istore        5
     182: goto          206
     185: aload_0
     186: iload         11
     188: aload         4
     190: iload         6
     192: iload_1
     193: isub
     194: aaload
     195: aastore
     196: iload         6
     198: istore        13
     200: iload         13
     202: iconst_1
     203: iadd
     204: istore        6
     206: nop
     207: nop
     208: goto          51
     211: nop
     212: return

  public static final <T extends java.lang.Comparable<? super T>> void mergeSort(T[]);
    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: iconst_0
       8: aload_0
       9: arraylength
      10: iconst_1
      11: isub
      12: invokestatic  #194                // Method mergeSort$__mergeSort:([Ljava/lang/Comparable;II)V
      15: return

  public static final <T extends java.lang.Comparable<? super T>> void bottomUpMergeSort(T[]);
    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: iconst_1
       7: istore_1
       8: iload_1
       9: aload_0
      10: arraylength
      11: if_icmpgt     64
      14: iconst_0
      15: istore_2
      16: iload_2
      17: iload_1
      18: iadd
      19: aload_0
      20: arraylength
      21: if_icmpge     57
      24: aload_0
      25: iload_2
      26: iload_2
      27: iload_1
      28: iadd
      29: iconst_1
      30: isub
      31: iload_2
      32: iload_1
      33: iadd
      34: iload_1
      35: iadd
      36: iconst_1
      37: isub
      38: aload_0
      39: arraylength
      40: iconst_1
      41: isub
      42: invokestatic  #202                // Method java/lang/Math.min:(II)I
      45: invokestatic  #204                // Method __merge:([Ljava/lang/Comparable;III)V
      48: iload_2
      49: iload_1
      50: iload_1
      51: iadd
      52: iadd
      53: istore_2
      54: goto          16
      57: iload_1
      58: iload_1
      59: iadd
      60: istore_1
      61: goto          8
      64: return

  public static final <T extends java.lang.Comparable<? super T>> void quickSort(T[]);
    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: iconst_0
       8: aload_0
       9: arraylength
      10: iconst_1
      11: isub
      12: invokestatic  #210                // Method quickSort$__quickSort:([Ljava/lang/Comparable;II)V
      15: return

  public static final <T extends java.lang.Comparable<? super T>> void quickSortRandom(T[]);
    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: iconst_0
       8: aload_0
       9: arraylength
      10: iconst_1
      11: isub
      12: invokestatic  #215                // Method quickSortRandom$__quickSort$15:([Ljava/lang/Comparable;II)V
      15: return

  public static final <T extends java.lang.Comparable<? super T>> void quickSortDoublePartition(T[]);
    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: iconst_0
       8: aload_0
       9: arraylength
      10: iconst_1
      11: isub
      12: invokestatic  #220                // Method quickSortDoublePartition$__quickSort$16:([Ljava/lang/Comparable;II)V
      15: return

  public static final <T extends java.lang.Comparable<? super T>> void quickSortTriplePartition(T[]);
    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: iconst_0
       8: aload_0
       9: arraylength
      10: iconst_1
      11: isub
      12: invokestatic  #225                // Method quickSortTriplePartition$__triple_partition:([Ljava/lang/Comparable;II)V
      15: return

  private static final boolean selectionSort$lambda$2$lambda$0(java.lang.Comparable[], kotlin.jvm.internal.Ref$IntRef, int);
    Code:
       0: aload_0
       1: iload_2
       2: aaload
       3: aload_0
       4: aload_1
       5: getfield      #59                 // Field kotlin/jvm/internal/Ref$IntRef.element:I
       8: aaload
       9: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      14: ifge          21
      17: iconst_1
      18: goto          22
      21: iconst_0
      22: ireturn

  private static final boolean insertionSort$lambda$5$lambda$3(java.lang.Comparable[], int);
    Code:
       0: aload_0
       1: iload_1
       2: aaload
       3: aload_0
       4: iload_1
       5: iconst_1
       6: isub
       7: aaload
       8: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      13: ifge          20
      16: iconst_1
      17: goto          21
      20: iconst_0
      21: ireturn

  private static final boolean improvedInsertionSort$lambda$8$lambda$6(java.lang.Comparable[], java.lang.Comparable, int);
    Code:
       0: aload_0
       1: iload_2
       2: iconst_1
       3: isub
       4: aaload
       5: aload_1
       6: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      11: ifle          18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: ireturn

  private static final <T extends java.lang.Comparable<? super T>> void mergeSort$__mergeSort(T[], int, int);
    Code:
       0: iload_1
       1: iload_2
       2: if_icmplt     6
       5: return
       6: iload_1
       7: iconst_2
       8: idiv
       9: iload_2
      10: iconst_2
      11: idiv
      12: iadd
      13: istore_3
      14: aload_0
      15: iload_1
      16: iload_3
      17: invokestatic  #194                // Method mergeSort$__mergeSort:([Ljava/lang/Comparable;II)V
      20: aload_0
      21: iload_3
      22: iconst_1
      23: iadd
      24: iload_2
      25: invokestatic  #194                // Method mergeSort$__mergeSort:([Ljava/lang/Comparable;II)V
      28: aload_0
      29: iload_1
      30: iload_3
      31: iload_2
      32: invokestatic  #204                // Method __merge:([Ljava/lang/Comparable;III)V
      35: return

  private static final <T extends java.lang.Comparable<? super T>> int quickSort$__partition(T[], int, int);
    Code:
       0: aload_0
       1: iload_1
       2: aaload
       3: astore_3
       4: iconst_0
       5: istore        4
       7: iload_1
       8: istore        4
      10: iload_1
      11: iconst_1
      12: iadd
      13: iload_2
      14: iconst_1
      15: iadd
      16: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      19: checkcast     #34                 // class java/lang/Iterable
      22: astore        5
      24: iconst_0
      25: istore        6
      27: aload         5
      29: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      34: astore        7
      36: aload         7
      38: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      43: ifeq          95
      46: aload         7
      48: checkcast     #46                 // class kotlin/collections/IntIterator
      51: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      54: istore        8
      56: iload         8
      58: istore        9
      60: iconst_0
      61: istore        10
      63: aload_0
      64: iload         9
      66: aaload
      67: aload_3
      68: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      73: ifge          90
      76: aload_0
      77: iload         4
      79: iconst_1
      80: iadd
      81: istore        4
      83: iload         4
      85: iload         9
      87: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
      90: nop
      91: nop
      92: goto          36
      95: nop
      96: aload_0
      97: iload_1
      98: iload         4
     100: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     103: iload         4
     105: ireturn

  private static final <T extends java.lang.Comparable<? super T>> void quickSort$__quickSort(T[], int, int);
    Code:
       0: iload_1
       1: iload_2
       2: if_icmplt     6
       5: return
       6: aload_0
       7: iload_1
       8: iload_2
       9: invokestatic  #240                // Method quickSort$__partition:([Ljava/lang/Comparable;II)I
      12: istore_3
      13: aload_0
      14: iload_1
      15: iload_3
      16: iconst_1
      17: isub
      18: invokestatic  #210                // Method quickSort$__quickSort:([Ljava/lang/Comparable;II)V
      21: aload_0
      22: iload_3
      23: iconst_1
      24: iadd
      25: iload_2
      26: invokestatic  #210                // Method quickSort$__quickSort:([Ljava/lang/Comparable;II)V
      29: return

  private static final <T extends java.lang.Comparable<? super T>> int quickSortRandom$__partition$14(T[], int, int);
    Code:
       0: aload_0
       1: iload_1
       2: new           #245                // class java/util/Random
       5: dup
       6: invokespecial #246                // Method java/util/Random."<init>":()V
       9: iload_2
      10: iload_1
      11: isub
      12: iconst_1
      13: iadd
      14: invokevirtual #249                // Method java/util/Random.nextInt:(I)I
      17: iload_1
      18: iadd
      19: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
      22: aload_0
      23: iload_1
      24: aaload
      25: astore_3
      26: iconst_0
      27: istore        4
      29: iload_1
      30: istore        4
      32: iload_1
      33: iconst_1
      34: iadd
      35: iload_2
      36: iconst_1
      37: iadd
      38: invokestatic  #65                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      41: checkcast     #34                 // class java/lang/Iterable
      44: astore        5
      46: iconst_0
      47: istore        6
      49: aload         5
      51: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      56: astore        7
      58: aload         7
      60: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      65: ifeq          117
      68: aload         7
      70: checkcast     #46                 // class kotlin/collections/IntIterator
      73: invokevirtual #50                 // Method kotlin/collections/IntIterator.nextInt:()I
      76: istore        8
      78: iload         8
      80: istore        9
      82: iconst_0
      83: istore        10
      85: aload_0
      86: iload         9
      88: aaload
      89: aload_3
      90: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      95: ifge          112
      98: aload_0
      99: iload         4
     101: iconst_1
     102: iadd
     103: istore        4
     105: iload         4
     107: iload         9
     109: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     112: nop
     113: nop
     114: goto          58
     117: nop
     118: aload_0
     119: iload_1
     120: iload         4
     122: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     125: iload         4
     127: ireturn

  private static final <T extends java.lang.Comparable<? super T>> void quickSortRandom$__quickSort$15(T[], int, int);
    Code:
       0: iload_1
       1: iload_2
       2: if_icmplt     6
       5: return
       6: aload_0
       7: iload_1
       8: iload_2
       9: invokestatic  #253                // Method quickSortRandom$__partition$14:([Ljava/lang/Comparable;II)I
      12: istore_3
      13: aload_0
      14: iload_1
      15: iload_3
      16: iconst_1
      17: isub
      18: invokestatic  #215                // Method quickSortRandom$__quickSort$15:([Ljava/lang/Comparable;II)V
      21: aload_0
      22: iload_3
      23: iconst_1
      24: iadd
      25: iload_2
      26: invokestatic  #215                // Method quickSortRandom$__quickSort$15:([Ljava/lang/Comparable;II)V
      29: return

  private static final <T extends java.lang.Comparable<? super T>> int quickSortDoublePartition$__double_partition(T[], int, int);
    Code:
       0: aload_0
       1: iload_1
       2: new           #245                // class java/util/Random
       5: dup
       6: invokespecial #246                // Method java/util/Random."<init>":()V
       9: iload_2
      10: iload_1
      11: isub
      12: iconst_1
      13: iadd
      14: invokevirtual #249                // Method java/util/Random.nextInt:(I)I
      17: iload_1
      18: iadd
      19: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
      22: aload_0
      23: iload_1
      24: aaload
      25: astore_3
      26: iload_1
      27: iconst_1
      28: iadd
      29: istore        4
      31: iload_2
      32: istore        5
      34: nop
      35: iload         4
      37: iload_2
      38: if_icmpgt     60
      41: aload_0
      42: iload         4
      44: aaload
      45: aload_3
      46: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      51: ifge          60
      54: iinc          4, 1
      57: goto          35
      60: iload         5
      62: iload_1
      63: iconst_1
      64: iadd
      65: if_icmplt     87
      68: aload_0
      69: iload         5
      71: aaload
      72: aload_3
      73: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      78: ifle          87
      81: iinc          5, -1
      84: goto          60
      87: iload         4
      89: iload         5
      91: if_icmpgt     111
      94: aload_0
      95: iload         4
      97: iload         5
      99: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     102: iinc          4, 1
     105: iinc          5, -1
     108: goto          34
     111: aload_0
     112: iload_1
     113: iload         5
     115: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     118: iload         5
     120: ireturn

  private static final <T extends java.lang.Comparable<? super T>> void quickSortDoublePartition$__quickSort$16(T[], int, int);
    Code:
       0: iload_1
       1: iload_2
       2: if_icmplt     6
       5: return
       6: aload_0
       7: iload_1
       8: iload_2
       9: invokestatic  #258                // Method quickSortDoublePartition$__double_partition:([Ljava/lang/Comparable;II)I
      12: istore_3
      13: aload_0
      14: iload_1
      15: iload_3
      16: iconst_1
      17: isub
      18: invokestatic  #220                // Method quickSortDoublePartition$__quickSort$16:([Ljava/lang/Comparable;II)V
      21: aload_0
      22: iload_3
      23: iconst_1
      24: iadd
      25: iload_2
      26: invokestatic  #220                // Method quickSortDoublePartition$__quickSort$16:([Ljava/lang/Comparable;II)V
      29: return

  private static final <T extends java.lang.Comparable<? super T>> void quickSortTriplePartition$__triple_partition(T[], int, int);
    Code:
       0: iload_1
       1: iload_2
       2: if_icmplt     6
       5: return
       6: aload_0
       7: iload_1
       8: new           #245                // class java/util/Random
      11: dup
      12: invokespecial #246                // Method java/util/Random."<init>":()V
      15: iload_2
      16: iload_1
      17: isub
      18: iconst_1
      19: iadd
      20: invokevirtual #249                // Method java/util/Random.nextInt:(I)I
      23: iload_1
      24: iadd
      25: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
      28: aload_0
      29: iload_1
      30: aaload
      31: astore_3
      32: iload_1
      33: istore        4
      35: iload_2
      36: iconst_1
      37: iadd
      38: istore        5
      40: iload_1
      41: iconst_1
      42: iadd
      43: istore        6
      45: iload         6
      47: iload         5
      49: if_icmpge     119
      52: aload_0
      53: iload         6
      55: aaload
      56: aload_3
      57: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      62: ifge          84
      65: aload_0
      66: iload         6
      68: iload         4
      70: iconst_1
      71: iadd
      72: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
      75: iinc          4, 1
      78: iinc          6, 1
      81: goto          45
      84: aload_0
      85: iload         6
      87: aaload
      88: aload_3
      89: invokeinterface #173,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      94: ifle          113
      97: aload_0
      98: iload         6
     100: iload         5
     102: iconst_1
     103: isub
     104: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     107: iinc          5, -1
     110: goto          45
     113: iinc          6, 1
     116: goto          45
     119: aload_0
     120: iload_1
     121: iload         4
     123: invokestatic  #111                // Method swap:([Ljava/lang/Object;II)V
     126: aload_0
     127: iload_1
     128: iload         4
     130: iconst_1
     131: isub
     132: invokestatic  #225                // Method quickSortTriplePartition$__triple_partition:([Ljava/lang/Comparable;II)V
     135: aload_0
     136: iload         5
     138: iload_2
     139: invokestatic  #225                // Method quickSortTriplePartition$__triple_partition:([Ljava/lang/Comparable;II)V
     142: return
}


package oop.algorithm

class ProgressionNextNumber {
  fun solution(common: IntArray): Int {
    return ProgressionHelper(progression = common.toList()).nextInt()
  }
}

class ProgressionHelper(
  private val progression: List<Int>
) {
  fun nextInt(): Int {
    val metadata = getMetadata()
    val nextNumberGenerator = when (metadata.type) {
      ProgressionType.ARITHMETIC -> ArithmeticalProgressionNextNumberGenerator
      ProgressionType.GEOMETRIC -> GeometricProgressionNextNumberGenerator
    }
    return nextNumberGenerator.generateWith(metadata)
  }

  private fun getMetadata(): ProgressionInformation {
    val (first, second) = progression

    return if (isArithmetic()) {
      ProgressionInformation(progression, ProgressionType.ARITHMETIC, second - first)
    } else {
      ProgressionInformation(progression, ProgressionType.GEOMETRIC, second / first)
    }
  }

  private fun isArithmetic(): Boolean {
    val (first, second, third) = progression
    return second * 2 == first + third
  }
}

data class ProgressionInformation(
  val progression: List<Int>,
  val type: ProgressionType,
  val distance: Int,
)

enum class ProgressionType {
  ARITHMETIC, GEOMETRIC
}

sealed interface ProgressionNextNumberGenerator {
  fun generateWith(metadata: ProgressionInformation): Int
}

object ArithmeticalProgressionNextNumberGenerator : ProgressionNextNumberGenerator {
  override fun generateWith(metadata: ProgressionInformation) = metadata.progression.last() + metadata.distance
}

object GeometricProgressionNextNumberGenerator : ProgressionNextNumberGenerator {
  override fun generateWith(metadata: ProgressionInformation) = metadata.progression.last() * metadata.distance
}

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

  public final int solution(int[]);
    Code:
       0: aload_1
       1: ldc           #15                 // String common
       3: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #23                 // class oop/algorithm/ProgressionHelper
       9: dup
      10: aload_1
      11: invokestatic  #29                 // Method kotlin/collections/ArraysKt.toList:([I)Ljava/util/List;
      14: invokespecial #32                 // Method oop/algorithm/ProgressionHelper."<init>":(Ljava/util/List;)V
      17: invokevirtual #36                 // Method oop/algorithm/ProgressionHelper.nextInt:()I
      20: ireturn
}