package com.nlkprojects.neuralnet.math.rational

import java.lang.RuntimeException

data class Rational(val numerator: Long, val denominator: Long): Number(), Comparable<Rational> {
    constructor(num: Int): this(num, num)
    constructor(num: Long): this(num, num)
    constructor(num: Int, den: Int): this(num.toLong(), den.toLong())

    operator fun div(that: Rational): Rational {
        return from(numerator * that.denominator, denominator * that.numerator)
    }
    operator fun plus(that: Rational): Rational {
        return from((numerator * that.denominator) + (denominator + that.numerator), denominator * that.denominator)
    }
    operator fun minus(that: Rational): Rational {
        return from((numerator * that.denominator) - (denominator + that.numerator), denominator * that.denominator)
    }
    operator fun times(that: Rational): Rational {
        return from(numerator * that.numerator, denominator * that.denominator)
    }

    override fun toInt(): Int {
        return (if (denominator == 0L) 0L else numerator / denominator).toInt()
    }
    override fun toByte(): Byte {
        return (if (denominator == 0L) 0L else numerator / denominator).toByte()
    }
    override fun toChar(): Char {
        throw RuntimeException("Rational does not fit into a Char")
    }
    override fun toLong(): Long {
        return if (denominator == 0L) 0L else numerator / denominator
    }
    override fun toShort(): Short {
        return (if (denominator == 0L) 0L else numerator / denominator).toShort()
    }
    override fun toFloat(): Float {
        return if (denominator == 0L) .0f else numerator / denominator.toFloat()
    }
    override fun toDouble(): Double {
        return if (denominator == 0L) .0 else numerator / denominator.toDouble()
    }

    override fun compareTo(other: Rational): Int {
        if (this == other)
            return 0

        val lhs = numerator * other.denominator
        val rhs = denominator * other.numerator
        return if (lhs < rhs) -1 else 1
    }

    override fun toString(): String {
        return "($numerator/$denominator)"
    }

    companion object {
        val ONE = Rational(1, 1)
        val ZERO = Rational(0, 0)
        val EMPTY = Rational(0, 1)

        fun from(num: Float): Rational {
            return if (num == .0f) return ZERO else from(num.toString())
        }
        fun from(num: Double): Rational {
            return if (num == .0) return ZERO else from(num.toString())
        }
        fun from(lhs: Int, rhs: Int): Rational {
            return from(lhs.toLong(), rhs.toLong())
        }
        fun from(lhs: Long, rhs: Long): Rational {
            if (rhs == 0L)
                return ZERO
            if (lhs == 0L)
                return Rational(0L, rhs)

            val d = gcd(lhs, rhs)
            return Rational(lhs / d, rhs / d)
        }
        private fun from(string: String): Rational {

            val arr = string.split(".").map { it.trim() }
            val clean = arr[1].dropLastWhile { it == '0' }
            if (clean.isEmpty())
                return Rational(arr[0].toLong(), 1L)

            val num = clean.toLong()
            val exc = arr[0].toLong()
            val den = clean.indices.fold("1") { acc, _ -> "${acc}0" }.toLong()

            val gcd  = gcd(num, den)
            val nDen = den / gcd
            return Rational((exc * nDen) + (num / gcd), den / gcd)
        }

        fun gcd(lhs: Int, rhs: Int): Long {
            return gcd(lhs.toLong(), rhs.toLong())
        }
        fun gcd(lhs: Long, rhs: Long): Long {
            var a = lhs
            var b = rhs
            var t: Long

            while (b != 0L) {
                t = a % b
                a = b
                b = t
            }

            return if (a < 0L) -a else a
        }
    }
}

fun main() {
    println(Rational.from(3/7.0).toDouble())
}

Compiled from "Rational.kt"
public final class com.nlkprojects.neuralnet.math.rational.RationalKt {
  public static final void main();
    Code:
       0: getstatic     #12                 // Field com/nlkprojects/neuralnet/math/rational/Rational.Companion:Lcom/nlkprojects/neuralnet/math/rational/Rational$Companion;
       3: ldc2_w        #13                 // double 0.42857142857142855d
       6: invokevirtual #20                 // Method com/nlkprojects/neuralnet/math/rational/Rational$Companion.from:(D)Lcom/nlkprojects/neuralnet/math/rational/Rational;
       9: invokevirtual #24                 // Method com/nlkprojects/neuralnet/math/rational/Rational.doubleValue:()D
      12: dstore_0
      13: getstatic     #30                 // Field java/lang/System.out:Ljava/io/PrintStream;
      16: dload_0
      17: invokevirtual #36                 // Method java/io/PrintStream.println:(D)V
      20: return

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

Compiled from "Rational.kt"
public final class com.nlkprojects.neuralnet.math.rational.Rational$Companion {
  private com.nlkprojects.neuralnet.math.rational.Rational$Companion();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final com.nlkprojects.neuralnet.math.rational.Rational getONE();
    Code:
       0: invokestatic  #18                 // Method com/nlkprojects/neuralnet/math/rational/Rational.access$getONE$cp:()Lcom/nlkprojects/neuralnet/math/rational/Rational;
       3: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational getZERO();
    Code:
       0: invokestatic  #22                 // Method com/nlkprojects/neuralnet/math/rational/Rational.access$getZERO$cp:()Lcom/nlkprojects/neuralnet/math/rational/Rational;
       3: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational getEMPTY();
    Code:
       0: invokestatic  #26                 // Method com/nlkprojects/neuralnet/math/rational/Rational.access$getEMPTY$cp:()Lcom/nlkprojects/neuralnet/math/rational/Rational;
       3: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational from(float);
    Code:
       0: fload_1
       1: fconst_0
       2: fcmpg
       3: ifne          10
       6: iconst_1
       7: goto          11
      10: iconst_0
      11: ifeq          19
      14: aload_0
      15: invokevirtual #30                 // Method getZERO:()Lcom/nlkprojects/neuralnet/math/rational/Rational;
      18: areturn
      19: aload_0
      20: fload_1
      21: invokestatic  #36                 // Method java/lang/String.valueOf:(F)Ljava/lang/String;
      24: invokespecial #39                 // Method from:(Ljava/lang/String;)Lcom/nlkprojects/neuralnet/math/rational/Rational;
      27: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational from(double);
    Code:
       0: dload_1
       1: dconst_0
       2: dcmpg
       3: ifne          10
       6: iconst_1
       7: goto          11
      10: iconst_0
      11: ifeq          19
      14: aload_0
      15: invokevirtual #30                 // Method getZERO:()Lcom/nlkprojects/neuralnet/math/rational/Rational;
      18: areturn
      19: aload_0
      20: dload_1
      21: invokestatic  #45                 // Method java/lang/String.valueOf:(D)Ljava/lang/String;
      24: invokespecial #39                 // Method from:(Ljava/lang/String;)Lcom/nlkprojects/neuralnet/math/rational/Rational;
      27: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational from(int, int);
    Code:
       0: aload_0
       1: iload_1
       2: i2l
       3: iload_2
       4: i2l
       5: invokevirtual #50                 // Method from:(JJ)Lcom/nlkprojects/neuralnet/math/rational/Rational;
       8: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational from(long, long);
    Code:
       0: lload_3
       1: lconst_0
       2: lcmp
       3: ifne          11
       6: aload_0
       7: invokevirtual #30                 // Method getZERO:()Lcom/nlkprojects/neuralnet/math/rational/Rational;
      10: areturn
      11: lload_1
      12: lconst_0
      13: lcmp
      14: ifne          27
      17: new           #15                 // class com/nlkprojects/neuralnet/math/rational/Rational
      20: dup
      21: lconst_0
      22: lload_3
      23: invokespecial #56                 // Method com/nlkprojects/neuralnet/math/rational/Rational."<init>":(JJ)V
      26: areturn
      27: aload_0
      28: lload_1
      29: lload_3
      30: invokevirtual #60                 // Method gcd:(JJ)J
      33: lstore        5
      35: new           #15                 // class com/nlkprojects/neuralnet/math/rational/Rational
      38: dup
      39: lload_1
      40: lload         5
      42: ldiv
      43: lload_3
      44: lload         5
      46: ldiv
      47: invokespecial #56                 // Method com/nlkprojects/neuralnet/math/rational/Rational."<init>":(JJ)V
      50: areturn

