package io.rbrincke.dice.core

/**
 * Sets up a solver that is able to find allocations of [labels] that lead to non-transitive
 * elements. The number of resulting elements equals the size of [labelGroupSizes], and each
 * element will contain precisely the number specified in [labelGroupSizes].
 *
 * @param labels labels that are to be allocated to elements
 * @param labelGroupSizes the group sizes in which labels should be allocated (sum of all elements must equal the size of [labels])
 * @param elementCreator function that describes how to to create an element from a list of [labels]
 */
class Solver<S, T : Element<T>>(
    private val labels: List<S>,
    private val labelGroupSizes: List<Int>,
    private val elementCreator: (List<S>) -> T
) {
    init {
        check(labelGroupSizes.isNotEmpty())
        check(labelGroupSizes.all { it > 0 }) {
            "Input set sizes must all be strictly positive."
        }

        check(labelGroupSizes.sum() == labels.size) {
            "Input set element count does not equal the total of combination sizes."
        }
    }

    private fun permutationToElementSet(permutation: List<Int>): Combination<T> {
        val target = labelGroupSizes.mapIndexed { index, i ->
            index to ArrayList<S>(i)
        }.toMap()

        permutation.mapIndexed { index, i ->
            target.getValue(i).add(labels[index])
        }

        val elements = target.values.map { elementCreator.invoke(it) }
        return Combination(elements)
    }

    /**
     * Find any non-transitive [Combination]s.
     */
    fun solve(): List<Combination<T>> {
        // Perform permutation on a mask to avoid duplicate groupings due
        // to group-internal ordering differences.
        val mask = mutableListOf<Int>()
        labelGroupSizes.forEachIndexed { idx, count ->
            repeat(count) { mask.add(idx) }
        }

        check(mask.size == labels.size)

        // Fix the first item to slot 0 to avoid identical solutions
        // with rotated positions.
        return MultisetPermutationIterator(mask.drop(1))
            .asSequence()
            .map { listOf(0) + it }
            .map(::permutationToElementSet)
            .filter { it.isNonTransitive() }
            .toList()
    }
}

Compiled from "Solver.kt"
public final class io.rbrincke.dice.core.Solver<S, T extends io.rbrincke.dice.core.Element<? super T>> {
  private final java.util.List<S> labels;

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

  private final kotlin.jvm.functions.Function1<java.util.List<? extends S>, T> elementCreator;

  public io.rbrincke.dice.core.Solver(java.util.List<? extends S>, java.util.List<java.lang.Integer>, kotlin.jvm.functions.Function1<? super java.util.List<? extends S>, ? extends T>);
    Code:
       0: aload_1
       1: ldc           #11                 // String labels
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #19                 // String labelGroupSizes
       9: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_3
      13: ldc           #21                 // String elementCreator
      15: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload_0
      19: invokespecial #24                 // Method java/lang/Object."<init>":()V
      22: aload_0
      23: aload_1
      24: putfield      #27                 // Field labels:Ljava/util/List;
      27: aload_0
      28: aload_2
      29: putfield      #29                 // Field labelGroupSizes:Ljava/util/List;
      32: aload_0
      33: aload_3
      34: putfield      #32                 // Field elementCreator:Lkotlin/jvm/functions/Function1;
      37: nop
      38: nop
      39: aload_0
      40: getfield      #29                 // Field labelGroupSizes:Ljava/util/List;
      43: checkcast     #34                 // class java/util/Collection
      46: invokeinterface #38,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      51: ifne          58
      54: iconst_1
      55: goto          59
      58: iconst_0
      59: ifne          72
      62: new           #40                 // class java/lang/IllegalStateException
      65: dup
      66: ldc           #42                 // String Check failed.
      68: invokespecial #45                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      71: athrow
      72: aload_0
      73: getfield      #29                 // Field labelGroupSizes:Ljava/util/List;
      76: checkcast     #47                 // class java/lang/Iterable
      79: astore        4
      81: iconst_0
      82: istore        5
      84: aload         4
      86: instanceof    #34                 // class java/util/Collection
      89: ifeq          109
      92: aload         4
      94: checkcast     #34                 // class java/util/Collection
      97: invokeinterface #38,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     102: ifeq          109
     105: iconst_1
     106: goto          168
     109: aload         4
     111: invokeinterface #51,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     116: astore        6
     118: aload         6
     120: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     125: ifeq          167
     128: aload         6
     130: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     135: astore        7
     137: aload         7
     139: checkcast     #62                 // class java/lang/Number
     142: invokevirtual #66                 // Method java/lang/Number.intValue:()I
     145: istore        8
     147: iconst_0
     148: istore        9
     150: iload         8
     152: ifle          159
     155: iconst_1
     156: goto          160
     159: iconst_0
     160: ifne          118
     163: iconst_0
     164: goto          168
     167: iconst_1
     168: ifne          191
     171: iconst_0
     172: istore        5
     174: ldc           #68                 // String Input set sizes must all be strictly positive.
     176: astore        5
     178: new           #40                 // class java/lang/IllegalStateException
     181: dup
     182: aload         5
     184: invokevirtual #72                 // Method java/lang/Object.toString:()Ljava/lang/String;
     187: invokespecial #45                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     190: athrow
     191: aload_0
     192: getfield      #29                 // Field labelGroupSizes:Ljava/util/List;
     195: checkcast     #47                 // class java/lang/Iterable
     198: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     201: aload_0
     202: getfield      #27                 // Field labels:Ljava/util/List;
     205: invokeinterface #83,  1           // InterfaceMethod java/util/List.size:()I
     210: if_icmpne     217
     213: iconst_1
     214: goto          218
     217: iconst_0
     218: ifne          241
     221: iconst_0
     222: istore        5
     224: ldc           #85                 // String Input set element count does not equal the total of combination sizes.
     226: astore        5
     228: new           #40                 // class java/lang/IllegalStateException
     231: dup
     232: aload         5
     234: invokevirtual #72                 // Method java/lang/Object.toString:()Ljava/lang/String;
     237: invokespecial #45                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     240: athrow
     241: nop
     242: return

