package org.mifek.wfc.utils

/**
 * Format waves
 *
 * @param waves
 * @return
 */
fun formatWaves(waves: Array<BooleanArray>): String {
    return " " + waves.indices.joinToString(" ") { idx ->
        val s = waves[idx].sumBy {
            when (it) {
                true -> 1
                else -> 0
            }
        }
        val r = when (s) {
            0 -> "[XX]"
            1 -> "[" + (if (waves[idx].withIndex().find { it.value }!!.index < 10) "0" + waves[idx].withIndex()
                .find { it.value }!!.index.toString() else waves[idx].withIndex()
                .find { it.value }!!.index.toString()) + "]"
            else -> " " + (if (s < 10) " $s" else s.toString()) + " "
        }
        if ((idx + 1) % 10 == 0) (r + "\n") else r
    }
}

/**
 * Format patterns
 *
 * @param patterns
 * @return
 */
fun formatPatterns(patterns: Array<IntArray>): String {
    return patterns.mapIndexed { index, it ->
        "$index:\n${it.joinToString(" ")}"
    }.joinToString("\n\n")
}

/**
 * Format propagator
 *
 * @param propagator
 * @return
 */
fun formatPropagator(propagator: Array<Array<IntArray>>): String {
    val x = "   "
    var result = propagator[0].indices.joinToString(" ") {
        x.subSequence(0, x.length - it.toString().length).toString() + it.toString()
    } + "\n"
    val template = "00"
    for (dir in propagator.indices) {
        result += propagator[dir].joinToString(" ") {
            when {
                it.isEmpty() -> "[X]"
                it.size > 1 -> "[?]"
                else -> template.slice(
                    0 until (3 - it[0].toString().length)
                ) + it[0].toString()
            }
        } + "\n"
    }
    return result
}

/**
 * Format neighbours
 *
 * @param propagator
 * @return
 */
fun formatNeighbours(propagator: Array<Array<IntArray>>): String {
    var ret = ""
    for (patternIndex in propagator[0].indices) {
        ret += "Pattern $patternIndex:\n"
        for (dir in propagator.indices) {
            ret += "\t${propagator[dir][patternIndex].joinToString(", ")}\n"
        }
        ret += "\n"
    }
    return ret
}

Compiled from "Formatters.kt"
public final class org.mifek.wfc.utils.FormattersKt {
  public static final java.lang.String formatWaves(boolean[][]);
    Code:
       0: aload_0
       1: ldc           #9                  // String waves
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class java/lang/StringBuilder
       9: dup
      10: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      13: bipush        32
      15: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      18: aload_0
      19: checkcast     #27                 // class "[Ljava/lang/Object;"
      22: invokestatic  #33                 // Method kotlin/collections/ArraysKt.getIndices:([Ljava/lang/Object;)Lkotlin/ranges/IntRange;
      25: checkcast     #35                 // class java/lang/Iterable
      28: ldc           #37                 // String
      30: checkcast     #39                 // class java/lang/CharSequence
      33: aconst_null
      34: aconst_null
      35: iconst_0
      36: aconst_null
      37: aload_0
      38: invokedynamic #59,  0             // InvokeDynamic #0:invoke:([[Z)Lkotlin/jvm/functions/Function1;
      43: bipush        30
      45: aconst_null
      46: invokestatic  #65                 // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
      49: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      52: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      55: areturn