  private final com.nlkprojects.neuralnet.math.rational.Rational from(java.lang.String);
    Code:
       0: aload_1
       1: checkcast     #64                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #32                 // class java/lang/String
       8: astore_3
       9: aload_3
      10: iconst_0
      11: ldc           #66                 // String .
      13: aastore
      14: aload_3
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #72                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: checkcast     #74                 // class java/lang/Iterable
      26: astore_3
      27: iconst_0
      28: istore        4
      30: aload_3
      31: astore        5
      33: new           #76                 // class java/util/ArrayList
      36: dup
      37: aload_3
      38: bipush        10
      40: invokestatic  #82                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      43: invokespecial #85                 // Method java/util/ArrayList."<init>":(I)V
      46: checkcast     #87                 // class java/util/Collection
      49: astore        6
      51: iconst_0
      52: istore        7
      54: aload         5
      56: invokeinterface #91,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      61: astore        8
      63: aload         8
      65: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      70: ifeq          120
      73: aload         8
      75: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      80: astore        9
      82: aload         6
      84: aload         9
      86: checkcast     #32                 // class java/lang/String
      89: astore        10
      91: astore        18
      93: iconst_0
      94: istore        11
      96: aload         10
      98: checkcast     #64                 // class java/lang/CharSequence
     101: invokestatic  #105                // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     104: invokevirtual #109                // Method java/lang/Object.toString:()Ljava/lang/String;
     107: nop
     108: aload         18
     110: swap
     111: invokeinterface #113,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     116: pop
     117: goto          63
     120: aload         6
     122: checkcast     #115                // class java/util/List
     125: nop
     126: astore_2
     127: aload_2
     128: iconst_1
     129: invokeinterface #119,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     134: checkcast     #32                 // class java/lang/String
     137: astore        4
     139: iconst_0
     140: istore        5
     142: aload         4
     144: checkcast     #64                 // class java/lang/CharSequence
     147: invokestatic  #123                // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
     150: istore        6
     152: iconst_m1
     153: iload         6
     155: if_icmpge     222
     158: aload         4
     160: iload         6
     162: invokevirtual #127                // Method java/lang/String.charAt:(I)C
     165: istore        7
     167: iconst_0
     168: istore        8
     170: iload         7
     172: bipush        48
     174: if_icmpne     181
     177: iconst_1
     178: goto          182
     181: iconst_0
     182: ifne          216
     185: aload         4
     187: astore        7
     189: iconst_0
     190: istore        8
     192: iload         6
     194: iconst_1
     195: iadd
     196: istore        9
     198: aload         7
     200: iload         8
     202: iload         9
     204: invokevirtual #131                // Method java/lang/String.substring:(II)Ljava/lang/String;
     207: dup
     208: ldc           #133                // String substring(...)
     210: invokestatic  #139                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     213: goto          224
     216: iinc          6, -1
     219: goto          152
     222: ldc           #141                // String
     224: astore_3
     225: aload_3
     226: checkcast     #64                 // class java/lang/CharSequence
     229: invokeinterface #145,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     234: ifne          241
     237: iconst_1
     238: goto          242
     241: iconst_0
     242: ifeq          267
     245: new           #15                 // class com/nlkprojects/neuralnet/math/rational/Rational
     248: dup
     249: aload_2
     250: iconst_0
     251: invokeinterface #119,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     256: checkcast     #32                 // class java/lang/String
     259: invokestatic  #151                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     262: lconst_1
     263: invokespecial #56                 // Method com/nlkprojects/neuralnet/math/rational/Rational."<init>":(JJ)V
     266: areturn
     267: aload_3
     268: invokestatic  #151                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     271: lstore        4
     273: aload_2
     274: iconst_0
     275: invokeinterface #119,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     280: checkcast     #32                 // class java/lang/String
     283: invokestatic  #151                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     286: lstore        6
     288: aload_3
     289: checkcast     #64                 // class java/lang/CharSequence
     292: invokestatic  #155                // Method kotlin/text/StringsKt.getIndices:(Ljava/lang/CharSequence;)Lkotlin/ranges/IntRange;
     295: checkcast     #74                 // class java/lang/Iterable
     298: astore        10
     300: ldc           #157                // String 1
     302: astore        11
     304: iconst_0
     305: istore        12
     307: aload         11
     309: astore        13
     311: aload         10
     313: invokeinterface #91,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     318: astore        14
     320: aload         14
     322: invokeinterface #97,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     327: ifeq          372
     330: aload         14
     332: checkcast     #159                // class kotlin/collections/IntIterator
     335: invokevirtual #162                // Method kotlin/collections/IntIterator.nextInt:()I
     338: istore        15
     340: aload         13
     342: astore        16
     344: iconst_0
     345: istore        17
     347: new           #164                // class java/lang/StringBuilder
     350: dup
     351: invokespecial #165                // Method java/lang/StringBuilder."<init>":()V
     354: aload         16
     356: invokevirtual #169                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     359: bipush        48
     361: invokevirtual #172                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     364: invokevirtual #173                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     367: astore        13
     369: goto          320
     372: aload         13
     374: invokestatic  #151                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     377: lstore        8
     379: aload_0
     380: lload         4
     382: lload         8
     384: invokevirtual #60                 // Method gcd:(JJ)J
     387: lstore        10
     389: lload         8
     391: lload         10
     393: ldiv
     394: lstore        12
     396: new           #15                 // class com/nlkprojects/neuralnet/math/rational/Rational
     399: dup
     400: lload         6
     402: lload         12
     404: lmul
     405: lload         4
     407: lload         10
     409: ldiv
     410: ladd
     411: lload         8
     413: lload         10
     415: ldiv
     416: invokespecial #56                 // Method com/nlkprojects/neuralnet/math/rational/Rational."<init>":(JJ)V
     419: areturn

  public final long gcd(int, int);
    Code:
       0: aload_0
       1: iload_1
       2: i2l
       3: iload_2
       4: i2l
       5: invokevirtual #60                 // Method gcd:(JJ)J
       8: lreturn

  public final long gcd(long, long);
    Code:
       0: lload_1
       1: lstore        5
       3: lload_3
       4: lstore        7
       6: lconst_0
       7: lstore        9
       9: lload         7
      11: lconst_0
      12: lcmp
      13: ifeq          34
      16: lload         5
      18: lload         7
      20: lrem
      21: lstore        9
      23: lload         7
      25: lstore        5
      27: lload         9
      29: lstore        7
      31: goto          9
      34: lload         5
      36: lconst_0
      37: lcmp
      38: ifge          47
      41: lload         5
      43: lneg
      44: goto          49
      47: lload         5
      49: lreturn

  public com.nlkprojects.neuralnet.math.rational.Rational$Companion(kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: aload_0
       1: invokespecial #210                // Method "<init>":()V
       4: return
}

Compiled from "Rational.kt"
public final class com.nlkprojects.neuralnet.math.rational.Rational extends java.lang.Number implements java.lang.Comparable<com.nlkprojects.neuralnet.math.rational.Rational> {
  public static final com.nlkprojects.neuralnet.math.rational.Rational$Companion Companion;

  private final long numerator;

  private final long denominator;

  private static final com.nlkprojects.neuralnet.math.rational.Rational ONE;

  private static final com.nlkprojects.neuralnet.math.rational.Rational ZERO;

  private static final com.nlkprojects.neuralnet.math.rational.Rational EMPTY;

  public com.nlkprojects.neuralnet.math.rational.Rational(long, long);
    Code:
       0: aload_0
       1: invokespecial #12                 // Method java/lang/Number."<init>":()V
       4: aload_0
       5: lload_1
       6: putfield      #16                 // Field numerator:J
       9: aload_0
      10: lload_3
      11: putfield      #19                 // Field denominator:J
      14: return

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

  public final long getDenominator();
    Code:
       0: aload_0
       1: getfield      #19                 // Field denominator:J
       4: lreturn

  public com.nlkprojects.neuralnet.math.rational.Rational(int);
    Code:
       0: aload_0
       1: iload_1
       2: iload_1
       3: invokespecial #28                 // Method "<init>":(II)V
       6: return

  public com.nlkprojects.neuralnet.math.rational.Rational(long);
    Code:
       0: aload_0
       1: lload_1
       2: lload_1
       3: invokespecial #33                 // Method "<init>":(JJ)V
       6: return