  private final io.rbrincke.dice.core.Combination<T> permutationToElementSet(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: getfield      #29                 // Field labelGroupSizes:Ljava/util/List;
       4: checkcast     #47                 // class java/lang/Iterable
       7: astore_3
       8: iconst_0
       9: istore        4
      11: aload_3
      12: astore        5
      14: new           #104                // class java/util/ArrayList
      17: dup
      18: aload_3
      19: bipush        10
      21: invokestatic  #108                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      24: invokespecial #111                // Method java/util/ArrayList."<init>":(I)V
      27: checkcast     #34                 // class java/util/Collection
      30: astore        6
      32: iconst_0
      33: istore        7
      35: iconst_0
      36: istore        8
      38: aload         5
      40: invokeinterface #51,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      45: astore        9
      47: aload         9
      49: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      54: ifeq          131
      57: aload         9
      59: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      64: astore        10
      66: aload         6
      68: iload         8
      70: iinc          8, 1
      73: istore        11
      75: iload         11
      77: ifge          83
      80: invokestatic  #114                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
      83: iload         11
      85: aload         10
      87: checkcast     #62                 // class java/lang/Number
      90: invokevirtual #66                 // Method java/lang/Number.intValue:()I
      93: istore        12
      95: istore        13
      97: astore        15
      99: iconst_0
     100: istore        14
     102: iload         13
     104: invokestatic  #120                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     107: new           #104                // class java/util/ArrayList
     110: dup
     111: iload         12
     113: invokespecial #111                // Method java/util/ArrayList."<init>":(I)V
     116: invokestatic  #126                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     119: aload         15
     121: swap
     122: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     127: pop
     128: goto          47
     131: aload         6
     133: checkcast     #80                 // class java/util/List
     136: nop
     137: checkcast     #47                 // class java/lang/Iterable
     140: invokestatic  #136                // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
     143: astore_2
     144: aload_1
     145: checkcast     #47                 // class java/lang/Iterable
     148: astore_3
     149: iconst_0
     150: istore        4
     152: aload_3
     153: astore        5
     155: new           #104                // class java/util/ArrayList
     158: dup
     159: aload_3
     160: bipush        10
     162: invokestatic  #108                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     165: invokespecial #111                // Method java/util/ArrayList."<init>":(I)V
     168: checkcast     #34                 // class java/util/Collection
     171: astore        6
     173: iconst_0
     174: istore        7
     176: iconst_0
     177: istore        8
     179: aload         5
     181: invokeinterface #51,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     186: astore        9
     188: aload         9
     190: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     195: ifeq          284
     198: aload         9
     200: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     205: astore        10
     207: aload         6
     209: iload         8
     211: iinc          8, 1
     214: istore        11
     216: iload         11
     218: ifge          224
     221: invokestatic  #114                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     224: iload         11
     226: aload         10
     228: checkcast     #62                 // class java/lang/Number
     231: invokevirtual #66                 // Method java/lang/Number.intValue:()I
     234: istore        12
     236: istore        13
     238: astore        15
     240: iconst_0
     241: istore        14
     243: aload_2
     244: iload         12
     246: invokestatic  #120                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     249: invokestatic  #140                // Method kotlin/collections/MapsKt.getValue:(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
     252: checkcast     #104                // class java/util/ArrayList
     255: aload_0
     256: getfield      #27                 // Field labels:Ljava/util/List;
     259: iload         13
     261: invokeinterface #144,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     266: invokevirtual #145                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     269: invokestatic  #150                // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
     272: aload         15
     274: swap
     275: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     280: pop
     281: goto          188
     284: aload         6
     286: checkcast     #80                 // class java/util/List
     289: nop
     290: pop
     291: aload_2
     292: invokeinterface #156,  1          // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
     297: checkcast     #47                 // class java/lang/Iterable
     300: astore        4
     302: iconst_0
     303: istore        5
     305: aload         4
     307: astore        6
     309: new           #104                // class java/util/ArrayList
     312: dup
     313: aload         4
     315: bipush        10
     317: invokestatic  #108                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     320: invokespecial #111                // Method java/util/ArrayList."<init>":(I)V
     323: checkcast     #34                 // class java/util/Collection
     326: astore        7
     328: iconst_0
     329: istore        8
     331: aload         6
     333: invokeinterface #51,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     338: astore        9
     340: aload         9
     342: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     347: ifeq          399
     350: aload         9
     352: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     357: astore        10
     359: aload         7
     361: aload         10
     363: checkcast     #104                // class java/util/ArrayList
     366: astore        11
     368: astore        15
     370: iconst_0
     371: istore        12
     373: aload_0
     374: getfield      #32                 // Field elementCreator:Lkotlin/jvm/functions/Function1;
     377: aload         11
     379: invokeinterface #160,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     384: checkcast     #162                // class io/rbrincke/dice/core/Element
     387: aload         15
     389: swap
     390: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     395: pop
     396: goto          340
     399: aload         7
     401: checkcast     #80                 // class java/util/List
     404: nop
     405: astore_3
     406: new           #164                // class io/rbrincke/dice/core/Combination
     409: dup
     410: aload_3
     411: invokespecial #167                // Method io/rbrincke/dice/core/Combination."<init>":(Ljava/util/List;)V
     414: areturn

  public final java.util.List<io.rbrincke.dice.core.Combination<T>> solve();
    Code:
       0: new           #104                // class java/util/ArrayList
       3: dup
       4: invokespecial #193                // Method java/util/ArrayList."<init>":()V
       7: checkcast     #80                 // class java/util/List
      10: astore_1
      11: aload_0
      12: getfield      #29                 // Field labelGroupSizes:Ljava/util/List;
      15: checkcast     #47                 // class java/lang/Iterable
      18: astore_2
      19: iconst_0
      20: istore_3
      21: iconst_0
      22: istore        4
      24: aload_2
      25: invokeinterface #51,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          123
      42: aload         5
      44: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      49: astore        6
      51: iload         4
      53: iinc          4, 1
      56: istore        7
      58: iload         7
      60: ifge          66
      63: invokestatic  #114                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
      66: iload         7
      68: aload         6
      70: checkcast     #62                 // class java/lang/Number
      73: invokevirtual #66                 // Method java/lang/Number.intValue:()I
      76: istore        8
      78: istore        9
      80: iconst_0
      81: istore        10
      83: iconst_0
      84: istore        11
      86: iload         11
      88: iload         8
      90: if_icmpge     118
      93: iload         11
      95: istore        12
      97: iconst_0
      98: istore        13
     100: aload_1
     101: iload         9
     103: invokestatic  #120                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     106: invokeinterface #194,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     111: pop
     112: iinc          11, 1
     115: goto          86
     118: nop
     119: nop
     120: goto          32
     123: nop
     124: aload_1
     125: invokeinterface #83,  1           // InterfaceMethod java/util/List.size:()I
     130: aload_0
     131: getfield      #27                 // Field labels:Ljava/util/List;
     134: invokeinterface #83,  1           // InterfaceMethod java/util/List.size:()I
     139: if_icmpne     146
     142: iconst_1
     143: goto          147
     146: iconst_0
     147: ifne          160
     150: new           #40                 // class java/lang/IllegalStateException
     153: dup
     154: ldc           #42                 // String Check failed.
     156: invokespecial #45                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     159: athrow
     160: new           #196                // class io/rbrincke/dice/core/MultisetPermutationIterator
     163: dup
     164: aload_1
     165: checkcast     #47                 // class java/lang/Iterable
     168: iconst_1
     169: invokestatic  #200                // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
     172: checkcast     #34                 // class java/util/Collection
     175: invokespecial #203                // Method io/rbrincke/dice/core/MultisetPermutationIterator."<init>":(Ljava/util/Collection;)V
     178: checkcast     #53                 // class java/util/Iterator
     181: invokestatic  #209                // Method kotlin/sequences/SequencesKt.asSequence:(Ljava/util/Iterator;)Lkotlin/sequences/Sequence;
     184: invokedynamic #226,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     189: invokestatic  #230                // Method kotlin/sequences/SequencesKt.map:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
     192: new           #232                // class io/rbrincke/dice/core/Solver$solve$3
     195: dup
     196: aload_0
     197: invokespecial #235                // Method io/rbrincke/dice/core/Solver$solve$3."<init>":(Ljava/lang/Object;)V
     200: checkcast     #99                 // class kotlin/jvm/functions/Function1
     203: invokestatic  #230                // Method kotlin/sequences/SequencesKt.map:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
     206: invokedynamic #243,  0            // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function1;
     211: invokestatic  #246                // Method kotlin/sequences/SequencesKt.filter:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
     214: invokestatic  #250                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
     217: areturn

  private static final java.util.List solve$lambda$8(java.util.List);
    Code:
       0: aload_0
       1: ldc_w         #260                // String it
       4: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: iconst_0
       8: invokestatic  #120                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      11: invokestatic  #264                // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      14: checkcast     #34                 // class java/util/Collection
      17: aload_0
      18: checkcast     #47                 // class java/lang/Iterable
      21: invokestatic  #268                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
      24: areturn

  private static final boolean solve$lambda$9(io.rbrincke.dice.core.Combination);
    Code:
       0: aload_0
       1: ldc_w         #260                // String it
       4: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #271                // Method io/rbrincke/dice/core/Combination.isNonTransitive:()Z
      11: ireturn

  public static final io.rbrincke.dice.core.Combination access$permutationToElementSet(io.rbrincke.dice.core.Solver, java.util.List);
    Code:
       0: aload_0
       1: aload_1
       2: invokespecial #276                // Method permutationToElementSet:(Ljava/util/List;)Lio/rbrincke/dice/core/Combination;
       5: areturn
}

Compiled from "Solver.kt"
final class io.rbrincke.dice.core.Solver$solve$3 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function1<java.util.List<? extends java.lang.Integer>, io.rbrincke.dice.core.Combination<T>> {
  io.rbrincke.dice.core.Solver$solve$3(java.lang.Object);
    Code:
       0: aload_0
       1: iconst_1
       2: aload_1
       3: ldc           #11                 // class io/rbrincke/dice/core/Solver
       5: ldc           #13                 // String permutationToElementSet
       7: ldc           #15                 // String permutationToElementSet(Ljava/util/List;)Lio/rbrincke/dice/core/Combination;
       9: iconst_0
      10: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      13: return

