package fr.pturpin.coursera.dynprog

class ArithmeticExpression(private val strExpression: String) {

    private val cache = ArrayList<MutableList<MinMaxExpression?>>(strExpression.length)

    fun getMaximumValue(): Long {
        clearCache()
        return computeCachedMaximumValue(0, strExpression.length).maxExpression
    }

    private fun clearCache() {
        cache.clear()
        for (i in 0..strExpression.length) {
            val elements = ArrayList<MinMaxExpression?>(strExpression.length)
            for (j in 0..strExpression.length) {
                elements.add(null)
            }
            cache.add(elements)
        }
    }

    private fun computeCachedMaximumValue(indexFrom: Int, indexTo: Int): MinMaxExpression {
        cache[indexFrom][indexTo]?.let { return it }
        val result = computeMaximumValue(indexFrom, indexTo)
        cache[indexFrom][indexTo] = result
        return result
    }

    private fun computeMaximumValue(indexFrom: Int, indexTo: Int): MinMaxExpression {
        if (indexFrom == indexTo - 1) {
            val strNumber = strExpression[indexFrom]
            val value = strNumber.toLong() - '0'.toLong()
            return MinMaxExpression(value, value)
        }

        var minimum = Long.MAX_VALUE
        var maximum = Long.MIN_VALUE

        getSplitExpressions(indexFrom, indexTo)
            .flatMap { computeCandidateValues(it) }
            .forEach { candidate ->
                if (candidate >= maximum) {
                    maximum = candidate
                }
                if (candidate <= minimum) {
                    minimum = candidate
                }
            }

        return MinMaxExpression(minimum, maximum)
    }

    private fun computeCandidateValues(splitExpression: SplitExpression): Sequence<Long> {
        val leftMinMax = computeCachedMaximumValue(splitExpression.leftFrom, splitExpression.leftTo)
        val rightMinMax = computeCachedMaximumValue(splitExpression.rightFrom, splitExpression.rightTo)

        return sequenceOf(
            evaluate(splitExpression.operator, leftMinMax.minExpression, rightMinMax.minExpression),
            evaluate(splitExpression.operator, leftMinMax.maxExpression, rightMinMax.minExpression),
            evaluate(splitExpression.operator, leftMinMax.minExpression, rightMinMax.maxExpression),
            evaluate(splitExpression.operator, leftMinMax.maxExpression, rightMinMax.maxExpression))
    }

    private fun evaluate(operator: Char, left: Long, right: Long): Long {
        when (operator) {
            '+' -> return left + right
            '-' -> return left - right
            '*' -> return left * right
        }
        throw UnsupportedOperationException()
    }

    private fun getSplitExpressions(indexFrom: Int, indexTo: Int): Sequence<SplitExpression> {
        return (indexFrom + 1 until indexTo).step(2)
            .asSequence()
            .map {
                SplitExpression(
                    indexFrom,
                    it,
                    it + 1,
                    indexTo,
                    strExpression[it]
                )
            }
    }

    private data class SplitExpression(
        val leftFrom: Int,
        val leftTo: Int,
        val rightFrom: Int,
        val rightTo: Int,
        val operator: Char)

    private data class MinMaxExpression(
        val minExpression: Long,
        val maxExpression: Long)

}

fun main(args: Array<String>) {
    val expression = readLine()!!
    val arithmeticExpression = ArithmeticExpression(expression)
    val maximumValue = arithmeticExpression.getMaximumValue()
    print(maximumValue)
}

Compiled from "ArithmeticExpression.kt"
public final class fr.pturpin.coursera.dynprog.ArithmeticExpression {
  private final java.lang.String strExpression;

  private final java.util.ArrayList<java.util.List<fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression>> cache;

  public fr.pturpin.coursera.dynprog.ArithmeticExpression(java.lang.String);
    Code:
       0: aload_1
       1: ldc           #9                  // String strExpression
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #18                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: aload_1
      12: putfield      #21                 // Field strExpression:Ljava/lang/String;
      15: aload_0
      16: new           #23                 // class java/util/ArrayList
      19: dup
      20: aload_0
      21: getfield      #21                 // Field strExpression:Ljava/lang/String;
      24: invokevirtual #29                 // Method java/lang/String.length:()I
      27: invokespecial #32                 // Method java/util/ArrayList."<init>":(I)V
      30: putfield      #36                 // Field cache:Ljava/util/ArrayList;
      33: return

  public final long getMaximumValue();
    Code:
       0: aload_0
       1: invokespecial #43                 // Method clearCache:()V
       4: aload_0
       5: iconst_0
       6: aload_0
       7: getfield      #21                 // Field strExpression:Ljava/lang/String;
      10: invokevirtual #29                 // Method java/lang/String.length:()I
      13: invokespecial #47                 // Method computeCachedMaximumValue:(II)Lfr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression;
      16: invokevirtual #52                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMaxExpression:()J
      19: lreturn

  private final void clearCache();
    Code:
       0: aload_0
       1: getfield      #36                 // Field cache:Ljava/util/ArrayList;
       4: invokevirtual #55                 // Method java/util/ArrayList.clear:()V
       7: iconst_0
       8: istore_1
       9: aload_0
      10: getfield      #21                 // Field strExpression:Ljava/lang/String;
      13: invokevirtual #29                 // Method java/lang/String.length:()I
      16: istore_2
      17: iload_1
      18: iload_2
      19: if_icmpgt     95
      22: new           #23                 // class java/util/ArrayList
      25: dup
      26: aload_0
      27: getfield      #21                 // Field strExpression:Ljava/lang/String;
      30: invokevirtual #29                 // Method java/lang/String.length:()I
      33: invokespecial #32                 // Method java/util/ArrayList."<init>":(I)V
      36: astore_3
      37: iconst_0
      38: istore        4
      40: aload_0
      41: getfield      #21                 // Field strExpression:Ljava/lang/String;
      44: invokevirtual #29                 // Method java/lang/String.length:()I
      47: istore        5
      49: iload         4
      51: iload         5
      53: if_icmpgt     75
      56: aload_3
      57: aconst_null
      58: invokevirtual #59                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      61: pop
      62: iload         4
      64: iload         5
      66: if_icmpeq     75
      69: iinc          4, 1
      72: goto          56
      75: aload_0
      76: getfield      #36                 // Field cache:Ljava/util/ArrayList;
      79: aload_3
      80: invokevirtual #59                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      83: pop
      84: iload_1
      85: iload_2
      86: if_icmpeq     95
      89: iinc          1, 1
      92: goto          22
      95: return

  private final fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression computeCachedMaximumValue(int, int);
    Code:
       0: aload_0
       1: getfield      #36                 // Field cache:Ljava/util/ArrayList;
       4: iload_1
       5: invokevirtual #67                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
       8: checkcast     #69                 // class java/util/List
      11: iload_2
      12: invokeinterface #70,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      17: checkcast     #49                 // class fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression
      20: dup
      21: ifnull        32
      24: astore        4
      26: iconst_0
      27: istore        5
      29: aload         4
      31: areturn
      32: pop
      33: aload_0
      34: iload_1
      35: iload_2
      36: invokespecial #73                 // Method computeMaximumValue:(II)Lfr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression;
      39: astore_3
      40: aload_0
      41: getfield      #36                 // Field cache:Ljava/util/ArrayList;
      44: iload_1
      45: invokevirtual #67                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      48: checkcast     #69                 // class java/util/List
      51: iload_2
      52: aload_3
      53: invokeinterface #77,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
      58: pop
      59: aload_3
      60: areturn