  public com.nlkprojects.neuralnet.math.rational.Rational(int, int);
    Code:
       0: aload_0
       1: iload_1
       2: i2l
       3: iload_2
       4: i2l
       5: invokespecial #33                 // Method "<init>":(JJ)V
       8: return

  public final com.nlkprojects.neuralnet.math.rational.Rational div(com.nlkprojects.neuralnet.math.rational.Rational);
    Code:
       0: aload_1
       1: ldc           #39                 // String that
       3: invokestatic  #45                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #49                 // Field Companion:Lcom/nlkprojects/neuralnet/math/rational/Rational$Companion;
       9: aload_0
      10: getfield      #16                 // Field numerator:J
      13: aload_1
      14: getfield      #19                 // Field denominator:J
      17: lmul
      18: aload_0
      19: getfield      #19                 // Field denominator:J
      22: aload_1
      23: getfield      #16                 // Field numerator:J
      26: lmul
      27: invokevirtual #55                 // Method com/nlkprojects/neuralnet/math/rational/Rational$Companion.from:(JJ)Lcom/nlkprojects/neuralnet/math/rational/Rational;
      30: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational plus(com.nlkprojects.neuralnet.math.rational.Rational);
    Code:
       0: aload_1
       1: ldc           #39                 // String that
       3: invokestatic  #45                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #49                 // Field Companion:Lcom/nlkprojects/neuralnet/math/rational/Rational$Companion;
       9: aload_0
      10: getfield      #16                 // Field numerator:J
      13: aload_1
      14: getfield      #19                 // Field denominator:J
      17: lmul
      18: aload_0
      19: getfield      #19                 // Field denominator:J
      22: aload_1
      23: getfield      #16                 // Field numerator:J
      26: ladd
      27: ladd
      28: aload_0
      29: getfield      #19                 // Field denominator:J
      32: aload_1
      33: getfield      #19                 // Field denominator:J
      36: lmul
      37: invokevirtual #55                 // Method com/nlkprojects/neuralnet/math/rational/Rational$Companion.from:(JJ)Lcom/nlkprojects/neuralnet/math/rational/Rational;
      40: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational minus(com.nlkprojects.neuralnet.math.rational.Rational);
    Code:
       0: aload_1
       1: ldc           #39                 // String that
       3: invokestatic  #45                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #49                 // Field Companion:Lcom/nlkprojects/neuralnet/math/rational/Rational$Companion;
       9: aload_0
      10: getfield      #16                 // Field numerator:J
      13: aload_1
      14: getfield      #19                 // Field denominator:J
      17: lmul
      18: aload_0
      19: getfield      #19                 // Field denominator:J
      22: aload_1
      23: getfield      #16                 // Field numerator:J
      26: ladd
      27: lsub
      28: aload_0
      29: getfield      #19                 // Field denominator:J
      32: aload_1
      33: getfield      #19                 // Field denominator:J
      36: lmul
      37: invokevirtual #55                 // Method com/nlkprojects/neuralnet/math/rational/Rational$Companion.from:(JJ)Lcom/nlkprojects/neuralnet/math/rational/Rational;
      40: areturn

  public final com.nlkprojects.neuralnet.math.rational.Rational times(com.nlkprojects.neuralnet.math.rational.Rational);
    Code:
       0: aload_1
       1: ldc           #39                 // String that
       3: invokestatic  #45                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #49                 // Field Companion:Lcom/nlkprojects/neuralnet/math/rational/Rational$Companion;
       9: aload_0
      10: getfield      #16                 // Field numerator:J
      13: aload_1
      14: getfield      #16                 // Field numerator:J
      17: lmul
      18: aload_0
      19: getfield      #19                 // Field denominator:J
      22: aload_1
      23: getfield      #19                 // Field denominator:J
      26: lmul
      27: invokevirtual #55                 // Method com/nlkprojects/neuralnet/math/rational/Rational$Companion.from:(JJ)Lcom/nlkprojects/neuralnet/math/rational/Rational;
      30: areturn

  public int toInt();
    Code:
       0: aload_0
       1: getfield      #19                 // Field denominator:J
       4: lconst_0
       5: lcmp
       6: ifne          13
       9: lconst_0
      10: goto          22
      13: aload_0
      14: getfield      #16                 // Field numerator:J
      17: aload_0
      18: getfield      #19                 // Field denominator:J
      21: ldiv
      22: l2i
      23: ireturn

  public byte toByte();
    Code:
       0: aload_0
       1: getfield      #19                 // Field denominator:J
       4: lconst_0
       5: lcmp
       6: ifne          13
       9: lconst_0
      10: goto          22
      13: aload_0
      14: getfield      #16                 // Field numerator:J
      17: aload_0
      18: getfield      #19                 // Field denominator:J
      21: ldiv
      22: l2i
      23: i2b
      24: ireturn

  public char toChar();
    Code:
       0: new           #66                 // class java/lang/RuntimeException
       3: dup
       4: ldc           #68                 // String Rational does not fit into a Char
       6: invokespecial #71                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
       9: athrow

  public long toLong();
    Code:
       0: aload_0
       1: getfield      #19                 // Field denominator:J
       4: lconst_0
       5: lcmp
       6: ifne          13
       9: lconst_0
      10: goto          22
      13: aload_0
      14: getfield      #16                 // Field numerator:J
      17: aload_0
      18: getfield      #19                 // Field denominator:J
      21: ldiv
      22: lreturn

  public short toShort();
    Code:
       0: aload_0
       1: getfield      #19                 // Field denominator:J
       4: lconst_0
       5: lcmp
       6: ifne          13
       9: lconst_0
      10: goto          22
      13: aload_0
      14: getfield      #16                 // Field numerator:J
      17: aload_0
      18: getfield      #19                 // Field denominator:J
      21: ldiv
      22: l2i
      23: i2s
      24: ireturn

  public float toFloat();
    Code:
       0: aload_0
       1: getfield      #19                 // Field denominator:J
       4: lconst_0
       5: lcmp
       6: ifne          13
       9: fconst_0
      10: goto          24
      13: aload_0
      14: getfield      #16                 // Field numerator:J
      17: l2f
      18: aload_0
      19: getfield      #19                 // Field denominator:J
      22: l2f
      23: fdiv
      24: freturn

  public double toDouble();
    Code:
       0: aload_0
       1: getfield      #19                 // Field denominator:J
       4: lconst_0
       5: lcmp
       6: ifne          13
       9: dconst_0
      10: goto          24
      13: aload_0
      14: getfield      #16                 // Field numerator:J
      17: l2d
      18: aload_0
      19: getfield      #19                 // Field denominator:J
      22: l2d
      23: ddiv
      24: dreturn

  public int compareTo(com.nlkprojects.neuralnet.math.rational.Rational);
    Code:
       0: aload_1
       1: ldc           #82                 // String other
       3: invokestatic  #45                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_1
       8: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      11: ifeq          16
      14: iconst_0
      15: ireturn
      16: aload_0
      17: getfield      #16                 // Field numerator:J
      20: aload_1
      21: getfield      #19                 // Field denominator:J
      24: lmul
      25: lstore_2
      26: aload_0
      27: getfield      #19                 // Field denominator:J
      30: aload_1
      31: getfield      #16                 // Field numerator:J
      34: lmul
      35: lstore        4
      37: lload_2
      38: lload         4
      40: lcmp
      41: ifge          48
      44: iconst_m1
      45: goto          49
      48: iconst_1
      49: ireturn

  public java.lang.String toString();
    Code:
       0: new           #92                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #93                 // Method java/lang/StringBuilder."<init>":()V
       7: bipush        40
       9: invokevirtual #97                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #16                 // Field numerator:J
      16: invokevirtual #100                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      19: bipush        47
      21: invokevirtual #97                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #19                 // Field denominator:J
      28: invokevirtual #100                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      31: bipush        41
      33: invokevirtual #97                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      36: invokevirtual #102                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn

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

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

  public final com.nlkprojects.neuralnet.math.rational.Rational copy(long, long);
    Code:
       0: new           #2                  // class com/nlkprojects/neuralnet/math/rational/Rational
       3: dup
       4: lload_1
       5: lload_3
       6: invokespecial #33                 // Method "<init>":(JJ)V
       9: areturn