  public final io.rbrincke.dice.core.Combination<T> invoke(java.util.List<java.lang.Integer>);
    Code:
       0: aload_1
       1: ldc           #27                 // String p0
       3: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: getfield      #35                 // Field receiver:Ljava/lang/Object;
      10: checkcast     #11                 // class io/rbrincke/dice/core/Solver
      13: aload_1
      14: invokestatic  #39                 // Method io/rbrincke/dice/core/Solver.access$permutationToElementSet:(Lio/rbrincke/dice/core/Solver;Ljava/util/List;)Lio/rbrincke/dice/core/Combination;
      17: areturn

  public java.lang.Object invoke(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #43                 // class java/util/List
       5: invokevirtual #45                 // Method invoke:(Ljava/util/List;)Lio/rbrincke/dice/core/Combination;
       8: areturn
}


package io.rbrincke.dice.core

/**
 * Multiset permutation iterator. Not thread safe.
 *
 * See *"Loopless Generation of Multiset Permutations using a Constant Number
 * of Variables by Prefix Shifts."*, <NAME>, 2009.
 */
class MultisetPermutationIterator<E : Comparable<E>>(input: Collection<E>) : Iterator<List<E>> {
    private val nodes: List<Node<E>>

    private var head: Node<E>
    private var i: Node<E>? = null
    private var afteri: Node<E>

    private var pristine = true

    init {
        check(input.isNotEmpty())

        nodes = initializeNodeList(input)
        head = nodes[0]

        if (input.size > 1) {
            i = nodes[nodes.size - 2]
        }

        afteri = nodes[nodes.size - 1]
    }

    private fun initializeNodeList(input: Collection<E>): List<Node<E>> {
        val nodes = input.reversed().map { Node(it) }.toList()

        for (i in 0 until nodes.size - 1) {
            nodes[i].next = nodes[i + 1]
        }

        return nodes
    }

    /**
     * Returns `true` if another permutation is available. (In other words, returns
     * true if the next call to [next] would return a permutation rather than
     * throwing an exception).
     */
    override fun hasNext(): Boolean {
        return pristine || afteri.next != null || afteri.value < head.value
    }

    /**
     * Returns the next permutation.
     * @throws NoSuchElementException if there are no more permutations
     */
    override fun next(): List<E> {
        if (!hasNext()) {
            throw NoSuchElementException()
        }

        if (pristine) {
            pristine = false
            return visit(head)
        }

        val afteriNext = afteri.next
        val beforek: Node<E> = if (afteriNext != null && i!!.value >= afteriNext.value) {
            afteri
        } else {
            i!!
        }

        val k = beforek.next
        checkNotNull(k)

        beforek.next = k.next
        k.next = head

        if (k.value < head.value) {
            i = k
        }

        afteri = i!!.next!!
        head = k

        return visit(head)
    }

    private fun visit(node: Node<E>): List<E> {
        val values = ArrayList<E>(nodes.size)

        values.add(node.value)

        var current = node
        while (current.next != null) {
            current = current.next!!
            values.add(current.value)
        }

        return values
    }
}

private class Node<E : Comparable<E>>(val value: E) {
    var next: Node<E>? = null
}

Compiled from "MultisetPermutationIterator.kt"
public final class io.rbrincke.dice.core.MultisetPermutationIterator<E extends java.lang.Comparable<? super E>> implements java.util.Iterator<java.util.List<? extends E>>, kotlin.jvm.internal.markers.KMappedMarker {
  private final java.util.List<io.rbrincke.dice.core.Node<E>> nodes;

  private io.rbrincke.dice.core.Node<E> head;

  private io.rbrincke.dice.core.Node<E> i;

  private io.rbrincke.dice.core.Node<E> afteri;

  private boolean pristine;

  public io.rbrincke.dice.core.MultisetPermutationIterator(java.util.Collection<? extends E>);
    Code:
       0: aload_1
       1: ldc           #15                 // String input
       3: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #24                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: iconst_1
      12: putfield      #28                 // Field pristine:Z
      15: nop
      16: nop
      17: aload_1
      18: invokeinterface #34,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      23: ifne          30
      26: iconst_1
      27: goto          31
      30: iconst_0
      31: ifne          44
      34: new           #36                 // class java/lang/IllegalStateException
      37: dup
      38: ldc           #38                 // String Check failed.
      40: invokespecial #41                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      43: athrow
      44: aload_0
      45: aload_0
      46: aload_1
      47: invokespecial #45                 // Method initializeNodeList:(Ljava/util/Collection;)Ljava/util/List;
      50: putfield      #49                 // Field nodes:Ljava/util/List;
      53: aload_0
      54: aload_0
      55: getfield      #49                 // Field nodes:Ljava/util/List;
      58: iconst_0
      59: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      64: checkcast     #57                 // class io/rbrincke/dice/core/Node
      67: putfield      #61                 // Field head:Lio/rbrincke/dice/core/Node;
      70: aload_1
      71: invokeinterface #65,  1           // InterfaceMethod java/util/Collection.size:()I
      76: iconst_1
      77: if_icmple     107
      80: aload_0
      81: aload_0
      82: getfield      #49                 // Field nodes:Ljava/util/List;
      85: aload_0
      86: getfield      #49                 // Field nodes:Ljava/util/List;
      89: invokeinterface #66,  1           // InterfaceMethod java/util/List.size:()I
      94: iconst_2
      95: isub
      96: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     101: checkcast     #57                 // class io/rbrincke/dice/core/Node
     104: putfield      #69                 // Field i:Lio/rbrincke/dice/core/Node;
     107: aload_0
     108: aload_0
     109: getfield      #49                 // Field nodes:Ljava/util/List;
     112: aload_0
     113: getfield      #49                 // Field nodes:Ljava/util/List;
     116: invokeinterface #66,  1           // InterfaceMethod java/util/List.size:()I
     121: iconst_1
     122: isub
     123: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     128: checkcast     #57                 // class io/rbrincke/dice/core/Node
     131: putfield      #72                 // Field afteri:Lio/rbrincke/dice/core/Node;
     134: nop
     135: return

  private final java.util.List<io.rbrincke.dice.core.Node<E>> initializeNodeList(java.util.Collection<? extends E>);
    Code:
       0: aload_1
       1: checkcast     #78                 // class java/lang/Iterable
       4: invokestatic  #84                 // Method kotlin/collections/CollectionsKt.reversed:(Ljava/lang/Iterable;)Ljava/util/List;
       7: checkcast     #78                 // class java/lang/Iterable
      10: astore_3
      11: iconst_0
      12: istore        4
      14: aload_3
      15: astore        5
      17: new           #86                 // class java/util/ArrayList
      20: dup
      21: aload_3
      22: bipush        10
      24: invokestatic  #90                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      27: invokespecial #93                 // Method java/util/ArrayList."<init>":(I)V
      30: checkcast     #30                 // class java/util/Collection
      33: astore        6
      35: iconst_0
      36: istore        7
      38: aload         5
      40: invokeinterface #97,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      45: astore        8
      47: aload         8
      49: invokeinterface #100,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      54: ifeq          101
      57: aload         8
      59: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      64: astore        9
      66: aload         6
      68: aload         9
      70: checkcast     #106                // class java/lang/Comparable
      73: astore        10
      75: astore        12
      77: iconst_0
      78: istore        11
      80: new           #57                 // class io/rbrincke/dice/core/Node
      83: dup
      84: aload         10
      86: invokespecial #109                // Method io/rbrincke/dice/core/Node."<init>":(Ljava/lang/Comparable;)V
      89: aload         12
      91: swap
      92: invokeinterface #113,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      97: pop
      98: goto          47
     101: aload         6
     103: checkcast     #51                 // class java/util/List
     106: nop
     107: checkcast     #78                 // class java/lang/Iterable
     110: invokestatic  #116                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     113: astore_2
     114: iconst_0
     115: istore_3
     116: aload_2
     117: invokeinterface #66,  1           // InterfaceMethod java/util/List.size:()I
     122: iconst_1
     123: isub
     124: istore        4
     126: iload_3
     127: iload         4
     129: if_icmpge     163
     132: aload_2
     133: iload_3
     134: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     139: checkcast     #57                 // class io/rbrincke/dice/core/Node
     142: aload_2
     143: iload_3
     144: iconst_1
     145: iadd
     146: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     151: checkcast     #57                 // class io/rbrincke/dice/core/Node
     154: invokevirtual #120                // Method io/rbrincke/dice/core/Node.setNext:(Lio/rbrincke/dice/core/Node;)V
     157: iinc          3, 1
     160: goto          126
     163: aload_2
     164: areturn