  public static final java.lang.String formatPatterns(int[][]);
    Code:
       0: aload_0
       1: ldc           #77                 // String patterns
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #27                 // class "[Ljava/lang/Object;"
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #79                 // class java/util/ArrayList
      18: dup
      19: aload_1
      20: arraylength
      21: invokespecial #82                 // Method java/util/ArrayList."<init>":(I)V
      24: checkcast     #84                 // class java/util/Collection
      27: astore        4
      29: iconst_0
      30: istore        5
      32: iconst_0
      33: istore        6
      35: iconst_0
      36: istore        7
      38: aload_3
      39: arraylength
      40: istore        8
      42: iload         7
      44: iload         8
      46: if_icmpge     132
      49: aload_3
      50: iload         7
      52: aaload
      53: astore        9
      55: aload         4
      57: iload         6
      59: iinc          6, 1
      62: aload         9
      64: checkcast     #86                 // class "[I"
      67: astore        10
      69: istore        11
      71: astore        13
      73: iconst_0
      74: istore        12
      76: new           #17                 // class java/lang/StringBuilder
      79: dup
      80: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      83: iload         11
      85: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      88: ldc           #91                 // String :\n
      90: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      93: aload         10
      95: ldc           #37                 // String
      97: checkcast     #39                 // class java/lang/CharSequence
     100: aconst_null
     101: aconst_null
     102: iconst_0
     103: aconst_null
     104: aconst_null
     105: bipush        62
     107: aconst_null
     108: invokestatic  #94                 // Method kotlin/collections/ArraysKt.joinToString$default:([ILjava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     111: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     114: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     117: aload         13
     119: swap
     120: invokeinterface #98,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     125: pop
     126: iinc          7, 1
     129: goto          42
     132: aload         4
     134: checkcast     #100                // class java/util/List
     137: nop
     138: checkcast     #35                 // class java/lang/Iterable
     141: ldc           #102                // String \n\n
     143: checkcast     #39                 // class java/lang/CharSequence
     146: aconst_null
     147: aconst_null
     148: iconst_0
     149: aconst_null
     150: aconst_null
     151: bipush        62
     153: aconst_null
     154: invokestatic  #65                 // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     157: areturn

  public static final java.lang.String formatPropagator(int[][][]);
    Code:
       0: aload_0
       1: ldc           #121                // String propagator
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #123                // String
       8: astore_1
       9: new           #17                 // class java/lang/StringBuilder
      12: dup
      13: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      16: aload_0
      17: iconst_0
      18: aaload
      19: checkcast     #27                 // class "[Ljava/lang/Object;"
      22: invokestatic  #33                 // Method kotlin/collections/ArraysKt.getIndices:([Ljava/lang/Object;)Lkotlin/ranges/IntRange;
      25: checkcast     #35                 // class java/lang/Iterable
      28: ldc           #37                 // String
      30: checkcast     #39                 // class java/lang/CharSequence
      33: aconst_null
      34: aconst_null
      35: iconst_0
      36: aconst_null
      37: aload_1
      38: invokedynamic #131,  0            // InvokeDynamic #1:invoke:(Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
      43: bipush        30
      45: aconst_null
      46: invokestatic  #65                 // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
      49: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      52: bipush        10
      54: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      57: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      60: astore_2
      61: ldc           #133                // String 00
      63: astore_3
      64: iconst_0
      65: istore        4
      67: aload_0
      68: checkcast     #27                 // class "[Ljava/lang/Object;"
      71: arraylength
      72: istore        5
      74: iload         4
      76: iload         5
      78: if_icmpge     138
      81: new           #17                 // class java/lang/StringBuilder
      84: dup
      85: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      88: aload_2
      89: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      92: aload_0
      93: iload         4
      95: aaload
      96: checkcast     #27                 // class "[Ljava/lang/Object;"
      99: ldc           #37                 // String
     101: checkcast     #39                 // class java/lang/CharSequence
     104: aconst_null
     105: aconst_null
     106: iconst_0
     107: aconst_null
     108: aload_3
     109: invokedynamic #141,  0            // InvokeDynamic #2:invoke:(Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
     114: bipush        30
     116: aconst_null
     117: invokestatic  #144                // Method kotlin/collections/ArraysKt.joinToString$default:([Ljava/lang/Object;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     120: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     123: bipush        10
     125: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     128: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     131: astore_2
     132: iinc          4, 1
     135: goto          74
     138: aload_2
     139: areturn