  public static com.nlkprojects.neuralnet.math.rational.Rational copy$default(com.nlkprojects.neuralnet.math.rational.Rational, long, long, int, java.lang.Object);
    Code:
       0: iload         5
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #16                 // Field numerator:J
      11: lstore_1
      12: iload         5
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #19                 // Field denominator:J
      23: lstore_3
      24: aload_0
      25: lload_1
      26: lload_3
      27: invokevirtual #109                // Method copy:(JJ)Lcom/nlkprojects/neuralnet/math/rational/Rational;
      30: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #16                 // Field numerator:J
       4: invokestatic  #115                // Method java/lang/Long.hashCode:(J)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #19                 // Field denominator:J
      16: invokestatic  #115                // 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 com/nlkprojects/neuralnet/math/rational/Rational
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class com/nlkprojects/neuralnet/math/rational/Rational
      20: astore_2
      21: aload_0
      22: getfield      #16                 // Field numerator:J
      25: aload_2
      26: getfield      #16                 // Field numerator:J
      29: lcmp
      30: ifeq          35
      33: iconst_0
      34: ireturn
      35: aload_0
      36: getfield      #19                 // Field denominator:J
      39: aload_2
      40: getfield      #19                 // Field denominator:J
      43: lcmp
      44: ifeq          49
      47: iconst_0
      48: ireturn
      49: iconst_1
      50: ireturn

  public final int intValue();
    Code:
       0: aload_0
       1: invokevirtual #123                // Method toInt:()I
       4: ireturn

  public final byte byteValue();
    Code:
       0: aload_0
       1: invokevirtual #126                // Method toByte:()B
       4: ireturn

  public final long longValue();
    Code:
       0: aload_0
       1: invokevirtual #129                // Method toLong:()J
       4: lreturn

  public final short shortValue();
    Code:
       0: aload_0
       1: invokevirtual #132                // Method toShort:()S
       4: ireturn

  public final float floatValue();
    Code:
       0: aload_0
       1: invokevirtual #135                // Method toFloat:()F
       4: freturn

  public final double doubleValue();
    Code:
       0: aload_0
       1: invokevirtual #138                // Method toDouble:()D
       4: dreturn

  public int compareTo(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #2                  // class com/nlkprojects/neuralnet/math/rational/Rational
       5: invokevirtual #141                // Method compareTo:(Lcom/nlkprojects/neuralnet/math/rational/Rational;)I
       8: ireturn

  public static final com.nlkprojects.neuralnet.math.rational.Rational access$getONE$cp();
    Code:
       0: getstatic     #146                // Field ONE:Lcom/nlkprojects/neuralnet/math/rational/Rational;
       3: areturn

  public static final com.nlkprojects.neuralnet.math.rational.Rational access$getZERO$cp();
    Code:
       0: getstatic     #150                // Field ZERO:Lcom/nlkprojects/neuralnet/math/rational/Rational;
       3: areturn

  public static final com.nlkprojects.neuralnet.math.rational.Rational access$getEMPTY$cp();
    Code:
       0: getstatic     #154                // Field EMPTY:Lcom/nlkprojects/neuralnet/math/rational/Rational;
       3: areturn

  static {};
    Code:
       0: new           #51                 // class com/nlkprojects/neuralnet/math/rational/Rational$Companion
       3: dup
       4: aconst_null
       5: invokespecial #158                // Method com/nlkprojects/neuralnet/math/rational/Rational$Companion."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #49                 // Field Companion:Lcom/nlkprojects/neuralnet/math/rational/Rational$Companion;
      11: new           #2                  // class com/nlkprojects/neuralnet/math/rational/Rational
      14: dup
      15: iconst_1
      16: iconst_1
      17: invokespecial #28                 // Method "<init>":(II)V
      20: putstatic     #146                // Field ONE:Lcom/nlkprojects/neuralnet/math/rational/Rational;
      23: new           #2                  // class com/nlkprojects/neuralnet/math/rational/Rational
      26: dup
      27: iconst_0
      28: iconst_0
      29: invokespecial #28                 // Method "<init>":(II)V
      32: putstatic     #150                // Field ZERO:Lcom/nlkprojects/neuralnet/math/rational/Rational;
      35: new           #2                  // class com/nlkprojects/neuralnet/math/rational/Rational
      38: dup
      39: iconst_0
      40: iconst_1
      41: invokespecial #28                 // Method "<init>":(II)V
      44: putstatic     #154                // Field EMPTY:Lcom/nlkprojects/neuralnet/math/rational/Rational;
      47: return
}


package pj_euler
import kotlin.math.floor
import kotlin.math.sqrt
import kotlin.comparisons.minOf
import kotlin.comparisons.maxOf
import java.math.BigInteger
import kotlin.Boolean
//TODO pj 64
fun main(args: Array<String>) {

    val frac = Fraction(BigInteger.valueOf(6), BigInteger.valueOf(4))
    println(frac)
    frac.reduce()
    println(frac)

    val frac2 = Fraction(BigInteger.valueOf(1),BigInteger.valueOf(3))
    println(frac.add(frac2))

    var idk = CFE(sqrt(2.0))

    idk.convergents.add(1)
    var num = 0
    var outputs = mutableListOf(Fraction(BigInteger.valueOf(1),BigInteger.valueOf(4)))
    for (i in 1..1000) {
        println(i)
        //idk.addNextConvergent() //this is inacurrate
        idk.convergents.add(2)
        val frac = idk.getFrac()
        //println(frac)
        if (frac.top.toString().length > frac.bot.toString().length) {
            num += 1
            outputs.add(frac)
            println("$i frac was up")
        }

    }
    println("Found $num fractions with top more digits than bot")
    println(outputs.subList(0, 9))
    println(outputs.lastIndex)
    println(idk.convergents)

}

class CFE(val target: Double) {
    var theta_i = target
    var convergents: MutableList<Int> = mutableListOf()
    fun addNextConvergent() {
        convergents.add(floor(theta_i).toInt())
        theta_i = 1/(theta_i - convergents.last())
    }

    fun add_many(rep_list: List<Int>, times: Int=1) {
        for (i in 1..times) {
            convergents.addAll(rep_list)
        }
    }

    //Returns the approximation of target given by the convergents
    fun getApproxDouble(): Double {
        var result = convergents.last().toDouble()
        for (conv in convergents.subList(0, convergents.lastIndex).reversed()) {
            result = conv.toDouble() + (1/(result))
        }
        return result
    }

    fun getFrac(): Fraction {
        var result = Fraction(BigInteger(convergents.last().toString()))
        for (conv in convergents.subList(0, convergents.lastIndex).reversed()) {
            result = Fraction(BigInteger(conv.toString())).add(result.flipped())
        }
        return result
    }
}

class Fraction(var top: BigInteger, var bot: BigInteger = BigInteger.ONE) {
    fun add(frac: Fraction): Fraction {
        val topNew = top * frac.bot + bot * frac.top
        val botNew = bot * frac.bot
        val newFrac = Fraction(topNew, botNew)
        newFrac.reduce()
        return newFrac
    }

    fun reduce() {
        val d = hcf(top, bot)
        top = top/d
        bot = bot/d
    }

    fun flipped(): Fraction {
        return Fraction(bot, top)
    }