  public boolean hasNext();
    Code:
       0: aload_0
       1: getfield      #28                 // Field pristine:Z
       4: ifne          39
       7: aload_0
       8: getfield      #72                 // Field afteri:Lio/rbrincke/dice/core/Node;
      11: invokevirtual #136                // Method io/rbrincke/dice/core/Node.getNext:()Lio/rbrincke/dice/core/Node;
      14: ifnonnull     39
      17: aload_0
      18: getfield      #72                 // Field afteri:Lio/rbrincke/dice/core/Node;
      21: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
      24: aload_0
      25: getfield      #61                 // Field head:Lio/rbrincke/dice/core/Node;
      28: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
      31: invokeinterface #144,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      36: ifge          43
      39: iconst_1
      40: goto          44
      43: iconst_0
      44: ireturn

  public java.util.List<E> next();
    Code:
       0: aload_0
       1: invokevirtual #147                // Method hasNext:()Z
       4: ifne          15
       7: new           #149                // class java/util/NoSuchElementException
      10: dup
      11: invokespecial #150                // Method java/util/NoSuchElementException."<init>":()V
      14: athrow
      15: aload_0
      16: getfield      #28                 // Field pristine:Z
      19: ifeq          36
      22: aload_0
      23: iconst_0
      24: putfield      #28                 // Field pristine:Z
      27: aload_0
      28: aload_0
      29: getfield      #61                 // Field head:Lio/rbrincke/dice/core/Node;
      32: invokespecial #154                // Method visit:(Lio/rbrincke/dice/core/Node;)Ljava/util/List;
      35: areturn
      36: aload_0
      37: getfield      #72                 // Field afteri:Lio/rbrincke/dice/core/Node;
      40: invokevirtual #136                // Method io/rbrincke/dice/core/Node.getNext:()Lio/rbrincke/dice/core/Node;
      43: astore_1
      44: aload_1
      45: ifnull        78
      48: aload_0
      49: getfield      #69                 // Field i:Lio/rbrincke/dice/core/Node;
      52: dup
      53: invokestatic  #158                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      56: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
      59: aload_1
      60: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
      63: invokeinterface #144,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      68: iflt          78
      71: aload_0
      72: getfield      #72                 // Field afteri:Lio/rbrincke/dice/core/Node;
      75: goto          86
      78: aload_0
      79: getfield      #69                 // Field i:Lio/rbrincke/dice/core/Node;
      82: dup
      83: invokestatic  #158                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      86: astore_2
      87: aload_2
      88: invokevirtual #136                // Method io/rbrincke/dice/core/Node.getNext:()Lio/rbrincke/dice/core/Node;
      91: astore_3
      92: aload_3
      93: dup
      94: ifnonnull     115
      97: pop
      98: ldc           #160                // String Required value was null.
     100: astore        4
     102: new           #36                 // class java/lang/IllegalStateException
     105: dup
     106: aload         4
     108: invokevirtual #164                // Method java/lang/Object.toString:()Ljava/lang/String;
     111: invokespecial #41                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     114: athrow
     115: pop
     116: aload_2
     117: aload_3
     118: invokevirtual #136                // Method io/rbrincke/dice/core/Node.getNext:()Lio/rbrincke/dice/core/Node;
     121: invokevirtual #120                // Method io/rbrincke/dice/core/Node.setNext:(Lio/rbrincke/dice/core/Node;)V
     124: aload_3
     125: aload_0
     126: getfield      #61                 // Field head:Lio/rbrincke/dice/core/Node;
     129: invokevirtual #120                // Method io/rbrincke/dice/core/Node.setNext:(Lio/rbrincke/dice/core/Node;)V
     132: aload_3
     133: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
     136: aload_0
     137: getfield      #61                 // Field head:Lio/rbrincke/dice/core/Node;
     140: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
     143: invokeinterface #144,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     148: ifge          156
     151: aload_0
     152: aload_3
     153: putfield      #69                 // Field i:Lio/rbrincke/dice/core/Node;
     156: aload_0
     157: aload_0
     158: getfield      #69                 // Field i:Lio/rbrincke/dice/core/Node;
     161: dup
     162: invokestatic  #158                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     165: invokevirtual #136                // Method io/rbrincke/dice/core/Node.getNext:()Lio/rbrincke/dice/core/Node;
     168: dup
     169: invokestatic  #158                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     172: putfield      #72                 // Field afteri:Lio/rbrincke/dice/core/Node;
     175: aload_0
     176: aload_3
     177: putfield      #61                 // Field head:Lio/rbrincke/dice/core/Node;
     180: aload_0
     181: aload_0
     182: getfield      #61                 // Field head:Lio/rbrincke/dice/core/Node;
     185: invokespecial #154                // Method visit:(Lio/rbrincke/dice/core/Node;)Ljava/util/List;
     188: areturn

  private final java.util.List<E> visit(io.rbrincke.dice.core.Node<E>);
    Code:
       0: new           #86                 // class java/util/ArrayList
       3: dup
       4: aload_0
       5: getfield      #49                 // Field nodes:Ljava/util/List;
       8: invokeinterface #66,  1           // InterfaceMethod java/util/List.size:()I
      13: invokespecial #93                 // Method java/util/ArrayList."<init>":(I)V
      16: astore_2
      17: aload_2
      18: aload_1
      19: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
      22: invokevirtual #169                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      25: pop
      26: aload_1
      27: astore_3
      28: aload_3
      29: invokevirtual #136                // Method io/rbrincke/dice/core/Node.getNext:()Lio/rbrincke/dice/core/Node;
      32: ifnull        56
      35: aload_3
      36: invokevirtual #136                // Method io/rbrincke/dice/core/Node.getNext:()Lio/rbrincke/dice/core/Node;
      39: dup
      40: invokestatic  #158                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      43: astore_3
      44: aload_2
      45: aload_3
      46: invokevirtual #140                // Method io/rbrincke/dice/core/Node.getValue:()Ljava/lang/Comparable;
      49: invokevirtual #169                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      52: pop
      53: goto          28
      56: aload_2
      57: checkcast     #51                 // class java/util/List
      60: areturn

  public void remove();
    Code:
       0: new           #176                // class java/lang/UnsupportedOperationException
       3: dup
       4: ldc           #178                // String Operation is not supported for read-only collection
       6: invokespecial #179                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
       9: athrow

  public java.lang.Object next();
    Code:
       0: aload_0
       1: invokevirtual #181                // Method next:()Ljava/util/List;
       4: areturn
}


package io.rbrincke.dice.core

class Combination<T : Element<T>>(private val elements: List<T>) {
    init {
        check(elements.isNotEmpty()) { "Elements may not be empty." }
    }

    /**
     * Matches element 1 to 2, ..., N - 1 to N, N to 1.
     */
    private val elementPairs = elements.mapIndexed { currentIdx, current ->
        val other = elements[(currentIdx + 1) % elements.size]
        current to other
    }

    /**
     * For the N elements in this set, compute the probability that die 1 beats die 2,
     * ..., N - 1 beats N, N beats 1.
     */
    private val dominanceProbabilities = elementPairs.map { (current, other) ->
        current.beats(other)
    }

    val elementPairDominanceProbabilities = elementPairs.zip(dominanceProbabilities)

    /**
     * True if element 1 beats element 2, ..., N - 1 beats N, N beats 1, false otherwise.
     */
    fun isNonTransitive() = dominanceProbabilities.all { v -> v > 0.5 }

    /**
     * Least of the probabilities that element 1 beats element 2, ..., N - 1 beats N, N beats 1.
     */
    fun leastDominance() = dominanceProbabilities.minOrNull() ?: throw IllegalStateException("Empty set.")

    /**
     * Probability that element 1 beats element 2, ..., N - 1 beats N, N beats 1.
     */
    fun dominance() = dominanceProbabilities.toList()

    /**
     * Pretty prints this combination.
     */
    fun prettyPrint() = elementPairDominanceProbabilities.joinToString { (elements, probability) ->
        val (current, other) = elements
        "$current beats $other with probability $probability"
    }
}

interface Element<in E> {
    /**
     * Probability that this element beats the other element [E]. If draws are possible,
     * they are assumed to be resolved by a coin toss.
     */
    fun beats(other: E): Double
}

Compiled from "Combination.kt"
public final class io.rbrincke.dice.core.Combination<T extends io.rbrincke.dice.core.Element<? super T>> {
  private final java.util.List<T> elements;