  private final fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression computeMaximumValue(int, int);
    Code:
       0: iload_1
       1: iload_2
       2: iconst_1
       3: isub
       4: if_icmpne     36
       7: aload_0
       8: getfield      #21                 // Field strExpression:Ljava/lang/String;
      11: iload_1
      12: invokevirtual #87                 // Method java/lang/String.charAt:(I)C
      15: istore_3
      16: iload_3
      17: i2l
      18: ldc2_w        #88                 // long 48l
      21: lsub
      22: lstore        4
      24: new           #49                 // class fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression
      27: dup
      28: lload         4
      30: lload         4
      32: invokespecial #92                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression."<init>":(JJ)V
      35: areturn
      36: lconst_0
      37: lstore        12
      39: ldc2_w        #93                 // long 9223372036854775807l
      42: lstore        12
      44: lconst_0
      45: lstore        14
      47: ldc2_w        #95                 // long -9223372036854775808l
      50: lstore        14
      52: aload_0
      53: iload_1
      54: iload_2
      55: invokespecial #100                // Method getSplitExpressions:(II)Lkotlin/sequences/Sequence;
      58: aload_0
      59: invokedynamic #120,  0            // InvokeDynamic #0:invoke:(Lfr/pturpin/coursera/dynprog/ArithmeticExpression;)Lkotlin/jvm/functions/Function1;
      64: invokestatic  #126                // Method kotlin/sequences/SequencesKt.flatMap:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      67: astore        5
      69: nop
      70: iconst_0
      71: istore        6
      73: aload         5
      75: invokeinterface #132,  1          // InterfaceMethod kotlin/sequences/Sequence.iterator:()Ljava/util/Iterator;
      80: astore        7
      82: aload         7
      84: invokeinterface #138,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      89: ifeq          143
      92: aload         7
      94: invokeinterface #142,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      99: astore        8
     101: aload         8
     103: checkcast     #144                // class java/lang/Number
     106: invokevirtual #147                // Method java/lang/Number.longValue:()J
     109: lstore        9
     111: iconst_0
     112: istore        11
     114: lload         9
     116: lload         14
     118: lcmp
     119: iflt          126
     122: lload         9
     124: lstore        14
     126: lload         9
     128: lload         12
     130: lcmp
     131: ifgt          138
     134: lload         9
     136: lstore        12
     138: nop
     139: nop
     140: goto          82
     143: nop
     144: new           #49                 // class fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression
     147: dup
     148: lload         12
     150: lload         14
     152: invokespecial #92                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression."<init>":(JJ)V
     155: areturn

  private final kotlin.sequences.Sequence<java.lang.Long> computeCandidateValues(fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression);
    Code:
       0: aload_0
       1: aload_1
       2: invokevirtual #167                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getLeftFrom:()I
       5: aload_1
       6: invokevirtual #170                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getLeftTo:()I
       9: invokespecial #47                 // Method computeCachedMaximumValue:(II)Lfr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression;
      12: astore_2
      13: aload_0
      14: aload_1
      15: invokevirtual #173                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getRightFrom:()I
      18: aload_1
      19: invokevirtual #176                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getRightTo:()I
      22: invokespecial #47                 // Method computeCachedMaximumValue:(II)Lfr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression;
      25: astore_3
      26: iconst_4
      27: anewarray     #178                // class java/lang/Long
      30: astore        4
      32: aload         4
      34: iconst_0
      35: aload_0
      36: aload_1
      37: invokevirtual #182                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getOperator:()C
      40: aload_2
      41: invokevirtual #185                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMinExpression:()J
      44: aload_3
      45: invokevirtual #185                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMinExpression:()J
      48: invokespecial #189                // Method evaluate:(CJJ)J
      51: invokestatic  #193                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      54: aastore
      55: aload         4
      57: iconst_1
      58: aload_0
      59: aload_1
      60: invokevirtual #182                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getOperator:()C
      63: aload_2
      64: invokevirtual #52                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMaxExpression:()J
      67: aload_3
      68: invokevirtual #185                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMinExpression:()J
      71: invokespecial #189                // Method evaluate:(CJJ)J
      74: invokestatic  #193                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      77: aastore
      78: aload         4
      80: iconst_2
      81: aload_0
      82: aload_1
      83: invokevirtual #182                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getOperator:()C
      86: aload_2
      87: invokevirtual #185                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMinExpression:()J
      90: aload_3
      91: invokevirtual #52                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMaxExpression:()J
      94: invokespecial #189                // Method evaluate:(CJJ)J
      97: invokestatic  #193                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     100: aastore
     101: aload         4
     103: iconst_3
     104: aload_0
     105: aload_1
     106: invokevirtual #182                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression.getOperator:()C
     109: aload_2
     110: invokevirtual #52                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMaxExpression:()J
     113: aload_3
     114: invokevirtual #52                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression.getMaxExpression:()J
     117: invokespecial #189                // Method evaluate:(CJJ)J
     120: invokestatic  #193                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     123: aastore
     124: aload         4
     126: invokestatic  #197                // Method kotlin/sequences/SequencesKt.sequenceOf:([Ljava/lang/Object;)Lkotlin/sequences/Sequence;
     129: areturn

  private final long evaluate(char, long, long);
    Code:
       0: iload_1
       1: tableswitch   { // 42 to 45
                    42: 42
                    43: 32
                    44: 47
                    45: 37
               default: 47
          }
      32: lload_2
      33: lload         4
      35: ladd
      36: lreturn
      37: lload_2
      38: lload         4
      40: lsub
      41: lreturn
      42: lload_2
      43: lload         4
      45: lmul
      46: lreturn
      47: new           #203                // class java/lang/UnsupportedOperationException
      50: dup
      51: invokespecial #204                // Method java/lang/UnsupportedOperationException."<init>":()V
      54: athrow

  private final kotlin.sequences.Sequence<fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression> getSplitExpressions(int, int);
    Code:
       0: iload_1
       1: iconst_1
       2: iadd
       3: iload_2
       4: invokestatic  #214                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
       7: checkcast     #216                // class kotlin/ranges/IntProgression
      10: iconst_2
      11: invokestatic  #220                // Method kotlin/ranges/RangesKt.step:(Lkotlin/ranges/IntProgression;I)Lkotlin/ranges/IntProgression;
      14: checkcast     #222                // class java/lang/Iterable
      17: invokestatic  #228                // Method kotlin/collections/CollectionsKt.asSequence:(Ljava/lang/Iterable;)Lkotlin/sequences/Sequence;
      20: iload_1
      21: iload_2
      22: aload_0
      23: invokedynamic #238,  0            // InvokeDynamic #1:invoke:(IILfr/pturpin/coursera/dynprog/ArithmeticExpression;)Lkotlin/jvm/functions/Function1;
      28: invokestatic  #241                // Method kotlin/sequences/SequencesKt.map:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      31: areturn

  private static final kotlin.sequences.Sequence computeMaximumValue$lambda$1(fr.pturpin.coursera.dynprog.ArithmeticExpression, fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression);
    Code:
       0: aload_1
       1: ldc           #242                // String it
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_1
       8: invokespecial #244                // Method computeCandidateValues:(Lfr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression;)Lkotlin/sequences/Sequence;
      11: areturn

  private static final fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression getSplitExpressions$lambda$3(int, int, fr.pturpin.coursera.dynprog.ArithmeticExpression, int);
    Code:
       0: new           #164                // class fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression
       3: dup
       4: iload_0
       5: iload_3
       6: iload_3
       7: iconst_1
       8: iadd
       9: iload_1
      10: aload_2
      11: getfield      #21                 // Field strExpression:Ljava/lang/String;
      14: iload_3
      15: invokevirtual #87                 // Method java/lang/String.charAt:(I)C
      18: invokespecial #248                // Method fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression."<init>":(IIIIC)V
      21: areturn
}

Compiled from "ArithmeticExpression.kt"
final class fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression {
  private final long minExpression;

  private final long maxExpression;

  public fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression(long, long);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: lload_1
       6: putfield      #13                 // Field minExpression:J
       9: aload_0
      10: lload_3
      11: putfield      #16                 // Field maxExpression:J
      14: return

  public final long getMinExpression();
    Code:
       0: aload_0
       1: getfield      #13                 // Field minExpression:J
       4: lreturn

  public final long getMaxExpression();
    Code:
       0: aload_0
       1: getfield      #16                 // Field maxExpression:J
       4: lreturn

  public final long component1();
    Code:
       0: aload_0
       1: getfield      #13                 // Field minExpression:J
       4: lreturn

  public final long component2();
    Code:
       0: aload_0
       1: getfield      #16                 // Field maxExpression:J
       4: lreturn

  public final fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression copy(long, long);
    Code:
       0: new           #2                  // class fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression
       3: dup
       4: lload_1
       5: lload_3
       6: invokespecial #28                 // Method "<init>":(JJ)V
       9: areturn

  public static fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression copy$default(fr.pturpin.coursera.dynprog.ArithmeticExpression$MinMaxExpression, long, long, int, java.lang.Object);
    Code:
       0: iload         5
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #13                 // Field minExpression:J
      11: lstore_1
      12: iload         5
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #16                 // Field maxExpression:J
      23: lstore_3
      24: aload_0
      25: lload_1
      26: lload_3
      27: invokevirtual #32                 // Method copy:(JJ)Lfr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression;
      30: areturn