    override fun toString(): String{
        return "$top/$bot"
    }

}

fun hcf(a: BigInteger, b: BigInteger): BigInteger {
    var a_i = maxOf(a, b)
    var b_i = minOf(a, b)
    while (!b_i.equals(BigInteger.ZERO)) {
        val q = a_i/b_i
        val r = a_i - q * b_i
        a_i = b_i
        b_i = r
    }
    return a_i
}

fun getFracExplicit(cfe: CFE): Fraction {
    var result = Fraction(BigInteger(cfe.convergents.last().toString()))
    println(result)
    val lastIndex = cfe.convergents.lastIndex
    for ((i, conv) in cfe.convergents.subList(0, lastIndex).reversed().withIndex()) {
        println("conv index ${lastIndex-i-1}: $conv + 1/frac = ")
        result = Fraction(BigInteger(conv.toString())).add(result.flipped())
        println(result)
    }
    return result
}

Compiled from "pj57.kt"
public final class pj_euler.Pj57Kt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class pj_euler/Fraction
       9: dup
      10: ldc2_w        #18                 // long 6l
      13: invokestatic  #25                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      16: dup
      17: ldc           #27                 // String valueOf(...)
      19: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      22: ldc2_w        #31                 // long 4l
      25: invokestatic  #25                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      28: dup
      29: ldc           #27                 // String valueOf(...)
      31: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      34: invokespecial #36                 // Method pj_euler/Fraction."<init>":(Ljava/math/BigInteger;Ljava/math/BigInteger;)V
      37: astore_1
      38: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
      41: aload_1
      42: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      45: aload_1
      46: invokevirtual #52                 // Method pj_euler/Fraction.reduce:()V
      49: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
      52: aload_1
      53: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      56: new           #17                 // class pj_euler/Fraction
      59: dup
      60: lconst_1
      61: invokestatic  #25                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      64: dup
      65: ldc           #27                 // String valueOf(...)
      67: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      70: ldc2_w        #53                 // long 3l
      73: invokestatic  #25                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
      76: dup
      77: ldc           #27                 // String valueOf(...)
      79: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      82: invokespecial #36                 // Method pj_euler/Fraction."<init>":(Ljava/math/BigInteger;Ljava/math/BigInteger;)V
      85: astore_2
      86: aload_1
      87: aload_2
      88: invokevirtual #58                 // Method pj_euler/Fraction.add:(Lpj_euler/Fraction;)Lpj_euler/Fraction;
      91: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
      94: swap
      95: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      98: new           #60                 // class pj_euler/CFE
     101: dup
     102: ldc2_w        #61                 // double 2.0d
     105: invokestatic  #68                 // Method java/lang/Math.sqrt:(D)D
     108: invokespecial #71                 // Method pj_euler/CFE."<init>":(D)V
     111: astore_3
     112: aload_3
     113: invokevirtual #75                 // Method pj_euler/CFE.getConvergents:()Ljava/util/List;
     116: iconst_1
     117: invokestatic  #80                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     120: invokeinterface #85,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     125: pop
     126: iconst_0
     127: istore        4
     129: iconst_1
     130: anewarray     #17                 // class pj_euler/Fraction
     133: astore        6
     135: aload         6
     137: iconst_0
     138: new           #17                 // class pj_euler/Fraction
     141: dup
     142: lconst_1
     143: invokestatic  #25                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
     146: dup
     147: ldc           #27                 // String valueOf(...)
     149: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     152: ldc2_w        #31                 // long 4l
     155: invokestatic  #25                 // Method java/math/BigInteger.valueOf:(J)Ljava/math/BigInteger;
     158: dup
     159: ldc           #27                 // String valueOf(...)
     161: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     164: invokespecial #36                 // Method pj_euler/Fraction."<init>":(Ljava/math/BigInteger;Ljava/math/BigInteger;)V
     167: aastore
     168: aload         6
     170: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
     173: astore        5
     175: iconst_1
     176: istore        6
     178: iload         6
     180: sipush        1001
     183: if_icmpge     285
     186: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     189: iload         6
     191: invokevirtual #94                 // Method java/io/PrintStream.println:(I)V
     194: aload_3
     195: invokevirtual #75                 // Method pj_euler/CFE.getConvergents:()Ljava/util/List;
     198: iconst_2
     199: invokestatic  #80                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     202: invokeinterface #85,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     207: pop
     208: aload_3
     209: invokevirtual #98                 // Method pj_euler/CFE.getFrac:()Lpj_euler/Fraction;
     212: astore        7
     214: aload         7
     216: invokevirtual #102                // Method pj_euler/Fraction.getTop:()Ljava/math/BigInteger;
     219: invokevirtual #106                // Method java/math/BigInteger.toString:()Ljava/lang/String;
     222: invokevirtual #112                // Method java/lang/String.length:()I
     225: aload         7
     227: invokevirtual #115                // Method pj_euler/Fraction.getBot:()Ljava/math/BigInteger;
     230: invokevirtual #106                // Method java/math/BigInteger.toString:()Ljava/lang/String;
     233: invokevirtual #112                // Method java/lang/String.length:()I
     236: if_icmple     279
     239: iinc          4, 1
     242: aload         5
     244: aload         7
     246: invokeinterface #85,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     251: pop
     252: new           #117                // class java/lang/StringBuilder
     255: dup
     256: invokespecial #119                // Method java/lang/StringBuilder."<init>":()V
     259: iload         6
     261: invokevirtual #123                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     264: ldc           #125                // String  frac was up
     266: invokevirtual #128                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     269: invokevirtual #129                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     272: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     275: swap
     276: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     279: iinc          6, 1
     282: goto          178
     285: new           #117                // class java/lang/StringBuilder
     288: dup
     289: invokespecial #119                // Method java/lang/StringBuilder."<init>":()V
     292: ldc           #131                // String Found
     294: invokevirtual #128                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     297: iload         4
     299: invokevirtual #123                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     302: ldc           #133                // String  fractions with top more digits than bot
     304: invokevirtual #128                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     307: invokevirtual #129                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     310: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     313: swap
     314: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     317: aload         5
     319: iconst_0
     320: bipush        9
     322: invokeinterface #137,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
     327: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     330: swap
     331: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     334: aload         5
     336: invokestatic  #141                // Method kotlin/collections/CollectionsKt.getLastIndex:(Ljava/util/List;)I
     339: istore        6
     341: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     344: iload         6
     346: invokevirtual #94                 // Method java/io/PrintStream.println:(I)V
     349: aload_3
     350: invokevirtual #75                 // Method pj_euler/CFE.getConvergents:()Ljava/util/List;
     353: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     356: swap
     357: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     360: return

  public static final java.math.BigInteger hcf(java.math.BigInteger, java.math.BigInteger);
    Code:
       0: aload_0
       1: ldc           #157                // String a
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #159                // String b
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #161                // class java/lang/Comparable
      16: aload_1
      17: checkcast     #161                // class java/lang/Comparable
      20: invokestatic  #167                // Method kotlin/comparisons/ComparisonsKt.maxOf:(Ljava/lang/Comparable;Ljava/lang/Comparable;)Ljava/lang/Comparable;
      23: checkcast     #21                 // class java/math/BigInteger
      26: astore_2
      27: aload_0
      28: checkcast     #161                // class java/lang/Comparable
      31: aload_1
      32: checkcast     #161                // class java/lang/Comparable
      35: invokestatic  #170                // Method kotlin/comparisons/ComparisonsKt.minOf:(Ljava/lang/Comparable;Ljava/lang/Comparable;)Ljava/lang/Comparable;
      38: checkcast     #21                 // class java/math/BigInteger
      41: astore_3
      42: aload_3
      43: getstatic     #174                // Field java/math/BigInteger.ZERO:Ljava/math/BigInteger;
      46: invokevirtual #177                // Method java/math/BigInteger.equals:(Ljava/lang/Object;)Z
      49: ifne          98
      52: aload_2
      53: aload_3
      54: invokevirtual #181                // Method java/math/BigInteger.divide:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      57: dup
      58: ldc           #183                // String divide(...)
      60: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      63: astore        4
      65: nop
      66: aload_2
      67: aload         4
      69: aload_3
      70: invokevirtual #186                // Method java/math/BigInteger.multiply:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      73: dup
      74: ldc           #188                // String multiply(...)
      76: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      79: invokevirtual #191                // Method java/math/BigInteger.subtract:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
      82: dup
      83: ldc           #193                // String subtract(...)
      85: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      88: astore        5
      90: aload_3
      91: astore_2
      92: aload         5
      94: astore_3
      95: goto          42
      98: aload_2
      99: areturn

