package sorting

//sort the left half
//sort the right half
//merge both the half

fun main() {
    val input = intArrayOf(23, 47, 81, -1, 95, 7, 14, 39, 55, 63, 74)
    val temp = IntArray(input.size) { -1 }

    println("before sorting")
    for (i in input) {
        println(i)
    }

    mergeSort(input, temp)
    println("after sorting")
    for (i in input) {
        println(i)
    }
}

fun mergeSort(input: IntArray, temp: IntArray) {
    val start = 0
    val end = input.size - 1
    mergeSortRec(input, temp, start, end)
}

fun mergeSortRec(input: IntArray, temp: IntArray, lowerBound: Int, upperBound: Int) {

    if (lowerBound == upperBound) {
        return
    }
    val mid = lowerBound + (upperBound - lowerBound) / 2

    mergeSortRec(input, temp, lowerBound, mid)
    mergeSortRec(input, temp, mid + 1, upperBound)
    merge(input, temp, lowerBound, mid + 1, upperBound)
}

fun merge(input: IntArray, temp: IntArray, start: Int, middle: Int, upperBound: Int) {
    var j = 0
    val mid = middle - 1
    var highPtr = middle
    var lowPtr = start
    val size = upperBound - start + 1

    while (lowPtr <= mid && highPtr <= upperBound) {
        if (input[lowPtr] < input[highPtr]) {
            temp[j++] = input[lowPtr++]
        } else {
            temp[j++] = input[highPtr++]
        }
    }

    while (lowPtr <= mid) {
        temp[j++] = input[lowPtr++]
    }

    while (highPtr <= upperBound) {
        temp[j++] = input[highPtr++]
    }

    for (k in 0 until size) {
        input[start + k] = temp[k]
    }
}

Compiled from "MergeSort.kt"
public final class sorting.MergeSortKt {
  public static final void main();
    Code:
       0: bipush        11
       2: newarray       int
       4: astore_1
       5: aload_1
       6: iconst_0
       7: bipush        23
       9: iastore
      10: aload_1
      11: iconst_1
      12: bipush        47
      14: iastore
      15: aload_1
      16: iconst_2
      17: bipush        81
      19: iastore
      20: aload_1
      21: iconst_3
      22: iconst_m1
      23: iastore
      24: aload_1
      25: iconst_4
      26: bipush        95
      28: iastore
      29: aload_1
      30: iconst_5
      31: bipush        7
      33: iastore
      34: aload_1
      35: bipush        6
      37: bipush        14
      39: iastore
      40: aload_1
      41: bipush        7
      43: bipush        39
      45: iastore
      46: aload_1
      47: bipush        8
      49: bipush        55
      51: iastore
      52: aload_1
      53: bipush        9
      55: bipush        63
      57: iastore
      58: aload_1
      59: bipush        10
      61: bipush        74
      63: iastore
      64: aload_1
      65: astore_0
      66: iconst_0
      67: istore_2
      68: aload_0
      69: arraylength
      70: istore_3
      71: iload_3
      72: newarray       int
      74: astore        4
      76: iload_2
      77: iload_3
      78: if_icmpge     96
      81: iload_2
      82: istore        5
      84: aload         4
      86: iload         5
      88: iconst_m1
      89: iastore
      90: iinc          2, 1
      93: goto          76
      96: aload         4
      98: astore_1
      99: ldc           #8                  // String before sorting
     101: getstatic     #14                 // Field java/lang/System.out:Ljava/io/PrintStream;
     104: swap
     105: invokevirtual #20                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     108: iconst_0
     109: istore_2
     110: aload_0
     111: arraylength
     112: istore_3
     113: iload_2
     114: iload_3
     115: if_icmpge     137
     118: aload_0
     119: iload_2
     120: iaload
     121: istore        4
     123: getstatic     #14                 // Field java/lang/System.out:Ljava/io/PrintStream;
     126: iload         4
     128: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V
     131: iinc          2, 1
     134: goto          113
     137: aload_0
     138: aload_1
     139: invokestatic  #27                 // Method mergeSort:([I[I)V
     142: ldc           #29                 // String after sorting
     144: getstatic     #14                 // Field java/lang/System.out:Ljava/io/PrintStream;
     147: swap
     148: invokevirtual #20                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     151: iconst_0
     152: istore_2
     153: aload_0
     154: arraylength
     155: istore_3
     156: iload_2
     157: iload_3
     158: if_icmpge     180
     161: aload_0
     162: iload_2
     163: iaload
     164: istore        4
     166: getstatic     #14                 // Field java/lang/System.out:Ljava/io/PrintStream;
     169: iload         4
     171: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V
     174: iinc          2, 1
     177: goto          156
     180: return

  public static final void mergeSort(int[], int[]);
    Code:
       0: aload_0
       1: ldc           #37                 // String input
       3: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #44                 // String temp
       9: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: iconst_0
      13: istore_2
      14: aload_0
      15: arraylength
      16: iconst_1
      17: isub
      18: istore_3
      19: aload_0
      20: aload_1
      21: iload_2
      22: iload_3
      23: invokestatic  #48                 // Method mergeSortRec:([I[III)V
      26: return

  public static final void mergeSortRec(int[], int[], int, int);
    Code:
       0: aload_0
       1: ldc           #37                 // String input
       3: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #44                 // String temp
       9: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: iload_2
      13: iload_3
      14: if_icmpne     18
      17: return
      18: iload_2
      19: iload_3
      20: iload_2
      21: isub
      22: iconst_2
      23: idiv
      24: iadd
      25: istore        4
      27: aload_0
      28: aload_1
      29: iload_2
      30: iload         4
      32: invokestatic  #48                 // Method mergeSortRec:([I[III)V
      35: aload_0
      36: aload_1
      37: iload         4
      39: iconst_1
      40: iadd
      41: iload_3
      42: invokestatic  #48                 // Method mergeSortRec:([I[III)V
      45: aload_0
      46: aload_1
      47: iload_2
      48: iload         4
      50: iconst_1
      51: iadd
      52: iload_3
      53: invokestatic  #54                 // Method merge:([I[IIII)V
      56: return