  public java.lang.String toString();
    Code:
       0: new           #36                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #37                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #39                 // String MinMaxExpression(minExpression=
       9: invokevirtual #43                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #13                 // Field minExpression:J
      16: invokevirtual #46                 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      19: ldc           #48                 // String , maxExpression=
      21: invokevirtual #43                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #16                 // Field maxExpression:J
      28: invokevirtual #46                 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      31: bipush        41
      33: invokevirtual #51                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      36: invokevirtual #53                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #13                 // Field minExpression:J
       4: invokestatic  #60                 // Method java/lang/Long.hashCode:(J)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #16                 // Field maxExpression:J
      16: invokestatic  #60                 // Method java/lang/Long.hashCode:(J)I
      19: iadd
      20: istore_1
      21: iload_1
      22: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class fr/pturpin/coursera/dynprog/ArithmeticExpression$MinMaxExpression
      20: astore_2
      21: aload_0
      22: getfield      #13                 // Field minExpression:J
      25: aload_2
      26: getfield      #13                 // Field minExpression:J
      29: lcmp
      30: ifeq          35
      33: iconst_0
      34: ireturn
      35: aload_0
      36: getfield      #16                 // Field maxExpression:J
      39: aload_2
      40: getfield      #16                 // Field maxExpression:J
      43: lcmp
      44: ifeq          49
      47: iconst_0
      48: ireturn
      49: iconst_1
      50: ireturn
}

Compiled from "ArithmeticExpression.kt"
public final class fr.pturpin.coursera.dynprog.ArithmeticExpressionKt {
  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: invokestatic  #21                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
       9: dup
      10: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      13: astore_1
      14: new           #27                 // class fr/pturpin/coursera/dynprog/ArithmeticExpression
      17: dup
      18: aload_1
      19: invokespecial #31                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression."<init>":(Ljava/lang/String;)V
      22: astore_2
      23: aload_2
      24: invokevirtual #35                 // Method fr/pturpin/coursera/dynprog/ArithmeticExpression.getMaximumValue:()J
      27: lstore_3
      28: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;
      31: lload_3
      32: invokevirtual #47                 // Method java/io/PrintStream.print:(J)V
      35: return
}

Compiled from "ArithmeticExpression.kt"
final class fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression {
  private final int leftFrom;

  private final int leftTo;

  private final int rightFrom;

  private final int rightTo;

  private final char operator;

  public fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression(int, int, int, int, char);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field leftFrom:I
       9: aload_0
      10: iload_2
      11: putfield      #16                 // Field leftTo:I
      14: aload_0
      15: iload_3
      16: putfield      #19                 // Field rightFrom:I
      19: aload_0
      20: iload         4
      22: putfield      #22                 // Field rightTo:I
      25: aload_0
      26: iload         5
      28: putfield      #26                 // Field operator:C
      31: return

  public final int getLeftFrom();
    Code:
       0: aload_0
       1: getfield      #13                 // Field leftFrom:I
       4: ireturn

  public final int getLeftTo();
    Code:
       0: aload_0
       1: getfield      #16                 // Field leftTo:I
       4: ireturn

  public final int getRightFrom();
    Code:
       0: aload_0
       1: getfield      #19                 // Field rightFrom:I
       4: ireturn

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

  public final char getOperator();
    Code:
       0: aload_0
       1: getfield      #26                 // Field operator:C
       4: ireturn

  public final int component1();
    Code:
       0: aload_0
       1: getfield      #13                 // Field leftFrom:I
       4: ireturn

  public final int component2();
    Code:
       0: aload_0
       1: getfield      #16                 // Field leftTo:I
       4: ireturn

  public final int component3();
    Code:
       0: aload_0
       1: getfield      #19                 // Field rightFrom:I
       4: ireturn

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

  public final char component5();
    Code:
       0: aload_0
       1: getfield      #26                 // Field operator:C
       4: ireturn

  public final fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression copy(int, int, int, int, char);
    Code:
       0: new           #2                  // class fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression
       3: dup
       4: iload_1
       5: iload_2
       6: iload_3
       7: iload         4
       9: iload         5
      11: invokespecial #45                 // Method "<init>":(IIIIC)V
      14: areturn

  public static fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression copy$default(fr.pturpin.coursera.dynprog.ArithmeticExpression$SplitExpression, int, int, int, int, char, int, java.lang.Object);
    Code:
       0: iload         6
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #13                 // Field leftFrom:I
      11: istore_1
      12: iload         6
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #16                 // Field leftTo:I
      23: istore_2
      24: iload         6
      26: iconst_4
      27: iand
      28: ifeq          36
      31: aload_0
      32: getfield      #19                 // Field rightFrom:I
      35: istore_3
      36: iload         6
      38: bipush        8
      40: iand
      41: ifeq          50
      44: aload_0
      45: getfield      #22                 // Field rightTo:I
      48: istore        4
      50: iload         6
      52: bipush        16
      54: iand
      55: ifeq          64
      58: aload_0
      59: getfield      #26                 // Field operator:C
      62: istore        5
      64: aload_0
      65: iload_1
      66: iload_2
      67: iload_3
      68: iload         4
      70: iload         5
      72: invokevirtual #49                 // Method copy:(IIIIC)Lfr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression;
      75: areturn

  public java.lang.String toString();
    Code:
       0: new           #53                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #54                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #56                 // String SplitExpression(leftFrom=
       9: invokevirtual #60                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #13                 // Field leftFrom:I
      16: invokevirtual #63                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      19: ldc           #65                 // String , leftTo=
      21: invokevirtual #60                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #16                 // Field leftTo:I
      28: invokevirtual #63                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      31: ldc           #67                 // String , rightFrom=
      33: invokevirtual #60                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      36: aload_0
      37: getfield      #19                 // Field rightFrom:I
      40: invokevirtual #63                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      43: ldc           #69                 // String , rightTo=
      45: invokevirtual #60                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      48: aload_0
      49: getfield      #22                 // Field rightTo:I
      52: invokevirtual #63                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      55: ldc           #71                 // String , operator=
      57: invokevirtual #60                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      60: aload_0
      61: getfield      #26                 // Field operator:C
      64: invokevirtual #74                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      67: bipush        41
      69: invokevirtual #74                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      72: invokevirtual #76                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      75: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #13                 // Field leftFrom:I
       4: invokestatic  #82                 // Method java/lang/Integer.hashCode:(I)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #16                 // Field leftTo:I
      16: invokestatic  #82                 // Method java/lang/Integer.hashCode:(I)I
      19: iadd
      20: istore_1
      21: iload_1
      22: bipush        31
      24: imul
      25: aload_0
      26: getfield      #19                 // Field rightFrom:I
      29: invokestatic  #82                 // Method java/lang/Integer.hashCode:(I)I
      32: iadd
      33: istore_1
      34: iload_1
      35: bipush        31
      37: imul
      38: aload_0
      39: getfield      #22                 // Field rightTo:I
      42: invokestatic  #82                 // Method java/lang/Integer.hashCode:(I)I
      45: iadd
      46: istore_1
      47: iload_1
      48: bipush        31
      50: imul
      51: aload_0
      52: getfield      #26                 // Field operator:C
      55: invokestatic  #87                 // Method java/lang/Character.hashCode:(C)I
      58: iadd
      59: istore_1
      60: iload_1
      61: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class fr/pturpin/coursera/dynprog/ArithmeticExpression$SplitExpression
      20: astore_2
      21: aload_0
      22: getfield      #13                 // Field leftFrom:I
      25: aload_2
      26: getfield      #13                 // Field leftFrom:I
      29: if_icmpeq     34
      32: iconst_0
      33: ireturn
      34: aload_0
      35: getfield      #16                 // Field leftTo:I
      38: aload_2
      39: getfield      #16                 // Field leftTo:I
      42: if_icmpeq     47
      45: iconst_0
      46: ireturn
      47: aload_0
      48: getfield      #19                 // Field rightFrom:I
      51: aload_2
      52: getfield      #19                 // Field rightFrom:I
      55: if_icmpeq     60
      58: iconst_0
      59: ireturn
      60: aload_0
      61: getfield      #22                 // Field rightTo:I
      64: aload_2
      65: getfield      #22                 // Field rightTo:I
      68: if_icmpeq     73
      71: iconst_0
      72: ireturn
      73: aload_0
      74: getfield      #26                 // Field operator:C
      77: aload_2
      78: getfield      #26                 // Field operator:C
      81: if_icmpeq     86
      84: iconst_0
      85: ireturn
      86: iconst_1
      87: ireturn
}


package fr.pturpin.coursera.dynprog

class PrimitiveCalculator(private val number: Int) {

