package com.simplemobiletools.calculator.helpers

fun updateStats(results: ArrayList<String>){
    getMean(results)
    getMedian(results)
    getMode(results)
    getRange(results)
}

fun getMean(results: ArrayList<String>): String{
    var avg = 0.0
    for(r in results) {
        if(r.isEmpty())
            return ""
        avg += r.replace(",","").toDouble()
    }

    avg /= results.size

    return String.format(java.util.Locale.US,"%.2f", avg)
}

fun getMedian(results: ArrayList<String>): String{
    for(r in results) {
        if (r.isEmpty())
            return ""
    }
    val listOfSortedResults = sortListOfStringsOfDoubles(results)
    return if(listOfSortedResults.size % 2 == 0) {
        ((listOfSortedResults[listOfSortedResults.size / 2] + listOfSortedResults[listOfSortedResults.size / 2 - 1]) / 2).toString()
    } else {
        (listOfSortedResults[listOfSortedResults.size / 2]).toString()
    }

}

fun getMode(results: ArrayList<String>): String{
    for(r in results) {
        if (r.isEmpty())
            return ""
    }
    val storeValues = hashMapOf<String, Int>()
    val listOfModes = arrayListOf<String>()
    var highestCount = 0

    //Get count of each occurrence
    for(r in results){
        if(storeValues[r] == null)
            storeValues[r] = 1
        else{
            val count = storeValues[r]
            storeValues[r] = count!! + 1
        }
    }
    //Store highest count
    for(s in storeValues){
        if(highestCount < s.value)
            highestCount = s.value
    }
    //Every number with an equal highest count is added to return list
    for(s in storeValues){
        if(s.value == highestCount)
            listOfModes.add(s.key)
    }
    val listOfSortedModes = sortListOfStringsOfDoubles(listOfModes)
    return listOfSortedModes.toString()
}

fun getRange(results: ArrayList<String>): String {
    for(r in results) {
        if (r.isEmpty())
            return ""
    }
    val listOfSortedModes = sortListOfStringsOfDoubles(results)
    return (listOfSortedModes.last() - listOfSortedModes.first()).toString()
}

private fun sortListOfStringsOfDoubles(listOfStringOfDoubles: ArrayList<String>): ArrayList<Double> {
    val listOfDoubles = ArrayList<Double>()
    for(l in listOfStringOfDoubles){
        listOfDoubles.add(l.replace(",","").toDouble())
    }
    listOfDoubles.sort()
    return listOfDoubles
}