  private final java.util.List<kotlin.Pair<T, T>> elementPairs;

  private final java.util.List<java.lang.Double> dominanceProbabilities;

  private final java.util.List<kotlin.Pair<kotlin.Pair<T, T>, java.lang.Double>> elementPairDominanceProbabilities;

  public io.rbrincke.dice.core.Combination(java.util.List<? extends T>);
    Code:
       0: aload_1
       1: ldc           #11                 // String elements
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #20                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: aload_1
      12: putfield      #23                 // Field elements:Ljava/util/List;
      15: nop
      16: aload_0
      17: getfield      #23                 // Field elements:Ljava/util/List;
      20: checkcast     #25                 // class java/util/Collection
      23: invokeinterface #29,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      28: ifne          35
      31: iconst_1
      32: goto          36
      35: iconst_0
      36: ifne          56
      39: iconst_0
      40: istore_3
      41: ldc           #31                 // String Elements may not be empty.
      43: astore_3
      44: new           #33                 // class java/lang/IllegalStateException
      47: dup
      48: aload_3
      49: invokevirtual #37                 // Method java/lang/Object.toString:()Ljava/lang/String;
      52: invokespecial #40                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      55: athrow
      56: nop
      57: aload_0
      58: aload_0
      59: getfield      #23                 // Field elements:Ljava/util/List;
      62: checkcast     #42                 // class java/lang/Iterable
      65: astore_2
      66: astore        15
      68: iconst_0
      69: istore_3
      70: aload_2
      71: astore        4
      73: new           #44                 // class java/util/ArrayList
      76: dup
      77: aload_2
      78: bipush        10
      80: invokestatic  #50                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      83: invokespecial #53                 // Method java/util/ArrayList."<init>":(I)V
      86: checkcast     #25                 // class java/util/Collection
      89: astore        5
      91: iconst_0
      92: istore        6
      94: iconst_0
      95: istore        7
      97: aload         4
      99: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     104: astore        8
     106: aload         8
     108: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     113: ifeq          205
     116: aload         8
     118: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     123: astore        9
     125: aload         5
     127: iload         7
     129: iinc          7, 1
     132: istore        10
     134: iload         10
     136: ifge          142
     139: invokestatic  #69                 // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     142: iload         10
     144: aload         9
     146: checkcast     #71                 // class io/rbrincke/dice/core/Element
     149: astore        11
     151: istore        12
     153: astore        16
     155: iconst_0
     156: istore        13
     158: aload_0
     159: getfield      #23                 // Field elements:Ljava/util/List;
     162: iload         12
     164: iconst_1
     165: iadd
     166: aload_0
     167: getfield      #23                 // Field elements:Ljava/util/List;
     170: invokeinterface #77,  1           // InterfaceMethod java/util/List.size:()I
     175: irem
     176: invokeinterface #81,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     181: checkcast     #71                 // class io/rbrincke/dice/core/Element
     184: astore        14
     186: aload         11
     188: aload         14
     190: invokestatic  #87                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     193: aload         16
     195: swap
     196: invokeinterface #91,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     201: pop
     202: goto          106
     205: aload         5
     207: checkcast     #73                 // class java/util/List
     210: nop
     211: aload         15
     213: swap
     214: putfield      #94                 // Field elementPairs:Ljava/util/List;
     217: aload_0
     218: aload_0
     219: getfield      #94                 // Field elementPairs:Ljava/util/List;
     222: checkcast     #42                 // class java/lang/Iterable
     225: astore_2
     226: astore        15
     228: iconst_0
     229: istore_3
     230: aload_2
     231: astore        4
     233: new           #44                 // class java/util/ArrayList
     236: dup
     237: aload_2
     238: bipush        10
     240: invokestatic  #50                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     243: invokespecial #53                 // Method java/util/ArrayList."<init>":(I)V
     246: checkcast     #25                 // class java/util/Collection
     249: astore        5
     251: iconst_0
     252: istore        6
     254: aload         4
     256: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     261: astore        7
     263: aload         7
     265: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     270: ifeq          340
     273: aload         7
     275: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     280: astore        8
     282: aload         5
     284: aload         8
     286: checkcast     #96                 // class kotlin/Pair
     289: astore        9
     291: astore        16
     293: iconst_0
     294: istore        10
     296: aload         9
     298: invokevirtual #99                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
     301: checkcast     #71                 // class io/rbrincke/dice/core/Element
     304: astore        11
     306: aload         9
     308: invokevirtual #102                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     311: checkcast     #71                 // class io/rbrincke/dice/core/Element
     314: astore        12
     316: aload         11
     318: aload         12
     320: invokeinterface #106,  2          // InterfaceMethod io/rbrincke/dice/core/Element.beats:(Ljava/lang/Object;)D
     325: invokestatic  #112                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     328: aload         16
     330: swap
     331: invokeinterface #91,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     336: pop
     337: goto          263
     340: aload         5
     342: checkcast     #73                 // class java/util/List
     345: nop
     346: aload         15
     348: swap
     349: putfield      #115                // Field dominanceProbabilities:Ljava/util/List;
     352: aload_0
     353: aload_0
     354: getfield      #94                 // Field elementPairs:Ljava/util/List;
     357: checkcast     #42                 // class java/lang/Iterable
     360: aload_0
     361: getfield      #115                // Field dominanceProbabilities:Ljava/util/List;
     364: checkcast     #42                 // class java/lang/Iterable
     367: invokestatic  #119                // Method kotlin/collections/CollectionsKt.zip:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/List;
     370: putfield      #122                // Field elementPairDominanceProbabilities:Ljava/util/List;
     373: return

  public final java.util.List<kotlin.Pair<kotlin.Pair<T, T>, java.lang.Double>> getElementPairDominanceProbabilities();
    Code:
       0: aload_0
       1: getfield      #122                // Field elementPairDominanceProbabilities:Ljava/util/List;
       4: areturn

  public final boolean isNonTransitive();
    Code:
       0: aload_0
       1: getfield      #115                // Field dominanceProbabilities:Ljava/util/List;
       4: checkcast     #42                 // class java/lang/Iterable
       7: astore_1
       8: iconst_0
       9: istore_2
      10: aload_1
      11: instanceof    #25                 // class java/util/Collection
      14: ifeq          33
      17: aload_1
      18: checkcast     #25                 // class java/util/Collection
      21: invokeinterface #29,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      26: ifeq          33
      29: iconst_1
      30: goto          92
      33: aload_1
      34: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      39: astore_3
      40: aload_3
      41: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      46: ifeq          91
      49: aload_3
      50: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        4
      57: aload         4
      59: checkcast     #152                // class java/lang/Number
      62: invokevirtual #156                // Method java/lang/Number.doubleValue:()D
      65: dstore        5
      67: iconst_0
      68: istore        7
      70: dload         5
      72: ldc2_w        #157                // double 0.5d
      75: dcmpl
      76: ifle          83
      79: iconst_1
      80: goto          84
      83: iconst_0
      84: ifne          40
      87: iconst_0
      88: goto          92
      91: iconst_1
      92: ireturn

  public final double leastDominance();
    Code:
       0: aload_0
       1: getfield      #115                // Field dominanceProbabilities:Ljava/util/List;
       4: checkcast     #42                 // class java/lang/Iterable
       7: invokestatic  #169                // Method kotlin/collections/CollectionsKt.minOrNull:(Ljava/lang/Iterable;)Ljava/lang/Double;
      10: dup
      11: ifnull        20
      14: invokevirtual #170                // Method java/lang/Double.doubleValue:()D
      17: goto          31
      20: pop
      21: new           #33                 // class java/lang/IllegalStateException
      24: dup
      25: ldc           #172                // String Empty set.
      27: invokespecial #40                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      30: athrow
      31: dreturn

  public final java.util.List<java.lang.Double> dominance();
    Code:
       0: aload_0
       1: getfield      #115                // Field dominanceProbabilities:Ljava/util/List;
       4: checkcast     #42                 // class java/lang/Iterable
       7: invokestatic  #178                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
      10: areturn