  public static final void merge(int[], int[], int, int, int);
    Code:
       0: aload_0
       1: ldc           #37                 // String input
       3: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #44                 // String temp
       9: invokestatic  #43                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: iconst_0
      13: istore        5
      15: iload_3
      16: iconst_1
      17: isub
      18: istore        6
      20: iload_3
      21: istore        7
      23: iload_2
      24: istore        8
      26: iload         4
      28: iload_2
      29: isub
      30: iconst_1
      31: iadd
      32: istore        9
      34: iload         8
      36: iload         6
      38: if_icmpgt     93
      41: iload         7
      43: iload         4
      45: if_icmpgt     93
      48: aload_0
      49: iload         8
      51: iaload
      52: aload_0
      53: iload         7
      55: iaload
      56: if_icmpge     76
      59: aload_1
      60: iload         5
      62: iinc          5, 1
      65: aload_0
      66: iload         8
      68: iinc          8, 1
      71: iaload
      72: iastore
      73: goto          34
      76: aload_1
      77: iload         5
      79: iinc          5, 1
      82: aload_0
      83: iload         7
      85: iinc          7, 1
      88: iaload
      89: iastore
      90: goto          34
      93: iload         8
      95: iload         6
      97: if_icmpgt     117
     100: aload_1
     101: iload         5
     103: iinc          5, 1
     106: aload_0
     107: iload         8
     109: iinc          8, 1
     112: iaload
     113: iastore
     114: goto          93
     117: iload         7
     119: iload         4
     121: if_icmpgt     141
     124: aload_1
     125: iload         5
     127: iinc          5, 1
     130: aload_0
     131: iload         7
     133: iinc          7, 1
     136: iaload
     137: iastore
     138: goto          117
     141: iconst_0
     142: istore        10
     144: iload         10
     146: iload         9
     148: if_icmpge     167
     151: aload_0
     152: iload_2
     153: iload         10
     155: iadd
     156: aload_1
     157: iload         10
     159: iaload
     160: iastore
     161: iinc          10, 1
     164: goto          144
     167: return

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


package krangl.util

//
// Functional Helpers (missing in kotlin-stdlib)
//

// todo should they go into separate artifact?

// adopted from https://stackoverflow.com/questions/44429419/what-is-basic-difference-between-fold-and-reduce-in-kotlin-when-to-use-which
// desc from https://stackoverflow.com/questions/17408880/reduce-fold-or-scan-left-right
/** scanLeft and scanRight cumulate a collection of intermediate cumulative results using a start value. */
fun <T, R> Sequence<T>.scanLeft(initial: R, operation: (R, T) -> R) =
    fold(listOf(initial), { list, curVal -> list + operation(list.last(), curVal) })

fun <T, R> Sequence<T>.foldWhile(initial: R, operation: (R, T) -> R, predicate: (R) -> Boolean): R =
    scanLeft(initial, operation).takeWhile { predicate(it) }.last()

fun <T, R> Sequence<T>.foldUntil(initial: R, operation: (R, T) -> R, predicate: (R) -> Boolean): R? =
    scanLeft(initial, operation).dropWhile { predicate(it) }.firstOrNull()

fun <T, R> Sequence<T>.reduceUntil(operation: (R?, T) -> R, predicate: (R) -> Boolean): R? =
    drop(1).scanLeft(operation(null, first()), operation).dropWhile { predicate(it) }.firstOrNull()

// Misc helpers

internal fun Sequence<*>.joinToMaxLengthString(
    maxLength: Int = 80,
    separator: CharSequence = ", ",
    truncated: CharSequence = "...",
    transform: ((Any?) -> String) = { it?.toString() ?: "" }
): String =
    reduceUntil({ a: String?, b -> (a?.let { it + separator } ?: "") + transform(b) }, { it.length < maxLength })?.let {
        when {
            it.length < maxLength -> it
            else -> it.substring(0, maxLength) + truncated
        }
    } ?: joinToString(transform = { transform(it) })

//fun main(args: Array<String>) {
//    //    listOf(1,2,3, 4).asSequence().scanLeft(0, { a, b -> a+b}).also{print(it)}
//
//    //    listOf("foo", "haus", "baum", "lala").asSequence().scanLeft("", {a,b ->a+b}).also{print(it)}
//    listOf("foo", "haus", "baum", "lala").asSequence().foldWhile("", { a, b -> a + b }, {
//        it.length < 30
//    }).also { print(it) }
//}

Compiled from "Util.kt"
public final class krangl.util.UtilKt {
  public static final <T, R> java.util.List<R> scanLeft(kotlin.sequences.Sequence<? extends T>, R, kotlin.jvm.functions.Function2<? super R, ? super T, ? extends R>);
    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_2
       7: ldc           #18                 // String operation
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: astore_3
      14: aload_1
      15: invokestatic  #24                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      18: astore        4
      20: iconst_0
      21: istore        5
      23: aload         4
      25: astore        6
      27: aload_3
      28: invokeinterface #30,  1           // InterfaceMethod kotlin/sequences/Sequence.iterator:()Ljava/util/Iterator;
      33: astore        7
      35: aload         7
      37: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      42: ifeq          91
      45: aload         7
      47: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      52: astore        8
      54: aload         6
      56: aload         8
      58: astore        9
      60: astore        10
      62: iconst_0
      63: istore        11
      65: aload         10
      67: checkcast     #42                 // class java/util/Collection
      70: aload_2
      71: aload         10
      73: invokestatic  #46                 // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
      76: aload         9
      78: invokeinterface #52,  3           // InterfaceMethod kotlin/jvm/functions/Function2.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      83: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Object;)Ljava/util/List;
      86: astore        6
      88: goto          35
      91: aload         6
      93: areturn

  public static final <T, R> R foldWhile(kotlin.sequences.Sequence<? extends T>, R, kotlin.jvm.functions.Function2<? super R, ? super T, ? extends R>, kotlin.jvm.functions.Function1<? super R, java.lang.Boolean>);
    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_2
       7: ldc           #18                 // String operation
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #78                 // String predicate
      15: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_0
      19: aload_1
      20: aload_2
      21: invokestatic  #80                 // Method scanLeft:(Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List;
      24: checkcast     #82                 // class java/lang/Iterable
      27: astore        4
      29: iconst_0
      30: istore        5
      32: new           #84                 // class java/util/ArrayList
      35: dup
      36: invokespecial #88                 // Method java/util/ArrayList."<init>":()V
      39: astore        6
      41: aload         4
      43: invokeinterface #89,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      48: astore        7
      50: aload         7
      52: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      57: ifeq          107
      60: aload         7
      62: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      67: astore        8
      69: aload         8
      71: astore        9
      73: iconst_0
      74: istore        10
      76: aload_3
      77: aload         9
      79: invokeinterface #94,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
      84: checkcast     #96                 // class java/lang/Boolean
      87: invokevirtual #99                 // Method java/lang/Boolean.booleanValue:()Z
      90: ifne          96
      93: goto          107
      96: aload         6
      98: aload         8
     100: invokevirtual #103                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     103: pop
     104: goto          50
     107: aload         6
     109: checkcast     #73                 // class java/util/List
     112: invokestatic  #46                 // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     115: areturn

  public static final <T, R> R foldUntil(kotlin.sequences.Sequence<? extends T>, R, kotlin.jvm.functions.Function2<? super R, ? super T, ? extends R>, kotlin.jvm.functions.Function1<? super R, java.lang.Boolean>);
    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_2
       7: ldc           #18                 // String operation
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #78                 // String predicate
      15: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_0
      19: aload_1
      20: aload_2
      21: invokestatic  #80                 // Method scanLeft:(Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List;
      24: checkcast     #82                 // class java/lang/Iterable
      27: astore        4
      29: iconst_0
      30: istore        5
      32: iconst_0
      33: istore        6
      35: new           #84                 // class java/util/ArrayList
      38: dup
      39: invokespecial #88                 // Method java/util/ArrayList."<init>":()V
      42: astore        7
      44: aload         4
      46: invokeinterface #89,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      51: astore        8
      53: aload         8
      55: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      60: ifeq          126
      63: aload         8
      65: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      70: astore        9
      72: iload         6
      74: ifeq          88
      77: aload         7
      79: aload         9
      81: invokevirtual #103                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      84: pop
      85: goto          53
      88: aload         9
      90: astore        10
      92: iconst_0
      93: istore        11
      95: aload_3
      96: aload         10
      98: invokeinterface #94,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     103: checkcast     #96                 // class java/lang/Boolean
     106: invokevirtual #99                 // Method java/lang/Boolean.booleanValue:()Z
     109: ifne          53
     112: aload         7
     114: aload         9
     116: invokevirtual #103                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     119: pop
     120: iconst_1
     121: istore        6
     123: goto          53
     126: aload         7
     128: checkcast     #73                 // class java/util/List
     131: invokestatic  #118                // Method kotlin/collections/CollectionsKt.firstOrNull:(Ljava/util/List;)Ljava/lang/Object;
     134: areturn

  public static final <T, R> R reduceUntil(kotlin.sequences.Sequence<? extends T>, kotlin.jvm.functions.Function2<? super R, ? super T, ? extends R>, kotlin.jvm.functions.Function1<? super R, java.lang.Boolean>);
    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_1
       7: ldc           #18                 // String operation
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: ldc           #78                 // String predicate
      15: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_0
      19: iconst_1
      20: invokestatic  #133                // Method kotlin/sequences/SequencesKt.drop:(Lkotlin/sequences/Sequence;I)Lkotlin/sequences/Sequence;
      23: aload_1
      24: aconst_null
      25: aload_0
      26: invokestatic  #137                // Method kotlin/sequences/SequencesKt.first:(Lkotlin/sequences/Sequence;)Ljava/lang/Object;
      29: invokeinterface #52,  3           // InterfaceMethod kotlin/jvm/functions/Function2.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      34: aload_1
      35: invokestatic  #80                 // Method scanLeft:(Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List;
      38: checkcast     #82                 // class java/lang/Iterable
      41: astore_3
      42: iconst_0
      43: istore        4
      45: iconst_0
      46: istore        5
      48: new           #84                 // class java/util/ArrayList
      51: dup
      52: invokespecial #88                 // Method java/util/ArrayList."<init>":()V
      55: astore        6
      57: aload_3
      58: invokeinterface #89,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      63: astore        7
      65: aload         7
      67: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      72: ifeq          138
      75: aload         7
      77: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      82: astore        8
      84: iload         5
      86: ifeq          100
      89: aload         6
      91: aload         8
      93: invokevirtual #103                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      96: pop
      97: goto          65
     100: aload         8
     102: astore        9
     104: iconst_0
     105: istore        10
     107: aload_2
     108: aload         9
     110: invokeinterface #94,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     115: checkcast     #96                 // class java/lang/Boolean
     118: invokevirtual #99                 // Method java/lang/Boolean.booleanValue:()Z
     121: ifne          65
     124: aload         6
     126: aload         8
     128: invokevirtual #103                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     131: pop
     132: iconst_1
     133: istore        5
     135: goto          65
     138: aload         6
     140: checkcast     #73                 // class java/util/List
     143: invokestatic  #118                // Method kotlin/collections/CollectionsKt.firstOrNull:(Ljava/util/List;)Ljava/lang/Object;
     146: areturn