Compiled from "StatFunctions.kt"
public final class com.simplemobiletools.calculator.helpers.StatFunctionsKt {
  public static final void updateStats(java.util.ArrayList<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #10                 // String results
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #20                 // Method getMean:(Ljava/util/ArrayList;)Ljava/lang/String;
      10: pop
      11: aload_0
      12: invokestatic  #23                 // Method getMedian:(Ljava/util/ArrayList;)Ljava/lang/String;
      15: pop
      16: aload_0
      17: invokestatic  #26                 // Method getMode:(Ljava/util/ArrayList;)Ljava/lang/String;
      20: pop
      21: aload_0
      22: invokestatic  #29                 // Method getRange:(Ljava/util/ArrayList;)Ljava/lang/String;
      25: pop
      26: return

  public static final java.lang.String getMean(java.util.ArrayList<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #10                 // String results
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: dconst_0
       7: dstore_1
       8: aload_0
       9: invokevirtual #37                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      12: dup
      13: ldc           #39                 // String iterator(...)
      15: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      18: astore_3
      19: aload_3
      20: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      25: ifeq          90
      28: aload_3
      29: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      34: dup
      35: ldc           #54                 // String next(...)
      37: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      40: checkcast     #56                 // class java/lang/String
      43: astore        4
      45: aload         4
      47: checkcast     #58                 // class java/lang/CharSequence
      50: invokeinterface #62,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      55: ifne          62
      58: iconst_1
      59: goto          63
      62: iconst_0
      63: ifeq          69
      66: ldc           #64                 // String
      68: areturn
      69: dload_1
      70: aload         4
      72: ldc           #66                 // String ,
      74: ldc           #64                 // String
      76: iconst_0
      77: iconst_4
      78: aconst_null
      79: invokestatic  #72                 // Method kotlin/text/StringsKt.replace$default:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Ljava/lang/String;
      82: invokestatic  #78                 // Method java/lang/Double.parseDouble:(Ljava/lang/String;)D
      85: dadd
      86: dstore_1
      87: goto          19
      90: dload_1
      91: aload_0
      92: invokevirtual #81                 // Method java/util/ArrayList.size:()I
      95: i2d
      96: ddiv
      97: dstore_1
      98: getstatic     #87                 // Field kotlin/jvm/internal/StringCompanionObject.INSTANCE:Lkotlin/jvm/internal/StringCompanionObject;
     101: pop
     102: getstatic     #93                 // Field java/util/Locale.US:Ljava/util/Locale;
     105: astore        4
     107: ldc           #95                 // String %.2f
     109: astore        5
     111: iconst_1
     112: anewarray     #4                  // class java/lang/Object
     115: astore        6
     117: aload         6
     119: iconst_0
     120: dload_1
     121: invokestatic  #99                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     124: aastore
     125: aload         6
     127: astore        6
     129: aload         4
     131: aload         5
     133: aload         6
     135: aload         6
     137: arraylength
     138: invokestatic  #105                // Method java/util/Arrays.copyOf:([Ljava/lang/Object;I)[Ljava/lang/Object;
     141: invokestatic  #109                // Method java/lang/String.format:(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
     144: dup
     145: ldc           #111                // String format(...)
     147: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     150: areturn

  public static final java.lang.String getMedian(java.util.ArrayList<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #10                 // String results
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #37                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      10: dup
      11: ldc           #39                 // String iterator(...)
      13: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      16: astore_1
      17: aload_1
      18: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      23: ifeq          65
      26: aload_1
      27: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      32: dup
      33: ldc           #54                 // String next(...)
      35: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      38: checkcast     #56                 // class java/lang/String
      41: astore_2
      42: aload_2
      43: checkcast     #58                 // class java/lang/CharSequence
      46: invokeinterface #62,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      51: ifne          58
      54: iconst_1
      55: goto          59
      58: iconst_0
      59: ifeq          17
      62: ldc           #64                 // String
      64: areturn
      65: aload_0
      66: invokestatic  #119                // Method sortListOfStringsOfDoubles:(Ljava/util/ArrayList;)Ljava/util/ArrayList;
      69: astore_1
      70: aload_1
      71: invokevirtual #81                 // Method java/util/ArrayList.size:()I
      74: iconst_2
      75: irem
      76: ifne          129
      79: aload_1
      80: aload_1
      81: invokevirtual #81                 // Method java/util/ArrayList.size:()I
      84: iconst_2
      85: idiv
      86: invokevirtual #123                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      89: checkcast     #125                // class java/lang/Number
      92: invokevirtual #129                // Method java/lang/Number.doubleValue:()D
      95: aload_1
      96: aload_1
      97: invokevirtual #81                 // Method java/util/ArrayList.size:()I
     100: iconst_2
     101: idiv
     102: iconst_1
     103: isub
     104: invokevirtual #123                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     107: dup
     108: ldc           #131                // String get(...)
     110: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     113: checkcast     #125                // class java/lang/Number
     116: invokevirtual #129                // Method java/lang/Number.doubleValue:()D
     119: dadd
     120: iconst_2
     121: i2d
     122: ddiv
     123: invokestatic  #134                // Method java/lang/String.valueOf:(D)Ljava/lang/String;
     126: goto          148
     129: aload_1
     130: aload_1
     131: invokevirtual #81                 // Method java/util/ArrayList.size:()I
     134: iconst_2
     135: idiv
     136: invokevirtual #123                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     139: checkcast     #125                // class java/lang/Number
     142: invokevirtual #129                // Method java/lang/Number.doubleValue:()D
     145: invokestatic  #134                // Method java/lang/String.valueOf:(D)Ljava/lang/String;
     148: areturn

  public static final java.lang.String getMode(java.util.ArrayList<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #10                 // String results
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #37                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      10: dup
      11: ldc           #39                 // String iterator(...)
      13: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      16: astore_1
      17: aload_1
      18: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      23: ifeq          65
      26: aload_1
      27: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      32: dup
      33: ldc           #54                 // String next(...)
      35: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      38: checkcast     #56                 // class java/lang/String
      41: astore_2
      42: aload_2
      43: checkcast     #58                 // class java/lang/CharSequence
      46: invokeinterface #62,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      51: ifne          58
      54: iconst_1
      55: goto          59
      58: iconst_0
      59: ifeq          17
      62: ldc           #64                 // String
      64: areturn
      65: new           #137                // class java/util/HashMap
      68: dup
      69: invokespecial #141                // Method java/util/HashMap."<init>":()V
      72: astore_1
      73: new           #33                 // class java/util/ArrayList
      76: dup
      77: invokespecial #142                // Method java/util/ArrayList."<init>":()V
      80: astore_2
      81: iconst_0
      82: istore_3
      83: aload_0
      84: invokevirtual #37                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      87: dup
      88: ldc           #39                 // String iterator(...)
      90: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      93: astore        4
      95: aload         4
      97: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     102: ifeq          191
     105: aload         4
     107: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     112: dup
     113: ldc           #54                 // String next(...)
     115: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     118: checkcast     #56                 // class java/lang/String
     121: astore        5
     123: aload_1
     124: aload         5
     126: invokevirtual #145                // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     129: ifnonnull     151
     132: aload_1
     133: checkcast     #147                // class java/util/Map
     136: aload         5
     138: iconst_1
     139: invokestatic  #152                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     142: invokeinterface #156,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     147: pop
     148: goto          95
     151: aload_1
     152: aload         5
     154: invokevirtual #145                // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     157: checkcast     #149                // class java/lang/Integer
     160: astore        6
     162: aload_1
     163: checkcast     #147                // class java/util/Map
     166: aload         5
     168: aload         6
     170: dup
     171: invokestatic  #160                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     174: invokevirtual #163                // Method java/lang/Integer.intValue:()I
     177: iconst_1
     178: iadd
     179: invokestatic  #152                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     182: invokeinterface #156,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     187: pop
     188: goto          95
     191: aload_1
     192: checkcast     #147                // class java/util/Map
     195: invokeinterface #167,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     200: invokeinterface #170,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
     205: astore        4
     207: aload         4
     209: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     214: ifeq          263
     217: aload         4
     219: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     224: checkcast     #172                // class java/util/Map$Entry
     227: astore        5
     229: iload_3
     230: aload         5
     232: invokeinterface #175,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     237: checkcast     #125                // class java/lang/Number
     240: invokevirtual #176                // Method java/lang/Number.intValue:()I
     243: if_icmpge     207
     246: aload         5
     248: invokeinterface #175,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     253: checkcast     #125                // class java/lang/Number
     256: invokevirtual #176                // Method java/lang/Number.intValue:()I
     259: istore_3
     260: goto          207
     263: aload_1
     264: checkcast     #147                // class java/util/Map
     267: invokeinterface #167,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     272: invokeinterface #170,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
     277: astore        4
     279: aload         4
     281: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     286: ifeq          333
     289: aload         4
     291: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     296: checkcast     #172                // class java/util/Map$Entry
     299: astore        5
     301: aload         5
     303: invokeinterface #175,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     308: checkcast     #125                // class java/lang/Number
     311: invokevirtual #176                // Method java/lang/Number.intValue:()I
     314: iload_3
     315: if_icmpne     279
     318: aload_2
     319: aload         5
     321: invokeinterface #179,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     326: invokevirtual #183                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     329: pop
     330: goto          279
     333: aload_2
     334: invokestatic  #119                // Method sortListOfStringsOfDoubles:(Ljava/util/ArrayList;)Ljava/util/ArrayList;
     337: astore        4
     339: aload         4
     341: invokevirtual #187                // Method java/util/ArrayList.toString:()Ljava/lang/String;
     344: dup
     345: ldc           #189                // String toString(...)
     347: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     350: areturn

  public static final java.lang.String getRange(java.util.ArrayList<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #10                 // String results
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #37                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      10: dup
      11: ldc           #39                 // String iterator(...)
      13: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      16: astore_1
      17: aload_1
      18: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      23: ifeq          65
      26: aload_1
      27: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      32: dup
      33: ldc           #54                 // String next(...)
      35: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      38: checkcast     #56                 // class java/lang/String
      41: astore_2
      42: aload_2
      43: checkcast     #58                 // class java/lang/CharSequence
      46: invokeinterface #62,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      51: ifne          58
      54: iconst_1
      55: goto          59
      58: iconst_0
      59: ifeq          17
      62: ldc           #64                 // String
      64: areturn
      65: aload_0
      66: invokestatic  #119                // Method sortListOfStringsOfDoubles:(Ljava/util/ArrayList;)Ljava/util/ArrayList;
      69: astore_1
      70: aload_1
      71: checkcast     #201                // class java/util/List
      74: invokestatic  #207                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
      77: checkcast     #125                // class java/lang/Number
      80: invokevirtual #129                // Method java/lang/Number.doubleValue:()D
      83: aload_1
      84: checkcast     #201                // class java/util/List
      87: invokestatic  #210                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      90: checkcast     #125                // class java/lang/Number
      93: invokevirtual #129                // Method java/lang/Number.doubleValue:()D
      96: dsub
      97: invokestatic  #134                // Method java/lang/String.valueOf:(D)Ljava/lang/String;
     100: areturn

  private static final java.util.ArrayList<java.lang.Double> sortListOfStringsOfDoubles(java.util.ArrayList<java.lang.String>);
    Code:
       0: new           #33                 // class java/util/ArrayList
       3: dup
       4: invokespecial #142                // Method java/util/ArrayList."<init>":()V
       7: astore_1
       8: aload_0
       9: invokevirtual #37                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      12: dup
      13: ldc           #39                 // String iterator(...)
      15: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      18: astore_2
      19: aload_2
      20: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      25: ifeq          69
      28: aload_2
      29: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      34: dup
      35: ldc           #54                 // String next(...)
      37: invokestatic  #42                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      40: checkcast     #56                 // class java/lang/String
      43: astore_3
      44: aload_1
      45: aload_3
      46: ldc           #66                 // String ,
      48: ldc           #64                 // String
      50: iconst_0
      51: iconst_4
      52: aconst_null
      53: invokestatic  #72                 // Method kotlin/text/StringsKt.replace$default:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Ljava/lang/String;
      56: invokestatic  #78                 // Method java/lang/Double.parseDouble:(Ljava/lang/String;)D
      59: invokestatic  #99                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      62: invokevirtual #183                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      65: pop
      66: goto          19
      69: aload_1
      70: checkcast     #201                // class java/util/List
      73: invokestatic  #215                // Method kotlin/collections/CollectionsKt.sort:(Ljava/util/List;)V
      76: aload_1
      77: areturn
}


package com.dzirbel.robopower.util

/**
 * Returns the key(s) whose associated values are the largest according to [comparator].
 */
internal fun <K, V> Map<K, V>.maxKeysBy(comparator: Comparator<V>): Set<K> {
    val iterator = iterator()
    if (!iterator.hasNext()) throw NoSuchElementException()

    val first = iterator.next()
    var maxValue = first.value
    val maxKeys = mutableSetOf(first.key)

    while (iterator.hasNext()) {
        val (key, value) = iterator.next()
        val comparison = comparator.compare(value, maxValue)
        if (maxValue == null || comparison > 0) {
            maxValue = value
            maxKeys.clear()
            maxKeys.add(key)
        } else if (comparison == 0) {
            maxKeys.add(key)
        }
    }

    return maxKeys
}

/**
 * Returns the first key (or an arbitrary key for unordered maps) whose value yields the maximum non-null result for
 * [selector].
 */
fun <K, V, R : Comparable<R>> Map<K, V>.maxKeyByOrNull(selector: (V) -> R?): K? {
    return this
        .mapNotNull { (key, value) -> selector(value)?.let { key to it } }
        .maxByOrNull { (_, value) -> value }
        ?.first
}

Compiled from "MapExtensions.kt"
public final class com.dzirbel.robopower.util.MapExtensionsKt {
  public static final <K, V> java.util.Set<K> maxKeysBy(java.util.Map<K, ? extends V>, java.util.Comparator<V>);
    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 comparator
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokeinterface #24,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      18: invokeinterface #30,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      23: astore_2
      24: aload_2
      25: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      30: ifne          41
      33: new           #38                 // class java/util/NoSuchElementException
      36: dup
      37: invokespecial #42                 // Method java/util/NoSuchElementException."<init>":()V
      40: athrow
      41: aload_2
      42: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      47: checkcast     #48                 // class java/util/Map$Entry
      50: astore_3
      51: aload_3
      52: invokeinterface #51,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      57: astore        4
      59: iconst_1
      60: anewarray     #4                  // class java/lang/Object
      63: astore        6
      65: aload         6
      67: iconst_0
      68: aload_3
      69: invokeinterface #54,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
      74: aastore
      75: aload         6
      77: invokestatic  #60                 // Method kotlin/collections/SetsKt.mutableSetOf:([Ljava/lang/Object;)Ljava/util/Set;
      80: astore        5
      82: aload_2
      83: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      88: ifeq          184
      91: aload_2
      92: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      97: checkcast     #48                 // class java/util/Map$Entry
     100: astore        6
     102: aload         6
     104: invokeinterface #54,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     109: astore        7
     111: aload         6
     113: invokeinterface #51,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     118: astore        8
     120: aload_1
     121: aload         8
     123: aload         4
     125: invokeinterface #66,  3           // InterfaceMethod java/util/Comparator.compare:(Ljava/lang/Object;Ljava/lang/Object;)I
     130: istore        9
     132: aload         4
     134: ifnull        142
     137: iload         9
     139: ifle          166
     142: aload         8
     144: astore        4
     146: aload         5
     148: invokeinterface #69,  1           // InterfaceMethod java/util/Set.clear:()V
     153: aload         5
     155: aload         7
     157: invokeinterface #73,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
     162: pop
     163: goto          82
     166: iload         9
     168: ifne          82
     171: aload         5
     173: aload         7
     175: invokeinterface #73,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
     180: pop
     181: goto          82
     184: aload         5
     186: areturn

  public static final <K, V, R extends java.lang.Comparable<? super R>> K maxKeyByOrNull(java.util.Map<K, ? extends V>, kotlin.jvm.functions.Function1<? super V, ? 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_1
       7: ldc           #93                 // String selector
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: astore_3
      14: nop
      15: iconst_0
      16: istore        4
      18: aload_3
      19: astore        5
      21: new           #95                 // class java/util/ArrayList
      24: dup
      25: invokespecial #96                 // Method java/util/ArrayList."<init>":()V
      28: checkcast     #98                 // class java/util/Collection
      31: astore        6
      33: iconst_0
      34: istore        7
      36: aload         5
      38: astore        8
      40: iconst_0
      41: istore        9
      43: aload         8
      45: invokeinterface #24,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      50: invokeinterface #30,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      55: astore        10
      57: aload         10
      59: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      64: ifeq          170
      67: aload         10
      69: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      74: checkcast     #48                 // class java/util/Map$Entry
      77: astore        11
      79: aload         11
      81: astore        12
      83: iconst_0
      84: istore        13
      86: aload         12
      88: astore        14
      90: iconst_0
      91: istore        15
      93: aload         14
      95: invokeinterface #54,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     100: astore        16
     102: aload         14
     104: invokeinterface #51,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     109: astore        17
     111: aload_1
     112: aload         17
     114: invokeinterface #104,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     119: checkcast     #106                // class java/lang/Comparable
     122: dup
     123: ifnull        141
     126: astore        18
     128: iconst_0
     129: istore        19
     131: aload         16
     133: aload         18
     135: invokestatic  #112                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     138: goto          143
     141: pop
     142: aconst_null
     143: dup
     144: ifnull        165
     147: astore        20
     149: iconst_0
     150: istore        21
     152: aload         6
     154: aload         20
     156: invokeinterface #113,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     161: pop
     162: goto          166
     165: pop
     166: nop
     167: goto          57
     170: nop
     171: aload         6
     173: checkcast     #115                // class java/util/List
     176: nop
     177: checkcast     #117                // class java/lang/Iterable
     180: astore_3
     181: nop
     182: iconst_0
     183: istore        4
     185: aload_3
     186: invokeinterface #118,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     191: astore        5
     193: aload         5
     195: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     200: ifne          207
     203: aconst_null
     204: goto          320
     207: aload         5
     209: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     214: astore        6
     216: aload         5
     218: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     223: ifne          231
     226: aload         6
     228: goto          320
     231: aload         6
     233: checkcast     #120                // class kotlin/Pair
     236: astore        7
     238: iconst_0
     239: istore        8
     241: aload         7
     243: invokevirtual #123                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     246: checkcast     #106                // class java/lang/Comparable
     249: astore        9
     251: aload         9
     253: astore        7
     255: aload         5
     257: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     262: astore        8
     264: aload         8
     266: checkcast     #120                // class kotlin/Pair
     269: astore        9
     271: iconst_0
     272: istore        10
     274: aload         9
     276: invokevirtual #123                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     279: checkcast     #106                // class java/lang/Comparable
     282: astore        11
     284: aload         11
     286: astore        9
     288: aload         7
     290: aload         9
     292: invokeinterface #127,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     297: ifge          308
     300: aload         8
     302: astore        6
     304: aload         9
     306: astore        7
     308: aload         5
     310: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     315: ifne          255
     318: aload         6
     320: checkcast     #120                // class kotlin/Pair
     323: astore_2
     324: aload_2
     325: ifnull        335
     328: aload_2
     329: invokevirtual #130                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     332: goto          336
     335: aconst_null
     336: areturn
}


package de.igorakkerman.challenge.maxtableprod

import java.lang.Integer.max

class MaxTableProd(val prodSize: Int, numbersTable: String) {

    val numbers: List<List<Int>>
    val width: Int
    val height: Int

    init {
        numbers = numbersTable
                .lines()
                .map { it.trim() }
                .filter { it.isNotEmpty() }
                .map { it.split(' ') }
                .map { it.map { it.toInt() } }

        if (prodSize < 1)
            throw IllegalArgumentException("prodSize=${prodSize}<1")

        height = numbers.size

        if (height < prodSize)
            throw IllegalArgumentException("height=${height}<${prodSize}=prodSize")

        width = numbers[0].size

        if (width < prodSize)
            throw IllegalArgumentException("row 0 width=${width}<${prodSize}=prodSize")

        numbers.forEachIndexed { rowIndex, row ->
            if (row.size != width)
                throw IllegalArgumentException("row ${rowIndex} width=${row.size}!=${width}")
        }
    }

    internal fun maxHorizontalProd(): Int {
        var maxProd = 0
        for (i in (0 until height)) {
            for (j in (0 .. width - prodSize)) {
                maxProd = max(maxProd, (0 until prodSize).map { numbers[i][j + it] }.reduce { x, y -> x * y })
            }
        }
        return maxProd
    }

    internal fun maxVerticalProd(): Int {
        var maxProd = 0
        for (j in (0 until width)) {
            for (i in (0 .. height - prodSize)) {
                maxProd = max(maxProd, (0 until prodSize).map { numbers[i + it][j] }.reduce { x, y -> x * y })
            }
        }
        return maxProd
    }

    internal fun maxDiagonalLeftProd(): Int {
        var maxProd = 0
        for (i in (prodSize - 1 until height)) {
            for (j in (prodSize - 1 until width)) {
                maxProd = max(maxProd, (0 until prodSize).map { numbers[i - it][j - it] }.reduce { x, y -> x * y })
            }
        }
        return maxProd
    }

    internal fun maxDiagonalRightProd(): Int {
        var maxProd = 0
        for (i in (prodSize - 1 until height)) {
            for (j in (0 .. width - prodSize)) {
                val fn = { k: Int -> numbers[i - k][j + k] }
                maxProd = max(maxProd, (0 until prodSize).map(fn).reduce { x, y -> x * y })
            }
        }
        return maxProd
    }
}

Compiled from "MaxTableProd.kt"
public final class de.igorakkerman.challenge.maxtableprod.MaxTableProd {
  private final int prodSize;

  private final java.util.List<java.util.List<java.lang.Integer>> numbers;

  private final int width;

  private final int height;

  public de.igorakkerman.challenge.maxtableprod.MaxTableProd(int, java.lang.String);
    Code:
       0: aload_2
       1: ldc           #9                  // String numbersTable
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #18                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: iload_1
      12: putfield      #22                 // Field prodSize:I
      15: nop
      16: aload_0
      17: aload_2
      18: checkcast     #24                 // class java/lang/CharSequence
      21: invokestatic  #30                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
      24: checkcast     #32                 // class java/lang/Iterable
      27: astore_3
      28: astore        22
      30: iconst_0
      31: istore        4
      33: aload_3
      34: astore        5
      36: new           #34                 // class java/util/ArrayList
      39: dup
      40: aload_3
      41: bipush        10
      43: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      46: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
      49: checkcast     #45                 // class java/util/Collection
      52: astore        6
      54: iconst_0
      55: istore        7
      57: aload         5
      59: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      64: astore        8
      66: aload         8
      68: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      73: ifeq          123
      76: aload         8
      78: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      83: astore        9
      85: aload         6
      87: aload         9
      89: checkcast     #61                 // class java/lang/String
      92: astore        10
      94: astore        23
      96: iconst_0
      97: istore        11
      99: aload         10
     101: checkcast     #24                 // class java/lang/CharSequence
     104: invokestatic  #65                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     107: invokevirtual #69                 // Method java/lang/Object.toString:()Ljava/lang/String;
     110: nop
     111: aload         23
     113: swap
     114: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     119: pop
     120: goto          66
     123: aload         6
     125: checkcast     #75                 // class java/util/List
     128: nop
     129: aload         22
     131: swap
     132: checkcast     #32                 // class java/lang/Iterable
     135: astore_3
     136: astore        22
     138: iconst_0
     139: istore        4
     141: aload_3
     142: astore        5
     144: new           #34                 // class java/util/ArrayList
     147: dup
     148: invokespecial #76                 // Method java/util/ArrayList."<init>":()V
     151: checkcast     #45                 // class java/util/Collection
     154: astore        6
     156: iconst_0
     157: istore        7
     159: aload         5
     161: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     166: astore        8
     168: aload         8
     170: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     175: ifeq          232
     178: aload         8
     180: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     185: astore        9
     187: aload         9
     189: checkcast     #61                 // class java/lang/String
     192: astore        10
     194: iconst_0
     195: istore        11
     197: aload         10
     199: checkcast     #24                 // class java/lang/CharSequence
     202: invokeinterface #80,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     207: ifle          214
     210: iconst_1
     211: goto          215
     214: iconst_0
     215: nop
     216: ifeq          168
     219: aload         6
     221: aload         9
     223: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     228: pop
     229: goto          168
     232: aload         6
     234: checkcast     #75                 // class java/util/List
     237: nop
     238: aload         22
     240: swap
     241: checkcast     #32                 // class java/lang/Iterable
     244: astore_3
     245: astore        22
     247: iconst_0
     248: istore        4
     250: aload_3
     251: astore        5
     253: new           #34                 // class java/util/ArrayList
     256: dup
     257: aload_3
     258: bipush        10
     260: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     263: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
     266: checkcast     #45                 // class java/util/Collection
     269: astore        6
     271: iconst_0
     272: istore        7
     274: aload         5
     276: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     281: astore        8
     283: aload         8
     285: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     290: ifeq          354
     293: aload         8
     295: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     300: astore        9
     302: aload         6
     304: aload         9
     306: checkcast     #61                 // class java/lang/String
     309: astore        10
     311: astore        23
     313: iconst_0
     314: istore        11
     316: aload         10
     318: checkcast     #24                 // class java/lang/CharSequence
     321: iconst_1
     322: newarray       char
     324: astore        12
     326: aload         12
     328: iconst_0
     329: bipush        32
     331: castore
     332: aload         12
     334: iconst_0
     335: iconst_0
     336: bipush        6
     338: aconst_null
     339: invokestatic  #84                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[CZIILjava/lang/Object;)Ljava/util/List;
     342: aload         23
     344: swap
     345: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     350: pop
     351: goto          283
     354: aload         6
     356: checkcast     #75                 // class java/util/List
     359: nop
     360: aload         22
     362: swap
     363: checkcast     #32                 // class java/lang/Iterable
     366: astore_3
     367: astore        22
     369: iconst_0
     370: istore        4
     372: aload_3
     373: astore        5
     375: new           #34                 // class java/util/ArrayList
     378: dup
     379: aload_3
     380: bipush        10
     382: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     385: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
     388: checkcast     #45                 // class java/util/Collection
     391: astore        6
     393: iconst_0
     394: istore        7
     396: aload         5
     398: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     403: astore        8
     405: aload         8
     407: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     412: ifeq          556
     415: aload         8
     417: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     422: astore        9
     424: aload         6
     426: aload         9
     428: checkcast     #75                 // class java/util/List
     431: astore        10
     433: astore        23
     435: iconst_0
     436: istore        11
     438: aload         10
     440: checkcast     #32                 // class java/lang/Iterable
     443: astore        12
     445: iconst_0
     446: istore        13
     448: aload         12
     450: astore        14
     452: new           #34                 // class java/util/ArrayList
     455: dup
     456: aload         12
     458: bipush        10
     460: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     463: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
     466: checkcast     #45                 // class java/util/Collection
     469: astore        15
     471: iconst_0
     472: istore        16
     474: aload         14
     476: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     481: astore        17
     483: aload         17
     485: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     490: ifeq          537
     493: aload         17
     495: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     500: astore        18
     502: aload         15
     504: aload         18
     506: checkcast     #61                 // class java/lang/String
     509: astore        19
     511: astore        20
     513: iconst_0
     514: istore        21
     516: aload         19
     518: invokestatic  #90                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     521: nop
     522: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     525: aload         20
     527: swap
     528: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     533: pop
     534: goto          483
     537: aload         15
     539: checkcast     #75                 // class java/util/List
     542: nop
     543: nop
     544: aload         23
     546: swap
     547: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     552: pop
     553: goto          405
     556: aload         6
     558: checkcast     #75                 // class java/util/List
     561: nop
     562: aload         22
     564: swap
     565: putfield      #98                 // Field numbers:Ljava/util/List;
     568: aload_0
     569: getfield      #22                 // Field prodSize:I
     572: iconst_1
     573: if_icmpge     611
     576: new           #100                // class java/lang/IllegalArgumentException
     579: dup
     580: new           #102                // class java/lang/StringBuilder
     583: dup
     584: invokespecial #103                // Method java/lang/StringBuilder."<init>":()V
     587: ldc           #105                // String prodSize=
     589: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     592: aload_0
     593: getfield      #22                 // Field prodSize:I
     596: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     599: ldc           #114                // String <1
     601: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     604: invokevirtual #115                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     607: invokespecial #118                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     610: athrow
     611: aload_0
     612: aload_0
     613: getfield      #98                 // Field numbers:Ljava/util/List;
     616: invokeinterface #121,  1          // InterfaceMethod java/util/List.size:()I
     621: putfield      #124                // Field height:I
     624: aload_0
     625: getfield      #124                // Field height:I
     628: aload_0
     629: getfield      #22                 // Field prodSize:I
     632: if_icmpge     682
     635: new           #100                // class java/lang/IllegalArgumentException
     638: dup
     639: new           #102                // class java/lang/StringBuilder
     642: dup
     643: invokespecial #103                // Method java/lang/StringBuilder."<init>":()V
     646: ldc           #126                // String height=
     648: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     651: aload_0
     652: getfield      #124                // Field height:I
     655: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     658: bipush        60
     660: invokevirtual #129                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     663: aload_0
     664: getfield      #22                 // Field prodSize:I
     667: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     670: ldc           #131                // String =prodSize
     672: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     675: invokevirtual #115                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     678: invokespecial #118                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     681: athrow
     682: aload_0
     683: aload_0
     684: getfield      #98                 // Field numbers:Ljava/util/List;
     687: iconst_0
     688: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     693: checkcast     #75                 // class java/util/List
     696: invokeinterface #121,  1          // InterfaceMethod java/util/List.size:()I
     701: putfield      #138                // Field width:I
     704: aload_0
     705: getfield      #138                // Field width:I
     708: aload_0
     709: getfield      #22                 // Field prodSize:I
     712: if_icmpge     762
     715: new           #100                // class java/lang/IllegalArgumentException
     718: dup
     719: new           #102                // class java/lang/StringBuilder
     722: dup
     723: invokespecial #103                // Method java/lang/StringBuilder."<init>":()V
     726: ldc           #140                // String row 0 width=
     728: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     731: aload_0
     732: getfield      #138                // Field width:I
     735: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     738: bipush        60
     740: invokevirtual #129                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     743: aload_0
     744: getfield      #22                 // Field prodSize:I
     747: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     750: ldc           #131                // String =prodSize
     752: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     755: invokevirtual #115                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     758: invokespecial #118                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     761: athrow
     762: aload_0
     763: getfield      #98                 // Field numbers:Ljava/util/List;
     766: checkcast     #32                 // class java/lang/Iterable
     769: astore_3
     770: iconst_0
     771: istore        4
     773: iconst_0
     774: istore        5
     776: aload_3
     777: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     782: astore        6
     784: aload         6
     786: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     791: ifeq          906
     794: aload         6
     796: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     801: astore        7
     803: iload         5
     805: iinc          5, 1
     808: istore        8
     810: iload         8
     812: ifge          818
     815: invokestatic  #143                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     818: iload         8
     820: aload         7
     822: checkcast     #75                 // class java/util/List
     825: astore        9
     827: istore        10
     829: iconst_0
     830: istore        11
     832: aload         9
     834: invokeinterface #121,  1          // InterfaceMethod java/util/List.size:()I
     839: aload_0
     840: getfield      #138                // Field width:I
     843: if_icmpeq     901
     846: new           #100                // class java/lang/IllegalArgumentException
     849: dup
     850: new           #102                // class java/lang/StringBuilder
     853: dup
     854: invokespecial #103                // Method java/lang/StringBuilder."<init>":()V
     857: ldc           #145                // String row
     859: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     862: iload         10
     864: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     867: ldc           #147                // String  width=
     869: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     872: aload         9
     874: invokeinterface #121,  1          // InterfaceMethod java/util/List.size:()I
     879: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     882: ldc           #149                // String !=
     884: invokevirtual #109                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     887: aload_0
     888: getfield      #138                // Field width:I
     891: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     894: invokevirtual #115                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     897: invokespecial #118                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     900: athrow
     901: nop
     902: nop
     903: goto          784
     906: nop
     907: nop
     908: return

  public final int getProdSize();
    Code:
       0: aload_0
       1: getfield      #22                 // Field prodSize:I
       4: ireturn

  public final java.util.List<java.util.List<java.lang.Integer>> getNumbers();
    Code:
       0: aload_0
       1: getfield      #98                 // Field numbers:Ljava/util/List;
       4: areturn

  public final int getWidth();
    Code:
       0: aload_0
       1: getfield      #138                // Field width:I
       4: ireturn

  public final int getHeight();
    Code:
       0: aload_0
       1: getfield      #124                // Field height:I
       4: ireturn

  public final int maxHorizontalProd$main();
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_0
       3: istore_2
       4: aload_0
       5: getfield      #124                // Field height:I
       8: istore_3
       9: iload_2
      10: iload_3
      11: if_icmpge     312
      14: iconst_0
      15: istore        4
      17: aload_0
      18: getfield      #138                // Field width:I
      21: aload_0
      22: getfield      #22                 // Field prodSize:I
      25: isub
      26: istore        5
      28: iload         4
      30: iload         5
      32: if_icmpgt     306
      35: iload_1
      36: iconst_0
      37: aload_0
      38: getfield      #22                 // Field prodSize:I
      41: invokestatic  #192                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      44: checkcast     #32                 // class java/lang/Iterable
      47: astore        6
      49: istore        15
      51: iconst_0
      52: istore        7
      54: aload         6
      56: astore        8
      58: new           #34                 // class java/util/ArrayList
      61: dup
      62: aload         6
      64: bipush        10
      66: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      69: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
      72: checkcast     #45                 // class java/util/Collection
      75: astore        9
      77: iconst_0
      78: istore        10
      80: aload         8
      82: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      87: astore        11
      89: aload         11
      91: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      96: ifeq          164
      99: aload         11
     101: checkcast     #194                // class kotlin/collections/IntIterator
     104: invokevirtual #197                // Method kotlin/collections/IntIterator.nextInt:()I
     107: istore        12
     109: aload         9
     111: iload         12
     113: istore        13
     115: astore        16
     117: iconst_0
     118: istore        14
     120: aload_0
     121: getfield      #98                 // Field numbers:Ljava/util/List;
     124: iload_2
     125: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     130: checkcast     #75                 // class java/util/List
     133: iload         4
     135: iload         13
     137: iadd
     138: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     143: checkcast     #199                // class java/lang/Number
     146: invokevirtual #202                // Method java/lang/Number.intValue:()I
     149: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     152: aload         16
     154: swap
     155: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     160: pop
     161: goto          89
     164: aload         9
     166: checkcast     #75                 // class java/util/List
     169: nop
     170: astore        16
     172: iload         15
     174: aload         16
     176: checkcast     #32                 // class java/lang/Iterable
     179: astore        6
     181: istore        15
     183: iconst_0
     184: istore        7
     186: aload         6
     188: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     193: astore        8
     195: aload         8
     197: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     202: ifne          215
     205: new           #204                // class java/lang/UnsupportedOperationException
     208: dup
     209: ldc           #206                // String Empty collection can\'t be reduced.
     211: invokespecial #207                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     214: athrow
     215: aload         8
     217: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     222: astore        9
     224: aload         8
     226: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     231: ifeq          275
     234: aload         9
     236: aload         8
     238: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     243: checkcast     #199                // class java/lang/Number
     246: invokevirtual #202                // Method java/lang/Number.intValue:()I
     249: istore        10
     251: checkcast     #199                // class java/lang/Number
     254: invokevirtual #202                // Method java/lang/Number.intValue:()I
     257: istore        11
     259: iconst_0
     260: istore        12
     262: iload         11
     264: iload         10
     266: imul
     267: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     270: astore        9
     272: goto          224
     275: aload         9
     277: astore        16
     279: iload         15
     281: aload         16
     283: checkcast     #199                // class java/lang/Number
     286: invokevirtual #202                // Method java/lang/Number.intValue:()I
     289: invokestatic  #211                // Method java/lang/Integer.max:(II)I
     292: istore_1
     293: iload         4
     295: iload         5
     297: if_icmpeq     306
     300: iinc          4, 1
     303: goto          35
     306: iinc          2, 1
     309: goto          9
     312: iload_1
     313: ireturn

  public final int maxVerticalProd$main();
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_0
       3: istore_2
       4: aload_0
       5: getfield      #138                // Field width:I
       8: istore_3
       9: iload_2
      10: iload_3
      11: if_icmpge     312
      14: iconst_0
      15: istore        4
      17: aload_0
      18: getfield      #124                // Field height:I
      21: aload_0
      22: getfield      #22                 // Field prodSize:I
      25: isub
      26: istore        5
      28: iload         4
      30: iload         5
      32: if_icmpgt     306
      35: iload_1
      36: iconst_0
      37: aload_0
      38: getfield      #22                 // Field prodSize:I
      41: invokestatic  #192                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      44: checkcast     #32                 // class java/lang/Iterable
      47: astore        6
      49: istore        15
      51: iconst_0
      52: istore        7
      54: aload         6
      56: astore        8
      58: new           #34                 // class java/util/ArrayList
      61: dup
      62: aload         6
      64: bipush        10
      66: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      69: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
      72: checkcast     #45                 // class java/util/Collection
      75: astore        9
      77: iconst_0
      78: istore        10
      80: aload         8
      82: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      87: astore        11
      89: aload         11
      91: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      96: ifeq          164
      99: aload         11
     101: checkcast     #194                // class kotlin/collections/IntIterator
     104: invokevirtual #197                // Method kotlin/collections/IntIterator.nextInt:()I
     107: istore        12
     109: aload         9
     111: iload         12
     113: istore        13
     115: astore        16
     117: iconst_0
     118: istore        14
     120: aload_0
     121: getfield      #98                 // Field numbers:Ljava/util/List;
     124: iload         4
     126: iload         13
     128: iadd
     129: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     134: checkcast     #75                 // class java/util/List
     137: iload_2
     138: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     143: checkcast     #199                // class java/lang/Number
     146: invokevirtual #202                // Method java/lang/Number.intValue:()I
     149: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     152: aload         16
     154: swap
     155: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     160: pop
     161: goto          89
     164: aload         9
     166: checkcast     #75                 // class java/util/List
     169: nop
     170: astore        16
     172: iload         15
     174: aload         16
     176: checkcast     #32                 // class java/lang/Iterable
     179: astore        6
     181: istore        15
     183: iconst_0
     184: istore        7
     186: aload         6
     188: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     193: astore        8
     195: aload         8
     197: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     202: ifne          215
     205: new           #204                // class java/lang/UnsupportedOperationException
     208: dup
     209: ldc           #206                // String Empty collection can\'t be reduced.
     211: invokespecial #207                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     214: athrow
     215: aload         8
     217: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     222: astore        9
     224: aload         8
     226: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     231: ifeq          275
     234: aload         9
     236: aload         8
     238: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     243: checkcast     #199                // class java/lang/Number
     246: invokevirtual #202                // Method java/lang/Number.intValue:()I
     249: istore        10
     251: checkcast     #199                // class java/lang/Number
     254: invokevirtual #202                // Method java/lang/Number.intValue:()I
     257: istore        11
     259: iconst_0
     260: istore        12
     262: iload         11
     264: iload         10
     266: imul
     267: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     270: astore        9
     272: goto          224
     275: aload         9
     277: astore        16
     279: iload         15
     281: aload         16
     283: checkcast     #199                // class java/lang/Number
     286: invokevirtual #202                // Method java/lang/Number.intValue:()I
     289: invokestatic  #211                // Method java/lang/Integer.max:(II)I
     292: istore_1
     293: iload         4
     295: iload         5
     297: if_icmpeq     306
     300: iinc          4, 1
     303: goto          35
     306: iinc          2, 1
     309: goto          9
     312: iload_1
     313: ireturn

  public final int maxDiagonalLeftProd$main();
    Code:
       0: iconst_0
       1: istore_1
       2: aload_0
       3: getfield      #22                 // Field prodSize:I
       6: iconst_1
       7: isub
       8: istore_2
       9: aload_0
      10: getfield      #124                // Field height:I
      13: istore_3
      14: iload_2
      15: iload_3
      16: if_icmpge     313
      19: aload_0
      20: getfield      #22                 // Field prodSize:I
      23: iconst_1
      24: isub
      25: istore        4
      27: aload_0
      28: getfield      #138                // Field width:I
      31: istore        5
      33: iload         4
      35: iload         5
      37: if_icmpge     307
      40: iload_1
      41: iconst_0
      42: aload_0
      43: getfield      #22                 // Field prodSize:I
      46: invokestatic  #192                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      49: checkcast     #32                 // class java/lang/Iterable
      52: astore        6
      54: istore        15
      56: iconst_0
      57: istore        7
      59: aload         6
      61: astore        8
      63: new           #34                 // class java/util/ArrayList
      66: dup
      67: aload         6
      69: bipush        10
      71: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      74: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
      77: checkcast     #45                 // class java/util/Collection
      80: astore        9
      82: iconst_0
      83: istore        10
      85: aload         8
      87: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      92: astore        11
      94: aload         11
      96: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     101: ifeq          172
     104: aload         11
     106: checkcast     #194                // class kotlin/collections/IntIterator
     109: invokevirtual #197                // Method kotlin/collections/IntIterator.nextInt:()I
     112: istore        12
     114: aload         9
     116: iload         12
     118: istore        13
     120: astore        16
     122: iconst_0
     123: istore        14
     125: aload_0
     126: getfield      #98                 // Field numbers:Ljava/util/List;
     129: iload_2
     130: iload         13
     132: isub
     133: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     138: checkcast     #75                 // class java/util/List
     141: iload         4
     143: iload         13
     145: isub
     146: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     151: checkcast     #199                // class java/lang/Number
     154: invokevirtual #202                // Method java/lang/Number.intValue:()I
     157: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     160: aload         16
     162: swap
     163: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     168: pop
     169: goto          94
     172: aload         9
     174: checkcast     #75                 // class java/util/List
     177: nop
     178: astore        16
     180: iload         15
     182: aload         16
     184: checkcast     #32                 // class java/lang/Iterable
     187: astore        6
     189: istore        15
     191: iconst_0
     192: istore        7
     194: aload         6
     196: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     201: astore        8
     203: aload         8
     205: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     210: ifne          223
     213: new           #204                // class java/lang/UnsupportedOperationException
     216: dup
     217: ldc           #206                // String Empty collection can\'t be reduced.
     219: invokespecial #207                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     222: athrow
     223: aload         8
     225: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     230: astore        9
     232: aload         8
     234: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     239: ifeq          283
     242: aload         9
     244: aload         8
     246: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     251: checkcast     #199                // class java/lang/Number
     254: invokevirtual #202                // Method java/lang/Number.intValue:()I
     257: istore        10
     259: checkcast     #199                // class java/lang/Number
     262: invokevirtual #202                // Method java/lang/Number.intValue:()I
     265: istore        11
     267: iconst_0
     268: istore        12
     270: iload         11
     272: iload         10
     274: imul
     275: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     278: astore        9
     280: goto          232
     283: aload         9
     285: astore        16
     287: iload         15
     289: aload         16
     291: checkcast     #199                // class java/lang/Number
     294: invokevirtual #202                // Method java/lang/Number.intValue:()I
     297: invokestatic  #211                // Method java/lang/Integer.max:(II)I
     300: istore_1
     301: iinc          4, 1
     304: goto          33
     307: iinc          2, 1
     310: goto          14
     313: iload_1
     314: ireturn

  public final int maxDiagonalRightProd$main();
    Code:
       0: iconst_0
       1: istore_1
       2: aload_0
       3: getfield      #22                 // Field prodSize:I
       6: iconst_1
       7: isub
       8: istore_2
       9: aload_0
      10: getfield      #124                // Field height:I
      13: istore_3
      14: iload_2
      15: iload_3
      16: if_icmpge     292
      19: iconst_0
      20: istore        4
      22: aload_0
      23: getfield      #138                // Field width:I
      26: aload_0
      27: getfield      #22                 // Field prodSize:I
      30: isub
      31: istore        5
      33: iload         4
      35: iload         5
      37: if_icmpgt     286
      40: aload_0
      41: iload_2
      42: iload         4
      44: invokedynamic #250,  0            // InvokeDynamic #0:invoke:(Lde/igorakkerman/challenge/maxtableprod/MaxTableProd;II)Lkotlin/jvm/functions/Function1;
      49: astore        6
      51: iload_1
      52: iconst_0
      53: aload_0
      54: getfield      #22                 // Field prodSize:I
      57: invokestatic  #192                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      60: checkcast     #32                 // class java/lang/Iterable
      63: astore        7
      65: istore        14
      67: iconst_0
      68: istore        8
      70: aload         7
      72: astore        9
      74: new           #34                 // class java/util/ArrayList
      77: dup
      78: aload         7
      80: bipush        10
      82: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      85: invokespecial #43                 // Method java/util/ArrayList."<init>":(I)V
      88: checkcast     #45                 // class java/util/Collection
      91: astore        10
      93: iconst_0
      94: istore        11
      96: aload         9
      98: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     103: astore        12
     105: aload         12
     107: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     112: ifeq          144
     115: aload         12
     117: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     122: astore        13
     124: aload         10
     126: aload         6
     128: aload         13
     130: invokeinterface #254,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     135: invokeinterface #73,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     140: pop
     141: goto          105
     144: aload         10
     146: checkcast     #75                 // class java/util/List
     149: nop
     150: astore        15
     152: iload         14
     154: aload         15
     156: checkcast     #32                 // class java/lang/Iterable
     159: astore        7
     161: istore        14
     163: iconst_0
     164: istore        8
     166: aload         7
     168: invokeinterface #49,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     173: astore        9
     175: aload         9
     177: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     182: ifne          195
     185: new           #204                // class java/lang/UnsupportedOperationException
     188: dup
     189: ldc           #206                // String Empty collection can\'t be reduced.
     191: invokespecial #207                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     194: athrow
     195: aload         9
     197: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     202: astore        10
     204: aload         9
     206: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     211: ifeq          255
     214: aload         10
     216: aload         9
     218: invokeinterface #59,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     223: checkcast     #199                // class java/lang/Number
     226: invokevirtual #202                // Method java/lang/Number.intValue:()I
     229: istore        11
     231: checkcast     #199                // class java/lang/Number
     234: invokevirtual #202                // Method java/lang/Number.intValue:()I
     237: istore        12
     239: iconst_0
     240: istore        13
     242: iload         12
     244: iload         11
     246: imul
     247: invokestatic  #94                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     250: astore        10
     252: goto          204
     255: aload         10
     257: astore        15
     259: iload         14
     261: aload         15
     263: checkcast     #199                // class java/lang/Number
     266: invokevirtual #202                // Method java/lang/Number.intValue:()I
     269: invokestatic  #211                // Method java/lang/Integer.max:(II)I
     272: istore_1
     273: iload         4
     275: iload         5
     277: if_icmpeq     286
     280: iinc          4, 1
     283: goto          40
     286: iinc          2, 1
     289: goto          14
     292: iload_1
     293: ireturn

  private static final int maxDiagonalRightProd$lambda$12(de.igorakkerman.challenge.maxtableprod.MaxTableProd, int, int, int);
    Code:
       0: aload_0
       1: getfield      #98                 // Field numbers:Ljava/util/List;
       4: iload_1
       5: iload_3
       6: isub
       7: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      12: checkcast     #75                 // class java/util/List
      15: iload_2
      16: iload_3
      17: iadd
      18: invokeinterface #135,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      23: checkcast     #199                // class java/lang/Number
      26: invokevirtual #202                // Method java/lang/Number.intValue:()I
      29: ireturn
}


package com.aesean.twentyfour

import java.math.BigDecimal
import java.util.*

interface CalculateRule {
    fun size(): Int
    fun calculate(a: String, index: Int, b: String): String
    fun symbol(index: Int): String
    fun deviation(): String
}

fun main(args: Array<String>) {
    test("8,8,3,3")
    test("5,5,5,1")
}

private fun String.format(): String {
    return String.format("%2.1f", this.toFloat())
}

private fun test(s: String) {
    val numbers = s.split(",")
    val nodes = MutableList(numbers.size) {
        Node(numbers[it])
    }
    val tree = Tree(nodes, CalculateRuleByBigDecimal())
    tree.find {
        if (Math.abs(it.number.toDouble() - 24) < 0.0000000001) {
            println("${it.desc} = ${it.number.format()}")
        }
    }
    println("**********")
    tree.find {
        if (Math.abs(it.number.toDouble()) <= 10) {
            println("${it.desc} = ${it.number.format()}")
        }
    }
}

class CalculateRuleNormal : CalculateRule {

    companion object {
        val SYMBOLS = arrayOf("+", "-", "×", "÷")
        const val DEVIATION = "0.00001"
    }

    override fun symbol(index: Int): String {
        return SYMBOLS[index]
    }

    override fun calculate(a: String, index: Int, b: String): String {
        val numA = a.toDouble()
        val numB = b.toDouble()
        when (index) {
            0 -> {
                return (numA + numB).toString()
            }
            1 -> {
                return (numA - numB).toString()
            }
            2 -> {
                return (numA * numB).toString()
            }
            3 -> {
                if (numB == 0.0) {
                    throw RuntimeException("Can't multiply 0")
                }
                return (numA / numB).toString()
            }
            else -> {
                throw RuntimeException("Unknown index")
            }
        }
    }

    override fun size(): Int {
        return SYMBOLS.size
    }

    override fun deviation(): String {
        return DEVIATION
    }

    override fun toString(): String {
        return "CalculateRuleNormal{SYMBOLS = ${Arrays.toString(SYMBOLS)}, deviation = ${deviation()}}"
    }
}

class CalculateRuleByBigDecimal : CalculateRule {

    companion object {
        val SYMBOLS = arrayOf("+", "-", "×", "÷")
        const val DEVIATION = "0.00000000001"
    }

    override fun symbol(index: Int): String {
        return SYMBOLS[index]
    }

    override fun calculate(a: String, index: Int, b: String): String {
        val numA = BigDecimal(a)
        val numB = BigDecimal(b)
        when (index) {
            0 -> {
                return numA.add(numB).toString()
            }
            1 -> {
                return numA.subtract(numB).toString()
            }
            2 -> {
                return numA.multiply(numB).toString()
            }
            3 -> {
                return numA.divide(numB, 16, BigDecimal.ROUND_HALF_UP).toString()
            }
            else -> {
                throw RuntimeException("Unknown index")
            }
        }
    }

    override fun size(): Int {
        return SYMBOLS.size
    }

    override fun deviation(): String {
        return DEVIATION
    }

    override fun toString(): String {
        return "CalculateRuleByBigDecimal{SYMBOLS = ${Arrays.toString(SYMBOLS)}, deviation = ${deviation()}}"
    }

}

class Tree(private val nodes: MutableList<Node>, private val calculateRule: CalculateRule) {

    private val nodeArrangement = Arrangement(nodes.size)

    fun find(filter: (result: Node) -> Unit) {
        nodeArrangement.traversal { left: Int, right: Int ->
            val leftNode = nodes[left]
            val rightNode = nodes[right]

            for (symbolIndex in 0 until calculateRule.size()) {
                val nextNodes: MutableList<Node> = ArrayList(nodes.size - 2)
                nodes.forEachIndexed { index, value ->
                    if ((index != left) and (index != right)) {
                        nextNodes.add(value)
                    }
                }
                val number: String
                try {
                    number = calculateRule.calculate(leftNode.number, symbolIndex, rightNode.number)
                } catch (e: Exception) {
                    continue
                }
                val node = Node(number)
                node.desc = "(${leftNode.desc}${calculateRule.symbol(symbolIndex)}${rightNode.desc})"
                nextNodes.add(node)
                if (nextNodes.size > 1) {
                    Tree(nextNodes, calculateRule).find(filter)
                } else {
                    val n = nextNodes[0]
                    filter.invoke(n)
                }
            }
        }
    }

    fun size(): Int {
        return nodes.size
    }
}

class Node(var number: String) {
    var desc: String = number

    override fun toString(): String {
        return desc
    }
}

class Arrangement(val size: Int) {
    private var mainIndex: Int = -1
    private var childIndex: Int = -1

    init {
        if (size < 2) {
            throw RuntimeException("size should be >= 2. ")
        }
    }

    private fun next(): Boolean {
        if ((mainIndex == -1) and (childIndex == -1)) {
            mainIndex = 0
            childIndex = 1
            return true
        }

        childIndex++
        var check = false
        if (childIndex < size) {
            check = true
        } else {
            childIndex = 0
            mainIndex++
            if (mainIndex < size) {
                check = true
            }
        }
        if (check) {
            return if (mainIndex == childIndex) {
                next()
            } else {
                true
            }
        }
        return false
    }

    fun traversal(result: (left: Int, right: Int) -> Unit) {
        mainIndex = -1
        childIndex = -1
        while (next()) {
            result.invoke(mainIndex, childIndex)
        }
    }
}

Compiled from "CalculateImpl.kt"
public final class com.aesean.twentyfour.CalculateImplKt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #17                 // String 8,8,3,3
       8: invokestatic  #21                 // Method test:(Ljava/lang/String;)V
      11: ldc           #23                 // String 5,5,5,1
      13: invokestatic  #21                 // Method test:(Ljava/lang/String;)V
      16: return

  private static final java.lang.String format(java.lang.String);
    Code:
       0: getstatic     #32                 // Field kotlin/jvm/internal/StringCompanionObject.INSTANCE:Lkotlin/jvm/internal/StringCompanionObject;
       3: pop
       4: ldc           #34                 // String %2.1f
       6: astore_1
       7: iconst_1
       8: anewarray     #4                  // class java/lang/Object
      11: astore_2
      12: aload_2
      13: iconst_0
      14: aload_0
      15: invokestatic  #40                 // Method java/lang/Float.parseFloat:(Ljava/lang/String;)F
      18: invokestatic  #44                 // Method java/lang/Float.valueOf:(F)Ljava/lang/Float;
      21: aastore
      22: aload_2
      23: astore_2
      24: aload_1
      25: aload_2
      26: aload_2
      27: arraylength
      28: invokestatic  #50                 // Method java/util/Arrays.copyOf:([Ljava/lang/Object;I)[Ljava/lang/Object;
      31: invokestatic  #55                 // Method java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
      34: dup
      35: ldc           #57                 // String format(...)
      37: invokestatic  #60                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      40: areturn

  private static final void test(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #64                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #52                 // class java/lang/String
       8: astore_2
       9: aload_2
      10: iconst_0
      11: ldc           #66                 // String ,
      13: aastore
      14: aload_2
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #72                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: astore_1
      24: aload_1
      25: invokeinterface #78,  1           // InterfaceMethod java/util/List.size:()I
      30: istore_3
      31: new           #80                 // class java/util/ArrayList
      34: dup
      35: iload_3
      36: invokespecial #84                 // Method java/util/ArrayList."<init>":(I)V
      39: astore        4
      41: iconst_0
      42: istore        5
      44: iload         5
      46: iload_3
      47: if_icmpge     96
      50: iload         5
      52: istore        6
      54: aload         4
      56: iload         6
      58: istore        7
      60: astore        9
      62: iconst_0
      63: istore        8
      65: new           #86                 // class com/aesean/twentyfour/Node
      68: dup
      69: aload_1
      70: iload         7
      72: invokeinterface #90,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      77: checkcast     #52                 // class java/lang/String
      80: invokespecial #92                 // Method com/aesean/twentyfour/Node."<init>":(Ljava/lang/String;)V
      83: aload         9
      85: swap
      86: invokevirtual #96                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      89: pop
      90: iinc          5, 1
      93: goto          44
      96: aload         4
      98: checkcast     #74                 // class java/util/List
     101: astore_2
     102: new           #98                 // class com/aesean/twentyfour/Tree
     105: dup
     106: aload_2
     107: new           #100                // class com/aesean/twentyfour/CalculateRuleByBigDecimal
     110: dup
     111: invokespecial #103                // Method com/aesean/twentyfour/CalculateRuleByBigDecimal."<init>":()V
     114: checkcast     #105                // class com/aesean/twentyfour/CalculateRule
     117: invokespecial #108                // Method com/aesean/twentyfour/Tree."<init>":(Ljava/util/List;Lcom/aesean/twentyfour/CalculateRule;)V
     120: astore_3
     121: aload_3
     122: invokedynamic #127,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     127: invokevirtual #131                // Method com/aesean/twentyfour/Tree.find:(Lkotlin/jvm/functions/Function1;)V
     130: ldc           #133                // String **********
     132: getstatic     #139                // Field java/lang/System.out:Ljava/io/PrintStream;
     135: swap
     136: invokevirtual #145                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     139: aload_3
     140: invokedynamic #150,  0            // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function1;
     145: invokevirtual #131                // Method com/aesean/twentyfour/Tree.find:(Lkotlin/jvm/functions/Function1;)V
     148: return

  private static final kotlin.Unit test$lambda$1(com.aesean.twentyfour.Node);
    Code:
       0: aload_0
       1: ldc           #161                // String it
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #165                // Method com/aesean/twentyfour/Node.getNumber:()Ljava/lang/String;
      10: invokestatic  #171                // Method java/lang/Double.parseDouble:(Ljava/lang/String;)D
      13: bipush        24
      15: i2d
      16: dsub
      17: invokestatic  #177                // Method java/lang/Math.abs:(D)D
      20: ldc2_w        #178                // double 1.0E-10d
      23: dcmpg
      24: ifge          66
      27: new           #181                // class java/lang/StringBuilder
      30: dup
      31: invokespecial #182                // Method java/lang/StringBuilder."<init>":()V
      34: aload_0
      35: invokevirtual #185                // Method com/aesean/twentyfour/Node.getDesc:()Ljava/lang/String;
      38: invokevirtual #189                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      41: ldc           #191                // String  =
      43: invokevirtual #189                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      46: aload_0
      47: invokevirtual #165                // Method com/aesean/twentyfour/Node.getNumber:()Ljava/lang/String;
      50: invokestatic  #193                // Method format:(Ljava/lang/String;)Ljava/lang/String;
      53: invokevirtual #189                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      56: invokevirtual #196                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      59: getstatic     #139                // Field java/lang/System.out:Ljava/io/PrintStream;
      62: swap
      63: invokevirtual #145                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      66: getstatic     #201                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      69: areturn

  private static final kotlin.Unit test$lambda$2(com.aesean.twentyfour.Node);
    Code:
       0: aload_0
       1: ldc           #161                // String it
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #165                // Method com/aesean/twentyfour/Node.getNumber:()Ljava/lang/String;
      10: invokestatic  #171                // Method java/lang/Double.parseDouble:(Ljava/lang/String;)D
      13: invokestatic  #177                // Method java/lang/Math.abs:(D)D
      16: ldc2_w        #203                // double 10.0d
      19: dcmpg
      20: ifgt          62
      23: new           #181                // class java/lang/StringBuilder
      26: dup
      27: invokespecial #182                // Method java/lang/StringBuilder."<init>":()V
      30: aload_0
      31: invokevirtual #185                // Method com/aesean/twentyfour/Node.getDesc:()Ljava/lang/String;
      34: invokevirtual #189                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      37: ldc           #191                // String  =
      39: invokevirtual #189                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      42: aload_0
      43: invokevirtual #165                // Method com/aesean/twentyfour/Node.getNumber:()Ljava/lang/String;
      46: invokestatic  #193                // Method format:(Ljava/lang/String;)Ljava/lang/String;
      49: invokevirtual #189                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      52: invokevirtual #196                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      55: getstatic     #139                // Field java/lang/System.out:Ljava/io/PrintStream;
      58: swap
      59: invokevirtual #145                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      62: getstatic     #201                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      65: areturn
}