  public final java.lang.String prettyPrint();
    Code:
       0: aload_0
       1: getfield      #122                // Field elementPairDominanceProbabilities:Ljava/util/List;
       4: checkcast     #42                 // class java/lang/Iterable
       7: aconst_null
       8: aconst_null
       9: aconst_null
      10: iconst_0
      11: aconst_null
      12: invokedynamic #198,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
      17: bipush        31
      19: aconst_null
      20: invokestatic  #202                // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
      23: areturn

  private static final java.lang.CharSequence prettyPrint$lambda$4(kotlin.Pair);
    Code:
       0: aload_0
       1: ldc           #204                // String <destruct>
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #99                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
      10: checkcast     #96                 // class kotlin/Pair
      13: astore_1
      14: aload_0
      15: invokevirtual #102                // Method kotlin/Pair.component2:()Ljava/lang/Object;
      18: checkcast     #152                // class java/lang/Number
      21: invokevirtual #156                // Method java/lang/Number.doubleValue:()D
      24: dstore_2
      25: aload_1
      26: invokevirtual #99                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
      29: checkcast     #71                 // class io/rbrincke/dice/core/Element
      32: astore        4
      34: aload_1
      35: invokevirtual #102                // Method kotlin/Pair.component2:()Ljava/lang/Object;
      38: checkcast     #71                 // class io/rbrincke/dice/core/Element
      41: astore        5
      43: new           #206                // class java/lang/StringBuilder
      46: dup
      47: invokespecial #207                // Method java/lang/StringBuilder."<init>":()V
      50: aload         4
      52: invokevirtual #211                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      55: ldc           #213                // String  beats
      57: invokevirtual #216                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      60: aload         5
      62: invokevirtual #211                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      65: ldc           #218                // String  with probability
      67: invokevirtual #216                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      70: dload_2
      71: invokevirtual #221                // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
      74: invokevirtual #222                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      77: checkcast     #224                // class java/lang/CharSequence
      80: areturn
}


package com.akshay.adventofcode

import java.io.File

data class Move(val quantity: Int, val source: Int, val target: Int) {

    companion object {
        fun of(line: String): Move {
            return line
                .split(" ")
                .filterIndexed { index, _ -> index % 2 == 1 }
                .map { it.toInt() }
                .let { Move(it[0], it[1] - 1, it[2] - 1) }
        }
    }
}

/**
 * Advent of Code 2022 - Day 5 (Supply Stacks)
 * http://adventofcode.com/2022/day/5
 */
class Day05 {

    fun partOne(stacks: List<ArrayDeque<Char>>, moves: List<Move>): String {
        moves.forEach { move -> repeat(move.quantity) { stacks[move.target].addFirst(stacks[move.source].removeFirst()) } }
        return stacks.map { it.first() }.joinToString(separator = "")
    }

    fun partTwo(stacks: List<ArrayDeque<Char>>, moves: List<Move>): String {
        moves.forEach { step ->
            stacks[step.source]
                .subList(0, step.quantity)
                .asReversed()
                .map { stacks[step.target].addFirst(it) }
                .map { stacks[step.source].removeFirst() }
        }
        return stacks.map { it.first() }.joinToString(separator = "")
    }

    fun populateStacks(lines: List<String>, onCharacterFound: (Int, Char) -> Unit) {
        lines
            .filter { it.contains("[") }
            .forEach { line ->
                line.mapIndexed { index, char ->
                    if (char.isLetter()) {
                        val stackNumber = index / 4
                        val value = line[index]
                        onCharacterFound(stackNumber, value)
                    }
                }
            }
    }
}

fun main() {
    val lines = File("input.txt").readLines()
    val day05 = Day05()

    // Calculate number of stacks needed
    val stacks = List(9) { ArrayDeque<Char>() }

    // Fill the stacks
    day05.populateStacks(lines) { stackNumber, value ->
        stacks[stackNumber].addLast(value)
    }

    // Get the moves
    val moves = lines.filter { it.contains("move") }.map { Move.of(it) }

    // Perform the moves
    println(day05.partOne(stacks.map { ArrayDeque(it) }.toList(), moves))
    println(day05.partTwo(stacks, moves))
}

Compiled from "Day05.kt"
public final class com.akshay.adventofcode.Day05Kt {
  public static final void main();
    Code:
       0: new           #8                  // class java/io/File
       3: dup
       4: ldc           #10                 // String input.txt
       6: invokespecial #14                 // Method java/io/File."<init>":(Ljava/lang/String;)V
       9: aconst_null
      10: iconst_1
      11: aconst_null
      12: invokestatic  #20                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      15: astore_0
      16: new           #22                 // class com/akshay/adventofcode/Day05
      19: dup
      20: invokespecial #24                 // Method com/akshay/adventofcode/Day05."<init>":()V
      23: astore_1
      24: bipush        9
      26: istore_3
      27: new           #26                 // class java/util/ArrayList
      30: dup
      31: iload_3
      32: invokespecial #29                 // Method java/util/ArrayList."<init>":(I)V
      35: astore        4
      37: iconst_0
      38: istore        5
      40: iload         5
      42: iload_3
      43: if_icmpge     81
      46: iload         5
      48: istore        6
      50: aload         4
      52: iload         6
      54: istore        7
      56: astore        13
      58: iconst_0
      59: istore        8
      61: new           #31                 // class kotlin/collections/ArrayDeque
      64: dup
      65: invokespecial #32                 // Method kotlin/collections/ArrayDeque."<init>":()V
      68: aload         13
      70: swap
      71: invokevirtual #36                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      74: pop
      75: iinc          5, 1
      78: goto          40
      81: aload         4
      83: checkcast     #38                 // class java/util/List
      86: astore_2
      87: aload_1
      88: aload_0
      89: aload_2
      90: invokedynamic #58,  0             // InvokeDynamic #0:invoke:(Ljava/util/List;)Lkotlin/jvm/functions/Function2;
      95: invokevirtual #62                 // Method com/akshay/adventofcode/Day05.populateStacks:(Ljava/util/List;Lkotlin/jvm/functions/Function2;)V
      98: aload_0
      99: checkcast     #64                 // class java/lang/Iterable
     102: astore        4
     104: iconst_0
     105: istore        5
     107: aload         4
     109: astore        6
     111: new           #26                 // class java/util/ArrayList
     114: dup
     115: invokespecial #65                 // Method java/util/ArrayList."<init>":()V
     118: checkcast     #67                 // class java/util/Collection
     121: astore        7
     123: iconst_0
     124: istore        8
     126: aload         6
     128: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     133: astore        9
     135: aload         9
     137: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     142: ifeq          196
     145: aload         9
     147: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     152: astore        10
     154: aload         10
     156: checkcast     #83                 // class java/lang/String
     159: astore        11
     161: iconst_0
     162: istore        12
     164: aload         11
     166: checkcast     #85                 // class java/lang/CharSequence
     169: ldc           #87                 // String move
     171: checkcast     #85                 // class java/lang/CharSequence
     174: iconst_0
     175: iconst_2
     176: aconst_null
     177: invokestatic  #93                 // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;ZILjava/lang/Object;)Z
     180: ifeq          135
     183: aload         7
     185: aload         10
     187: invokeinterface #94,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     192: pop
     193: goto          135
     196: aload         7
     198: checkcast     #38                 // class java/util/List
     201: nop
     202: checkcast     #64                 // class java/lang/Iterable
     205: astore        4
     207: nop
     208: iconst_0
     209: istore        5
     211: aload         4
     213: astore        6
     215: new           #26                 // class java/util/ArrayList
     218: dup
     219: aload         4
     221: bipush        10
     223: invokestatic  #100                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     226: invokespecial #29                 // Method java/util/ArrayList."<init>":(I)V
     229: checkcast     #67                 // class java/util/Collection
     232: astore        7
     234: iconst_0
     235: istore        8
     237: aload         6
     239: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     244: astore        9
     246: aload         9
     248: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     253: ifeq          299
     256: aload         9
     258: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     263: astore        10
     265: aload         7
     267: aload         10
     269: checkcast     #83                 // class java/lang/String
     272: astore        11
     274: astore        13
     276: iconst_0
     277: istore        12
     279: getstatic     #106                // Field com/akshay/adventofcode/Move.Companion:Lcom/akshay/adventofcode/Move$Companion;
     282: aload         11
     284: invokevirtual #112                // Method com/akshay/adventofcode/Move$Companion.of:(Ljava/lang/String;)Lcom/akshay/adventofcode/Move;
     287: aload         13
     289: swap
     290: invokeinterface #94,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     295: pop
     296: goto          246
     299: aload         7
     301: checkcast     #38                 // class java/util/List
     304: nop
     305: astore_3
     306: aload_1
     307: aload_2
     308: checkcast     #64                 // class java/lang/Iterable
     311: astore        4
     313: astore        13
     315: iconst_0
     316: istore        5
     318: aload         4
     320: astore        6
     322: new           #26                 // class java/util/ArrayList
     325: dup
     326: aload         4
     328: bipush        10
     330: invokestatic  #100                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     333: invokespecial #29                 // Method java/util/ArrayList."<init>":(I)V
     336: checkcast     #67                 // class java/util/Collection
     339: astore        7
     341: iconst_0
     342: istore        8
     344: aload         6
     346: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     351: astore        9
     353: aload         9
     355: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     360: ifeq          410
     363: aload         9
     365: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     370: astore        10
     372: aload         7
     374: aload         10
     376: checkcast     #31                 // class kotlin/collections/ArrayDeque
     379: astore        11
     381: astore        14
     383: iconst_0
     384: istore        12
     386: new           #31                 // class kotlin/collections/ArrayDeque
     389: dup
     390: aload         11
     392: checkcast     #67                 // class java/util/Collection
     395: invokespecial #115                // Method kotlin/collections/ArrayDeque."<init>":(Ljava/util/Collection;)V
     398: aload         14
     400: swap
     401: invokeinterface #94,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     406: pop
     407: goto          353
     410: aload         7
     412: checkcast     #38                 // class java/util/List
     415: nop
     416: aload         13
     418: swap
     419: checkcast     #64                 // class java/lang/Iterable
     422: invokestatic  #119                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     425: aload_3
     426: invokevirtual #123                // Method com/akshay/adventofcode/Day05.partOne:(Ljava/util/List;Ljava/util/List;)Ljava/lang/String;
     429: getstatic     #129                // Field java/lang/System.out:Ljava/io/PrintStream;
     432: swap
     433: invokevirtual #135                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     436: aload_1
     437: aload_2
     438: aload_3
     439: invokevirtual #138                // Method com/akshay/adventofcode/Day05.partTwo:(Ljava/util/List;Ljava/util/List;)Ljava/lang/String;
     442: getstatic     #129                // Field java/lang/System.out:Ljava/io/PrintStream;
     445: swap
     446: invokevirtual #135                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     449: return

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