  public static final pj_euler.Fraction getFracExplicit(pj_euler.CFE);
    Code:
       0: aload_0
       1: ldc           #201                // String cfe
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class pj_euler/Fraction
       9: dup
      10: new           #21                 // class java/math/BigInteger
      13: dup
      14: aload_0
      15: invokevirtual #75                 // Method pj_euler/CFE.getConvergents:()Ljava/util/List;
      18: invokestatic  #205                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
      21: checkcast     #207                // class java/lang/Number
      24: invokevirtual #210                // Method java/lang/Number.intValue:()I
      27: invokestatic  #213                // Method java/lang/String.valueOf:(I)Ljava/lang/String;
      30: invokespecial #216                // Method java/math/BigInteger."<init>":(Ljava/lang/String;)V
      33: aconst_null
      34: iconst_2
      35: aconst_null
      36: invokespecial #219                // Method pj_euler/Fraction."<init>":(Ljava/math/BigInteger;Ljava/math/BigInteger;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      39: astore_1
      40: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
      43: aload_1
      44: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      47: aload_0
      48: invokevirtual #75                 // Method pj_euler/CFE.getConvergents:()Ljava/util/List;
      51: invokestatic  #141                // Method kotlin/collections/CollectionsKt.getLastIndex:(Ljava/util/List;)I
      54: istore_2
      55: aload_0
      56: invokevirtual #75                 // Method pj_euler/CFE.getConvergents:()Ljava/util/List;
      59: iconst_0
      60: iload_2
      61: invokeinterface #137,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
      66: checkcast     #221                // class java/lang/Iterable
      69: invokestatic  #225                // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
      72: checkcast     #221                // class java/lang/Iterable
      75: invokeinterface #229,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      80: astore_3
      81: iconst_0
      82: istore        4
      84: aload_3
      85: invokeinterface #235,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      90: ifeq          203
      93: iload         4
      95: istore        5
      97: iload         4
      99: iconst_1
     100: iadd
     101: istore        4
     103: aload_3
     104: invokeinterface #239,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     109: checkcast     #207                // class java/lang/Number
     112: invokevirtual #210                // Method java/lang/Number.intValue:()I
     115: istore        6
     117: new           #117                // class java/lang/StringBuilder
     120: dup
     121: invokespecial #119                // Method java/lang/StringBuilder."<init>":()V
     124: ldc           #241                // String conv index
     126: invokevirtual #128                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     129: iload_2
     130: iload         5
     132: isub
     133: iconst_1
     134: isub
     135: invokevirtual #123                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     138: ldc           #243                // String :
     140: invokevirtual #128                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     143: iload         6
     145: invokevirtual #123                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     148: ldc           #245                // String  + 1/frac =
     150: invokevirtual #128                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     153: invokevirtual #129                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     156: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     159: swap
     160: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     163: new           #17                 // class pj_euler/Fraction
     166: dup
     167: new           #21                 // class java/math/BigInteger
     170: dup
     171: iload         6
     173: invokestatic  #213                // Method java/lang/String.valueOf:(I)Ljava/lang/String;
     176: invokespecial #216                // Method java/math/BigInteger."<init>":(Ljava/lang/String;)V
     179: aconst_null
     180: iconst_2
     181: aconst_null
     182: invokespecial #219                // Method pj_euler/Fraction."<init>":(Ljava/math/BigInteger;Ljava/math/BigInteger;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
     185: aload_1
     186: invokevirtual #248                // Method pj_euler/Fraction.flipped:()Lpj_euler/Fraction;
     189: invokevirtual #58                 // Method pj_euler/Fraction.add:(Lpj_euler/Fraction;)Lpj_euler/Fraction;
     192: astore_1
     193: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     196: aload_1
     197: invokevirtual #48                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     200: goto          84
     203: aload_1
     204: areturn
}


package wardrobe.sal

typealias Width = Int
typealias Price = Int

fun combinations(
    goal: Width = 250,
    availableSizes: List<Width> = listOf(50, 75, 100, 120)
): Set<List<Width>> =
    if (goal == 0)
        setOf(emptyList())
    else
        availableSizes
            .filter { it <= goal }
            .flatMap { width ->
                val rest = goal - width
                val partial = combinations(rest, availableSizes)
                partial.map { it + width }
            }
            .map { it.sorted() }
            .toSet()

fun Collection<List<Width>>.cheapest(
    costs: Map<Width, Price>
): Pair<List<Width>, Price> =
    map { it to (it priced costs) }
        .minByOrNull { (_, cost) -> cost }!!

private infix fun List<Width>.priced(costs: Map<Width, Price>) =
    sumOf { costs[it] ?: throw IllegalArgumentException("Invalid cost $it") }

fun main() {
    val ikea = combinations()
    ikea
        .toList()
        .sortedByDescending { it.maxOf { list -> list } }
        .sortedByDescending { it.size }
        .forEachIndexed { i, list ->
            println("#${(i + 1).toString().padStart(3)}: $list")
        }

    val costs = mapOf(50 to 59, 75 to 62, 100 to 90, 120 to 111)
    val (best, price) = ikea.cheapest(costs)

    println("The cheapest combinations costs $price USD: $best")
}

Compiled from "Comparisons.kt"
public final class wardrobe.sal.SalWardrobeKt$main$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public wardrobe.sal.SalWardrobeKt$main$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class java/util/List
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: checkcast     #25                 // class java/lang/Iterable
      12: invokeinterface #29,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      17: astore        5
      19: aload         5
      21: invokeinterface #35,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      26: ifne          37
      29: new           #37                 // class java/util/NoSuchElementException
      32: dup
      33: invokespecial #38                 // Method java/util/NoSuchElementException."<init>":()V
      36: athrow
      37: aload         5
      39: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      44: checkcast     #44                 // class java/lang/Number
      47: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      50: istore        6
      52: iconst_0
      53: istore        7
      55: iload         6
      57: invokestatic  #54                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      60: checkcast     #56                 // class java/lang/Comparable
      63: astore        6
      65: aload         5
      67: invokeinterface #35,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      72: ifeq          122
      75: aload         5
      77: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      82: checkcast     #44                 // class java/lang/Number
      85: invokevirtual #48                 // Method java/lang/Number.intValue:()I
      88: istore        7
      90: iconst_0
      91: istore        8
      93: iload         7
      95: invokestatic  #54                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      98: checkcast     #56                 // class java/lang/Comparable
     101: astore        7
     103: aload         6
     105: aload         7
     107: invokeinterface #60,  2           // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     112: ifge          65
     115: aload         7
     117: astore        6
     119: goto          65
     122: aload         6
     124: checkcast     #50                 // class java/lang/Integer
     127: nop
     128: checkcast     #56                 // class java/lang/Comparable
     131: aload_1
     132: checkcast     #23                 // class java/util/List
     135: astore_3
     136: astore        9
     138: iconst_0
     139: istore        4
     141: aload_3
     142: checkcast     #25                 // class java/lang/Iterable
     145: invokeinterface #29,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     150: astore        5
     152: aload         5
     154: invokeinterface #35,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     159: ifne          170
     162: new           #37                 // class java/util/NoSuchElementException
     165: dup
     166: invokespecial #38                 // Method java/util/NoSuchElementException."<init>":()V
     169: athrow
     170: aload         5
     172: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     177: checkcast     #44                 // class java/lang/Number
     180: invokevirtual #48                 // Method java/lang/Number.intValue:()I
     183: istore        6
     185: iconst_0
     186: istore        7
     188: iload         6
     190: invokestatic  #54                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     193: checkcast     #56                 // class java/lang/Comparable
     196: astore        6
     198: aload         5
     200: invokeinterface #35,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     205: ifeq          255
     208: aload         5
     210: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     215: checkcast     #44                 // class java/lang/Number
     218: invokevirtual #48                 // Method java/lang/Number.intValue:()I
     221: istore        7
     223: iconst_0
     224: istore        8
     226: iload         7
     228: invokestatic  #54                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     231: checkcast     #56                 // class java/lang/Comparable
     234: astore        7
     236: aload         6
     238: aload         7
     240: invokeinterface #60,  2           // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     245: ifge          198
     248: aload         7
     250: astore        6
     252: goto          198
     255: aload         6
     257: checkcast     #50                 // class java/lang/Integer
     260: nop
     261: aload         9
     263: swap
     264: checkcast     #56                 // class java/lang/Comparable
     267: invokestatic  #66                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
     270: ireturn
}

Compiled from "SalWardrobe.kt"
public final class wardrobe.sal.SalWardrobeKt {
  public static final java.util.Set<java.util.List<java.lang.Integer>> combinations(int, java.util.List<java.lang.Integer>);
    Code:
       0: aload_1
       1: ldc           #10                 // String availableSizes
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_0
       7: ifne          19
      10: invokestatic  #22                 // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
      13: invokestatic  #28                 // Method kotlin/collections/SetsKt.setOf:(Ljava/lang/Object;)Ljava/util/Set;
      16: goto          436
      19: aload_1
      20: checkcast     #30                 // class java/lang/Iterable
      23: astore_2
      24: nop
      25: iconst_0
      26: istore_3
      27: aload_2
      28: astore        4
      30: new           #32                 // class java/util/ArrayList
      33: dup
      34: invokespecial #36                 // Method java/util/ArrayList."<init>":()V
      37: checkcast     #38                 // class java/util/Collection
      40: astore        5
      42: iconst_0
      43: istore        6
      45: aload         4
      47: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      52: astore        7
      54: aload         7
      56: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      61: ifeq          113
      64: aload         7
      66: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      71: astore        8
      73: aload         8
      75: checkcast     #54                 // class java/lang/Number
      78: invokevirtual #58                 // Method java/lang/Number.intValue:()I
      81: istore        9
      83: iconst_0
      84: istore        10
      86: iload         9
      88: iload_0
      89: if_icmpgt     96
      92: iconst_1
      93: goto          97
      96: iconst_0
      97: ifeq          54
     100: aload         5
     102: aload         8
     104: invokeinterface #62,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     109: pop
     110: goto          54
     113: aload         5
     115: checkcast     #64                 // class java/util/List
     118: nop
     119: checkcast     #30                 // class java/lang/Iterable
     122: astore_2
     123: nop
     124: iconst_0
     125: istore_3
     126: aload_2
     127: astore        4
     129: new           #32                 // class java/util/ArrayList
     132: dup
     133: invokespecial #36                 // Method java/util/ArrayList."<init>":()V
     136: checkcast     #38                 // class java/util/Collection
     139: astore        5
     141: iconst_0
     142: istore        6
     144: aload         4
     146: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     151: astore        7
     153: aload         7
     155: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     160: ifeq          325
     163: aload         7
     165: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     170: astore        8
     172: aload         8
     174: checkcast     #54                 // class java/lang/Number
     177: invokevirtual #58                 // Method java/lang/Number.intValue:()I
     180: istore        9
     182: iconst_0
     183: istore        10
     185: iload_0
     186: iload         9
     188: isub
     189: istore        11
     191: iload         11
     193: aload_1
     194: invokestatic  #66                 // Method combinations:(ILjava/util/List;)Ljava/util/Set;
     197: astore        12
     199: aload         12
     201: checkcast     #30                 // class java/lang/Iterable
     204: astore        13
     206: iconst_0
     207: istore        14
     209: aload         13
     211: astore        15
     213: new           #32                 // class java/util/ArrayList
     216: dup
     217: aload         13
     219: bipush        10
     221: invokestatic  #70                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     224: invokespecial #73                 // Method java/util/ArrayList."<init>":(I)V
     227: checkcast     #38                 // class java/util/Collection
     230: astore        16
     232: iconst_0
     233: istore        17
     235: aload         15
     237: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     242: astore        18
     244: aload         18
     246: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     251: ifeq          302
     254: aload         18
     256: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     261: astore        19
     263: aload         16
     265: aload         19
     267: checkcast     #64                 // class java/util/List
     270: astore        20
     272: astore        21
     274: iconst_0
     275: istore        22
     277: aload         20
     279: checkcast     #38                 // class java/util/Collection
     282: iload         9
     284: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     287: invokestatic  #83                 // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Object;)Ljava/util/List;
     290: aload         21
     292: swap
     293: invokeinterface #62,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     298: pop
     299: goto          244
     302: aload         16
     304: checkcast     #64                 // class java/util/List
     307: nop
     308: checkcast     #30                 // class java/lang/Iterable
     311: nop
     312: astore        9
     314: aload         5
     316: aload         9
     318: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     321: pop
     322: goto          153
     325: aload         5
     327: checkcast     #64                 // class java/util/List
     330: nop
     331: checkcast     #30                 // class java/lang/Iterable
     334: astore_2
     335: nop
     336: iconst_0
     337: istore_3
     338: aload_2
     339: astore        4
     341: new           #32                 // class java/util/ArrayList
     344: dup
     345: aload_2
     346: bipush        10
     348: invokestatic  #70                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     351: invokespecial #73                 // Method java/util/ArrayList."<init>":(I)V
     354: checkcast     #38                 // class java/util/Collection
     357: astore        5
     359: iconst_0
     360: istore        6
     362: aload         4
     364: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     369: astore        7
     371: aload         7
     373: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     378: ifeq          424
     381: aload         7
     383: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     388: astore        8
     390: aload         5
     392: aload         8
     394: checkcast     #64                 // class java/util/List
     397: astore        9
     399: astore        23
     401: iconst_0
     402: istore        10
     404: aload         9
     406: checkcast     #30                 // class java/lang/Iterable
     409: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.sorted:(Ljava/lang/Iterable;)Ljava/util/List;
     412: aload         23
     414: swap
     415: invokeinterface #62,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     420: pop
     421: goto          371
     424: aload         5
     426: checkcast     #64                 // class java/util/List
     429: nop
     430: checkcast     #30                 // class java/lang/Iterable
     433: invokestatic  #95                 // Method kotlin/collections/CollectionsKt.toSet:(Ljava/lang/Iterable;)Ljava/util/Set;
     436: areturn