  public static final java.lang.String formatNeighbours(int[][][]);
    Code:
       0: aload_0
       1: ldc           #121                // String propagator
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #156                // String
       8: astore_1
       9: iconst_0
      10: istore_2
      11: aload_0
      12: iconst_0
      13: aaload
      14: checkcast     #27                 // class "[Ljava/lang/Object;"
      17: arraylength
      18: istore_3
      19: iload_2
      20: iload_3
      21: if_icmpge     152
      24: new           #17                 // class java/lang/StringBuilder
      27: dup
      28: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      31: aload_1
      32: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      35: ldc           #158                // String Pattern
      37: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      40: iload_2
      41: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      44: ldc           #91                 // String :\n
      46: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      49: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      52: astore_1
      53: iconst_0
      54: istore        4
      56: aload_0
      57: checkcast     #27                 // class "[Ljava/lang/Object;"
      60: arraylength
      61: istore        5
      63: iload         4
      65: iload         5
      67: if_icmpge     126
      70: new           #17                 // class java/lang/StringBuilder
      73: dup
      74: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      77: aload_1
      78: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      81: bipush        9
      83: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      86: aload_0
      87: iload         4
      89: aaload
      90: iload_2
      91: aaload
      92: ldc           #160                // String ,
      94: checkcast     #39                 // class java/lang/CharSequence
      97: aconst_null
      98: aconst_null
      99: iconst_0
     100: aconst_null
     101: aconst_null
     102: bipush        62
     104: aconst_null
     105: invokestatic  #94                 // Method kotlin/collections/ArraysKt.joinToString$default:([ILjava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     108: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     111: bipush        10
     113: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     116: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     119: astore_1
     120: iinc          4, 1
     123: goto          63
     126: new           #17                 // class java/lang/StringBuilder
     129: dup
     130: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
     133: aload_1
     134: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     137: bipush        10
     139: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     142: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     145: astore_1
     146: iinc          2, 1
     149: goto          19
     152: aload_1
     153: areturn