    private val availableOperations = listOf(
        MultByOperation(2),
        MultByOperation(3),
        AddToOperation(1)
    )

    private val cache = mutableMapOf<Int, OperationStates>()

    fun getMinimumOperationsToCompute(): OperationStates {
        cache.clear()
        cache[1] = NoOpStates(1)

        for (currentNumber in 1..number) {
            val currentOperation = cache[currentNumber]!!

            availableOperations.forEach {
                val appliedNumber = it.apply(currentNumber)
                cache.compute(appliedNumber) { _, oldState ->
                    val newState = LinkedOperationStates(
                        appliedNumber,
                        currentOperation
                    )
                    if (oldState == null || newState.size() < oldState.size()) {
                        newState
                    } else {
                        oldState
                    }
                }
                if (appliedNumber == number) {
                    return cache[number]!!
                }
            }
        }

        return cache[number]!!
    }

    private interface Operation {
        fun apply(number: Int): Int
    }

    private class MultByOperation(private val factor: Int) :
        Operation {
        override fun apply(number: Int): Int {
            return number * factor
        }
    }

    private class AddToOperation(private val term: Int) :
        Operation {
        override fun apply(number: Int): Int {
            return number + term
        }

    }

    interface OperationStates {
        fun size(): Int
        fun getStates(): Iterable<Int>
    }

    private class LinkedOperationStates(
        private val currentState: Int,
        private val nextState: OperationStates
    )
        : OperationStates {

        private val size = nextState.size() + 1

        override fun size() = size

        override fun getStates(): Iterable<Int> {
            return listOf(currentState) + nextState.getStates()
        }
    }

    private class NoOpStates(private val initialValue: Int):
        OperationStates {
        override fun size() = 0

        override fun getStates() = listOf(initialValue)
    }

}

fun main(args: Array<String>) {
    val number = readLine()!!.toInt()

    val primitiveCalculator = PrimitiveCalculator(number)
    val minimumOperationsToCompute = primitiveCalculator.getMinimumOperationsToCompute()

    println(minimumOperationsToCompute.size())
    print(minimumOperationsToCompute.getStates().reversed().joinToString(" "))
}

Compiled from "PrimitiveCalculator.kt"
final class fr.pturpin.coursera.dynprog.PrimitiveCalculator$NoOpStates implements fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates {
  private final int initialValue;

  public fr.pturpin.coursera.dynprog.PrimitiveCalculator$NoOpStates(int);
    Code:
       0: aload_0
       1: invokespecial #11                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #15                 // Field initialValue:I
       9: return

  public int size();
    Code:
       0: iconst_0
       1: ireturn

  public java.util.List<java.lang.Integer> getStates();
    Code:
       0: aload_0
       1: getfield      #15                 // Field initialValue:I
       4: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       7: invokestatic  #35                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      10: areturn

  public java.lang.Iterable getStates();
    Code:
       0: aload_0
       1: invokevirtual #38                 // Method getStates:()Ljava/util/List;
       4: checkcast     #40                 // class java/lang/Iterable
       7: areturn
}

Compiled from "PrimitiveCalculator.kt"
interface fr.pturpin.coursera.dynprog.PrimitiveCalculator$Operation {
  public abstract int apply(int);
}

Compiled from "PrimitiveCalculator.kt"
public final class fr.pturpin.coursera.dynprog.PrimitiveCalculatorKt {
  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: invokestatic  #21                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
       9: dup
      10: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      13: invokestatic  #31                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      16: istore_1
      17: new           #33                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator
      20: dup
      21: iload_1
      22: invokespecial #37                 // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator."<init>":(I)V
      25: astore_2
      26: aload_2
      27: invokevirtual #41                 // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator.getMinimumOperationsToCompute:()Lfr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates;
      30: astore_3
      31: aload_3
      32: invokeinterface #47,  1           // InterfaceMethod fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates.size:()I
      37: istore        4
      39: getstatic     #53                 // Field java/lang/System.out:Ljava/io/PrintStream;
      42: iload         4
      44: invokevirtual #58                 // Method java/io/PrintStream.println:(I)V
      47: aload_3
      48: invokeinterface #62,  1           // InterfaceMethod fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates.getStates:()Ljava/lang/Iterable;
      53: invokestatic  #68                 // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
      56: checkcast     #70                 // class java/lang/Iterable
      59: ldc           #72                 // String
      61: checkcast     #74                 // class java/lang/CharSequence
      64: aconst_null
      65: aconst_null
      66: iconst_0
      67: aconst_null
      68: aconst_null
      69: bipush        62
      71: aconst_null
      72: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
      75: getstatic     #53                 // Field java/lang/System.out:Ljava/io/PrintStream;
      78: swap
      79: invokevirtual #81                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      82: return
}

Compiled from "PrimitiveCalculator.kt"
final class fr.pturpin.coursera.dynprog.PrimitiveCalculator$MultByOperation implements fr.pturpin.coursera.dynprog.PrimitiveCalculator$Operation {
  private final int factor;

  public fr.pturpin.coursera.dynprog.PrimitiveCalculator$MultByOperation(int);
    Code:
       0: aload_0
       1: invokespecial #11                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #15                 // Field factor:I
       9: return

  public int apply(int);
    Code:
       0: iload_1
       1: aload_0
       2: getfield      #15                 // Field factor:I
       5: imul
       6: ireturn
}

Compiled from "PrimitiveCalculator.kt"
public interface fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates {
  public abstract int size();

  public abstract java.lang.Iterable<java.lang.Integer> getStates();
}

Compiled from "PrimitiveCalculator.kt"
public final class fr.pturpin.coursera.dynprog.PrimitiveCalculator {
  private final int number;

  private final java.util.List<fr.pturpin.coursera.dynprog.PrimitiveCalculator$Operation> availableOperations;

  private final java.util.Map<java.lang.Integer, fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates> cache;