  private static final kotlin.Unit main$lambda$1(java.util.List, int, char);
    Code:
       0: aload_0
       1: iload_1
       2: invokeinterface #175,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
       7: checkcast     #31                 // class kotlin/collections/ArrayDeque
      10: iload_2
      11: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      14: invokevirtual #184                // Method kotlin/collections/ArrayDeque.addLast:(Ljava/lang/Object;)V
      17: getstatic     #190                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      20: areturn
}

Compiled from "Day05.kt"
public final class com.akshay.adventofcode.Day05 {
  public com.akshay.adventofcode.Day05();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final java.lang.String partOne(java.util.List<kotlin.collections.ArrayDeque<java.lang.Character>>, java.util.List<com.akshay.adventofcode.Move>);
    Code:
       0: aload_1
       1: ldc           #16                 // String stacks
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #24                 // String moves
       9: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: checkcast     #26                 // class java/lang/Iterable
      16: astore_3
      17: iconst_0
      18: istore        4
      20: aload_3
      21: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      26: astore        5
      28: aload         5
      30: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      35: ifeq          126
      38: aload         5
      40: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      45: astore        6
      47: aload         6
      49: checkcast     #42                 // class com/akshay/adventofcode/Move
      52: astore        7
      54: iconst_0
      55: istore        8
      57: aload         7
      59: invokevirtual #46                 // Method com/akshay/adventofcode/Move.getQuantity:()I
      62: istore        9
      64: iconst_0
      65: istore        10
      67: iload         10
      69: iload         9
      71: if_icmpge     121
      74: iload         10
      76: istore        11
      78: iconst_0
      79: istore        12
      81: aload_1
      82: aload         7
      84: invokevirtual #49                 // Method com/akshay/adventofcode/Move.getTarget:()I
      87: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      92: checkcast     #57                 // class kotlin/collections/ArrayDeque
      95: aload_1
      96: aload         7
      98: invokevirtual #60                 // Method com/akshay/adventofcode/Move.getSource:()I
     101: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     106: checkcast     #57                 // class kotlin/collections/ArrayDeque
     109: invokevirtual #63                 // Method kotlin/collections/ArrayDeque.removeFirst:()Ljava/lang/Object;
     112: invokevirtual #67                 // Method kotlin/collections/ArrayDeque.addFirst:(Ljava/lang/Object;)V
     115: iinc          10, 1
     118: goto          67
     121: nop
     122: nop
     123: goto          28
     126: nop
     127: aload_1
     128: checkcast     #26                 // class java/lang/Iterable
     131: astore_3
     132: iconst_0
     133: istore        4
     135: aload_3
     136: astore        5
     138: new           #69                 // class java/util/ArrayList
     141: dup
     142: aload_3
     143: bipush        10
     145: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     148: invokespecial #78                 // Method java/util/ArrayList."<init>":(I)V
     151: checkcast     #80                 // class java/util/Collection
     154: astore        6
     156: iconst_0
     157: istore        7
     159: aload         5
     161: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     166: astore        8
     168: aload         8
     170: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     175: ifeq          227
     178: aload         8
     180: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     185: astore        9
     187: aload         6
     189: aload         9
     191: checkcast     #57                 // class kotlin/collections/ArrayDeque
     194: astore        10
     196: astore        13
     198: iconst_0
     199: istore        11
     201: aload         10
     203: invokevirtual #83                 // Method kotlin/collections/ArrayDeque.first:()Ljava/lang/Object;
     206: checkcast     #85                 // class java/lang/Character
     209: invokevirtual #89                 // Method java/lang/Character.charValue:()C
     212: invokestatic  #93                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     215: aload         13
     217: swap
     218: invokeinterface #97,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     223: pop
     224: goto          168
     227: aload         6
     229: checkcast     #51                 // class java/util/List
     232: nop
     233: checkcast     #26                 // class java/lang/Iterable
     236: ldc           #99                 // String
     238: checkcast     #101                // class java/lang/CharSequence
     241: aconst_null
     242: aconst_null
     243: iconst_0
     244: aconst_null
     245: aconst_null
     246: bipush        62
     248: aconst_null
     249: invokestatic  #105                // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     252: areturn