  private static final java.lang.CharSequence formatWaves$lambda$4(boolean[][], int);
    Code:
       0: aload_0
       1: iload_1
       2: aaload
       3: astore_3
       4: iconst_0
       5: istore        4
       7: iconst_0
       8: istore        5
      10: iconst_0
      11: istore        6
      13: aload_3
      14: arraylength
      15: istore        7
      17: iload         6
      19: iload         7
      21: if_icmpge     68
      24: aload_3
      25: iload         6
      27: baload
      28: istore        8
      30: iload         5
      32: iload         8
      34: istore        9
      36: istore        11
      38: iconst_0
      39: istore        10
      41: iload         9
      43: iconst_1
      44: if_icmpne     51
      47: iconst_1
      48: goto          52
      51: iconst_0
      52: nop
      53: istore        12
      55: iload         11
      57: iload         12
      59: iadd
      60: istore        5
      62: iinc          6, 1
      65: goto          17
      68: iload         5
      70: istore_2
      71: iload_2
      72: tableswitch   { // 0 to 1
                     0: 96
                     1: 101
               default: 418
          }
      96: ldc           #164                // String [XX]
      98: goto          473
     101: new           #17                 // class java/lang/StringBuilder
     104: dup
     105: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
     108: bipush        91
     110: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     113: aload_0
     114: iload_1
     115: aaload
     116: invokestatic  #168                // Method kotlin/collections/ArraysKt.withIndex:([Z)Ljava/lang/Iterable;
     119: astore        5
     121: astore        11
     123: aload         5
     125: astore        6
     127: aload         6
     129: invokeinterface #172,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     134: astore        7
     136: aload         7
     138: invokeinterface #178,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     143: ifeq          184
     146: aload         7
     148: invokeinterface #182,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     153: astore        8
     155: aload         8
     157: checkcast     #184                // class kotlin/collections/IndexedValue
     160: astore        9
     162: iconst_0
     163: istore        10
     165: aload         9
     167: invokevirtual #187                // Method kotlin/collections/IndexedValue.getValue:()Ljava/lang/Object;
     170: checkcast     #189                // class java/lang/Boolean
     173: invokevirtual #192                // Method java/lang/Boolean.booleanValue:()Z
     176: ifeq          136
     179: aload         8
     181: goto          185
     184: aconst_null
     185: aload         11
     187: swap
     188: dup
     189: invokestatic  #196                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     192: checkcast     #184                // class kotlin/collections/IndexedValue
     195: invokevirtual #200                // Method kotlin/collections/IndexedValue.getIndex:()I
     198: bipush        10
     200: if_icmpge     316
     203: new           #17                 // class java/lang/StringBuilder
     206: dup
     207: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
     210: bipush        48
     212: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     215: aload_0
     216: iload_1
     217: aaload
     218: invokestatic  #168                // Method kotlin/collections/ArraysKt.withIndex:([Z)Ljava/lang/Iterable;
     221: astore        5
     223: astore        12
     225: astore        11
     227: aload         5
     229: astore        6
     231: aload         6
     233: invokeinterface #172,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     238: astore        7
     240: aload         7
     242: invokeinterface #178,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     247: ifeq          288
     250: aload         7
     252: invokeinterface #182,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     257: astore        8
     259: aload         8
     261: checkcast     #184                // class kotlin/collections/IndexedValue
     264: astore        9
     266: iconst_0
     267: istore        10
     269: aload         9
     271: invokevirtual #187                // Method kotlin/collections/IndexedValue.getValue:()Ljava/lang/Object;
     274: checkcast     #189                // class java/lang/Boolean
     277: invokevirtual #192                // Method java/lang/Boolean.booleanValue:()Z
     280: ifeq          240
     283: aload         8
     285: goto          289
     288: aconst_null
     289: astore        13
     291: aload         11
     293: aload         12
     295: aload         13
     297: dup
     298: invokestatic  #196                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     301: checkcast     #184                // class kotlin/collections/IndexedValue
     304: invokevirtual #200                // Method kotlin/collections/IndexedValue.getIndex:()I
     307: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     310: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     313: goto          404
     316: aload_0
     317: iload_1
     318: aaload
     319: invokestatic  #168                // Method kotlin/collections/ArraysKt.withIndex:([Z)Ljava/lang/Iterable;
     322: astore        5
     324: astore        11
     326: aload         5
     328: astore        6
     330: aload         6
     332: invokeinterface #172,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     337: astore        7
     339: aload         7
     341: invokeinterface #178,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     346: ifeq          387
     349: aload         7
     351: invokeinterface #182,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     356: astore        8
     358: aload         8
     360: checkcast     #184                // class kotlin/collections/IndexedValue
     363: astore        9
     365: iconst_0
     366: istore        10
     368: aload         9
     370: invokevirtual #187                // Method kotlin/collections/IndexedValue.getValue:()Ljava/lang/Object;
     373: checkcast     #189                // class java/lang/Boolean
     376: invokevirtual #192                // Method java/lang/Boolean.booleanValue:()Z
     379: ifeq          339
     382: aload         8
     384: goto          388
     387: aconst_null
     388: aload         11
     390: swap
     391: dup
     392: invokestatic  #196                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     395: checkcast     #184                // class kotlin/collections/IndexedValue
     398: invokevirtual #200                // Method kotlin/collections/IndexedValue.getIndex:()I
     401: invokestatic  #204                // Method java/lang/String.valueOf:(I)Ljava/lang/String;
     404: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     407: bipush        93
     409: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     412: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     415: goto          473
     418: new           #17                 // class java/lang/StringBuilder
     421: dup
     422: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
     425: bipush        32
     427: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     430: iload_2
     431: bipush        10
     433: if_icmpge     458
     436: new           #17                 // class java/lang/StringBuilder
     439: dup
     440: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
     443: bipush        32
     445: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     448: iload_2
     449: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     452: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     455: goto          462
     458: iload_2
     459: invokestatic  #204                // Method java/lang/String.valueOf:(I)Ljava/lang/String;
     462: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     465: bipush        32
     467: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     470: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     473: astore_3
     474: iload_1
     475: iconst_1
     476: iadd
     477: bipush        10
     479: irem
     480: ifne          508
     483: new           #17                 // class java/lang/StringBuilder
     486: dup
     487: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
     490: aload_3
     491: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     494: bipush        10
     496: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     499: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     502: checkcast     #39                 // class java/lang/CharSequence
     505: goto          512
     508: aload_3
     509: checkcast     #39                 // class java/lang/CharSequence
     512: areturn