  public static final java.lang.String joinToMaxLengthString(kotlin.sequences.Sequence<?>, int, java.lang.CharSequence, java.lang.CharSequence, kotlin.jvm.functions.Function1<java.lang.Object, java.lang.String>);
    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_2
       7: ldc           #144                // String separator
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #146                // String truncated
      15: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload         4
      20: ldc           #148                // String transform
      22: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      25: aload_0
      26: aload         4
      28: aload_2
      29: invokedynamic #166,  0            // InvokeDynamic #0:invoke:(Lkotlin/jvm/functions/Function1;Ljava/lang/CharSequence;)Lkotlin/jvm/functions/Function2;
      34: iload_1
      35: invokedynamic #177,  0            // InvokeDynamic #1:invoke:(I)Lkotlin/jvm/functions/Function1;
      40: invokestatic  #179                // Method reduceUntil:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
      43: checkcast     #181                // class java/lang/String
      46: dup
      47: ifnull        106
      50: astore        5
      52: iconst_0
      53: istore        6
      55: nop
      56: aload         5
      58: invokevirtual #185                // Method java/lang/String.length:()I
      61: iload_1
      62: if_icmpge     70
      65: aload         5
      67: goto          100
      70: new           #187                // class java/lang/StringBuilder
      73: dup
      74: invokespecial #188                // Method java/lang/StringBuilder."<init>":()V
      77: aload         5
      79: iconst_0
      80: iload_1
      81: invokevirtual #192                // Method java/lang/String.substring:(II)Ljava/lang/String;
      84: dup
      85: ldc           #194                // String substring(...)
      87: invokestatic  #197                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      90: invokevirtual #201                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      93: aload_3
      94: invokevirtual #204                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      97: invokevirtual #208                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     100: nop
     101: nop
     102: dup
     103: ifnonnull     126
     106: pop
     107: aload_0
     108: aconst_null
     109: aconst_null
     110: aconst_null
     111: iconst_0
     112: aconst_null
     113: aload         4
     115: invokedynamic #218,  0            // InvokeDynamic #2:invoke:(Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1;
     120: bipush        31
     122: aconst_null
     123: invokestatic  #222                // Method kotlin/sequences/SequencesKt.joinToString$default:(Lkotlin/sequences/Sequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     126: areturn

  public static java.lang.String joinToMaxLengthString$default(kotlin.sequences.Sequence, int, java.lang.CharSequence, java.lang.CharSequence, kotlin.jvm.functions.Function1, int, java.lang.Object);
    Code:
       0: iload         5
       2: iconst_1
       3: iand
       4: ifeq          10
       7: bipush        80
       9: istore_1
      10: iload         5
      12: iconst_2
      13: iand
      14: ifeq          23
      17: ldc           #233                // String ,
      19: checkcast     #229                // class java/lang/CharSequence
      22: astore_2
      23: iload         5
      25: iconst_4
      26: iand
      27: ifeq          36
      30: ldc           #235                // String ...
      32: checkcast     #229                // class java/lang/CharSequence
      35: astore_3
      36: iload         5
      38: bipush        8
      40: iand
      41: ifeq          51
      44: invokedynamic #244,  0            // InvokeDynamic #3:invoke:()Lkotlin/jvm/functions/Function1;
      49: astore        4
      51: aload_0
      52: iload_1
      53: aload_2
      54: aload_3
      55: aload         4
      57: invokestatic  #246                // Method joinToMaxLengthString:(Lkotlin/sequences/Sequence;ILjava/lang/CharSequence;Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/String;
      60: areturn

  private static final java.lang.String joinToMaxLengthString$lambda$4(java.lang.Object);
    Code:
       0: aload_0
       1: dup
       2: ifnull        12
       5: invokevirtual #247                // Method java/lang/Object.toString:()Ljava/lang/String;
       8: dup
       9: ifnonnull     15
      12: pop
      13: ldc           #249                // String
      15: areturn

  private static final java.lang.String joinToMaxLengthString$lambda$6(kotlin.jvm.functions.Function1, java.lang.CharSequence, java.lang.String, java.lang.Object);
    Code:
       0: new           #187                // class java/lang/StringBuilder
       3: dup
       4: invokespecial #188                // Method java/lang/StringBuilder."<init>":()V
       7: aload_2
       8: dup
       9: ifnull        46
      12: astore        4
      14: astore        6
      16: iconst_0
      17: istore        5
      19: new           #187                // class java/lang/StringBuilder
      22: dup
      23: invokespecial #188                // Method java/lang/StringBuilder."<init>":()V
      26: aload         4
      28: invokevirtual #201                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      31: aload_1
      32: invokevirtual #204                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      35: invokevirtual #208                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      38: aload         6
      40: swap
      41: nop
      42: dup
      43: ifnonnull     49
      46: pop
      47: ldc           #249                // String
      49: invokevirtual #201                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      52: aload_0
      53: aload_3
      54: invokeinterface #94,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
      59: checkcast     #181                // class java/lang/String
      62: invokevirtual #201                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      65: invokevirtual #208                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      68: areturn