  public final java.lang.String partTwo(java.util.List<kotlin.collections.ArrayDeque<java.lang.Character>>, java.util.List<com.akshay.adventofcode.Move>);
    Code:
       0: aload_1
       1: ldc           #16                 // String stacks
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #24                 // String moves
       9: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: checkcast     #26                 // class java/lang/Iterable
      16: astore_3
      17: iconst_0
      18: istore        4
      20: aload_3
      21: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      26: astore        5
      28: aload         5
      30: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      35: ifeq          332
      38: aload         5
      40: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      45: astore        6
      47: aload         6
      49: checkcast     #42                 // class com/akshay/adventofcode/Move
      52: astore        7
      54: iconst_0
      55: istore        8
      57: aload_1
      58: aload         7
      60: invokevirtual #60                 // Method com/akshay/adventofcode/Move.getSource:()I
      63: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      68: checkcast     #57                 // class kotlin/collections/ArrayDeque
      71: iconst_0
      72: aload         7
      74: invokevirtual #46                 // Method com/akshay/adventofcode/Move.getQuantity:()I
      77: invokevirtual #131                // Method kotlin/collections/ArrayDeque.subList:(II)Ljava/util/List;
      80: invokestatic  #135                // Method kotlin/collections/CollectionsKt.asReversedMutable:(Ljava/util/List;)Ljava/util/List;
      83: checkcast     #26                 // class java/lang/Iterable
      86: astore        9
      88: nop
      89: iconst_0
      90: istore        10
      92: aload         9
      94: astore        11
      96: new           #69                 // class java/util/ArrayList
      99: dup
     100: aload         9
     102: bipush        10
     104: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     107: invokespecial #78                 // Method java/util/ArrayList."<init>":(I)V
     110: checkcast     #80                 // class java/util/Collection
     113: astore        12
     115: iconst_0
     116: istore        13
     118: aload         11
     120: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     125: astore        14
     127: aload         14
     129: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     134: ifeq          199
     137: aload         14
     139: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     144: astore        15
     146: aload         12
     148: aload         15
     150: checkcast     #85                 // class java/lang/Character
     153: invokevirtual #89                 // Method java/lang/Character.charValue:()C
     156: istore        16
     158: astore        17
     160: iconst_0
     161: istore        18
     163: aload_1
     164: aload         7
     166: invokevirtual #49                 // Method com/akshay/adventofcode/Move.getTarget:()I
     169: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     174: checkcast     #57                 // class kotlin/collections/ArrayDeque
     177: iload         16
     179: invokestatic  #93                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     182: invokevirtual #67                 // Method kotlin/collections/ArrayDeque.addFirst:(Ljava/lang/Object;)V
     185: aload         17
     187: getstatic     #141                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     190: invokeinterface #97,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     195: pop
     196: goto          127
     199: aload         12
     201: checkcast     #51                 // class java/util/List
     204: nop
     205: checkcast     #26                 // class java/lang/Iterable
     208: astore        9
     210: nop
     211: iconst_0
     212: istore        10
     214: aload         9
     216: astore        11
     218: new           #69                 // class java/util/ArrayList
     221: dup
     222: aload         9
     224: bipush        10
     226: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     229: invokespecial #78                 // Method java/util/ArrayList."<init>":(I)V
     232: checkcast     #80                 // class java/util/Collection
     235: astore        12
     237: iconst_0
     238: istore        13
     240: aload         11
     242: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     247: astore        14
     249: aload         14
     251: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     256: ifeq          320
     259: aload         14
     261: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     266: astore        15
     268: aload         12
     270: aload         15
     272: checkcast     #137                // class kotlin/Unit
     275: astore        16
     277: astore        17
     279: iconst_0
     280: istore        18
     282: aload_1
     283: aload         7
     285: invokevirtual #60                 // Method com/akshay/adventofcode/Move.getSource:()I
     288: invokeinterface #55,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     293: checkcast     #57                 // class kotlin/collections/ArrayDeque
     296: invokevirtual #63                 // Method kotlin/collections/ArrayDeque.removeFirst:()Ljava/lang/Object;
     299: checkcast     #85                 // class java/lang/Character
     302: invokevirtual #89                 // Method java/lang/Character.charValue:()C
     305: invokestatic  #93                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     308: aload         17
     310: swap
     311: invokeinterface #97,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     316: pop
     317: goto          249
     320: aload         12
     322: checkcast     #51                 // class java/util/List
     325: nop
     326: pop
     327: nop
     328: nop
     329: goto          28
     332: nop
     333: aload_1
     334: checkcast     #26                 // class java/lang/Iterable
     337: astore_3
     338: iconst_0
     339: istore        4
     341: aload_3
     342: astore        5
     344: new           #69                 // class java/util/ArrayList
     347: dup
     348: aload_3
     349: bipush        10
     351: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     354: invokespecial #78                 // Method java/util/ArrayList."<init>":(I)V
     357: checkcast     #80                 // class java/util/Collection
     360: astore        6
     362: iconst_0
     363: istore        7
     365: aload         5
     367: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     372: astore        8
     374: aload         8
     376: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     381: ifeq          433
     384: aload         8
     386: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     391: astore        9
     393: aload         6
     395: aload         9
     397: checkcast     #57                 // class kotlin/collections/ArrayDeque
     400: astore        10
     402: astore        19
     404: iconst_0
     405: istore        11
     407: aload         10
     409: invokevirtual #83                 // Method kotlin/collections/ArrayDeque.first:()Ljava/lang/Object;
     412: checkcast     #85                 // class java/lang/Character
     415: invokevirtual #89                 // Method java/lang/Character.charValue:()C
     418: invokestatic  #93                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     421: aload         19
     423: swap
     424: invokeinterface #97,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     429: pop
     430: goto          374
     433: aload         6
     435: checkcast     #51                 // class java/util/List
     438: nop
     439: checkcast     #26                 // class java/lang/Iterable
     442: ldc           #99                 // String
     444: checkcast     #101                // class java/lang/CharSequence
     447: aconst_null
     448: aconst_null
     449: iconst_0
     450: aconst_null
     451: aconst_null
     452: bipush        62
     454: aconst_null
     455: invokestatic  #105                // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     458: areturn

  public final void populateStacks(java.util.List<java.lang.String>, kotlin.jvm.functions.Function2<? super java.lang.Integer, ? super java.lang.Character, kotlin.Unit>);
    Code:
       0: aload_1
       1: ldc           #152                // String lines
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #154                // String onCharacterFound
       9: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: checkcast     #26                 // class java/lang/Iterable
      16: astore_3
      17: nop
      18: iconst_0
      19: istore        4
      21: aload_3
      22: astore        5
      24: new           #69                 // class java/util/ArrayList
      27: dup
      28: invokespecial #155                // Method java/util/ArrayList."<init>":()V
      31: checkcast     #80                 // class java/util/Collection
      34: astore        6
      36: iconst_0
      37: istore        7
      39: aload         5
      41: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      46: astore        8
      48: aload         8
      50: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      55: ifeq          109
      58: aload         8
      60: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      65: astore        9
      67: aload         9
      69: checkcast     #157                // class java/lang/String
      72: astore        10
      74: iconst_0
      75: istore        11
      77: aload         10
      79: checkcast     #101                // class java/lang/CharSequence
      82: ldc           #159                // String [
      84: checkcast     #101                // class java/lang/CharSequence
      87: iconst_0
      88: iconst_2
      89: aconst_null
      90: invokestatic  #165                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;ZILjava/lang/Object;)Z
      93: ifeq          48
      96: aload         6
      98: aload         9
     100: invokeinterface #97,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     105: pop
     106: goto          48
     109: aload         6
     111: checkcast     #51                 // class java/util/List
     114: nop
     115: checkcast     #26                 // class java/lang/Iterable
     118: astore_3
     119: nop
     120: iconst_0
     121: istore        4
     123: aload_3
     124: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     129: astore        5
     131: aload         5
     133: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     138: ifeq          313
     141: aload         5
     143: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     148: astore        6
     150: aload         6
     152: checkcast     #157                // class java/lang/String
     155: astore        7
     157: iconst_0
     158: istore        8
     160: aload         7
     162: checkcast     #101                // class java/lang/CharSequence
     165: astore        9
     167: iconst_0
     168: istore        10
     170: aload         9
     172: astore        11
     174: new           #69                 // class java/util/ArrayList
     177: dup
     178: aload         9
     180: invokeinterface #168,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     185: invokespecial #78                 // Method java/util/ArrayList."<init>":(I)V
     188: checkcast     #80                 // class java/util/Collection
     191: astore        12
     193: iconst_0
     194: istore        13
     196: iconst_0
     197: istore        14
     199: iconst_0
     200: istore        15
     202: iload         15
     204: aload         11
     206: invokeinterface #168,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     211: if_icmpge     301
     214: aload         11
     216: iload         15
     218: invokeinterface #172,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     223: istore        16
     225: aload         12
     227: iload         14
     229: iinc          14, 1
     232: iload         16
     234: istore        17
     236: istore        18
     238: astore        19
     240: iconst_0
     241: istore        20
     243: iload         17
     245: invokestatic  #176                // Method java/lang/Character.isLetter:(C)Z
     248: ifeq          283
     251: iload         18
     253: iconst_4
     254: idiv
     255: istore        21
     257: aload         7
     259: iload         18
     261: invokevirtual #177                // Method java/lang/String.charAt:(I)C
     264: istore        22
     266: aload_2
     267: iload         21
     269: invokestatic  #182                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     272: iload         22
     274: invokestatic  #93                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     277: invokeinterface #188,  3          // InterfaceMethod kotlin/jvm/functions/Function2.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     282: pop
     283: nop
     284: aload         19
     286: getstatic     #141                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     289: invokeinterface #97,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     294: pop
     295: iinc          15, 1
     298: goto          202
     301: aload         12
     303: checkcast     #51                 // class java/util/List
     306: nop
     307: pop
     308: nop
     309: nop
     310: goto          131
     313: nop
     314: return
}