  private static final java.lang.CharSequence formatPropagator$lambda$6(java.lang.String, int);
    Code:
       0: new           #17                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
       7: aload_0
       8: iconst_0
       9: aload_0
      10: invokevirtual #224                // Method java/lang/String.length:()I
      13: iload_1
      14: invokestatic  #204                // Method java/lang/String.valueOf:(I)Ljava/lang/String;
      17: invokevirtual #224                // Method java/lang/String.length:()I
      20: isub
      21: invokevirtual #228                // Method java/lang/String.subSequence:(II)Ljava/lang/CharSequence;
      24: invokevirtual #231                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      27: iload_1
      28: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      31: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      34: checkcast     #39                 // class java/lang/CharSequence
      37: areturn

  private static final java.lang.CharSequence formatPropagator$lambda$7(java.lang.String, int[]);
    Code:
       0: aload_1
       1: ldc           #233                // String it
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: nop
       7: aload_1
       8: arraylength
       9: ifne          16
      12: iconst_1
      13: goto          17
      16: iconst_0
      17: ifeq          28
      20: ldc           #235                // String [X]
      22: checkcast     #39                 // class java/lang/CharSequence
      25: goto          83
      28: aload_1
      29: arraylength
      30: iconst_1
      31: if_icmple     42
      34: ldc           #237                // String [?]
      36: checkcast     #39                 // class java/lang/CharSequence
      39: goto          83
      42: new           #17                 // class java/lang/StringBuilder
      45: dup
      46: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      49: aload_0
      50: iconst_0
      51: iconst_3
      52: aload_1
      53: iconst_0
      54: iaload
      55: invokestatic  #204                // Method java/lang/String.valueOf:(I)Ljava/lang/String;
      58: invokevirtual #224                // Method java/lang/String.length:()I
      61: isub
      62: invokestatic  #243                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      65: invokestatic  #249                // Method kotlin/text/StringsKt.slice:(Ljava/lang/String;Lkotlin/ranges/IntRange;)Ljava/lang/String;
      68: invokevirtual #68                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      71: aload_1
      72: iconst_0
      73: iaload
      74: invokevirtual #89                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      77: invokevirtual #72                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      80: checkcast     #39                 // class java/lang/CharSequence
      83: areturn
}


package com.radix2.algorithms.week1

interface UF {
    fun union(p: Int, q: Int)

    fun connected(p: Int, q: Int): Boolean
}

class QuickFindUF(size: Int) : UF {
    private val ids: IntArray = IntArray(size) { it }

    override fun connected(p: Int, q: Int): Boolean = ids[p] == ids[q]

    override fun union(p: Int, q: Int) {
        val pId = ids[p]
        val qId = ids[q]

        for (i in 0 until ids.size) {
            if (ids[i] == pId) {
                ids[i] = qId
            }
        }
    }
}

open class QuickUnionUF(size: Int) : UF {
    protected val ids: IntArray = IntArray(size) { it }

    override fun union(p: Int, q: Int) {
        val pRoot = root(p)
        val qRoot = root(q)

        ids[pRoot] = qRoot
    }

    override fun connected(p: Int, q: Int): Boolean = root(p) == root(q)

    protected open fun root(p: Int): Int {
        var i = p

        while (i != ids[i]) {
            i = ids[i]
        }

        return i
    }
}

open class WeightedQuickUnionUF(size: Int) : QuickUnionUF(size) {
    protected val size: IntArray = IntArray(size) { 1 }

    override fun union(p: Int, q: Int) {
        val pRoot = root(p)
        val qRoot = root(q)

        if (pRoot == qRoot) return

        if (size[pRoot] < size[qRoot]) {
            ids[pRoot] = ids[qRoot]
            size[qRoot] += size[pRoot]
        } else {
            ids[qRoot] = ids[pRoot]
            size[pRoot] += size[qRoot]
        }
    }
}