  public fr.pturpin.coursera.dynprog.PrimitiveCalculator(int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field number:I
       9: aload_0
      10: iconst_3
      11: anewarray     #15                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$Operation
      14: astore_2
      15: aload_2
      16: iconst_0
      17: new           #17                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$MultByOperation
      20: dup
      21: iconst_2
      22: invokespecial #19                 // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator$MultByOperation."<init>":(I)V
      25: aastore
      26: aload_2
      27: iconst_1
      28: new           #17                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$MultByOperation
      31: dup
      32: iconst_3
      33: invokespecial #19                 // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator$MultByOperation."<init>":(I)V
      36: aastore
      37: aload_2
      38: iconst_2
      39: new           #21                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$AddToOperation
      42: dup
      43: iconst_1
      44: invokespecial #22                 // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator$AddToOperation."<init>":(I)V
      47: aastore
      48: aload_2
      49: invokestatic  #28                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      52: putfield      #32                 // Field availableOperations:Ljava/util/List;
      55: aload_0
      56: new           #34                 // class java/util/LinkedHashMap
      59: dup
      60: invokespecial #35                 // Method java/util/LinkedHashMap."<init>":()V
      63: checkcast     #37                 // class java/util/Map
      66: putfield      #41                 // Field cache:Ljava/util/Map;
      69: return

  public final fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates getMinimumOperationsToCompute();
    Code:
       0: aload_0
       1: getfield      #41                 // Field cache:Ljava/util/Map;
       4: invokeinterface #49,  1           // InterfaceMethod java/util/Map.clear:()V
       9: aload_0
      10: getfield      #41                 // Field cache:Ljava/util/Map;
      13: iconst_1
      14: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      17: new           #57                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$NoOpStates
      20: dup
      21: iconst_1
      22: invokespecial #58                 // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator$NoOpStates."<init>":(I)V
      25: invokeinterface #62,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      30: pop
      31: iconst_1
      32: istore_1
      33: aload_0
      34: getfield      #13                 // Field number:I
      37: istore_2
      38: iload_1
      39: iload_2
      40: if_icmpgt     202
      43: aload_0
      44: getfield      #41                 // Field cache:Ljava/util/Map;
      47: iload_1
      48: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      51: invokeinterface #66,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      56: dup
      57: invokestatic  #72                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      60: checkcast     #74                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates
      63: astore_3
      64: aload_0
      65: getfield      #32                 // Field availableOperations:Ljava/util/List;
      68: checkcast     #76                 // class java/lang/Iterable
      71: astore        4
      73: iconst_0
      74: istore        5
      76: aload         4
      78: invokeinterface #80,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      83: astore        6
      85: aload         6
      87: invokeinterface #86,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      92: ifeq          190
      95: aload         6
      97: invokeinterface #90,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     102: astore        7
     104: aload         7
     106: checkcast     #15                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$Operation
     109: astore        8
     111: iconst_0
     112: istore        9
     114: aload         8
     116: iload_1
     117: invokeinterface #94,  2           // InterfaceMethod fr/pturpin/coursera/dynprog/PrimitiveCalculator$Operation.apply:(I)I
     122: istore        10
     124: aload_0
     125: getfield      #41                 // Field cache:Ljava/util/Map;
     128: iload         10
     130: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     133: iload         10
     135: aload_3
     136: invokedynamic #113,  0            // InvokeDynamic #0:invoke:(ILfr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates;)Lkotlin/jvm/functions/Function2;
     141: invokedynamic #123,  0            // InvokeDynamic #1:apply:(Lkotlin/jvm/functions/Function2;)Ljava/util/function/BiFunction;
     146: invokeinterface #127,  3          // InterfaceMethod java/util/Map.compute:(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;
     151: pop
     152: iload         10
     154: aload_0
     155: getfield      #13                 // Field number:I
     158: if_icmpne     185
     161: aload_0
     162: getfield      #41                 // Field cache:Ljava/util/Map;
     165: aload_0
     166: getfield      #13                 // Field number:I
     169: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     172: invokeinterface #66,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     177: dup
     178: invokestatic  #72                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     181: checkcast     #74                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates
     184: areturn
     185: nop
     186: nop
     187: goto          85
     190: nop
     191: iload_1
     192: iload_2
     193: if_icmpeq     202
     196: iinc          1, 1
     199: goto          43
     202: aload_0
     203: getfield      #41                 // Field cache:Ljava/util/Map;
     206: aload_0
     207: getfield      #13                 // Field number:I
     210: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     213: invokeinterface #66,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     218: dup
     219: invokestatic  #72                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     222: checkcast     #74                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates
     225: areturn

  private static final fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates getMinimumOperationsToCompute$lambda$2$lambda$0(int, fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates, java.lang.Integer, fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates);
    Code:
       0: aload_2
       1: ldc           #141                // String <unused var>
       3: invokestatic  #145                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #147                // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$LinkedOperationStates
       9: dup
      10: iload_0
      11: aload_1
      12: invokespecial #150                // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator$LinkedOperationStates."<init>":(ILfr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates;)V
      15: astore        4
      17: aload_3
      18: ifnull        35
      21: aload         4
      23: invokevirtual #154                // Method fr/pturpin/coursera/dynprog/PrimitiveCalculator$LinkedOperationStates.size:()I
      26: aload_3
      27: invokeinterface #155,  1          // InterfaceMethod fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates.size:()I
      32: if_icmpge     43
      35: aload         4
      37: checkcast     #74                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates
      40: goto          44
      43: aload_3
      44: areturn

  private static final fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates getMinimumOperationsToCompute$lambda$2$lambda$1(kotlin.jvm.functions.Function2, java.lang.Object, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: aload_2
       3: invokeinterface #164,  3          // InterfaceMethod kotlin/jvm/functions/Function2.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
       8: checkcast     #74                 // class fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates
      11: areturn
}

Compiled from "PrimitiveCalculator.kt"
final class fr.pturpin.coursera.dynprog.PrimitiveCalculator$LinkedOperationStates implements fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates {
  private final int currentState;

  private final fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates nextState;

  private final int size;

  public fr.pturpin.coursera.dynprog.PrimitiveCalculator$LinkedOperationStates(int, fr.pturpin.coursera.dynprog.PrimitiveCalculator$OperationStates);
    Code:
       0: aload_2
       1: ldc           #11                 // String nextState
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #20                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: iload_1
      12: putfield      #24                 // Field currentState:I
      15: aload_0
      16: aload_2
      17: putfield      #27                 // Field nextState:Lfr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates;
      20: aload_0
      21: aload_0
      22: getfield      #27                 // Field nextState:Lfr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates;
      25: invokeinterface #31,  1           // InterfaceMethod fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates.size:()I
      30: iconst_1
      31: iadd
      32: putfield      #33                 // Field size:I
      35: return

  public int size();
    Code:
       0: aload_0
       1: getfield      #33                 // Field size:I
       4: ireturn

  public java.lang.Iterable<java.lang.Integer> getStates();
    Code:
       0: aload_0
       1: getfield      #24                 // Field currentState:I
       4: invokestatic  #44                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       7: invokestatic  #50                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      10: checkcast     #52                 // class java/util/Collection
      13: aload_0
      14: getfield      #27                 // Field nextState:Lfr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates;
      17: invokeinterface #54,  1           // InterfaceMethod fr/pturpin/coursera/dynprog/PrimitiveCalculator$OperationStates.getStates:()Ljava/lang/Iterable;
      22: invokestatic  #58                 // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
      25: checkcast     #60                 // class java/lang/Iterable
      28: areturn
}

Compiled from "PrimitiveCalculator.kt"
final class fr.pturpin.coursera.dynprog.PrimitiveCalculator$AddToOperation implements fr.pturpin.coursera.dynprog.PrimitiveCalculator$Operation {
  private final int term;

  public fr.pturpin.coursera.dynprog.PrimitiveCalculator$AddToOperation(int);
    Code:
       0: aload_0
       1: invokespecial #11                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #15                 // Field term:I
       9: return

  public int apply(int);
    Code:
       0: iload_1
       1: aload_0
       2: getfield      #15                 // Field term:I
       5: iadd
       6: ireturn
}


package fr.pturpin.coursera.divconquer

import java.util.*

class QuickSort(private val elements: IntArray) {

    private val random = Random(42)

    fun sortInPlace(): IntArray {
        sortInPlace(0, elements.size)
        return elements
    }

    private fun sortInPlace(from: Int, untilExcluded: Int) {
        if (from == untilExcluded) {
            return
        }

        val pivotIndex = getPivotIndex(from, untilExcluded)
        val partition = partitionAround(elements[pivotIndex], from, untilExcluded)
        sortInPlace(partition.lowerFrom, partition.lowerUntil)
        sortInPlace(partition.higherFrom, partition.higherUntil)
    }

    private fun partitionAround(pivotValue: Int, from: Int, untilExcluded: Int): Partition {
        var lowerUntil = from
        var higherFrom = untilExcluded

        var i = from
        while(i < higherFrom) {
            val currentValue = elements[i]
            if (currentValue < pivotValue) {
                swap(lowerUntil, i)
                lowerUntil++
            } else if (currentValue > pivotValue) {
                higherFrom--
                swap(higherFrom, i)
                i--
            }
            i++
        }

        elements.fill(pivotValue, lowerUntil, higherFrom - 1)

        return Partition(from, lowerUntil, higherFrom, untilExcluded)
    }

    private fun swap(i: Int, j: Int) {
        val tmp = elements[i]
        elements[i] = elements[j]
        elements[j] = tmp
    }

    private fun getPivotIndex(from: Int, untilExcluded: Int): Int {
        return random.nextInt(untilExcluded - from) + from
    }

    private data class Partition(val lowerFrom: Int, val lowerUntil: Int, val higherFrom: Int, val higherUntil: Int) {

        init {
            assert(lowerFrom <= lowerUntil)
            assert(lowerUntil < higherFrom)
            assert(higherFrom <= higherUntil)
        }

    }

}

fun main(args: Array<String>) {
    readLine()!!
    val elements = readLine()!!.split(" ").map { it.toInt() }.toIntArray()

    val quickSort = QuickSort(elements)
    val sorted = quickSort.sortInPlace()

    print(sorted.joinToString(" "))
}

Compiled from "QuickSort.kt"
public final class fr.pturpin.coursera.divconquer.QuickSort {
  private final int[] elements;

  private final java.util.Random random;

  public fr.pturpin.coursera.divconquer.QuickSort(int[]);
    Code:
       0: aload_1
       1: ldc           #9                  // String elements
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #18                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: aload_1
      12: putfield      #21                 // Field elements:[I
      15: aload_0
      16: new           #23                 // class java/util/Random
      19: dup
      20: ldc2_w        #24                 // long 42l
      23: invokespecial #28                 // Method java/util/Random."<init>":(J)V
      26: putfield      #32                 // Field random:Ljava/util/Random;
      29: return

  public final int[] sortInPlace();
    Code:
       0: aload_0
       1: iconst_0
       2: aload_0
       3: getfield      #21                 // Field elements:[I
       6: arraylength
       7: invokespecial #39                 // Method sortInPlace:(II)V
      10: aload_0
      11: getfield      #21                 // Field elements:[I
      14: areturn

  private final void sortInPlace(int, int);
    Code:
       0: iload_1
       1: iload_2
       2: if_icmpne     6
       5: return
       6: aload_0
       7: iload_1
       8: iload_2
       9: invokespecial #43                 // Method getPivotIndex:(II)I
      12: istore_3
      13: aload_0
      14: aload_0
      15: getfield      #21                 // Field elements:[I
      18: iload_3
      19: iaload
      20: iload_1
      21: iload_2
      22: invokespecial #47                 // Method partitionAround:(III)Lfr/pturpin/coursera/divconquer/QuickSort$Partition;
      25: astore        4
      27: aload_0
      28: aload         4
      30: invokevirtual #53                 // Method fr/pturpin/coursera/divconquer/QuickSort$Partition.getLowerFrom:()I
      33: aload         4
      35: invokevirtual #56                 // Method fr/pturpin/coursera/divconquer/QuickSort$Partition.getLowerUntil:()I
      38: invokespecial #39                 // Method sortInPlace:(II)V
      41: aload_0
      42: aload         4
      44: invokevirtual #59                 // Method fr/pturpin/coursera/divconquer/QuickSort$Partition.getHigherFrom:()I
      47: aload         4
      49: invokevirtual #62                 // Method fr/pturpin/coursera/divconquer/QuickSort$Partition.getHigherUntil:()I
      52: invokespecial #39                 // Method sortInPlace:(II)V
      55: return

  private final fr.pturpin.coursera.divconquer.QuickSort$Partition partitionAround(int, int, int);
    Code:
       0: iload_2
       1: istore        4
       3: iload_3
       4: istore        5
       6: iload_2
       7: istore        6
       9: iload         6
      11: iload         5
      13: if_icmpge     71
      16: aload_0
      17: getfield      #21                 // Field elements:[I
      20: iload         6
      22: iaload
      23: istore        7
      25: iload         7
      27: iload_1
      28: if_icmpge     45
      31: aload_0
      32: iload         4
      34: iload         6
      36: invokespecial #71                 // Method swap:(II)V
      39: iinc          4, 1
      42: goto          65
      45: iload         7
      47: iload_1
      48: if_icmple     65
      51: iinc          5, -1
      54: aload_0
      55: iload         5
      57: iload         6
      59: invokespecial #71                 // Method swap:(II)V
      62: iinc          6, -1
      65: iinc          6, 1
      68: goto          9
      71: aload_0
      72: getfield      #21                 // Field elements:[I
      75: iload_1
      76: iload         4
      78: iload         5
      80: iconst_1
      81: isub
      82: invokestatic  #77                 // Method kotlin/collections/ArraysKt.fill:([IIII)V
      85: new           #49                 // class fr/pturpin/coursera/divconquer/QuickSort$Partition
      88: dup
      89: iload_2
      90: iload         4
      92: iload         5
      94: iload_3
      95: invokespecial #80                 // Method fr/pturpin/coursera/divconquer/QuickSort$Partition."<init>":(IIII)V
      98: areturn

  private final void swap(int, int);
    Code:
       0: aload_0
       1: getfield      #21                 // Field elements:[I
       4: iload_1
       5: iaload
       6: istore_3
       7: aload_0
       8: getfield      #21                 // Field elements:[I
      11: iload_1
      12: aload_0
      13: getfield      #21                 // Field elements:[I
      16: iload_2
      17: iaload
      18: iastore
      19: aload_0
      20: getfield      #21                 // Field elements:[I
      23: iload_2
      24: iload_3
      25: iastore
      26: return

  private final int getPivotIndex(int, int);
    Code:
       0: aload_0
       1: getfield      #32                 // Field random:Ljava/util/Random;
       4: iload_2
       5: iload_1
       6: isub
       7: invokevirtual #91                 // Method java/util/Random.nextInt:(I)I
      10: iload_1
      11: iadd
      12: ireturn
}

Compiled from "QuickSort.kt"
final class fr.pturpin.coursera.divconquer.QuickSort$Partition {
  private final int lowerFrom;

  private final int lowerUntil;

  private final int higherFrom;

  private final int higherUntil;

  public fr.pturpin.coursera.divconquer.QuickSort$Partition(int, int, int, int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field lowerFrom:I
       9: aload_0
      10: iload_2
      11: putfield      #16                 // Field lowerUntil:I
      14: aload_0
      15: iload_3
      16: putfield      #19                 // Field higherFrom:I
      19: aload_0
      20: iload         4
      22: putfield      #22                 // Field higherUntil:I
      25: nop
      26: aload_0
      27: getfield      #13                 // Field lowerFrom:I
      30: aload_0
      31: getfield      #16                 // Field lowerUntil:I
      34: if_icmpgt     41
      37: iconst_1
      38: goto          42
      41: iconst_0
      42: istore        5
      44: getstatic     #28                 // Field kotlin/_Assertions.ENABLED:Z
      47: ifeq          69
      50: iload         5
      52: ifne          69
      55: ldc           #30                 // String Assertion failed
      57: astore        6
      59: new           #32                 // class java/lang/AssertionError
      62: dup
      63: aload         6
      65: invokespecial #35                 // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      68: athrow
      69: aload_0
      70: getfield      #16                 // Field lowerUntil:I
      73: aload_0
      74: getfield      #19                 // Field higherFrom:I
      77: if_icmpge     84
      80: iconst_1
      81: goto          85
      84: iconst_0
      85: istore        5
      87: getstatic     #28                 // Field kotlin/_Assertions.ENABLED:Z
      90: ifeq          112
      93: iload         5
      95: ifne          112
      98: ldc           #30                 // String Assertion failed
     100: astore        6
     102: new           #32                 // class java/lang/AssertionError
     105: dup
     106: aload         6
     108: invokespecial #35                 // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
     111: athrow
     112: aload_0
     113: getfield      #19                 // Field higherFrom:I
     116: aload_0
     117: getfield      #22                 // Field higherUntil:I
     120: if_icmpgt     127
     123: iconst_1
     124: goto          128
     127: iconst_0
     128: istore        5
     130: getstatic     #28                 // Field kotlin/_Assertions.ENABLED:Z
     133: ifeq          155
     136: iload         5
     138: ifne          155
     141: ldc           #30                 // String Assertion failed
     143: astore        6
     145: new           #32                 // class java/lang/AssertionError
     148: dup
     149: aload         6
     151: invokespecial #35                 // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
     154: athrow
     155: nop
     156: return

  public final int getLowerFrom();
    Code:
       0: aload_0
       1: getfield      #13                 // Field lowerFrom:I
       4: ireturn

  public final int getLowerUntil();
    Code:
       0: aload_0
       1: getfield      #16                 // Field lowerUntil:I
       4: ireturn

  public final int getHigherFrom();
    Code:
       0: aload_0
       1: getfield      #19                 // Field higherFrom:I
       4: ireturn

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

  public final int component1();
    Code:
       0: aload_0
       1: getfield      #13                 // Field lowerFrom:I
       4: ireturn

  public final int component2();
    Code:
       0: aload_0
       1: getfield      #16                 // Field lowerUntil:I
       4: ireturn

  public final int component3();
    Code:
       0: aload_0
       1: getfield      #19                 // Field higherFrom:I
       4: ireturn

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

  public final fr.pturpin.coursera.divconquer.QuickSort$Partition copy(int, int, int, int);
    Code:
       0: new           #2                  // class fr/pturpin/coursera/divconquer/QuickSort$Partition
       3: dup
       4: iload_1
       5: iload_2
       6: iload_3
       7: iload         4
       9: invokespecial #51                 // Method "<init>":(IIII)V
      12: areturn

  public static fr.pturpin.coursera.divconquer.QuickSort$Partition copy$default(fr.pturpin.coursera.divconquer.QuickSort$Partition, int, int, int, int, int, java.lang.Object);
    Code:
       0: iload         5
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #13                 // Field lowerFrom:I
      11: istore_1
      12: iload         5
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #16                 // Field lowerUntil:I
      23: istore_2
      24: iload         5
      26: iconst_4
      27: iand
      28: ifeq          36
      31: aload_0
      32: getfield      #19                 // Field higherFrom:I
      35: istore_3
      36: iload         5
      38: bipush        8
      40: iand
      41: ifeq          50
      44: aload_0
      45: getfield      #22                 // Field higherUntil:I
      48: istore        4
      50: aload_0
      51: iload_1
      52: iload_2
      53: iload_3
      54: iload         4
      56: invokevirtual #55                 // Method copy:(IIII)Lfr/pturpin/coursera/divconquer/QuickSort$Partition;
      59: areturn

  public java.lang.String toString();
    Code:
       0: new           #59                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #60                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #62                 // String Partition(lowerFrom=
       9: invokevirtual #66                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #13                 // Field lowerFrom:I
      16: invokevirtual #69                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      19: ldc           #71                 // String , lowerUntil=
      21: invokevirtual #66                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #16                 // Field lowerUntil:I
      28: invokevirtual #69                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      31: ldc           #73                 // String , higherFrom=
      33: invokevirtual #66                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      36: aload_0
      37: getfield      #19                 // Field higherFrom:I
      40: invokevirtual #69                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      43: ldc           #75                 // String , higherUntil=
      45: invokevirtual #66                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      48: aload_0
      49: getfield      #22                 // Field higherUntil:I
      52: invokevirtual #69                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      55: bipush        41
      57: invokevirtual #78                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      60: invokevirtual #80                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      63: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #13                 // Field lowerFrom:I
       4: invokestatic  #86                 // Method java/lang/Integer.hashCode:(I)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #16                 // Field lowerUntil:I
      16: invokestatic  #86                 // Method java/lang/Integer.hashCode:(I)I
      19: iadd
      20: istore_1
      21: iload_1
      22: bipush        31
      24: imul
      25: aload_0
      26: getfield      #19                 // Field higherFrom:I
      29: invokestatic  #86                 // Method java/lang/Integer.hashCode:(I)I
      32: iadd
      33: istore_1
      34: iload_1
      35: bipush        31
      37: imul
      38: aload_0
      39: getfield      #22                 // Field higherUntil:I
      42: invokestatic  #86                 // Method java/lang/Integer.hashCode:(I)I
      45: iadd
      46: istore_1
      47: iload_1
      48: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class fr/pturpin/coursera/divconquer/QuickSort$Partition
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class fr/pturpin/coursera/divconquer/QuickSort$Partition
      20: astore_2
      21: aload_0
      22: getfield      #13                 // Field lowerFrom:I
      25: aload_2
      26: getfield      #13                 // Field lowerFrom:I
      29: if_icmpeq     34
      32: iconst_0
      33: ireturn
      34: aload_0
      35: getfield      #16                 // Field lowerUntil:I
      38: aload_2
      39: getfield      #16                 // Field lowerUntil:I
      42: if_icmpeq     47
      45: iconst_0
      46: ireturn
      47: aload_0
      48: getfield      #19                 // Field higherFrom:I
      51: aload_2
      52: getfield      #19                 // Field higherFrom:I
      55: if_icmpeq     60
      58: iconst_0
      59: ireturn
      60: aload_0
      61: getfield      #22                 // Field higherUntil:I
      64: aload_2
      65: getfield      #22                 // Field higherUntil:I
      68: if_icmpeq     73
      71: iconst_0
      72: ireturn
      73: iconst_1
      74: ireturn
}

Compiled from "QuickSort.kt"
public final class fr.pturpin.coursera.divconquer.QuickSortKt {
  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: invokestatic  #21                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
       9: dup
      10: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      13: pop
      14: invokestatic  #21                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
      17: dup
      18: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      21: checkcast     #27                 // class java/lang/CharSequence
      24: iconst_1
      25: anewarray     #29                 // class java/lang/String
      28: astore_2
      29: aload_2
      30: iconst_0
      31: ldc           #31                 // String
      33: aastore
      34: aload_2
      35: iconst_0
      36: iconst_0
      37: bipush        6
      39: aconst_null
      40: invokestatic  #37                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      43: checkcast     #39                 // class java/lang/Iterable
      46: astore_2
      47: iconst_0
      48: istore_3
      49: aload_2
      50: astore        4
      52: new           #41                 // class java/util/ArrayList
      55: dup
      56: aload_2
      57: bipush        10
      59: invokestatic  #47                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      62: invokespecial #51                 // Method java/util/ArrayList."<init>":(I)V
      65: checkcast     #53                 // class java/util/Collection
      68: astore        5
      70: iconst_0
      71: istore        6
      73: aload         4
      75: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      80: astore        7
      82: aload         7
      84: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      89: ifeq          136
      92: aload         7
      94: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      99: astore        8
     101: aload         5
     103: aload         8
     105: checkcast     #29                 // class java/lang/String
     108: astore        9
     110: astore        11
     112: iconst_0
     113: istore        10
     115: aload         9
     117: invokestatic  #73                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     120: nop
     121: invokestatic  #77                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     124: aload         11
     126: swap
     127: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     132: pop
     133: goto          82
     136: aload         5
     138: checkcast     #83                 // class java/util/List
     141: nop
     142: checkcast     #53                 // class java/util/Collection
     145: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.toIntArray:(Ljava/util/Collection;)[I
     148: astore_1
     149: new           #89                 // class fr/pturpin/coursera/divconquer/QuickSort
     152: dup
     153: aload_1
     154: invokespecial #92                 // Method fr/pturpin/coursera/divconquer/QuickSort."<init>":([I)V
     157: astore_2
     158: aload_2
     159: invokevirtual #96                 // Method fr/pturpin/coursera/divconquer/QuickSort.sortInPlace:()[I
     162: astore_3
     163: aload_3
     164: ldc           #31                 // String
     166: checkcast     #27                 // class java/lang/CharSequence
     169: aconst_null
     170: aconst_null
     171: iconst_0
     172: aconst_null
     173: aconst_null
     174: bipush        62
     176: aconst_null
     177: invokestatic  #102                // Method kotlin/collections/ArraysKt.joinToString$default:([ILjava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     180: getstatic     #108                // Field java/lang/System.out:Ljava/io/PrintStream;
     183: swap
     184: invokevirtual #113                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     187: return
}


package com.eugenenosenko.coding.problems.arrays.compose_from_old

// brute force approach
fun createArray(arr: IntArray): IntArray {
    val result = mutableListOf<Int>()
    for (i in arr.indices) {
        result.add(
                arr.foldIndexed(1) { index: Int, acc: Int, item: Int ->
                    // ignore current index
                    if (i == index) acc else acc * item
                }
        )
    }
    return result.toIntArray()
}

// more efficient
fun createArrayMoreEfficientWithDivision(arr: IntArray): IntArray {
    val product = arr.reduce { acc, v -> acc * v }
    val result = IntArray(arr.size)
    for ((i, v) in arr.withIndex()) {
        result[i] = product / v
    }

    return result
}

fun createArrayMoreEfficientWithoutDivision(arr: IntArray): IntArray {
    val prefixes = arrayListOf<Int>()

    for (number in arr) {
        if (prefixes.isNotEmpty()) {
            prefixes.add(prefixes.last() * number)
        } else {
            prefixes.add(number)
        }
    }

    // peak prefixes
    println("Prefixes are $prefixes")

    val suffixes = arrayListOf<Int>()
    for (number in arr.reversed()) {
        if (suffixes.isNotEmpty()) {
            suffixes.add(suffixes.last() * number)
        } else {
            suffixes.add(number)
        }
    }

    // peak suffixes
    suffixes.reverse()
    println("Suffixes are $suffixes")

    val result = arrayListOf<Int>()
    for (i in arr.indices) {
        when (i) {
            0 -> result.add(suffixes[i + 1])
            arr.lastIndex -> result.add(prefixes[i - 1])
            else -> result.add(suffixes[i + 1] * prefixes[i - 1])
        }
    }

    return result.toIntArray()
}

Compiled from "ComposeArrayFromOldSolution.kt"
public final class com.eugenenosenko.coding.problems.arrays.compose_from_old.ComposeArrayFromOldSolutionKt {
  public static final int[] createArray(int[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String arr
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class java/util/ArrayList
       9: dup
      10: invokespecial #21                 // Method java/util/ArrayList."<init>":()V
      13: checkcast     #23                 // class java/util/List
      16: astore_1
      17: iconst_0
      18: istore_2
      19: aload_0
      20: arraylength
      21: istore_3
      22: iload_2
      23: iload_3
      24: if_icmpge     139
      27: aload_1
      28: aload_0
      29: astore        4
      31: iconst_1
      32: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      35: astore        5
      37: astore        16
      39: iconst_0
      40: istore        6
      42: iconst_0
      43: istore        7
      45: aload         5
      47: astore        8
      49: iconst_0
      50: istore        9
      52: aload         4
      54: arraylength
      55: istore        10
      57: iload         9
      59: iload         10
      61: if_icmpge     122
      64: aload         4
      66: iload         9
      68: iaload
      69: istore        11
      71: iload         7
      73: iinc          7, 1
      76: aload         8
      78: iload         11
      80: istore        12
      82: checkcast     #31                 // class java/lang/Number
      85: invokevirtual #35                 // Method java/lang/Number.intValue:()I
      88: istore        13
      90: istore        14
      92: iconst_0
      93: istore        15
      95: iload_2
      96: iload         14
      98: if_icmpne     106
     101: iload         13
     103: goto          111
     106: iload         13
     108: iload         12
     110: imul
     111: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     114: astore        8
     116: iinc          9, 1
     119: goto          57
     122: aload         8
     124: aload         16
     126: swap
     127: invokeinterface #39,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     132: pop
     133: iinc          2, 1
     136: goto          22
     139: aload_1
     140: checkcast     #41                 // class java/util/Collection
     143: invokestatic  #47                 // Method kotlin/collections/CollectionsKt.toIntArray:(Ljava/util/Collection;)[I
     146: areturn

  public static final int[] createArrayMoreEfficientWithDivision(int[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String arr
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: astore_2
       8: iconst_0
       9: istore_3
      10: aload_2
      11: arraylength
      12: ifne          19
      15: iconst_1
      16: goto          20
      19: iconst_0
      20: ifeq          33
      23: new           #67                 // class java/lang/UnsupportedOperationException
      26: dup
      27: ldc           #69                 // String Empty array can\'t be reduced.
      29: invokespecial #72                 // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
      32: athrow
      33: aload_2
      34: iconst_0
      35: iaload
      36: istore        4
      38: iconst_1
      39: istore        5
      41: aload_2
      42: invokestatic  #78                 // Method kotlin/collections/ArraysKt.getLastIndex:([I)I
      45: istore        6
      47: iload         5
      49: iload         6
      51: if_icmpgt     87
      54: iload         4
      56: aload_2
      57: iload         5
      59: iaload
      60: istore        7
      62: istore        8
      64: iconst_0
      65: istore        9
      67: iload         8
      69: iload         7
      71: imul
      72: istore        4
      74: iload         5
      76: iload         6
      78: if_icmpeq     87
      81: iinc          5, 1
      84: goto          54
      87: iload         4
      89: istore_1
      90: aload_0
      91: arraylength
      92: newarray       int
      94: astore_2
      95: iconst_0
      96: istore_3
      97: aload_0
      98: arraylength
      99: istore        4
     101: iload_3
     102: iload         4
     104: if_icmpge     129
     107: iload_3
     108: istore        5
     110: aload_0
     111: iload_3
     112: iaload
     113: istore        6
     115: aload_2
     116: iload         5
     118: iload_1
     119: iload         6
     121: idiv
     122: iastore
     123: iinc          3, 1
     126: goto          101
     129: aload_2
     130: areturn

  public static final int[] createArrayMoreEfficientWithoutDivision(int[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String arr
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class java/util/ArrayList
       9: dup
      10: invokespecial #21                 // Method java/util/ArrayList."<init>":()V
      13: astore_1
      14: iconst_0
      15: istore_2
      16: aload_0
      17: arraylength
      18: istore_3
      19: iload_2
      20: iload_3
      21: if_icmpge     91
      24: aload_0
      25: iload_2
      26: iaload
      27: istore        4
      29: aload_1
      30: checkcast     #41                 // class java/util/Collection
      33: invokeinterface #88,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      38: ifne          45
      41: iconst_1
      42: goto          46
      45: iconst_0
      46: ifeq          75
      49: aload_1
      50: aload_1
      51: checkcast     #23                 // class java/util/List
      54: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
      57: checkcast     #31                 // class java/lang/Number
      60: invokevirtual #35                 // Method java/lang/Number.intValue:()I
      63: iload         4
      65: imul
      66: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      69: invokevirtual #93                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      72: goto          84
      75: aload_1
      76: iload         4
      78: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      81: invokevirtual #93                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      84: pop
      85: iinc          2, 1
      88: goto          19
      91: new           #95                 // class java/lang/StringBuilder
      94: dup
      95: invokespecial #96                 // Method java/lang/StringBuilder."<init>":()V
      98: ldc           #98                 // String Prefixes are
     100: invokevirtual #102                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     103: aload_1
     104: invokevirtual #105                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     107: invokevirtual #109                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     110: getstatic     #115                // Field java/lang/System.out:Ljava/io/PrintStream;
     113: swap
     114: invokevirtual #121                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     117: new           #17                 // class java/util/ArrayList
     120: dup
     121: invokespecial #21                 // Method java/util/ArrayList."<init>":()V
     124: astore_2
     125: aload_0
     126: invokestatic  #125                // Method kotlin/collections/ArraysKt.reversed:([I)Ljava/util/List;
     129: astore_3
     130: iconst_0
     131: istore        4
     133: aload_3
     134: invokeinterface #128,  1          // InterfaceMethod java/util/List.size:()I
     139: istore        5
     141: iload         4
     143: iload         5
     145: if_icmpge     226
     148: aload_3
     149: iload         4
     151: invokeinterface #132,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     156: checkcast     #31                 // class java/lang/Number
     159: invokevirtual #35                 // Method java/lang/Number.intValue:()I
     162: istore        6
     164: aload_2
     165: checkcast     #41                 // class java/util/Collection
     168: invokeinterface #88,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     173: ifne          180
     176: iconst_1
     177: goto          181
     180: iconst_0
     181: ifeq          210
     184: aload_2
     185: aload_2
     186: checkcast     #23                 // class java/util/List
     189: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
     192: checkcast     #31                 // class java/lang/Number
     195: invokevirtual #35                 // Method java/lang/Number.intValue:()I
     198: iload         6
     200: imul
     201: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     204: invokevirtual #93                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     207: goto          219
     210: aload_2
     211: iload         6
     213: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     216: invokevirtual #93                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     219: pop
     220: iinc          4, 1
     223: goto          141
     226: aload_2
     227: checkcast     #23                 // class java/util/List
     230: invokestatic  #136                // Method kotlin/collections/CollectionsKt.reverse:(Ljava/util/List;)V
     233: new           #95                 // class java/lang/StringBuilder
     236: dup
     237: invokespecial #96                 // Method java/lang/StringBuilder."<init>":()V
     240: ldc           #138                // String Suffixes are
     242: invokevirtual #102                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     245: aload_2
     246: invokevirtual #105                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     249: invokevirtual #109                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     252: getstatic     #115                // Field java/lang/System.out:Ljava/io/PrintStream;
     255: swap
     256: invokevirtual #121                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     259: new           #17                 // class java/util/ArrayList
     262: dup
     263: invokespecial #21                 // Method java/util/ArrayList."<init>":()V
     266: astore_3
     267: iconst_0
     268: istore        4
     270: aload_0
     271: arraylength
     272: istore        5
     274: iload         4
     276: iload         5
     278: if_icmpge     378
     281: iload         4
     283: istore        6
     285: iload         6
     287: ifne          305
     290: aload_3
     291: aload_2
     292: iload         4
     294: iconst_1
     295: iadd
     296: invokevirtual #139                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     299: invokevirtual #93                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     302: goto          371
     305: iload         6
     307: aload_0
     308: invokestatic  #78                 // Method kotlin/collections/ArraysKt.getLastIndex:([I)I
     311: if_icmpne     329
     314: aload_3
     315: aload_1
     316: iload         4
     318: iconst_1
     319: isub
     320: invokevirtual #139                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     323: invokevirtual #93                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     326: goto          371
     329: aload_3
     330: aload_2
     331: iload         4
     333: iconst_1
     334: iadd
     335: invokevirtual #139                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     338: checkcast     #31                 // class java/lang/Number
     341: invokevirtual #35                 // Method java/lang/Number.intValue:()I
     344: aload_1
     345: iload         4
     347: iconst_1
     348: isub
     349: invokevirtual #139                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     352: dup
     353: ldc           #141                // String get(...)
     355: invokestatic  #144                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     358: checkcast     #31                 // class java/lang/Number
     361: invokevirtual #35                 // Method java/lang/Number.intValue:()I
     364: imul
     365: invokestatic  #29                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     368: invokevirtual #93                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     371: pop
     372: iinc          4, 1
     375: goto          274
     378: aload_3
     379: checkcast     #41                 // class java/util/Collection
     382: invokestatic  #47                 // Method kotlin/collections/CollectionsKt.toIntArray:(Ljava/util/Collection;)[I
     385: areturn
}