  private static final boolean joinToMaxLengthString$lambda$7(int, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #255                // String it
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokevirtual #185                // Method java/lang/String.length:()I
      10: iload_0
      11: if_icmpge     18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: ireturn

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


package org.rgoussey.aoc2023.day3

import java.io.File
import kotlin.math.max
import kotlin.math.min

fun main() {
    val lines = File({}.javaClass.getResource("/day3/input.txt")!!.toURI()).readLines();

    process(lines);
}

fun process(lines: List<String>) {
    val characters = mutableListOf<MutableList<Char>>()
    val symbols = mutableListOf<MutableList<Boolean>>()
    val numbers = mutableListOf<MutableList<Boolean>>()
    val closeToSymbol = mutableListOf<MutableList<Boolean>>()
    for (i in lines.indices) {
        characters.add(i, mutableListOf())
        symbols.add(i, mutableListOf())
        numbers.add(i, mutableListOf())
        closeToSymbol.add(i, mutableListOf())
        for (j in lines[i].indices) {
            val currentChar = lines[i][j]
            characters[i].add(j, currentChar)
            val isSymbol = isSymbol(currentChar)
            symbols[i].add(j, isSymbol)
            numbers[i].add(j, isNumber(currentChar))
        }
    }

    for (i in lines.indices) {
        for (j in lines[i].indices) {
            closeToSymbol[i].add(j, adjacentToSymbol(symbols, i, j))
        }
    }

    printMap(symbols)
    printMap(numbers)
    printMap(closeToSymbol)

    var sum = 0;
    for (i in characters.indices) {
        var currentNumber = "";
        var lastNumberIndex = 0;
        var numberIsValid = false;
        for (j in characters[i].indices) {
            val isNumber = numbers[i][j]
            if (isNumber) {
                numberIsValid = numberIsValid or adjacentToSymbol(symbols, i, j)
                lastNumberIndex = j
                currentNumber += characters[i][j]
                val endOfLine = j == characters[i].size-1
                if (endOfLine) {
                    val number = Integer.parseInt(currentNumber)
                    if (numberIsValid) {
//                        println("Valid number $number")
                        sum += number;
                    } else {
//                        println("     Not valid number $number")
                    }
                    currentNumber = ""
                    lastNumberIndex = 0;
                }
            } else {
                val numberEnded = lastNumberIndex + 1 == j
                if (numberEnded && currentNumber != "") {
                    val number = Integer.parseInt(currentNumber)
//                    println("Number is detected %s".format(number))
                    if (numberIsValid) {
//                        println("Valid number $number")
                        sum += number;
                    } else {
//                        println("      Not valid number $number")
                    }
                    currentNumber = "";
                    numberIsValid=false
                }
                lastNumberIndex = 0;
            }
        }
    }
    println("Sum is $sum")
}

fun printMap(map: MutableList<MutableList<Boolean>>) {
    for (i in map.indices) {
        for (j in map[i].indices) {
            if (map[i][j]) {
                print('x')
            } else {
                print('.')
            }
        }
        print("\n");
    }
    print("\n");

}

fun adjacentToSymbol(symbols: MutableList<MutableList<Boolean>>, x: Int, y: Int): Boolean {
    for (i in max(x - 1, 0)..min(x + 1, symbols.size - 1)) {
        for (j in max(y - 1, 0)..min(y + 1, symbols[x].size - 1)) {
            if (symbols[i][j]) {
                return true
            }
        }
    }
    return false;
}

fun isSymbol(char: Char): Boolean {
    return !isNumber(char) && char != '.';
}

fun isNumber(char: Char): Boolean {
    return char in '0'..'9';
}

Compiled from "Main.kt"
public final class org.rgoussey.aoc2023.day3.MainKt {
  public static final void main();
    Code:
       0: new           #8                  // class java/io/File
       3: dup
       4: invokedynamic #27,  0             // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function0;
       9: invokevirtual #31                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
      12: ldc           #33                 // String /day3/input.txt
      14: invokevirtual #39                 // Method java/lang/Class.getResource:(Ljava/lang/String;)Ljava/net/URL;
      17: dup
      18: invokestatic  #45                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      21: invokevirtual #51                 // Method java/net/URL.toURI:()Ljava/net/URI;
      24: invokespecial #55                 // Method java/io/File."<init>":(Ljava/net/URI;)V
      27: aconst_null
      28: iconst_1
      29: aconst_null
      30: invokestatic  #61                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      33: astore_0
      34: aload_0
      35: invokestatic  #65                 // Method process:(Ljava/util/List;)V
      38: return

  public static final void process(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #70                 // String lines
       3: invokestatic  #74                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #76                 // class java/util/ArrayList
       9: dup
      10: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
      13: checkcast     #80                 // class java/util/List
      16: astore_1
      17: new           #76                 // class java/util/ArrayList
      20: dup
      21: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
      24: checkcast     #80                 // class java/util/List
      27: astore_2
      28: new           #76                 // class java/util/ArrayList
      31: dup
      32: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
      35: checkcast     #80                 // class java/util/List
      38: astore_3
      39: new           #76                 // class java/util/ArrayList
      42: dup
      43: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
      46: checkcast     #80                 // class java/util/List
      49: astore        4
      51: iconst_0
      52: istore        5
      54: aload_0
      55: checkcast     #82                 // class java/util/Collection
      58: invokeinterface #86,  1           // InterfaceMethod java/util/Collection.size:()I
      63: istore        6
      65: iload         5
      67: iload         6
      69: if_icmpge     282
      72: aload_1
      73: iload         5
      75: new           #76                 // class java/util/ArrayList
      78: dup
      79: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
      82: checkcast     #80                 // class java/util/List
      85: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
      90: aload_2
      91: iload         5
      93: new           #76                 // class java/util/ArrayList
      96: dup
      97: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
     100: checkcast     #80                 // class java/util/List
     103: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
     108: aload_3
     109: iload         5
     111: new           #76                 // class java/util/ArrayList
     114: dup
     115: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
     118: checkcast     #80                 // class java/util/List
     121: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
     126: aload         4
     128: iload         5
     130: new           #76                 // class java/util/ArrayList
     133: dup
     134: invokespecial #78                 // Method java/util/ArrayList."<init>":()V
     137: checkcast     #80                 // class java/util/List
     140: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
     145: iconst_0
     146: istore        7
     148: aload_0
     149: iload         5
     151: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     156: checkcast     #96                 // class java/lang/CharSequence
     159: invokeinterface #99,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     164: istore        8
     166: iload         7
     168: iload         8
     170: if_icmpge     276
     173: aload_0
     174: iload         5
     176: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     181: checkcast     #101                // class java/lang/String
     184: iload         7
     186: invokevirtual #105                // Method java/lang/String.charAt:(I)C
     189: istore        9
     191: aload_1
     192: iload         5
     194: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     199: checkcast     #80                 // class java/util/List
     202: iload         7
     204: iload         9
     206: invokestatic  #111                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     209: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
     214: iload         9
     216: invokestatic  #115                // Method isSymbol:(C)Z
     219: istore        10
     221: aload_2
     222: iload         5
     224: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     229: checkcast     #80                 // class java/util/List
     232: iload         7
     234: iload         10
     236: invokestatic  #120                // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
     239: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
     244: aload_3
     245: iload         5
     247: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     252: checkcast     #80                 // class java/util/List
     255: iload         7
     257: iload         9
     259: invokestatic  #123                // Method isNumber:(C)Z
     262: invokestatic  #120                // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
     265: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
     270: iinc          7, 1
     273: goto          166
     276: iinc          5, 1
     279: goto          65
     282: iconst_0
     283: istore        5
     285: aload_0
     286: checkcast     #82                 // class java/util/Collection
     289: invokeinterface #86,  1           // InterfaceMethod java/util/Collection.size:()I
     294: istore        6
     296: iload         5
     298: iload         6
     300: if_icmpge     373
     303: iconst_0
     304: istore        7
     306: aload_0
     307: iload         5
     309: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     314: checkcast     #96                 // class java/lang/CharSequence
     317: invokeinterface #99,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     322: istore        8
     324: iload         7
     326: iload         8
     328: if_icmpge     367
     331: aload         4
     333: iload         5
     335: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     340: checkcast     #80                 // class java/util/List
     343: iload         7
     345: aload_2
     346: iload         5
     348: iload         7
     350: invokestatic  #127                // Method adjacentToSymbol:(Ljava/util/List;II)Z
     353: invokestatic  #120                // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
     356: invokeinterface #90,  3           // InterfaceMethod java/util/List.add:(ILjava/lang/Object;)V
     361: iinc          7, 1
     364: goto          324
     367: iinc          5, 1
     370: goto          296
     373: aload_2
     374: invokestatic  #130                // Method printMap:(Ljava/util/List;)V
     377: aload_3
     378: invokestatic  #130                // Method printMap:(Ljava/util/List;)V
     381: aload         4
     383: invokestatic  #130                // Method printMap:(Ljava/util/List;)V
     386: iconst_0
     387: istore        5
     389: iconst_0
     390: istore        6
     392: aload_1
     393: checkcast     #82                 // class java/util/Collection
     396: invokeinterface #86,  1           // InterfaceMethod java/util/Collection.size:()I
     401: istore        7
     403: iload         6
     405: iload         7
     407: if_icmpge     676
     410: ldc           #132                // String
     412: astore        8
     414: iconst_0
     415: istore        9
     417: iconst_0
     418: istore        10
     420: iconst_0
     421: istore        11
     423: aload_1
     424: iload         6
     426: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     431: checkcast     #82                 // class java/util/Collection
     434: invokeinterface #86,  1           // InterfaceMethod java/util/Collection.size:()I
     439: istore        12
     441: iload         11
     443: iload         12
     445: if_icmpge     670
     448: aload_3
     449: iload         6
     451: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     456: checkcast     #80                 // class java/util/List
     459: iload         11
     461: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     466: checkcast     #117                // class java/lang/Boolean
     469: invokevirtual #136                // Method java/lang/Boolean.booleanValue:()Z
     472: istore        13
     474: iload         13
     476: ifeq          604
     479: iload         10
     481: aload_2
     482: iload         6
     484: iload         11
     486: invokestatic  #127                // Method adjacentToSymbol:(Ljava/util/List;II)Z
     489: ior
     490: istore        10
     492: iload         11
     494: istore        9
     496: new           #138                // class java/lang/StringBuilder
     499: dup
     500: invokespecial #139                // Method java/lang/StringBuilder."<init>":()V
     503: aload         8
     505: invokevirtual #143                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     508: aload_1
     509: iload         6
     511: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     516: checkcast     #80                 // class java/util/List
     519: iload         11
     521: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     526: checkcast     #107                // class java/lang/Character
     529: invokevirtual #147                // Method java/lang/Character.charValue:()C
     532: invokevirtual #150                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     535: invokevirtual #154                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     538: astore        8
     540: iload         11
     542: aload_1
     543: iload         6
     545: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     550: checkcast     #80                 // class java/util/List
     553: invokeinterface #155,  1          // InterfaceMethod java/util/List.size:()I
     558: iconst_1
     559: isub
     560: if_icmpne     567
     563: iconst_1
     564: goto          568
     567: iconst_0
     568: istore        14
     570: iload         14
     572: ifeq          664
     575: aload         8
     577: invokestatic  #161                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     580: istore        15
     582: iload         10
     584: ifeq          594
     587: iload         5
     589: iload         15
     591: iadd
     592: istore        5
     594: ldc           #132                // String
     596: astore        8
     598: iconst_0
     599: istore        9
     601: goto          664
     604: iload         9
     606: iconst_1
     607: iadd
     608: iload         11
     610: if_icmpne     617
     613: iconst_1
     614: goto          618
     617: iconst_0
     618: istore        14
     620: iload         14
     622: ifeq          661
     625: aload         8
     627: ldc           #132                // String
     629: invokestatic  #165                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     632: ifne          661
     635: aload         8
     637: invokestatic  #161                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     640: istore        15
     642: iload         10
     644: ifeq          654
     647: iload         5
     649: iload         15
     651: iadd
     652: istore        5
     654: ldc           #132                // String
     656: astore        8
     658: iconst_0
     659: istore        10
     661: iconst_0
     662: istore        9
     664: iinc          11, 1
     667: goto          441
     670: iinc          6, 1
     673: goto          403
     676: new           #138                // class java/lang/StringBuilder
     679: dup
     680: invokespecial #139                // Method java/lang/StringBuilder."<init>":()V
     683: ldc           #167                // String Sum is
     685: invokevirtual #143                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     688: iload         5
     690: invokevirtual #170                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     693: invokevirtual #154                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     696: getstatic     #176                // Field java/lang/System.out:Ljava/io/PrintStream;
     699: swap
     700: invokevirtual #181                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     703: return

  public static final void printMap(java.util.List<java.util.List<java.lang.Boolean>>);
    Code:
       0: aload_0
       1: ldc           #202                // String map
       3: invokestatic  #74                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: aload_0
       9: checkcast     #82                 // class java/util/Collection
      12: invokeinterface #86,  1           // InterfaceMethod java/util/Collection.size:()I
      17: istore_2
      18: iload_1
      19: iload_2
      20: if_icmpge     121
      23: iconst_0
      24: istore_3
      25: aload_0
      26: iload_1
      27: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      32: checkcast     #82                 // class java/util/Collection
      35: invokeinterface #86,  1           // InterfaceMethod java/util/Collection.size:()I
      40: istore        4
      42: iload_3
      43: iload         4
      45: if_icmpge     106
      48: aload_0
      49: iload_1
      50: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      55: checkcast     #80                 // class java/util/List
      58: iload_3
      59: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      64: checkcast     #117                // class java/lang/Boolean
      67: invokevirtual #136                // Method java/lang/Boolean.booleanValue:()Z
      70: ifeq          88
      73: bipush        120
      75: istore        5
      77: getstatic     #176                // Field java/lang/System.out:Ljava/io/PrintStream;
      80: iload         5
      82: invokevirtual #206                // Method java/io/PrintStream.print:(C)V
      85: goto          100
      88: bipush        46
      90: istore        5
      92: getstatic     #176                // Field java/lang/System.out:Ljava/io/PrintStream;
      95: iload         5
      97: invokevirtual #206                // Method java/io/PrintStream.print:(C)V
     100: iinc          3, 1
     103: goto          42
     106: ldc           #208                // String \n
     108: getstatic     #176                // Field java/lang/System.out:Ljava/io/PrintStream;
     111: swap
     112: invokevirtual #210                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     115: iinc          1, 1
     118: goto          18
     121: ldc           #208                // String \n
     123: getstatic     #176                // Field java/lang/System.out:Ljava/io/PrintStream;
     126: swap
     127: invokevirtual #210                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     130: return

  public static final boolean adjacentToSymbol(java.util.List<java.util.List<java.lang.Boolean>>, int, int);
    Code:
       0: aload_0
       1: ldc           #212                // String symbols
       3: invokestatic  #74                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: iconst_1
       8: isub
       9: iconst_0
      10: invokestatic  #218                // Method java/lang/Math.max:(II)I
      13: istore_3
      14: iload_1
      15: iconst_1
      16: iadd
      17: aload_0
      18: invokeinterface #155,  1          // InterfaceMethod java/util/List.size:()I
      23: iconst_1
      24: isub
      25: invokestatic  #221                // Method java/lang/Math.min:(II)I
      28: istore        4
      30: iload_3
      31: iload         4
      33: if_icmpgt     130
      36: iload_2
      37: iconst_1
      38: isub
      39: iconst_0
      40: invokestatic  #218                // Method java/lang/Math.max:(II)I
      43: istore        5
      45: iload_2
      46: iconst_1
      47: iadd
      48: aload_0
      49: iload_1
      50: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      55: checkcast     #80                 // class java/util/List
      58: invokeinterface #155,  1          // InterfaceMethod java/util/List.size:()I
      63: iconst_1
      64: isub
      65: invokestatic  #221                // Method java/lang/Math.min:(II)I
      68: istore        6
      70: iload         5
      72: iload         6
      74: if_icmpgt     118
      77: aload_0
      78: iload_3
      79: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      84: checkcast     #80                 // class java/util/List
      87: iload         5
      89: invokeinterface #94,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      94: checkcast     #117                // class java/lang/Boolean
      97: invokevirtual #136                // Method java/lang/Boolean.booleanValue:()Z
     100: ifeq          105
     103: iconst_1
     104: ireturn
     105: iload         5
     107: iload         6
     109: if_icmpeq     118
     112: iinc          5, 1
     115: goto          77
     118: iload_3
     119: iload         4
     121: if_icmpeq     130
     124: iinc          3, 1
     127: goto          36
     130: iconst_0
     131: ireturn

  public static final boolean isSymbol(char);
    Code:
       0: iload_0
       1: invokestatic  #123                // Method isNumber:(C)Z
       4: ifne          17
       7: iload_0
       8: bipush        46
      10: if_icmpeq     17
      13: iconst_1
      14: goto          18
      17: iconst_0
      18: ireturn

  public static final boolean isNumber(char);
    Code:
       0: bipush        48
       2: iload_0
       3: if_icmpgt     20
       6: iload_0
       7: bipush        58
       9: if_icmpge     16
      12: iconst_1
      13: goto          21
      16: iconst_0
      17: goto          21
      20: iconst_0
      21: ireturn

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

  private static final kotlin.Unit main$lambda$0();
    Code:
       0: getstatic     #235                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
       3: areturn
}


package io.github.brunogabriel.math

fun matrixMultiplication(
    matrixA: List<List<Long>>,
    matrixB: List<List<Long>>
): List<List<Long>> {

    if (matrixA.first().size != matrixB.size) {
        return emptyList()
    }

    val result = Array(matrixA.size) { Array(matrixB.first().size) { 0L } }

    for (i in matrixA.indices) {
        for (j in matrixB[i].indices) {
            for (k in matrixA[i].indices) {
                result[i][j] += matrixA[i][k] * matrixB[k][j]
            }
        }
    }

    return result.map { it.toList() }
}

fun matrixSummation(
    matrixA: List<List<Long>>,
    matrixB: List<List<Long>>
): List<List<Long>> {

    if (matrixA.size != matrixB.size || matrixA.indices != matrixB.indices) {
        return emptyList()
    }

    matrixA.indices.forEach {
        if (matrixA[it].size != matrixB[it].size) {
            return emptyList()
        }
    }

    val result = Array(matrixA.size) { Array(matrixA.first().size) { 0L } }

    for (i in matrixA.indices) {
        for (j in matrixA[i].indices) {
            result[i][j] = matrixA[i][j] + matrixB[i][j]
        }
    }

    return result.map { it.toList() }
}

operator fun List<List<Long>>.times(other: List<List<Long>>): List<List<Long>> =
    matrixMultiplication(this, other)

operator fun List<List<Long>>.plus(other: List<List<Long>>): List<List<Long>> =
    matrixSummation(this, other)

Compiled from "MatrixOperations.kt"
public final class io.github.brunogabriel.math.MatrixOperationsKt {
  public static final java.util.List<java.util.List<java.lang.Long>> matrixMultiplication(java.util.List<? extends java.util.List<java.lang.Long>>, java.util.List<? extends java.util.List<java.lang.Long>>);
    Code:
       0: aload_0
       1: ldc           #10                 // String matrixA
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #18                 // String matrixB
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokestatic  #24                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      16: checkcast     #26                 // class java/util/List
      19: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
      24: aload_1
      25: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
      30: if_icmpeq     37
      33: invokestatic  #34                 // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      36: areturn
      37: iconst_0
      38: istore_3
      39: aload_0
      40: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
      45: istore        4
      47: iload         4
      49: anewarray     #36                 // class "[Ljava/lang/Long;"
      52: astore        5
      54: iload_3
      55: iload         4
      57: if_icmpge     134
      60: iload_3
      61: istore        6
      63: aload         5
      65: iload         6
      67: iconst_0
      68: istore        7
      70: aload_1
      71: invokestatic  #24                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      74: checkcast     #26                 // class java/util/List
      77: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
      82: istore        8
      84: iload         8
      86: anewarray     #38                 // class java/lang/Long
      89: astore        9
      91: istore        14
      93: astore        13
      95: iload         7
      97: iload         8
      99: if_icmpge     121
     102: iload         7
     104: istore        10
     106: aload         9
     108: iload         10
     110: lconst_0
     111: invokestatic  #42                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     114: aastore
     115: iinc          7, 1
     118: goto          95
     121: aload         13
     123: iload         14
     125: aload         9
     127: aastore
     128: iinc          3, 1
     131: goto          54
     134: aload         5
     136: astore_2
     137: iconst_0
     138: istore_3
     139: aload_0
     140: checkcast     #44                 // class java/util/Collection
     143: invokeinterface #45,  1           // InterfaceMethod java/util/Collection.size:()I
     148: istore        4
     150: iload_3
     151: iload         4
     153: if_icmpge     302
     156: iconst_0
     157: istore        5
     159: aload_1
     160: iload_3
     161: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     166: checkcast     #44                 // class java/util/Collection
     169: invokeinterface #45,  1           // InterfaceMethod java/util/Collection.size:()I
     174: istore        6
     176: iload         5
     178: iload         6
     180: if_icmpge     296
     183: iconst_0
     184: istore        7
     186: aload_0
     187: iload_3
     188: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     193: checkcast     #44                 // class java/util/Collection
     196: invokeinterface #45,  1           // InterfaceMethod java/util/Collection.size:()I
     201: istore        8
     203: iload         7
     205: iload         8
     207: if_icmpge     290
     210: aload_2
     211: iload_3
     212: aaload
     213: astore        9
     215: iload         5
     217: istore        10
     219: aload         9
     221: iload         10
     223: aload         9
     225: iload         10
     227: aaload
     228: invokevirtual #53                 // Method java/lang/Long.longValue:()J
     231: aload_0
     232: iload_3
     233: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     238: checkcast     #26                 // class java/util/List
     241: iload         7
     243: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     248: checkcast     #55                 // class java/lang/Number
     251: invokevirtual #56                 // Method java/lang/Number.longValue:()J
     254: aload_1
     255: iload         7
     257: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     262: checkcast     #26                 // class java/util/List
     265: iload         5
     267: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     272: checkcast     #55                 // class java/lang/Number
     275: invokevirtual #56                 // Method java/lang/Number.longValue:()J
     278: lmul
     279: ladd
     280: invokestatic  #42                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     283: aastore
     284: iinc          7, 1
     287: goto          203
     290: iinc          5, 1
     293: goto          176
     296: iinc          3, 1
     299: goto          150
     302: aload_2
     303: checkcast     #58                 // class "[Ljava/lang/Object;"
     306: astore_3
     307: iconst_0
     308: istore        4
     310: aload_3
     311: astore        5
     313: new           #60                 // class java/util/ArrayList
     316: dup
     317: aload_3
     318: arraylength
     319: invokespecial #64                 // Method java/util/ArrayList."<init>":(I)V
     322: checkcast     #44                 // class java/util/Collection
     325: astore        6
     327: iconst_0
     328: istore        7
     330: iconst_0
     331: istore        8
     333: aload         5
     335: arraylength
     336: istore        9
     338: iload         8
     340: iload         9
     342: if_icmpge     386
     345: aload         5
     347: iload         8
     349: aaload
     350: astore        10
     352: aload         6
     354: aload         10
     356: checkcast     #36                 // class "[Ljava/lang/Long;"
     359: astore        11
     361: astore        13
     363: iconst_0
     364: istore        12
     366: aload         11
     368: invokestatic  #70                 // Method kotlin/collections/ArraysKt.toList:([Ljava/lang/Object;)Ljava/util/List;
     371: aload         13
     373: swap
     374: invokeinterface #74,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     379: pop
     380: iinc          8, 1
     383: goto          338
     386: aload         6
     388: checkcast     #26                 // class java/util/List
     391: nop
     392: areturn

  public static final java.util.List<java.util.List<java.lang.Long>> matrixSummation(java.util.List<? extends java.util.List<java.lang.Long>>, java.util.List<? extends java.util.List<java.lang.Long>>);
    Code:
       0: aload_0
       1: ldc           #10                 // String matrixA
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #18                 // String matrixB
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
      18: aload_1
      19: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
      24: if_icmpne     47
      27: aload_0
      28: checkcast     #44                 // class java/util/Collection
      31: invokestatic  #97                 // Method kotlin/collections/CollectionsKt.getIndices:(Ljava/util/Collection;)Lkotlin/ranges/IntRange;
      34: aload_1
      35: checkcast     #44                 // class java/util/Collection
      38: invokestatic  #97                 // Method kotlin/collections/CollectionsKt.getIndices:(Ljava/util/Collection;)Lkotlin/ranges/IntRange;
      41: invokestatic  #101                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      44: ifne          51
      47: invokestatic  #34                 // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      50: areturn
      51: aload_0
      52: checkcast     #44                 // class java/util/Collection
      55: invokestatic  #97                 // Method kotlin/collections/CollectionsKt.getIndices:(Ljava/util/Collection;)Lkotlin/ranges/IntRange;
      58: checkcast     #103                // class java/lang/Iterable
      61: astore_2
      62: iconst_0
      63: istore_3
      64: aload_2
      65: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      70: astore        4
      72: aload         4
      74: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      79: ifeq          143
      82: aload         4
      84: checkcast     #115                // class kotlin/collections/IntIterator
      87: invokevirtual #118                // Method kotlin/collections/IntIterator.nextInt:()I
      90: istore        5
      92: iload         5
      94: istore        6
      96: iconst_0
      97: istore        7
      99: aload_0
     100: iload         6
     102: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     107: checkcast     #26                 // class java/util/List
     110: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
     115: aload_1
     116: iload         6
     118: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     123: checkcast     #26                 // class java/util/List
     126: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
     131: if_icmpeq     138
     134: invokestatic  #34                 // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     137: areturn
     138: nop
     139: nop
     140: goto          72
     143: nop
     144: iconst_0
     145: istore_3
     146: aload_0
     147: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
     152: istore        4
     154: iload         4
     156: anewarray     #36                 // class "[Ljava/lang/Long;"
     159: astore        5
     161: iload_3
     162: iload         4
     164: if_icmpge     241
     167: iload_3
     168: istore        6
     170: aload         5
     172: iload         6
     174: iconst_0
     175: istore        7
     177: aload_0
     178: invokestatic  #24                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     181: checkcast     #26                 // class java/util/List
     184: invokeinterface #30,  1           // InterfaceMethod java/util/List.size:()I
     189: istore        8
     191: iload         8
     193: anewarray     #38                 // class java/lang/Long
     196: astore        9
     198: istore        14
     200: astore        13
     202: iload         7
     204: iload         8
     206: if_icmpge     228
     209: iload         7
     211: istore        10
     213: aload         9
     215: iload         10
     217: lconst_0
     218: invokestatic  #42                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     221: aastore
     222: iinc          7, 1
     225: goto          202
     228: aload         13
     230: iload         14
     232: aload         9
     234: aastore
     235: iinc          3, 1
     238: goto          161
     241: aload         5
     243: astore_2
     244: iconst_0
     245: istore_3
     246: aload_0
     247: checkcast     #44                 // class java/util/Collection
     250: invokeinterface #45,  1           // InterfaceMethod java/util/Collection.size:()I
     255: istore        4
     257: iload_3
     258: iload         4
     260: if_icmpge     358
     263: iconst_0
     264: istore        5
     266: aload_0
     267: iload_3
     268: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     273: checkcast     #44                 // class java/util/Collection
     276: invokeinterface #45,  1           // InterfaceMethod java/util/Collection.size:()I
     281: istore        6
     283: iload         5
     285: iload         6
     287: if_icmpge     352
     290: aload_2
     291: iload_3
     292: aaload
     293: iload         5
     295: aload_0
     296: iload_3
     297: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     302: checkcast     #26                 // class java/util/List
     305: iload         5
     307: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     312: checkcast     #55                 // class java/lang/Number
     315: invokevirtual #56                 // Method java/lang/Number.longValue:()J
     318: aload_1
     319: iload_3
     320: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     325: checkcast     #26                 // class java/util/List
     328: iload         5
     330: invokeinterface #49,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     335: checkcast     #55                 // class java/lang/Number
     338: invokevirtual #56                 // Method java/lang/Number.longValue:()J
     341: ladd
     342: invokestatic  #42                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     345: aastore
     346: iinc          5, 1
     349: goto          283
     352: iinc          3, 1
     355: goto          257
     358: aload_2
     359: checkcast     #58                 // class "[Ljava/lang/Object;"
     362: astore_3
     363: iconst_0
     364: istore        4
     366: aload_3
     367: astore        5
     369: new           #60                 // class java/util/ArrayList
     372: dup
     373: aload_3
     374: arraylength
     375: invokespecial #64                 // Method java/util/ArrayList."<init>":(I)V
     378: checkcast     #44                 // class java/util/Collection
     381: astore        6
     383: iconst_0
     384: istore        7
     386: iconst_0
     387: istore        8
     389: aload         5
     391: arraylength
     392: istore        9
     394: iload         8
     396: iload         9
     398: if_icmpge     442
     401: aload         5
     403: iload         8
     405: aaload
     406: astore        10
     408: aload         6
     410: aload         10
     412: checkcast     #36                 // class "[Ljava/lang/Long;"
     415: astore        11
     417: astore        13
     419: iconst_0
     420: istore        12
     422: aload         11
     424: invokestatic  #70                 // Method kotlin/collections/ArraysKt.toList:([Ljava/lang/Object;)Ljava/util/List;
     427: aload         13
     429: swap
     430: invokeinterface #74,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     435: pop
     436: iinc          8, 1
     439: goto          394
     442: aload         6
     444: checkcast     #26                 // class java/util/List
     447: nop
     448: areturn

  public static final java.util.List<java.util.List<java.lang.Long>> times(java.util.List<? extends java.util.List<java.lang.Long>>, java.util.List<? extends java.util.List<java.lang.Long>>);
    Code:
       0: aload_0
       1: ldc           #127                // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #129                // String other
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: aload_1
      14: invokestatic  #131                // Method matrixMultiplication:(Ljava/util/List;Ljava/util/List;)Ljava/util/List;
      17: areturn

  public static final java.util.List<java.util.List<java.lang.Long>> plus(java.util.List<? extends java.util.List<java.lang.Long>>, java.util.List<? extends java.util.List<java.lang.Long>>);
    Code:
       0: aload_0
       1: ldc           #127                // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #129                // String other
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: aload_1
      14: invokestatic  #135                // Method matrixSummation:(Ljava/util/List;Ljava/util/List;)Ljava/util/List;
      17: areturn
}


package io.github.vihangpatil.kotlintricks.range

/**
 * @param[other] [ClosedRange]<[T]>
 * @return [Boolean] if this [Comparable]<[T]> overlaps with [other]
 */
private fun <T : Comparable<T>> ClosedRange<T>.overlapsWith(
        other: ClosedRange<T>
): Boolean {
    return (other.start in start..endInclusive || other.endInclusive in start..endInclusive)
}

/**
 * @param[other] [ClosedRange]<[T]>
 * @return [Collection]<[ClosedRange]<[T]>> with [this] and [other] if they do not overlap, or with just one merged
 *   [ClosedRange]<[T]> if they overlap.
 */
private fun <T : Comparable<T>> ClosedRange<T>.mergeWith(
        other: ClosedRange<T>
): Collection<ClosedRange<T>> {

    // if they do not overlap
    return if (!overlapsWith(other)) {
        // then return them separately
        listOf(this, other)
    } else {
        // else merge them
        listOf(minOf(start, other.start)..maxOf(endInclusive, other.endInclusive))
    }
}

/**
 * @return [Collection]<[ClosedRange]<[T]>> with overlapping [ClosedRange]<[T]> merged.
 */
fun <T : Comparable<T>> Collection<ClosedRange<T>>.mergeRanges(): Collection<ClosedRange<T>> {
    // no changes for empty collection or collection with single element
    if (this.size < 2) {
        return this
    }
    return sortedBy { it.start } // sort by start of range
            .fold(initial = emptyList()) { list: List<ClosedRange<T>>, element: ClosedRange<T> ->
                if (list.isEmpty()) {
                    // for first element
                    listOf(element)
                } else {
                    // Attempt to merge last of the list with the element.
                    // If they are overlapping, [mergeWith] will return collection with single merged element.
                    // Or else, it will return list with two elements.
                    list.last().mergeWith(element) +
                            // drop last element to avoid it to be duplicate
                            list.dropLast(1)
                }
            }
}

/**
 * @param[asRange] Function to map [E] to [ClosedRange]<[T]>.
 * @param[asElement] Function to map [ClosedRange]<[T]> to [E].
 * @return [Collection]<[E]> with overlapping [ClosedRange]<[T]> merged.
 */
fun <E, T : Comparable<T>> Collection<E>.mergeBy(
        asRange: (E) -> ClosedRange<T>,
        asElement: (ClosedRange<T>) -> E
): Collection<E> {

    // no changes for empty collection or collection with single element
    if (this.size < 2) {
        return this
    }
    return sortedBy { element -> // sort by start of range
        asRange(element).start
    }.fold(initial = emptyList()) { list: List<E>, element: E ->
        if (list.isEmpty()) {
            // for first element
            listOf(element)
        } else {
            // Attempt to merge last of the list with the element.
            // If they are overlapping, [mergeWith] will return collection with single merged element.
            // Or else, it will return list with two elements.
            asRange(list.last()).mergeWith(asRange(element)).map(asElement) +
                    // drop last element to avoid it to be duplicate
                    list.dropLast(1)
        }
    }
}

Compiled from "Comparisons.kt"
public final class io.github.vihangpatil.kotlintricks.range.RangeExtensionsKt$mergeBy$$inlined$sortedBy$1<T> implements java.util.Comparator {
  final kotlin.jvm.functions.Function1 $asRange$inlined;

  public io.github.vihangpatil.kotlintricks.range.RangeExtensionsKt$mergeBy$$inlined$sortedBy$1(kotlin.jvm.functions.Function1);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #18                 // Field $asRange$inlined:Lkotlin/jvm/functions/Function1;
       5: aload_0
       6: invokespecial #21                 // Method java/lang/Object."<init>":()V
       9: return

  public final int compare(T, T);
    Code:
       0: aload_1
       1: astore_3
       2: iconst_0
       3: istore        4
       5: aload_0
       6: getfield      #18                 // Field $asRange$inlined:Lkotlin/jvm/functions/Function1;
       9: aload_3
      10: invokeinterface #32,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
      15: checkcast     #34                 // class kotlin/ranges/ClosedRange
      18: invokeinterface #38,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      23: aload_2
      24: astore_3
      25: astore        5
      27: iconst_0
      28: istore        4
      30: aload_0
      31: getfield      #18                 // Field $asRange$inlined:Lkotlin/jvm/functions/Function1;
      34: aload_3
      35: invokeinterface #32,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
      40: checkcast     #34                 // class kotlin/ranges/ClosedRange
      43: invokeinterface #38,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      48: aload         5
      50: swap
      51: invokestatic  #44                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      54: ireturn
}

Compiled from "RangeExtensions.kt"
public final class io.github.vihangpatil.kotlintricks.range.RangeExtensionsKt {
  private static final <T extends java.lang.Comparable<? super T>> boolean overlapsWith(kotlin.ranges.ClosedRange<T>, kotlin.ranges.ClosedRange<T>);
    Code:
       0: aload_0
       1: invokeinterface #13,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
       6: astore_2
       7: aload_0
       8: invokeinterface #16,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getEndInclusive:()Ljava/lang/Comparable;
      13: astore_3
      14: aload_1
      15: invokeinterface #13,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      20: astore        4
      22: iconst_0
      23: aload         4
      25: aload_2
      26: invokeinterface #22,  2           // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      31: if_icmpgt     53
      34: aload         4
      36: aload_3
      37: invokeinterface #22,  2           // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      42: ifgt          49
      45: iconst_1
      46: goto          54
      49: iconst_0
      50: goto          54
      53: iconst_0
      54: ifne          114
      57: aload_0
      58: invokeinterface #13,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      63: astore_2
      64: aload_0
      65: invokeinterface #16,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getEndInclusive:()Ljava/lang/Comparable;
      70: astore_3
      71: aload_1
      72: invokeinterface #16,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getEndInclusive:()Ljava/lang/Comparable;
      77: astore        4
      79: iconst_0
      80: aload         4
      82: aload_2
      83: invokeinterface #22,  2           // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      88: if_icmpgt     110
      91: aload         4
      93: aload_3
      94: invokeinterface #22,  2           // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      99: ifgt          106
     102: iconst_1
     103: goto          111
     106: iconst_0
     107: goto          111
     110: iconst_0
     111: ifeq          118
     114: iconst_1
     115: goto          119
     118: iconst_0
     119: ireturn

  private static final <T extends java.lang.Comparable<? super T>> java.util.Collection<kotlin.ranges.ClosedRange<T>> mergeWith(kotlin.ranges.ClosedRange<T>, kotlin.ranges.ClosedRange<T>);
    Code:
       0: aload_0
       1: aload_1
       2: invokestatic  #30                 // Method overlapsWith:(Lkotlin/ranges/ClosedRange;Lkotlin/ranges/ClosedRange;)Z
       5: ifne          31
       8: iconst_2
       9: anewarray     #9                  // class kotlin/ranges/ClosedRange
      12: astore_2
      13: aload_2
      14: iconst_0
      15: aload_0
      16: aastore
      17: aload_2
      18: iconst_1
      19: aload_1
      20: aastore
      21: aload_2
      22: invokestatic  #36                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      25: checkcast     #38                 // class java/util/Collection
      28: goto          70
      31: aload_0
      32: invokeinterface #13,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      37: aload_1
      38: invokeinterface #13,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      43: invokestatic  #44                 // Method kotlin/comparisons/ComparisonsKt.minOf:(Ljava/lang/Comparable;Ljava/lang/Comparable;)Ljava/lang/Comparable;
      46: aload_0
      47: invokeinterface #16,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getEndInclusive:()Ljava/lang/Comparable;
      52: aload_1
      53: invokeinterface #16,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getEndInclusive:()Ljava/lang/Comparable;
      58: invokestatic  #47                 // Method kotlin/comparisons/ComparisonsKt.maxOf:(Ljava/lang/Comparable;Ljava/lang/Comparable;)Ljava/lang/Comparable;
      61: invokestatic  #53                 // Method kotlin/ranges/RangesKt.rangeTo:(Ljava/lang/Comparable;Ljava/lang/Comparable;)Lkotlin/ranges/ClosedRange;
      64: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      67: checkcast     #38                 // class java/util/Collection
      70: areturn

  public static final <T extends java.lang.Comparable<? super T>> java.util.Collection<kotlin.ranges.ClosedRange<T>> mergeRanges(java.util.Collection<? extends kotlin.ranges.ClosedRange<T>>);
    Code:
       0: aload_0
       1: ldc           #63                 // String <this>
       3: invokestatic  #69                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #73,  1           // InterfaceMethod java/util/Collection.size:()I
      12: iconst_2
      13: if_icmpge     18
      16: aload_0
      17: areturn
      18: aload_0
      19: checkcast     #75                 // class java/lang/Iterable
      22: astore_1
      23: iconst_0
      24: istore_2
      25: aload_1
      26: new           #77                 // class io/github/vihangpatil/kotlintricks/range/RangeExtensionsKt$mergeRanges$$inlined$sortedBy$1
      29: dup
      30: invokespecial #81                 // Method io/github/vihangpatil/kotlintricks/range/RangeExtensionsKt$mergeRanges$$inlined$sortedBy$1."<init>":()V
      33: checkcast     #83                 // class java/util/Comparator
      36: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      39: checkcast     #75                 // class java/lang/Iterable
      42: astore_1
      43: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      46: astore_2
      47: iconst_0
      48: istore_3
      49: aload_2
      50: astore        4
      52: aload_1
      53: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      58: astore        5
      60: aload         5
      62: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      67: ifeq          142
      70: aload         5
      72: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      77: astore        6
      79: aload         4
      81: aload         6
      83: checkcast     #9                  // class kotlin/ranges/ClosedRange
      86: astore        7
      88: astore        8
      90: iconst_0
      91: istore        9
      93: aload         8
      95: invokeinterface #110,  1          // InterfaceMethod java/util/List.isEmpty:()Z
     100: ifeq          111
     103: aload         7
     105: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
     108: goto          136
     111: aload         8
     113: invokestatic  #114                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     116: checkcast     #9                  // class kotlin/ranges/ClosedRange
     119: aload         7
     121: invokestatic  #116                // Method mergeWith:(Lkotlin/ranges/ClosedRange;Lkotlin/ranges/ClosedRange;)Ljava/util/Collection;
     124: aload         8
     126: iconst_1
     127: invokestatic  #120                // Method kotlin/collections/CollectionsKt.dropLast:(Ljava/util/List;I)Ljava/util/List;
     130: checkcast     #75                 // class java/lang/Iterable
     133: invokestatic  #124                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     136: nop
     137: astore        4
     139: goto          60
     142: aload         4
     144: checkcast     #38                 // class java/util/Collection
     147: areturn

  public static final <E, T extends java.lang.Comparable<? super T>> java.util.Collection<E> mergeBy(java.util.Collection<? extends E>, kotlin.jvm.functions.Function1<? super E, ? extends kotlin.ranges.ClosedRange<T>>, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedRange<T>, ? extends E>);
    Code:
       0: aload_0
       1: ldc           #63                 // String <this>
       3: invokestatic  #69                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #145                // String asRange
       9: invokestatic  #69                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: ldc           #147                // String asElement
      15: invokestatic  #69                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_0
      19: invokeinterface #73,  1           // InterfaceMethod java/util/Collection.size:()I
      24: iconst_2
      25: if_icmpge     30
      28: aload_0
      29: areturn
      30: aload_0
      31: checkcast     #75                 // class java/lang/Iterable
      34: astore_3
      35: iconst_0
      36: istore        4
      38: aload_3
      39: new           #149                // class io/github/vihangpatil/kotlintricks/range/RangeExtensionsKt$mergeBy$$inlined$sortedBy$1
      42: dup
      43: aload_1
      44: invokespecial #152                // Method io/github/vihangpatil/kotlintricks/range/RangeExtensionsKt$mergeBy$$inlined$sortedBy$1."<init>":(Lkotlin/jvm/functions/Function1;)V
      47: checkcast     #83                 // class java/util/Comparator
      50: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      53: checkcast     #75                 // class java/lang/Iterable
      56: astore_3
      57: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      60: astore        4
      62: iconst_0
      63: istore        5
      65: aload         4
      67: astore        6
      69: aload_3
      70: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      75: astore        7
      77: aload         7
      79: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      84: ifeq          261
      87: aload         7
      89: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      94: astore        8
      96: aload         6
      98: aload         8
     100: astore        9
     102: astore        10
     104: iconst_0
     105: istore        11
     107: aload         10
     109: invokeinterface #110,  1          // InterfaceMethod java/util/List.isEmpty:()Z
     114: ifeq          125
     117: aload         9
     119: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
     122: goto          255
     125: aload_1
     126: aload         10
     128: invokestatic  #114                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     131: invokeinterface #158,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     136: checkcast     #9                  // class kotlin/ranges/ClosedRange
     139: aload_1
     140: aload         9
     142: invokeinterface #158,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     147: checkcast     #9                  // class kotlin/ranges/ClosedRange
     150: invokestatic  #116                // Method mergeWith:(Lkotlin/ranges/ClosedRange;Lkotlin/ranges/ClosedRange;)Ljava/util/Collection;
     153: checkcast     #75                 // class java/lang/Iterable
     156: astore        12
     158: iconst_0
     159: istore        13
     161: aload         12
     163: astore        14
     165: new           #160                // class java/util/ArrayList
     168: dup
     169: aload         12
     171: bipush        10
     173: invokestatic  #164                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     176: invokespecial #167                // Method java/util/ArrayList."<init>":(I)V
     179: checkcast     #38                 // class java/util/Collection
     182: astore        15
     184: iconst_0
     185: istore        16
     187: aload         14
     189: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     194: astore        17
     196: aload         17
     198: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     203: ifeq          234
     206: aload         17
     208: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     213: astore        18
     215: aload         15
     217: aload_2
     218: aload         18
     220: invokeinterface #158,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     225: invokeinterface #171,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     230: pop
     231: goto          196
     234: aload         15
     236: checkcast     #107                // class java/util/List
     239: nop
     240: checkcast     #38                 // class java/util/Collection
     243: aload         10
     245: iconst_1
     246: invokestatic  #120                // Method kotlin/collections/CollectionsKt.dropLast:(Ljava/util/List;I)Ljava/util/List;
     249: checkcast     #75                 // class java/lang/Iterable
     252: invokestatic  #124                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     255: nop
     256: astore        6
     258: goto          77
     261: aload         6
     263: checkcast     #38                 // class java/util/Collection
     266: areturn
}

Compiled from "Comparisons.kt"
public final class io.github.vihangpatil.kotlintricks.range.RangeExtensionsKt$mergeRanges$$inlined$sortedBy$1<T> implements java.util.Comparator {
  public io.github.vihangpatil.kotlintricks.range.RangeExtensionsKt$mergeRanges$$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/ranges/ClosedRange
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokeinterface #27,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      14: aload_2
      15: checkcast     #23                 // class kotlin/ranges/ClosedRange
      18: astore_3
      19: astore        5
      21: iconst_0
      22: istore        4
      24: aload_3
      25: invokeinterface #27,  1           // InterfaceMethod kotlin/ranges/ClosedRange.getStart:()Ljava/lang/Comparable;
      30: aload         5
      32: swap
      33: invokestatic  #33                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      36: ireturn
}