class WeightedQuickUnionWithPathCompressionUF(size: Int) : WeightedQuickUnionUF(size) {
    override fun root(p: Int): Int {
        var i = p

        while (i != ids[i]) {
            ids[i] = ids[ids[i]]
            i = ids[i]
        }

        return i
    }
}

fun main(args: Array<String>) {
    val uf = WeightedQuickUnionWithPathCompressionUF(10)

    uf.union(4, 3)
    uf.union(3, 8)
    uf.union(6, 5)
    uf.union(9, 4)
    uf.union(2, 1)
    uf.union(5, 0)
    uf.union(7, 2)
    uf.union(6, 1)
    uf.union(7, 3)

    //println(uf.find(3))
}

Compiled from "UnionFind.kt"
public final class com.radix2.algorithms.week1.UnionFindKt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF
       9: dup
      10: bipush        10
      12: invokespecial #21                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF."<init>":(I)V
      15: astore_1
      16: aload_1
      17: iconst_4
      18: iconst_3
      19: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      22: aload_1
      23: iconst_3
      24: bipush        8
      26: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      29: aload_1
      30: bipush        6
      32: iconst_5
      33: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      36: aload_1
      37: bipush        9
      39: iconst_4
      40: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      43: aload_1
      44: iconst_2
      45: iconst_1
      46: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      49: aload_1
      50: iconst_5
      51: iconst_0
      52: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      55: aload_1
      56: bipush        7
      58: iconst_2
      59: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      62: aload_1
      63: bipush        6
      65: iconst_1
      66: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      69: aload_1
      70: bipush        7
      72: iconst_3
      73: invokevirtual #25                 // Method com/radix2/algorithms/week1/WeightedQuickUnionWithPathCompressionUF.union:(II)V
      76: return
}


package com.radix2.algorithms.week2

fun IntArray.selectionSort() {
    for (i in 0 until size) {
        var j = i
        var minIndex = j

        while (j < size) {
            if (this[minIndex] > this[j]) {
                minIndex = j
            }

            j++
        }

        val temp = this[i]
        this[i] = this[minIndex]
        this[minIndex] = temp
    }
}

fun IntArray.insertionSort() {
    for (i in 0 until this.size) {
        var j = i

        while (j > 0) {
            if (this[j] < this[j - 1]) {
                val temp = this[j - 1]
                this[j - 1] = this[j]
                this[j] = temp
            } else {
                break
            }

            j--
        }
    }
}

enum class Color(val id: Int) {
    BLUE(0), WHITE(1), RED(2);
}

data class Pebble(val color: Color)

fun dutchNationalFlag(array: Array<Pebble>) {
    var left = 0
    var mid = 0
    var right = array.size - 1

    fun swap(i: Int, j: Int) {
        val temp = array[i]
        array[i] = array[j]
        array[j] = temp
    }

    while (mid <= right) {
        when {
            array[mid].color == Color.BLUE -> swap(left++, mid++)
            array[mid].color === Color.RED -> swap(mid, right--)
            array[mid].color == Color.WHITE -> mid++
        }
    }
}

fun main(args: Array<String>) {
    val array = arrayOf(Pebble(Color.WHITE), Pebble(Color.RED), Pebble(Color.BLUE), Pebble(Color.RED), Pebble(Color.WHITE), Pebble(Color.BLUE))

    dutchNationalFlag(array)

    val str = array.joinToString { pebble ->
        pebble.color.toString()
    }

    println(str)
}