  public static java.util.Set combinations$default(int, java.util.List, int, java.lang.Object);
    Code:
       0: iload_2
       1: iconst_1
       2: iand
       3: ifeq          10
       6: sipush        250
       9: istore_0
      10: iload_2
      11: iconst_2
      12: iand
      13: ifeq          64
      16: iconst_4
      17: anewarray     #75                 // class java/lang/Integer
      20: astore        4
      22: aload         4
      24: iconst_0
      25: bipush        50
      27: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      30: aastore
      31: aload         4
      33: iconst_1
      34: bipush        75
      36: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      39: aastore
      40: aload         4
      42: iconst_2
      43: bipush        100
      45: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      48: aastore
      49: aload         4
      51: iconst_3
      52: bipush        120
      54: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      57: aastore
      58: aload         4
      60: invokestatic  #134                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      63: astore_1
      64: iload_0
      65: aload_1
      66: invokestatic  #66                 // Method combinations:(ILjava/util/List;)Ljava/util/Set;
      69: areturn

  public static final kotlin.Pair<java.util.List<java.lang.Integer>, java.lang.Integer> cheapest(java.util.Collection<? extends java.util.List<java.lang.Integer>>, java.util.Map<java.lang.Integer, java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #139                // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #141                // String costs
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #30                 // class java/lang/Iterable
      16: astore_2
      17: iconst_0
      18: istore_3
      19: aload_2
      20: astore        4
      22: new           #32                 // class java/util/ArrayList
      25: dup
      26: aload_2
      27: bipush        10
      29: invokestatic  #70                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      32: invokespecial #73                 // Method java/util/ArrayList."<init>":(I)V
      35: checkcast     #38                 // class java/util/Collection
      38: astore        5
      40: iconst_0
      41: istore        6
      43: aload         4
      45: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      50: astore        7
      52: aload         7
      54: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      59: ifeq          111
      62: aload         7
      64: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      69: astore        8
      71: aload         5
      73: aload         8
      75: checkcast     #64                 // class java/util/List
      78: astore        9
      80: astore        11
      82: iconst_0
      83: istore        10
      85: aload         9
      87: aload         9
      89: aload_1
      90: invokestatic  #145                // Method priced:(Ljava/util/List;Ljava/util/Map;)I
      93: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      96: invokestatic  #151                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      99: aload         11
     101: swap
     102: invokeinterface #62,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     107: pop
     108: goto          52
     111: aload         5
     113: checkcast     #64                 // class java/util/List
     116: nop
     117: checkcast     #30                 // class java/lang/Iterable
     120: astore_2
     121: nop
     122: iconst_0
     123: istore_3
     124: aload_2
     125: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     130: astore        4
     132: aload         4
     134: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     139: ifne          146
     142: aconst_null
     143: goto          260
     146: aload         4
     148: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     153: astore        5
     155: aload         4
     157: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     162: ifne          170
     165: aload         5
     167: goto          260
     170: aload         5
     172: checkcast     #153                // class kotlin/Pair
     175: astore        6
     177: iconst_0
     178: istore        7
     180: aload         6
     182: invokevirtual #156                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     185: checkcast     #54                 // class java/lang/Number
     188: invokevirtual #58                 // Method java/lang/Number.intValue:()I
     191: istore        8
     193: iload         8
     195: istore        6
     197: aload         4
     199: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     204: astore        7
     206: aload         7
     208: checkcast     #153                // class kotlin/Pair
     211: astore        8
     213: iconst_0
     214: istore        9
     216: aload         8
     218: invokevirtual #156                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     221: checkcast     #54                 // class java/lang/Number
     224: invokevirtual #58                 // Method java/lang/Number.intValue:()I
     227: istore        10
     229: iload         10
     231: istore        8
     233: iload         6
     235: iload         8
     237: if_icmple     248
     240: aload         7
     242: astore        5
     244: iload         8
     246: istore        6
     248: aload         4
     250: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     255: ifne          197
     258: aload         5
     260: dup
     261: invokestatic  #160                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     264: checkcast     #153                // class kotlin/Pair
     267: areturn

  private static final int priced(java.util.List<java.lang.Integer>, java.util.Map<java.lang.Integer, java.lang.Integer>);
    Code:
       0: aload_0
       1: checkcast     #30                 // class java/lang/Iterable
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore        4
      15: aload         4
      17: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      22: ifeq          114
      25: aload         4
      27: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      32: astore        5
      34: iload_3
      35: aload         5
      37: checkcast     #54                 // class java/lang/Number
      40: invokevirtual #58                 // Method java/lang/Number.intValue:()I
      43: istore        6
      45: istore        8
      47: iconst_0
      48: istore        7
      50: aload_1
      51: iload         6
      53: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      56: invokeinterface #180,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      61: checkcast     #75                 // class java/lang/Integer
      64: dup
      65: ifnull        74
      68: invokevirtual #181                // Method java/lang/Integer.intValue:()I
      71: goto          103
      74: pop
      75: new           #183                // class java/lang/IllegalArgumentException
      78: dup
      79: new           #185                // class java/lang/StringBuilder
      82: dup
      83: invokespecial #186                // Method java/lang/StringBuilder."<init>":()V
      86: ldc           #188                // String Invalid cost
      88: invokevirtual #192                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      91: iload         6
      93: invokevirtual #195                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      96: invokevirtual #199                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      99: invokespecial #202                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     102: athrow
     103: istore        9
     105: iload         8
     107: iload         9
     109: iadd
     110: istore_3
     111: goto          15
     114: iload_3
     115: ireturn

  public static final void main();
    Code:
       0: iconst_0
       1: aconst_null
       2: iconst_3
       3: aconst_null
       4: invokestatic  #207                // Method combinations$default:(ILjava/util/List;ILjava/lang/Object;)Ljava/util/Set;
       7: astore_0
       8: aload_0
       9: checkcast     #30                 // class java/lang/Iterable
      12: invokestatic  #210                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
      15: checkcast     #30                 // class java/lang/Iterable
      18: astore_1
      19: nop
      20: iconst_0
      21: istore_2
      22: aload_1
      23: new           #212                // class wardrobe/sal/SalWardrobeKt$main$$inlined$sortedByDescending$1
      26: dup
      27: invokespecial #213                // Method wardrobe/sal/SalWardrobeKt$main$$inlined$sortedByDescending$1."<init>":()V
      30: checkcast     #215                // class java/util/Comparator
      33: invokestatic  #219                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      36: checkcast     #30                 // class java/lang/Iterable
      39: astore_1
      40: nop
      41: iconst_0
      42: istore_2
      43: aload_1
      44: new           #221                // class wardrobe/sal/SalWardrobeKt$main$$inlined$sortedByDescending$2
      47: dup
      48: invokespecial #222                // Method wardrobe/sal/SalWardrobeKt$main$$inlined$sortedByDescending$2."<init>":()V
      51: checkcast     #215                // class java/util/Comparator
      54: invokestatic  #219                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      57: checkcast     #30                 // class java/lang/Iterable
      60: astore_1
      61: nop
      62: iconst_0
      63: istore_2
      64: iconst_0
      65: istore_3
      66: aload_1
      67: invokeinterface #42,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      72: astore        4
      74: aload         4
      76: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      81: ifeq          175
      84: aload         4
      86: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      91: astore        5
      93: iload_3
      94: iinc          3, 1
      97: istore        6
      99: iload         6
     101: ifge          107
     104: invokestatic  #225                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     107: iload         6
     109: aload         5
     111: checkcast     #64                 // class java/util/List
     114: astore        7
     116: istore        8
     118: iconst_0
     119: istore        9
     121: new           #185                // class java/lang/StringBuilder
     124: dup
     125: invokespecial #186                // Method java/lang/StringBuilder."<init>":()V
     128: bipush        35
     130: invokevirtual #228                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     133: iload         8
     135: iconst_1
     136: iadd
     137: invokestatic  #233                // Method java/lang/String.valueOf:(I)Ljava/lang/String;
     140: iconst_3
     141: iconst_0
     142: iconst_2
     143: aconst_null
     144: invokestatic  #239                // Method kotlin/text/StringsKt.padStart$default:(Ljava/lang/String;ICILjava/lang/Object;)Ljava/lang/String;
     147: invokevirtual #192                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     150: ldc           #241                // String :
     152: invokevirtual #192                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     155: aload         7
     157: invokevirtual #244                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     160: invokevirtual #199                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     163: getstatic     #250                // Field java/lang/System.out:Ljava/io/PrintStream;
     166: swap
     167: invokevirtual #255                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     170: nop
     171: nop
     172: goto          74
     175: nop
     176: iconst_4
     177: anewarray     #153                // class kotlin/Pair
     180: astore_2
     181: aload_2
     182: iconst_0
     183: bipush        50
     185: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     188: bipush        59
     190: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     193: invokestatic  #151                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     196: aastore
     197: aload_2
     198: iconst_1
     199: bipush        75
     201: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     204: bipush        62
     206: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     209: invokestatic  #151                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     212: aastore
     213: aload_2
     214: iconst_2
     215: bipush        100
     217: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     220: bipush        90
     222: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     225: invokestatic  #151                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     228: aastore
     229: aload_2
     230: iconst_3
     231: bipush        120
     233: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     236: bipush        111
     238: invokestatic  #79                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     241: invokestatic  #151                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     244: aastore
     245: aload_2
     246: invokestatic  #261                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     249: astore_1
     250: aload_0
     251: checkcast     #38                 // class java/util/Collection
     254: aload_1
     255: invokestatic  #263                // Method cheapest:(Ljava/util/Collection;Ljava/util/Map;)Lkotlin/Pair;
     258: astore_2
     259: aload_2
     260: invokevirtual #266                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     263: checkcast     #64                 // class java/util/List
     266: astore_3
     267: aload_2
     268: invokevirtual #156                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     271: checkcast     #54                 // class java/lang/Number
     274: invokevirtual #58                 // Method java/lang/Number.intValue:()I
     277: istore        4
     279: new           #185                // class java/lang/StringBuilder
     282: dup
     283: invokespecial #186                // Method java/lang/StringBuilder."<init>":()V
     286: ldc_w         #268                // String The cheapest combinations costs
     289: invokevirtual #192                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     292: iload         4
     294: invokevirtual #195                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     297: ldc_w         #270                // String  USD:
     300: invokevirtual #192                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     303: aload_3
     304: invokevirtual #244                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     307: invokevirtual #199                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     310: getstatic     #250                // Field java/lang/System.out:Ljava/io/PrintStream;
     313: swap
     314: invokevirtual #255                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     317: return

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

Compiled from "Comparisons.kt"
public final class wardrobe.sal.SalWardrobeKt$main$$inlined$sortedByDescending$2<T> implements java.util.Comparator {
  public wardrobe.sal.SalWardrobeKt$main$$inlined$sortedByDescending$2();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class java/util/List
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokeinterface #27,  1           // InterfaceMethod java/util/List.size:()I
      14: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      17: checkcast     #35                 // class java/lang/Comparable
      20: aload_1
      21: checkcast     #23                 // class java/util/List
      24: astore_3
      25: astore        5
      27: iconst_0
      28: istore        4
      30: aload_3
      31: invokeinterface #27,  1           // InterfaceMethod java/util/List.size:()I
      36: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      39: aload         5
      41: swap
      42: checkcast     #35                 // class java/lang/Comparable
      45: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      48: ireturn
}