Compiled from "Sorting.kt"
public final class com.radix2.algorithms.week2.SortingKt {
  public static final void selectionSort(int[]);
    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: arraylength
      10: istore_2
      11: iload_1
      12: iload_2
      13: if_icmpge     70
      16: iload_1
      17: istore_3
      18: iload_3
      19: istore        4
      21: iload_3
      22: aload_0
      23: arraylength
      24: if_icmpge     46
      27: aload_0
      28: iload         4
      30: iaload
      31: aload_0
      32: iload_3
      33: iaload
      34: if_icmple     40
      37: iload_3
      38: istore        4
      40: iinc          3, 1
      43: goto          21
      46: aload_0
      47: iload_1
      48: iaload
      49: istore        5
      51: aload_0
      52: iload_1
      53: aload_0
      54: iload         4
      56: iaload
      57: iastore
      58: aload_0
      59: iload         4
      61: iload         5
      63: iastore
      64: iinc          1, 1
      67: goto          11
      70: return

  public static final void insertionSort(int[]);
    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: arraylength
      10: istore_2
      11: iload_1
      12: iload_2
      13: if_icmpge     71
      16: iload_1
      17: istore_3
      18: iload_3
      19: ifle          65
      22: aload_0
      23: iload_3
      24: iaload
      25: aload_0
      26: iload_3
      27: iconst_1
      28: isub
      29: iaload
      30: if_icmpge     56
      33: aload_0
      34: iload_3
      35: iconst_1
      36: isub
      37: iaload
      38: istore        4
      40: aload_0
      41: iload_3
      42: iconst_1
      43: isub
      44: aload_0
      45: iload_3
      46: iaload
      47: iastore
      48: aload_0
      49: iload_3
      50: iload         4
      52: iastore
      53: goto          59
      56: goto          65
      59: iinc          3, -1
      62: goto          18
      65: iinc          1, 1
      68: goto          11
      71: return

  public static final void dutchNationalFlag(com.radix2.algorithms.week2.Pebble[]);
    Code:
       0: aload_0
       1: ldc           #28                 // String array
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: iconst_0
       9: istore_2
      10: aload_0
      11: arraylength
      12: iconst_1
      13: isub
      14: istore_3
      15: iload_2
      16: iload_3
      17: if_icmpgt     90
      20: nop
      21: aload_0
      22: iload_2
      23: aaload
      24: invokevirtual #34                 // Method com/radix2/algorithms/week2/Pebble.getColor:()Lcom/radix2/algorithms/week2/Color;
      27: getstatic     #40                 // Field com/radix2/algorithms/week2/Color.BLUE:Lcom/radix2/algorithms/week2/Color;
      30: if_acmpne     48
      33: aload_0
      34: iload_1
      35: iinc          1, 1
      38: iload_2
      39: iinc          2, 1
      42: invokestatic  #44                 // Method dutchNationalFlag$swap:([Lcom/radix2/algorithms/week2/Pebble;II)V
      45: goto          15
      48: aload_0
      49: iload_2
      50: aaload
      51: invokevirtual #34                 // Method com/radix2/algorithms/week2/Pebble.getColor:()Lcom/radix2/algorithms/week2/Color;
      54: getstatic     #47                 // Field com/radix2/algorithms/week2/Color.RED:Lcom/radix2/algorithms/week2/Color;
      57: if_acmpne     72
      60: aload_0
      61: iload_2
      62: iload_3
      63: iinc          3, -1
      66: invokestatic  #44                 // Method dutchNationalFlag$swap:([Lcom/radix2/algorithms/week2/Pebble;II)V
      69: goto          15
      72: aload_0
      73: iload_2
      74: aaload
      75: invokevirtual #34                 // Method com/radix2/algorithms/week2/Pebble.getColor:()Lcom/radix2/algorithms/week2/Color;
      78: getstatic     #50                 // Field com/radix2/algorithms/week2/Color.WHITE:Lcom/radix2/algorithms/week2/Color;
      81: if_acmpne     15
      84: iinc          2, 1
      87: goto          15
      90: return

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #58                 // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: bipush        6
       8: anewarray     #30                 // class com/radix2/algorithms/week2/Pebble
      11: astore_2
      12: aload_2
      13: iconst_0
      14: new           #30                 // class com/radix2/algorithms/week2/Pebble
      17: dup
      18: getstatic     #50                 // Field com/radix2/algorithms/week2/Color.WHITE:Lcom/radix2/algorithms/week2/Color;
      21: invokespecial #62                 // Method com/radix2/algorithms/week2/Pebble."<init>":(Lcom/radix2/algorithms/week2/Color;)V
      24: aastore
      25: aload_2
      26: iconst_1
      27: new           #30                 // class com/radix2/algorithms/week2/Pebble
      30: dup
      31: getstatic     #47                 // Field com/radix2/algorithms/week2/Color.RED:Lcom/radix2/algorithms/week2/Color;
      34: invokespecial #62                 // Method com/radix2/algorithms/week2/Pebble."<init>":(Lcom/radix2/algorithms/week2/Color;)V
      37: aastore
      38: aload_2
      39: iconst_2
      40: new           #30                 // class com/radix2/algorithms/week2/Pebble
      43: dup
      44: getstatic     #40                 // Field com/radix2/algorithms/week2/Color.BLUE:Lcom/radix2/algorithms/week2/Color;
      47: invokespecial #62                 // Method com/radix2/algorithms/week2/Pebble."<init>":(Lcom/radix2/algorithms/week2/Color;)V
      50: aastore
      51: aload_2
      52: iconst_3
      53: new           #30                 // class com/radix2/algorithms/week2/Pebble
      56: dup
      57: getstatic     #47                 // Field com/radix2/algorithms/week2/Color.RED:Lcom/radix2/algorithms/week2/Color;
      60: invokespecial #62                 // Method com/radix2/algorithms/week2/Pebble."<init>":(Lcom/radix2/algorithms/week2/Color;)V
      63: aastore
      64: aload_2
      65: iconst_4
      66: new           #30                 // class com/radix2/algorithms/week2/Pebble
      69: dup
      70: getstatic     #50                 // Field com/radix2/algorithms/week2/Color.WHITE:Lcom/radix2/algorithms/week2/Color;
      73: invokespecial #62                 // Method com/radix2/algorithms/week2/Pebble."<init>":(Lcom/radix2/algorithms/week2/Color;)V
      76: aastore
      77: aload_2
      78: iconst_5
      79: new           #30                 // class com/radix2/algorithms/week2/Pebble
      82: dup
      83: getstatic     #40                 // Field com/radix2/algorithms/week2/Color.BLUE:Lcom/radix2/algorithms/week2/Color;
      86: invokespecial #62                 // Method com/radix2/algorithms/week2/Pebble."<init>":(Lcom/radix2/algorithms/week2/Color;)V
      89: aastore
      90: aload_2
      91: astore_1
      92: aload_1
      93: invokestatic  #64                 // Method dutchNationalFlag:([Lcom/radix2/algorithms/week2/Pebble;)V
      96: aload_1
      97: aconst_null
      98: aconst_null
      99: aconst_null
     100: iconst_0
     101: aconst_null
     102: invokedynamic #83,  0             // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     107: bipush        31
     109: aconst_null
     110: invokestatic  #89                 // Method kotlin/collections/ArraysKt.joinToString$default:([Ljava/lang/Object;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     113: astore_2
     114: getstatic     #95                 // Field java/lang/System.out:Ljava/io/PrintStream;
     117: aload_2
     118: invokevirtual #101                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     121: return

  private static final void dutchNationalFlag$swap(com.radix2.algorithms.week2.Pebble[], int, int);
    Code:
       0: aload_0
       1: iload_1
       2: aaload
       3: astore_3
       4: aload_0
       5: iload_1
       6: aload_0
       7: iload_2
       8: aaload
       9: aastore
      10: aload_0
      11: iload_2
      12: aload_3
      13: aastore
      14: return

  private static final java.lang.CharSequence main$lambda$0(com.radix2.algorithms.week2.Pebble);
    Code:
       0: aload_0
       1: ldc           #108                // String pebble
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #34                 // Method com/radix2/algorithms/week2/Pebble.getColor:()Lcom/radix2/algorithms/week2/Color;
      10: invokevirtual #112                // Method com/radix2/algorithms/week2/Color.toString:()Ljava/lang/String;
      13: checkcast     #114                // class java/lang/CharSequence
      16: areturn
}