fun mergeSort(list : MutableList<Int>) : MutableList<Int>{
    // check if the given list has more than 1 elements
    if (list.size > 1){
        // a list to store sorted list
        val sortedList = MutableList(list.size) { 0 }
        // taking note of middle element of the list
        val middle = list.size / 2

        // splitting list into a left side and right side
        var leftSide = list.slice(0 until middle).toMutableList()
        var rightSide = list.slice(middle until list.size).toMutableList()

        // performing mergesort on the list and storing the results as the sides name
        leftSide = mergeSort(leftSide)
        rightSide = mergeSort(rightSide)

        var i = 0; var j = 0; var k = 0

        // getting smaller elements from the list until one of them is exhausted
        // once one list gets exhausted we know that the elements in the remaining
        // list are larger than the one's we sorted
        while (i < leftSide.size && j < rightSide.size){
            if (leftSide[i] < rightSide[j]) {
                sortedList[k] = leftSide[i]
                i++
            }
            else {
                sortedList[k] = rightSide[j]
                j++
            }
            k++
        }

        // putting the elements of leftSide if they are left after one list gets
        // exhausted
        while ( i < leftSide.size){
            sortedList[k] = leftSide[i]
            i++
            k++
        }

        // putting the elements of rightSide if they are left after one list gets
        // exhausted
        while ( j < rightSide.size){
            sortedList[k] = rightSide[j]
            j++
            k++
        }

        // returning the sorted list
        return sortedList
    }
    // if the size is less than 1 then the list is considered as sorted
    // in itself, just return the item
    return list
}

fun main() {
    print("Enter the number of items to sort - ")
    val lengthOfList = readLine()!!.toInt()

    val list = MutableList(lengthOfList) { 0 }
    list.withIndex().forEach {
        print("Enter value ${it.index + 1} - ")
        list[it.index] = readLine()!!.toInt()
    }
    println("unsorted list is $list")

    val sorted = mergeSort(list.toMutableList());
    println("sorted list is $sorted")
}

/*
    Enter the number of items to sort - 12
    Enter value 1 - 1
    Enter value 2 - 3
    Enter value 3 - 5
    Enter value 4 - 2
    Enter value 5 - 90
    Enter value 6 - 24
    Enter value 7 - 67
    Enter value 8 - 48
    Enter value 9 - 95
    Enter value 10 - 29
    Enter value 11 - 5
    Enter value 12 - 16
    unsorted list is [1, 3, 5, 2, 90, 24, 67, 48, 95, 29, 5, 16]
    sorted list is [1, 2, 3, 5, 5, 16, 24, 29, 48, 67, 90, 95]

    Time Complexity -
    Best Case Complexity: O(n*log n)
    Worst Case Complexity: O(n*log n)
    Average Case Complexity: O(n*log n)

    Space Complexity -
    The space complexity of merge sort is O(n).
 */

Compiled from "MergeSort.kt"
public final class MergeSortKt {
  public static final java.util.List<java.lang.Integer> mergeSort(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #10                 // String list
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
      12: iconst_1
      13: if_icmple     328
      16: aload_0
      17: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
      22: istore_2
      23: new           #24                 // class java/util/ArrayList
      26: dup
      27: iload_2
      28: invokespecial #28                 // Method java/util/ArrayList."<init>":(I)V
      31: astore_3
      32: iconst_0
      33: istore        4
      35: iload         4
      37: iload_2
      38: if_icmpge     72
      41: iload         4
      43: istore        5
      45: aload_3
      46: iload         5
      48: istore        6
      50: astore        8
      52: iconst_0
      53: istore        7
      55: iconst_0
      56: invokestatic  #34                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      59: aload         8
      61: swap
      62: invokevirtual #38                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      65: pop
      66: iinc          4, 1
      69: goto          35
      72: aload_3
      73: checkcast     #18                 // class java/util/List
      76: astore_1
      77: aload_0
      78: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
      83: iconst_2
      84: idiv
      85: istore_2
      86: aload_0
      87: iconst_0
      88: iload_2
      89: invokestatic  #44                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
      92: invokestatic  #50                 // Method kotlin/collections/CollectionsKt.slice:(Ljava/util/List;Lkotlin/ranges/IntRange;)Ljava/util/List;
      95: checkcast     #52                 // class java/util/Collection
      98: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.toMutableList:(Ljava/util/Collection;)Ljava/util/List;
     101: astore_3
     102: aload_0
     103: iload_2
     104: aload_0
     105: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
     110: invokestatic  #44                 // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
     113: invokestatic  #50                 // Method kotlin/collections/CollectionsKt.slice:(Ljava/util/List;Lkotlin/ranges/IntRange;)Ljava/util/List;
     116: checkcast     #52                 // class java/util/Collection
     119: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.toMutableList:(Ljava/util/Collection;)Ljava/util/List;
     122: astore        4
     124: aload_3
     125: invokestatic  #58                 // Method mergeSort:(Ljava/util/List;)Ljava/util/List;
     128: astore_3
     129: aload         4
     131: invokestatic  #58                 // Method mergeSort:(Ljava/util/List;)Ljava/util/List;
     134: astore        4
     136: iconst_0
     137: istore        5
     139: iconst_0
     140: istore        6
     142: iconst_0
     143: istore        7
     145: iload         5
     147: aload_3
     148: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
     153: if_icmpge     250
     156: iload         6
     158: aload         4
     160: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
     165: if_icmpge     250
     168: aload_3
     169: iload         5
     171: invokeinterface #62,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     176: checkcast     #64                 // class java/lang/Number
     179: invokevirtual #67                 // Method java/lang/Number.intValue:()I
     182: aload         4
     184: iload         6
     186: invokeinterface #62,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     191: checkcast     #64                 // class java/lang/Number
     194: invokevirtual #67                 // Method java/lang/Number.intValue:()I
     197: if_icmpge     223
     200: aload_1
     201: iload         7
     203: aload_3
     204: iload         5
     206: invokeinterface #62,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     211: invokeinterface #71,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
     216: pop
     217: iinc          5, 1
     220: goto          244
     223: aload_1
     224: iload         7
     226: aload         4
     228: iload         6
     230: invokeinterface #62,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     235: invokeinterface #71,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
     240: pop
     241: iinc          6, 1
     244: iinc          7, 1
     247: goto          145
     250: iload         5
     252: aload_3
     253: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
     258: if_icmpge     287
     261: aload_1
     262: iload         7
     264: aload_3
     265: iload         5
     267: invokeinterface #62,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     272: invokeinterface #71,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
     277: pop
     278: iinc          5, 1
     281: iinc          7, 1
     284: goto          250
     287: iload         6
     289: aload         4
     291: invokeinterface #22,  1           // InterfaceMethod java/util/List.size:()I
     296: if_icmpge     326
     299: aload_1
     300: iload         7
     302: aload         4
     304: iload         6
     306: invokeinterface #62,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     311: invokeinterface #71,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
     316: pop
     317: iinc          6, 1
     320: iinc          7, 1
     323: goto          287
     326: aload_1
     327: areturn
     328: aload_0
     329: areturn

  public static final void main();
    Code:
       0: ldc           #86                 // String Enter the number of items to sort -
       2: getstatic     #92                 // Field java/lang/System.out:Ljava/io/PrintStream;
       5: swap
       6: invokevirtual #98                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
       9: invokestatic  #104                // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
      12: dup
      13: invokestatic  #107                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      16: invokestatic  #111                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      19: istore_0
      20: new           #24                 // class java/util/ArrayList
      23: dup
      24: iload_0
      25: invokespecial #28                 // Method java/util/ArrayList."<init>":(I)V
      28: astore_2
      29: iconst_0
      30: istore_3
      31: iload_3
      32: iload_0
      33: if_icmpge     66
      36: iload_3
      37: istore        4
      39: aload_2
      40: iload         4
      42: istore        5
      44: astore        8
      46: iconst_0
      47: istore        6
      49: iconst_0
      50: invokestatic  #34                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      53: aload         8
      55: swap
      56: invokevirtual #38                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      59: pop
      60: iinc          3, 1
      63: goto          31
      66: aload_2
      67: checkcast     #18                 // class java/util/List
      70: astore_1
      71: aload_1
      72: checkcast     #113                // class java/lang/Iterable
      75: invokestatic  #117                // Method kotlin/collections/CollectionsKt.withIndex:(Ljava/lang/Iterable;)Ljava/lang/Iterable;
      78: astore_2
      79: iconst_0
      80: istore_3
      81: aload_2
      82: invokeinterface #121,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      87: astore        4
      89: aload         4
      91: invokeinterface #127,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      96: ifeq          185
      99: aload         4
     101: invokeinterface #131,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     106: astore        5
     108: aload         5
     110: checkcast     #133                // class kotlin/collections/IndexedValue
     113: astore        6
     115: iconst_0
     116: istore        7
     118: new           #135                // class java/lang/StringBuilder
     121: dup
     122: invokespecial #137                // Method java/lang/StringBuilder."<init>":()V
     125: ldc           #139                // String Enter value
     127: invokevirtual #143                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     130: aload         6
     132: invokevirtual #146                // Method kotlin/collections/IndexedValue.getIndex:()I
     135: iconst_1
     136: iadd
     137: invokevirtual #149                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     140: ldc           #151                // String  -
     142: invokevirtual #143                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     145: invokevirtual #154                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     148: getstatic     #92                 // Field java/lang/System.out:Ljava/io/PrintStream;
     151: swap
     152: invokevirtual #98                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     155: aload_1
     156: aload         6
     158: invokevirtual #146                // Method kotlin/collections/IndexedValue.getIndex:()I
     161: invokestatic  #104                // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
     164: dup
     165: invokestatic  #107                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     168: invokestatic  #111                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     171: invokestatic  #34                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     174: invokeinterface #71,  3           // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
     179: pop
     180: nop
     181: nop
     182: goto          89
     185: nop
     186: new           #135                // class java/lang/StringBuilder
     189: dup
     190: invokespecial #137                // Method java/lang/StringBuilder."<init>":()V
     193: ldc           #156                // String unsorted list is
     195: invokevirtual #143                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     198: aload_1
     199: invokevirtual #159                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     202: invokevirtual #154                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     205: getstatic     #92                 // Field java/lang/System.out:Ljava/io/PrintStream;
     208: swap
     209: invokevirtual #162                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     212: aload_1
     213: checkcast     #52                 // class java/util/Collection
     216: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.toMutableList:(Ljava/util/Collection;)Ljava/util/List;
     219: invokestatic  #58                 // Method mergeSort:(Ljava/util/List;)Ljava/util/List;
     222: astore_2
     223: new           #135                // class java/lang/StringBuilder
     226: dup
     227: invokespecial #137                // Method java/lang/StringBuilder."<init>":()V
     230: ldc           #164                // String sorted list is
     232: invokevirtual #143                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     235: aload_2
     236: invokevirtual #159                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     239: invokevirtual #154                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     242: getstatic     #92                 // Field java/lang/System.out:Ljava/io/PrintStream;
     245: swap
     246: invokevirtual #162                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     249: return

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


//Kotlin program to implement ternary search using recursive approach

import java.util.*

// A function to declare ternary search
fun ternarySearch(left:Int, right:Int, key:Int, array: ArrayList<Int>): Int{
    if (right >= left) {

        // Finding the midterms
        val mid1 = left + (right - left) / 3
        val mid2 = right - (right - left) / 3

        // Check if the value is present in the first mid term
        if (array[mid1] == key) {
            return mid1
        }

        // Check if the value is present in the second mid term
        if (array[mid2] == key) {
            return mid2
        }

        // If the element is not present in the mid positions, the following cases can be a possibility.

        // Checking if the value is less than mid1 element
        if (key < array[mid1]) {

            return ternarySearch(left, mid1 - 1, key, array)
        }

        // Checking if the value is greater than mid2 element
        else if (key > array[mid2]) {
            return ternarySearch(mid2 + 1, right, key, array)
        }

        // The last possibility is that, the element may be present between the mid1 and mid2
        else {
            return ternarySearch(mid1 + 1, mid2 - 1, key, array)
        }
    }
    // If all the possibilities fail, the element is not present inside the array
    return -1
    }

//Testing code
fun main(){

    val input = Scanner(System.`in`)

    println("Enter the length of the array")
    val arrayLength = input.nextInt()
    val arrayOfElements = arrayListOf<Int>()

    println("Enter the elements of the array in ascending order")
    for(index in 0 until arrayLength) {
        val element = input.nextInt()
        arrayOfElements.add(element)
    }

    print("Enter the number you want to search for :")
    val number = input.nextInt()
    input.close()
    val left:Int = -1
    val right:Int = arrayLength - 1

    // Search the number using ternarySearch
    val position = ternarySearch(left, right, number, arrayOfElements) + 1

    if(position == 0)
        println("Key: $number is not present in the array")
    else
        println("Key: $number is present in the array at position $position")
}

/*
    Sample Test Cases:-

    Test Case 1:-
    Enter the length of the array
    5
    Enter the elements of the array in ascending order
    1 2 3 4 5
    Enter the number you want to search for :5
    Key: 5 is present in the array at position 5

    Test Case 2:-
    Enter the length of the array
    5
    Enter the elements of the array in ascending order
    10 20 30 40 50
    Enter the number you want to search for :60
    Key: 60 is not present in the array

    Time Complexity:- The time complexity of this algorithm is O(log3n), where n is the size of the array
    Space cComplexity:- The space complexity of this algorithm is O(1), which is constant, irrespective of any case.
 */

Compiled from "TernarySearch.kt"
public final class TernarySearchKt {
  public static final int ternarySearch(int, int, int, java.util.ArrayList<java.lang.Integer>);
    Code:
       0: aload_3
       1: ldc           #10                 // String array
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: iload_0
       8: if_icmplt     159
      11: iload_0
      12: iload_1
      13: iload_0
      14: isub
      15: iconst_3
      16: idiv
      17: iadd
      18: istore        4
      20: iload_1
      21: iload_1
      22: iload_0
      23: isub
      24: iconst_3
      25: idiv
      26: isub
      27: istore        5
      29: aload_3
      30: iload         4
      32: invokevirtual #22                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      35: checkcast     #24                 // class java/lang/Integer
      38: iload_2
      39: istore        6
      41: dup
      42: ifnonnull     49
      45: pop
      46: goto          60
      49: invokevirtual #28                 // Method java/lang/Integer.intValue:()I
      52: iload         6
      54: if_icmpne     60
      57: iload         4
      59: ireturn
      60: aload_3
      61: iload         5
      63: invokevirtual #22                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      66: checkcast     #24                 // class java/lang/Integer
      69: iload_2
      70: istore        6
      72: dup
      73: ifnonnull     80
      76: pop
      77: goto          91
      80: invokevirtual #28                 // Method java/lang/Integer.intValue:()I
      83: iload         6
      85: if_icmpne     91
      88: iload         5
      90: ireturn
      91: iload_2
      92: aload_3
      93: iload         4
      95: invokevirtual #22                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      98: checkcast     #30                 // class java/lang/Number
     101: invokevirtual #31                 // Method java/lang/Number.intValue:()I
     104: if_icmpge     118
     107: iload_0
     108: iload         4
     110: iconst_1
     111: isub
     112: iload_2
     113: aload_3
     114: invokestatic  #33                 // Method ternarySearch:(IIILjava/util/ArrayList;)I
     117: ireturn
     118: iload_2
     119: aload_3
     120: iload         5
     122: invokevirtual #22                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     125: checkcast     #30                 // class java/lang/Number
     128: invokevirtual #31                 // Method java/lang/Number.intValue:()I
     131: if_icmple     145
     134: iload         5
     136: iconst_1
     137: iadd
     138: iload_1
     139: iload_2
     140: aload_3
     141: invokestatic  #33                 // Method ternarySearch:(IIILjava/util/ArrayList;)I
     144: ireturn
     145: iload         4
     147: iconst_1
     148: iadd
     149: iload         5
     151: iconst_1
     152: isub
     153: iload_2
     154: aload_3
     155: invokestatic  #33                 // Method ternarySearch:(IIILjava/util/ArrayList;)I
     158: ireturn
     159: iconst_m1
     160: ireturn

  public static final void main();
    Code:
       0: new           #44                 // class java/util/Scanner
       3: dup
       4: getstatic     #50                 // Field java/lang/System.in:Ljava/io/InputStream;
       7: invokespecial #54                 // Method java/util/Scanner."<init>":(Ljava/io/InputStream;)V
      10: astore_0
      11: ldc           #56                 // String Enter the length of the array
      13: getstatic     #60                 // Field java/lang/System.out:Ljava/io/PrintStream;
      16: swap
      17: invokevirtual #66                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      20: aload_0
      21: invokevirtual #69                 // Method java/util/Scanner.nextInt:()I
      24: istore_1
      25: new           #18                 // class java/util/ArrayList
      28: dup
      29: invokespecial #71                 // Method java/util/ArrayList."<init>":()V
      32: astore_2
      33: ldc           #73                 // String Enter the elements of the array in ascending order
      35: getstatic     #60                 // Field java/lang/System.out:Ljava/io/PrintStream;
      38: swap
      39: invokevirtual #66                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      42: iconst_0
      43: istore_3
      44: iload_3
      45: iload_1
      46: if_icmpge     71
      49: aload_0
      50: invokevirtual #69                 // Method java/util/Scanner.nextInt:()I
      53: istore        4
      55: aload_2
      56: iload         4
      58: invokestatic  #77                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      61: invokevirtual #81                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      64: pop
      65: iinc          3, 1
      68: goto          44
      71: ldc           #83                 // String Enter the number you want to search for :
      73: getstatic     #60                 // Field java/lang/System.out:Ljava/io/PrintStream;
      76: swap
      77: invokevirtual #86                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      80: aload_0
      81: invokevirtual #69                 // Method java/util/Scanner.nextInt:()I
      84: istore_3
      85: aload_0
      86: invokevirtual #89                 // Method java/util/Scanner.close:()V
      89: iconst_m1
      90: istore        4
      92: iload_1
      93: iconst_1
      94: isub
      95: istore        5
      97: iload         4
      99: iload         5
     101: iload_3
     102: aload_2
     103: invokestatic  #33                 // Method ternarySearch:(IIILjava/util/ArrayList;)I
     106: iconst_1
     107: iadd
     108: istore        6
     110: iload         6
     112: ifne          149
     115: new           #91                 // class java/lang/StringBuilder
     118: dup
     119: invokespecial #92                 // Method java/lang/StringBuilder."<init>":()V
     122: ldc           #94                 // String Key:
     124: invokevirtual #98                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     127: iload_3
     128: invokevirtual #101                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     131: ldc           #103                // String  is not present in the array
     133: invokevirtual #98                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     136: invokevirtual #107                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     139: getstatic     #60                 // Field java/lang/System.out:Ljava/io/PrintStream;
     142: swap
     143: invokevirtual #66                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     146: goto          185
     149: new           #91                 // class java/lang/StringBuilder
     152: dup
     153: invokespecial #92                 // Method java/lang/StringBuilder."<init>":()V
     156: ldc           #94                 // String Key:
     158: invokevirtual #98                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     161: iload_3
     162: invokevirtual #101                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     165: ldc           #109                // String  is present in the array at position
     167: invokevirtual #98                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     170: iload         6
     172: invokevirtual #101                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     175: invokevirtual #107                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     178: getstatic     #60                 // Field java/lang/System.out:Ljava/io/PrintStream;
     181: swap
     182: invokevirtual #66                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     185: return

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


// Function to Implement Radix Sort
// The radix sorting algorithm is an integer sorting algorithm,
// that sorts by grouping numbers by their individual digits (or by their radix).
// It uses each radix/digit as a key, and implements counting sort or
// bucket sort under the hood in order to do the work of sorting.

// Takes an IntArray as arguments and returns a sorted IntArray to the caller function
fun radixSort(original: IntArray): IntArray {
    // Array needs to be mutable
    var old = original
    for (shift in 31 downTo 0) {
        val tmp = IntArray(old.size)
        // The number of 0s
        var j = 0
        // Move the 0s to the new array, and the 1s to the old one
        for (i in 0 until old.size) {
            // If there is a 1 in the bit we are testing, the number will be negative
            val move = (old[i] shl shift) >= 0
            // If this is the last bit, negative numbers are actually lower
            val toBeMoved = if (shift != 0) move else !move
            if (toBeMoved) {
                tmp[j++] = old[i]
            }
            else {
                // It's a 1, so stick it in the old array for now
                old[i - j] = old[i]
            }
        }
        // Copy over the 1s from the old array
        for (i in j until tmp.size) {
            tmp[i] = old[i - j]
        }
        old = tmp
    }
    return old
}

fun main(args: Array<String>) {
    print("Enter N: ");
    val n= readLine()!!.toInt();
    println("Enter array of N integers: ");
    val arrays = IntArray(n) { readLine()!!.toInt() }
    val array= radixSort(arrays);
    print("Array after Radix Sort is: ")
    for(i in array){
        print("$i ")
    }
}

/*
Time Complexity: O(log n)
Sample Input:
Enter N: 5
Enter array of N integers:
3
-1
2
3
4

Sample Output:
Array after Radix Sort is: -1 2 3 3 4
 */

Compiled from "RadixSort.kt"
public final class RadixSortKt {
  public static final int[] radixSort(int[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String original
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: astore_1
       8: bipush        31
      10: istore_2
      11: iconst_m1
      12: iload_2
      13: if_icmpge     151
      16: aload_1
      17: arraylength
      18: newarray       int
      20: astore_3
      21: iconst_0
      22: istore        4
      24: iconst_0
      25: istore        5
      27: aload_1
      28: arraylength
      29: istore        6
      31: iload         5
      33: iload         6
      35: if_icmpge     111
      38: aload_1
      39: iload         5
      41: iaload
      42: iload_2
      43: ishl
      44: iflt          51
      47: iconst_1
      48: goto          52
      51: iconst_0
      52: istore        7
      54: iload_2
      55: ifeq          63
      58: iload         7
      60: goto          73
      63: iload         7
      65: ifne          72
      68: iconst_1
      69: goto          73
      72: iconst_0
      73: istore        8
      75: iload         8
      77: ifeq          94
      80: aload_3
      81: iload         4
      83: iinc          4, 1
      86: aload_1
      87: iload         5
      89: iaload
      90: iastore
      91: goto          105
      94: aload_1
      95: iload         5
      97: iload         4
      99: isub
     100: aload_1
     101: iload         5
     103: iaload
     104: iastore
     105: iinc          5, 1
     108: goto          31
     111: iload         4
     113: istore        5
     115: aload_3
     116: arraylength
     117: istore        6
     119: iload         5
     121: iload         6
     123: if_icmpge     143
     126: aload_3
     127: iload         5
     129: aload_1
     130: iload         5
     132: iload         4
     134: isub
     135: iaload
     136: iastore
     137: iinc          5, 1
     140: goto          119
     143: aload_3
     144: astore_1
     145: iinc          2, -1
     148: goto          11
     151: aload_1
     152: areturn

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #30                 // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #32                 // String Enter N:
       8: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: swap
      12: invokevirtual #44                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      15: invokestatic  #50                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
      18: dup
      19: invokestatic  #53                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      22: invokestatic  #59                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      25: istore_1
      26: ldc           #61                 // String Enter array of N integers:
      28: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
      31: swap
      32: invokevirtual #64                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      35: iconst_0
      36: istore_3
      37: iload_1
      38: newarray       int
      40: astore        4
      42: iload_3
      43: iload_1
      44: if_icmpge     71
      47: iload_3
      48: istore        5
      50: aload         4
      52: iload         5
      54: invokestatic  #50                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
      57: dup
      58: invokestatic  #53                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      61: invokestatic  #59                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      64: iastore
      65: iinc          3, 1
      68: goto          42
      71: aload         4
      73: astore_2
      74: aload_2
      75: invokestatic  #66                 // Method radixSort:([I)[I
      78: astore_3
      79: ldc           #68                 // String Array after Radix Sort is:
      81: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
      84: swap
      85: invokevirtual #44                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      88: iconst_0
      89: istore        4
      91: aload_3
      92: arraylength
      93: istore        5
      95: iload         4
      97: iload         5
      99: if_icmpge     141
     102: aload_3
     103: iload         4
     105: iaload
     106: istore        6
     108: new           #70                 // class java/lang/StringBuilder
     111: dup
     112: invokespecial #74                 // Method java/lang/StringBuilder."<init>":()V
     115: iload         6
     117: invokevirtual #78                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     120: bipush        32
     122: invokevirtual #81                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     125: invokevirtual #84                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     128: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
     131: swap
     132: invokevirtual #44                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     135: iinc          4, 1
     138: goto          95
     141: return
}


/*
QuickSort Algortihm works on Divide and Conquer Algorithm. It creates two empty arrays to hold elements less than the pivot value and
elements greater than the pivot value, and then recursively sort the sub arrays. There are two basic operations in the algorithm,
swapping items in place and partitioning a section of the array.
*/

//Importing the Java.util package, it is needed because we are using the scanner object.
import java.util.*

//The function which will sort the given array in ascending order using QuickSort Algortihm
fun quicksort(items:List<Int>):List<Int>{
    //If there is only one element in the list, then there is no need to sort
    if (items.count() < 2){
        return items
    }

    //Vaiable pivot stores the index of middle element of the list
    val pivot = items[items.count()/2]

    //Variable equalto stores the elements at the pivot index
    val equalto = items.filter { it == pivot }

    //Variable lesser stores the list of element with indexes less than the pivot index
    val lesser = items.filter { it < pivot }

    //Variable greater stores the list of element with indexes less than the pivot index
    val greater = items.filter { it > pivot }

    //Calling the quicksort function recursively on the splitted arrays
    //This will get recursively called until left with multiple arrays with a single element and arranged in order
    return quicksort(lesser) + equalto + quicksort(greater)
}
//Main Driver Code
fun main() {
    val input = Scanner(System.`in`)

    println("Enter the length of the array")
    val arrayLength = input.nextInt()
    val arrayOfElements = arrayListOf<Int>()

    println("Enter the List of numbers you want to Sort:")
    for(index in 0 until arrayLength) {
        val element = input.nextInt()
        arrayOfElements.add(element)
    }
    print("Original List: ")
    for(index in 0..4)
    {
        val number: Int = arrayOfElements[index]
        print("$number\t")
    }
    print("\nOrdered list: ")
    val ordered =  quicksort(arrayOfElements)
    println(ordered)
}

/*
First Testcasee:
Enter the length of the array
6
Enter the List of numbers you want to Sort:
34
33
67
3
2
45
Original List: 34	33	67	3	2   45
Ordered list: [2, 3, 33, 34, 45, 67]

Time Complexity: O(n log n)
Space Complexity: O(log n)
*/

Compiled from "QuickSort.kt"
public final class QuickSortKt {
  public static final java.util.List<java.lang.Integer> quicksort(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #10                 // String items
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #18                 // class java/util/Collection
      10: invokeinterface #22,  1           // InterfaceMethod java/util/Collection.size:()I
      15: iconst_2
      16: if_icmpge     21
      19: aload_0
      20: areturn
      21: aload_0
      22: aload_0
      23: checkcast     #18                 // class java/util/Collection
      26: invokeinterface #22,  1           // InterfaceMethod java/util/Collection.size:()I
      31: iconst_2
      32: idiv
      33: invokeinterface #28,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      38: checkcast     #30                 // class java/lang/Number
      41: invokevirtual #33                 // Method java/lang/Number.intValue:()I
      44: istore_1
      45: aload_0
      46: checkcast     #35                 // class java/lang/Iterable
      49: astore_3
      50: iconst_0
      51: istore        4
      53: aload_3
      54: astore        5
      56: new           #37                 // class java/util/ArrayList
      59: dup
      60: invokespecial #41                 // Method java/util/ArrayList."<init>":()V
      63: checkcast     #18                 // class java/util/Collection
      66: astore        6
      68: iconst_0
      69: istore        7
      71: aload         5
      73: invokeinterface #45,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      78: astore        8
      80: aload         8
      82: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      87: ifeq          139
      90: aload         8
      92: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      97: astore        9
      99: aload         9
     101: checkcast     #30                 // class java/lang/Number
     104: invokevirtual #33                 // Method java/lang/Number.intValue:()I
     107: istore        10
     109: iconst_0
     110: istore        11
     112: iload         10
     114: iload_1
     115: if_icmpne     122
     118: iconst_1
     119: goto          123
     122: iconst_0
     123: ifeq          80
     126: aload         6
     128: aload         9
     130: invokeinterface #59,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     135: pop
     136: goto          80
     139: aload         6
     141: checkcast     #24                 // class java/util/List
     144: nop
     145: astore_2
     146: aload_0
     147: checkcast     #35                 // class java/lang/Iterable
     150: astore        4
     152: iconst_0
     153: istore        5
     155: aload         4
     157: astore        6
     159: new           #37                 // class java/util/ArrayList
     162: dup
     163: invokespecial #41                 // Method java/util/ArrayList."<init>":()V
     166: checkcast     #18                 // class java/util/Collection
     169: astore        7
     171: iconst_0
     172: istore        8
     174: aload         6
     176: invokeinterface #45,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     181: astore        9
     183: aload         9
     185: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     190: ifeq          242
     193: aload         9
     195: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     200: astore        10
     202: aload         10
     204: checkcast     #30                 // class java/lang/Number
     207: invokevirtual #33                 // Method java/lang/Number.intValue:()I
     210: istore        11
     212: iconst_0
     213: istore        12
     215: iload         11
     217: iload_1
     218: if_icmpge     225
     221: iconst_1
     222: goto          226
     225: iconst_0
     226: ifeq          183
     229: aload         7
     231: aload         10
     233: invokeinterface #59,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     238: pop
     239: goto          183
     242: aload         7
     244: checkcast     #24                 // class java/util/List
     247: nop
     248: astore_3
     249: aload_0
     250: checkcast     #35                 // class java/lang/Iterable
     253: astore        5
     255: iconst_0
     256: istore        6
     258: aload         5
     260: astore        7
     262: new           #37                 // class java/util/ArrayList
     265: dup
     266: invokespecial #41                 // Method java/util/ArrayList."<init>":()V
     269: checkcast     #18                 // class java/util/Collection
     272: astore        8
     274: iconst_0
     275: istore        9
     277: aload         7
     279: invokeinterface #45,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     284: astore        10
     286: aload         10
     288: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     293: ifeq          345
     296: aload         10
     298: invokeinterface #55,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     303: astore        11
     305: aload         11
     307: checkcast     #30                 // class java/lang/Number
     310: invokevirtual #33                 // Method java/lang/Number.intValue:()I
     313: istore        12
     315: iconst_0
     316: istore        13
     318: iload         12
     320: iload_1
     321: if_icmple     328
     324: iconst_1
     325: goto          329
     328: iconst_0
     329: ifeq          286
     332: aload         8
     334: aload         11
     336: invokeinterface #59,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     341: pop
     342: goto          286
     345: aload         8
     347: checkcast     #24                 // class java/util/List
     350: nop
     351: astore        4
     353: aload_3
     354: invokestatic  #61                 // Method quicksort:(Ljava/util/List;)Ljava/util/List;
     357: checkcast     #18                 // class java/util/Collection
     360: aload_2
     361: checkcast     #35                 // class java/lang/Iterable
     364: invokestatic  #67                 // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     367: checkcast     #18                 // class java/util/Collection
     370: aload         4
     372: invokestatic  #61                 // Method quicksort:(Ljava/util/List;)Ljava/util/List;
     375: checkcast     #35                 // class java/lang/Iterable
     378: invokestatic  #67                 // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     381: areturn

  public static final void main();
    Code:
       0: new           #89                 // class java/util/Scanner
       3: dup
       4: getstatic     #95                 // Field java/lang/System.in:Ljava/io/InputStream;
       7: invokespecial #98                 // Method java/util/Scanner."<init>":(Ljava/io/InputStream;)V
      10: astore_0
      11: ldc           #100                // String Enter the length of the array
      13: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
      16: swap
      17: invokevirtual #110                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      20: aload_0
      21: invokevirtual #113                // Method java/util/Scanner.nextInt:()I
      24: istore_1
      25: new           #37                 // class java/util/ArrayList
      28: dup
      29: invokespecial #41                 // Method java/util/ArrayList."<init>":()V
      32: astore_2
      33: ldc           #115                // String Enter the List of numbers you want to Sort:
      35: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
      38: swap
      39: invokevirtual #110                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      42: iconst_0
      43: istore_3
      44: iload_3
      45: iload_1
      46: if_icmpge     71
      49: aload_0
      50: invokevirtual #113                // Method java/util/Scanner.nextInt:()I
      53: istore        4
      55: aload_2
      56: iload         4
      58: invokestatic  #121                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      61: invokevirtual #122                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      64: pop
      65: iinc          3, 1
      68: goto          44
      71: ldc           #124                // String Original List:
      73: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
      76: swap
      77: invokevirtual #127                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      80: iconst_0
      81: istore_3
      82: iload_3
      83: iconst_5
      84: if_icmpge     139
      87: aload_2
      88: iload_3
      89: invokevirtual #128                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      92: dup
      93: ldc           #130                // String get(...)
      95: invokestatic  #133                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      98: checkcast     #30                 // class java/lang/Number
     101: invokevirtual #33                 // Method java/lang/Number.intValue:()I
     104: istore        4
     106: new           #135                // class java/lang/StringBuilder
     109: dup
     110: invokespecial #136                // Method java/lang/StringBuilder."<init>":()V
     113: iload         4
     115: invokevirtual #140                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     118: bipush        9
     120: invokevirtual #143                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     123: invokevirtual #147                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     126: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
     129: swap
     130: invokevirtual #127                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     133: iinc          3, 1
     136: goto          82
     139: ldc           #149                // String \nOrdered list:
     141: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
     144: swap
     145: invokevirtual #127                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     148: aload_2
     149: checkcast     #24                 // class java/util/List
     152: invokestatic  #61                 // Method quicksort:(Ljava/util/List;)Ljava/util/List;
     155: astore_3
     156: getstatic     #104                // Field java/lang/System.out:Ljava/io/PrintStream;
     159: aload_3
     160: invokevirtual #110                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     163: return

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


/**
 * Solution to https://adventofcode.com/2020/day/21
 */

import java.io.File

fun main(args: Array<String>) {
  var input: String = args[0]
  var potentialAllergens = mutableMapOf<String, MutableSet<String>>()
  var allIngredients = mutableListOf<String>()
  var pattern: Regex = Regex("((\\w+ )+)\\(contains (\\w+(, \\w+)*)\\)\n?")
  File(input).forEachLine { line ->
    var match = pattern.matchEntire(line)
    var ingredients = match!!.groupValues[1].split(" ").filter { it.isNotBlank() }
    allIngredients.addAll(ingredients)
    match.groupValues[3].split(", ").forEach { element ->
      if (element.isNotBlank()) {
        if (element in potentialAllergens) {
          potentialAllergens[element] = potentialAllergens[element]!!.intersect(ingredients) as MutableSet<String>
        } else {
          potentialAllergens[element] = ingredients.toMutableSet()
        }
      }
    }
  }

  var allPotentialIngredients = mutableSetOf<String>()
  potentialAllergens.values.forEach { ingredients ->
    allPotentialIngredients.addAll(ingredients)
  }

  var safeIngredients = 0
  allIngredients.forEach { ingredient ->
    if (!allPotentialIngredients.contains(ingredient)) {
      safeIngredients += 1
    }
  }
  println("Safe ingredients: ${safeIngredients}")

  val foundIngredients = mutableSetOf<String>()
  val foundAllergens = mutableMapOf<String,String>()
  var unmatchedAllergens = true
  while (unmatchedAllergens) {
    unmatchedAllergens = false
    potentialAllergens.forEach { allergen, ingredients ->
      if (!(allergen in foundAllergens)) {
	unmatchedAllergens = true
        if (potentialAllergens[allergen]!!.size == 1) {
	  foundIngredients.addAll(ingredients)
	  foundAllergens[allergen] = ingredients.first()
	} else {
	  potentialAllergens[allergen]!!.removeAll(foundIngredients)
	}
      }
    }
  }

  println("Ingredients: ${foundAllergens.toSortedMap().values.joinTo(StringBuffer(""), ",").toString()}")
}

Compiled from "allergens.kt"
public final class AllergensKt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_0
       8: aaload
       9: astore_1
      10: new           #17                 // class kotlin/jvm/internal/Ref$ObjectRef
      13: dup
      14: invokespecial #21                 // Method kotlin/jvm/internal/Ref$ObjectRef."<init>":()V
      17: astore_2
      18: aload_2
      19: new           #23                 // class java/util/LinkedHashMap
      22: dup
      23: invokespecial #24                 // Method java/util/LinkedHashMap."<init>":()V
      26: checkcast     #26                 // class java/util/Map
      29: putfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
      32: new           #17                 // class kotlin/jvm/internal/Ref$ObjectRef
      35: dup
      36: invokespecial #21                 // Method kotlin/jvm/internal/Ref$ObjectRef."<init>":()V
      39: astore_3
      40: aload_3
      41: new           #32                 // class java/util/ArrayList
      44: dup
      45: invokespecial #33                 // Method java/util/ArrayList."<init>":()V
      48: checkcast     #35                 // class java/util/List
      51: putfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
      54: new           #17                 // class kotlin/jvm/internal/Ref$ObjectRef
      57: dup
      58: invokespecial #21                 // Method kotlin/jvm/internal/Ref$ObjectRef."<init>":()V
      61: astore        4
      63: aload         4
      65: new           #37                 // class kotlin/text/Regex
      68: dup
      69: ldc           #39                 // String ((\\w+ )+)\\(contains (\\w+(, \\w+)*)\\)\n?
      71: invokespecial #42                 // Method kotlin/text/Regex."<init>":(Ljava/lang/String;)V
      74: putfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
      77: new           #44                 // class java/io/File
      80: dup
      81: aload_1
      82: invokespecial #45                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      85: aconst_null
      86: aload         4
      88: aload_3
      89: aload_2
      90: invokedynamic #65,  0             // InvokeDynamic #0:invoke:(Lkotlin/jvm/internal/Ref$ObjectRef;Lkotlin/jvm/internal/Ref$ObjectRef;Lkotlin/jvm/internal/Ref$ObjectRef;)Lkotlin/jvm/functions/Function1;
      95: iconst_1
      96: aconst_null
      97: invokestatic  #71                 // Method kotlin/io/FilesKt.forEachLine$default:(Ljava/io/File;Ljava/nio/charset/Charset;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
     100: aconst_null
     101: astore        5
     103: new           #73                 // class java/util/LinkedHashSet
     106: dup
     107: invokespecial #74                 // Method java/util/LinkedHashSet."<init>":()V
     110: checkcast     #76                 // class java/util/Set
     113: astore        5
     115: aload_2
     116: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     119: checkcast     #26                 // class java/util/Map
     122: invokeinterface #80,  1           // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
     127: checkcast     #82                 // class java/lang/Iterable
     130: astore        6
     132: iconst_0
     133: istore        7
     135: aload         6
     137: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     142: astore        8
     144: aload         8
     146: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     151: ifeq          191
     154: aload         8
     156: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     161: astore        9
     163: aload         9
     165: checkcast     #76                 // class java/util/Set
     168: astore        10
     170: iconst_0
     171: istore        11
     173: aload         5
     175: aload         10
     177: checkcast     #98                 // class java/util/Collection
     180: invokeinterface #102,  2          // InterfaceMethod java/util/Set.addAll:(Ljava/util/Collection;)Z
     185: pop
     186: nop
     187: nop
     188: goto          144
     191: nop
     192: iconst_0
     193: istore        6
     195: aload_3
     196: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     199: checkcast     #82                 // class java/lang/Iterable
     202: astore        7
     204: iconst_0
     205: istore        8
     207: aload         7
     209: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     214: astore        9
     216: aload         9
     218: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     223: ifeq          268
     226: aload         9
     228: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     233: astore        10
     235: aload         10
     237: checkcast     #104                // class java/lang/String
     240: astore        11
     242: iconst_0
     243: istore        12
     245: aload         5
     247: aload         11
     249: invokeinterface #108,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     254: ifne          263
     257: iload         6
     259: iconst_1
     260: iadd
     261: istore        6
     263: nop
     264: nop
     265: goto          216
     268: nop
     269: new           #110                // class java/lang/StringBuilder
     272: dup
     273: invokespecial #111                // Method java/lang/StringBuilder."<init>":()V
     276: ldc           #113                // String Safe ingredients:
     278: invokevirtual #117                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     281: iload         6
     283: invokevirtual #120                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     286: invokevirtual #124                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     289: getstatic     #130                // Field java/lang/System.out:Ljava/io/PrintStream;
     292: swap
     293: invokevirtual #136                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     296: new           #73                 // class java/util/LinkedHashSet
     299: dup
     300: invokespecial #74                 // Method java/util/LinkedHashSet."<init>":()V
     303: checkcast     #76                 // class java/util/Set
     306: astore        7
     308: new           #23                 // class java/util/LinkedHashMap
     311: dup
     312: invokespecial #24                 // Method java/util/LinkedHashMap."<init>":()V
     315: checkcast     #26                 // class java/util/Map
     318: astore        8
     320: new           #138                // class kotlin/jvm/internal/Ref$BooleanRef
     323: dup
     324: invokespecial #139                // Method kotlin/jvm/internal/Ref$BooleanRef."<init>":()V
     327: astore        9
     329: aload         9
     331: iconst_1
     332: putfield      #142                // Field kotlin/jvm/internal/Ref$BooleanRef.element:Z
     335: aload         9
     337: getfield      #142                // Field kotlin/jvm/internal/Ref$BooleanRef.element:Z
     340: ifeq          381
     343: aload         9
     345: iconst_0
     346: putfield      #142                // Field kotlin/jvm/internal/Ref$BooleanRef.element:Z
     349: aload_2
     350: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     353: checkcast     #26                 // class java/util/Map
     356: aload         8
     358: aload         9
     360: aload_2
     361: aload         7
     363: invokedynamic #154,  0            // InvokeDynamic #1:invoke:(Ljava/util/Map;Lkotlin/jvm/internal/Ref$BooleanRef;Lkotlin/jvm/internal/Ref$ObjectRef;Ljava/util/Set;)Lkotlin/jvm/functions/Function2;
     368: invokedynamic #165,  0            // InvokeDynamic #2:accept:(Lkotlin/jvm/functions/Function2;)Ljava/util/function/BiConsumer;
     373: invokeinterface #169,  2          // InterfaceMethod java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
     378: goto          335
     381: new           #110                // class java/lang/StringBuilder
     384: dup
     385: invokespecial #111                // Method java/lang/StringBuilder."<init>":()V
     388: ldc           #171                // String Ingredients:
     390: invokevirtual #117                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     393: aload         8
     395: invokestatic  #177                // Method kotlin/collections/MapsKt.toSortedMap:(Ljava/util/Map;)Ljava/util/SortedMap;
     398: invokeinterface #180,  1          // InterfaceMethod java/util/SortedMap.values:()Ljava/util/Collection;
     403: dup
     404: ldc           #182                // String <get-values>(...)
     406: invokestatic  #185                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     409: checkcast     #82                 // class java/lang/Iterable
     412: new           #187                // class java/lang/StringBuffer
     415: dup
     416: ldc           #189                // String
     418: invokespecial #190                // Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
     421: checkcast     #192                // class java/lang/Appendable
     424: ldc           #194                // String ,
     426: checkcast     #196                // class java/lang/CharSequence
     429: aconst_null
     430: aconst_null
     431: iconst_0
     432: aconst_null
     433: aconst_null
     434: bipush        124
     436: aconst_null
     437: invokestatic  #202                // Method kotlin/collections/CollectionsKt.joinTo$default:(Ljava/lang/Iterable;Ljava/lang/Appendable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/Appendable;
     440: invokevirtual #205                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     443: invokevirtual #124                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     446: getstatic     #130                // Field java/lang/System.out:Ljava/io/PrintStream;
     449: swap
     450: invokevirtual #136                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     453: return

  private static final kotlin.Unit main$lambda$2(kotlin.jvm.internal.Ref$ObjectRef, kotlin.jvm.internal.Ref$ObjectRef, kotlin.jvm.internal.Ref$ObjectRef, java.lang.String);
    Code:
       0: aload_3
       1: ldc           #232                // String line
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
      10: checkcast     #37                 // class kotlin/text/Regex
      13: aload_3
      14: checkcast     #196                // class java/lang/CharSequence
      17: invokevirtual #236                // Method kotlin/text/Regex.matchEntire:(Ljava/lang/CharSequence;)Lkotlin/text/MatchResult;
      20: astore        4
      22: aconst_null
      23: astore        5
      25: aload         4
      27: dup
      28: invokestatic  #239                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      31: invokeinterface #245,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
      36: iconst_1
      37: invokeinterface #249,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      42: checkcast     #196                // class java/lang/CharSequence
      45: iconst_1
      46: anewarray     #104                // class java/lang/String
      49: astore        6
      51: aload         6
      53: iconst_0
      54: ldc           #251                // String
      56: aastore
      57: aload         6
      59: iconst_0
      60: iconst_0
      61: bipush        6
      63: aconst_null
      64: invokestatic  #257                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      67: checkcast     #82                 // class java/lang/Iterable
      70: astore        6
      72: iconst_0
      73: istore        7
      75: aload         6
      77: astore        8
      79: new           #32                 // class java/util/ArrayList
      82: dup
      83: invokespecial #33                 // Method java/util/ArrayList."<init>":()V
      86: checkcast     #98                 // class java/util/Collection
      89: astore        9
      91: iconst_0
      92: istore        10
      94: aload         8
      96: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     101: astore        11
     103: aload         11
     105: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     110: ifeq          165
     113: aload         11
     115: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     120: astore        12
     122: aload         12
     124: checkcast     #104                // class java/lang/String
     127: astore        13
     129: iconst_0
     130: istore        14
     132: aload         13
     134: checkcast     #196                // class java/lang/CharSequence
     137: invokestatic  #261                // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
     140: ifne          147
     143: iconst_1
     144: goto          148
     147: iconst_0
     148: nop
     149: ifeq          103
     152: aload         9
     154: aload         12
     156: invokeinterface #264,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     161: pop
     162: goto          103
     165: aload         9
     167: checkcast     #35                 // class java/util/List
     170: nop
     171: astore        5
     173: aload_1
     174: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     177: checkcast     #35                 // class java/util/List
     180: aload         5
     182: checkcast     #98                 // class java/util/Collection
     185: invokeinterface #265,  2          // InterfaceMethod java/util/List.addAll:(Ljava/util/Collection;)Z
     190: pop
     191: aload         4
     193: invokeinterface #245,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     198: iconst_3
     199: invokeinterface #249,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     204: checkcast     #196                // class java/lang/CharSequence
     207: iconst_1
     208: anewarray     #104                // class java/lang/String
     211: astore        6
     213: aload         6
     215: iconst_0
     216: ldc_w         #267                // String ,
     219: aastore
     220: aload         6
     222: iconst_0
     223: iconst_0
     224: bipush        6
     226: aconst_null
     227: invokestatic  #257                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     230: checkcast     #82                 // class java/lang/Iterable
     233: astore        6
     235: iconst_0
     236: istore        7
     238: aload         6
     240: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     245: astore        8
     247: aload         8
     249: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     254: ifeq          405
     257: aload         8
     259: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     264: astore        9
     266: aload         9
     268: checkcast     #104                // class java/lang/String
     271: astore        10
     273: iconst_0
     274: istore        11
     276: aload         10
     278: checkcast     #196                // class java/lang/CharSequence
     281: invokestatic  #261                // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
     284: ifne          291
     287: iconst_1
     288: goto          292
     291: iconst_0
     292: ifeq          400
     295: aload_2
     296: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     299: checkcast     #26                 // class java/util/Map
     302: aload         10
     304: invokeinterface #270,  2          // InterfaceMethod java/util/Map.containsKey:(Ljava/lang/Object;)Z
     309: ifeq          377
     312: aload_2
     313: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     316: checkcast     #26                 // class java/util/Map
     319: astore        12
     321: aload_2
     322: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     325: checkcast     #26                 // class java/util/Map
     328: aload         10
     330: invokeinterface #272,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     335: dup
     336: invokestatic  #239                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     339: checkcast     #82                 // class java/lang/Iterable
     342: aload         5
     344: checkcast     #82                 // class java/lang/Iterable
     347: invokestatic  #276                // Method kotlin/collections/CollectionsKt.intersect:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/Set;
     350: dup
     351: ldc_w         #278                // String null cannot be cast to non-null type kotlin.collections.MutableSet<kotlin.String>
     354: invokestatic  #280                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
     357: invokestatic  #286                // Method kotlin/jvm/internal/TypeIntrinsics.asMutableSet:(Ljava/lang/Object;)Ljava/util/Set;
     360: astore        13
     362: aload         12
     364: aload         10
     366: aload         13
     368: invokeinterface #289,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     373: pop
     374: goto          400
     377: aload_2
     378: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
     381: checkcast     #26                 // class java/util/Map
     384: aload         10
     386: aload         5
     388: checkcast     #82                 // class java/lang/Iterable
     391: invokestatic  #293                // Method kotlin/collections/CollectionsKt.toMutableSet:(Ljava/lang/Iterable;)Ljava/util/Set;
     394: invokeinterface #289,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     399: pop
     400: nop
     401: nop
     402: goto          247
     405: nop
     406: getstatic     #299                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     409: areturn

  private static final kotlin.Unit main$lambda$5(java.util.Map, kotlin.jvm.internal.Ref$BooleanRef, kotlin.jvm.internal.Ref$ObjectRef, java.util.Set, java.lang.String, java.util.Set);
    Code:
       0: aload         4
       2: ldc_w         #316                // String allergen
       5: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       8: aload         5
      10: ldc_w         #317                // String ingredients
      13: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      16: aload_0
      17: aload         4
      19: invokeinterface #270,  2          // InterfaceMethod java/util/Map.containsKey:(Ljava/lang/Object;)Z
      24: ifne          125
      27: aload_1
      28: iconst_1
      29: putfield      #142                // Field kotlin/jvm/internal/Ref$BooleanRef.element:Z
      32: aload_2
      33: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
      36: checkcast     #26                 // class java/util/Map
      39: aload         4
      41: invokeinterface #272,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      46: dup
      47: invokestatic  #239                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      50: checkcast     #76                 // class java/util/Set
      53: invokeinterface #321,  1          // InterfaceMethod java/util/Set.size:()I
      58: iconst_1
      59: if_icmpne     94
      62: aload_3
      63: aload         5
      65: checkcast     #98                 // class java/util/Collection
      68: invokeinterface #102,  2          // InterfaceMethod java/util/Set.addAll:(Ljava/util/Collection;)Z
      73: pop
      74: aload_0
      75: aload         4
      77: aload         5
      79: checkcast     #82                 // class java/lang/Iterable
      82: invokestatic  #325                // Method kotlin/collections/CollectionsKt.first:(Ljava/lang/Iterable;)Ljava/lang/Object;
      85: invokeinterface #289,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      90: pop
      91: goto          125
      94: aload_2
      95: getfield      #30                 // Field kotlin/jvm/internal/Ref$ObjectRef.element:Ljava/lang/Object;
      98: checkcast     #26                 // class java/util/Map
     101: aload         4
     103: invokeinterface #272,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     108: dup
     109: invokestatic  #239                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     112: checkcast     #76                 // class java/util/Set
     115: aload_3
     116: checkcast     #98                 // class java/util/Collection
     119: invokeinterface #328,  2          // InterfaceMethod java/util/Set.removeAll:(Ljava/util/Collection;)Z
     124: pop
     125: getstatic     #299                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     128: areturn

  private static final void main$lambda$6(kotlin.jvm.functions.Function2, java.lang.Object, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: aload_2
       3: invokeinterface #335,  3          // InterfaceMethod kotlin/jvm/functions/Function2.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
       8: pop
       9: return
}


/**
 * Solution to https://adventofcode.com/2020/day/13
 */

import java.io.File

fun gcf(a: Long, b: Long): Long {
  var tmp: Long
  var aa = a
  var bb = b
  while (bb != 0L) {
    tmp = aa % bb
    aa = bb
    bb = tmp
  }
  return aa
}

fun lcm(vals: List<Long>): Long {
  return vals.reduce{a, b -> a*b/gcf(a,b)}
}

fun main(args: Array<String>) {
  var input: String = args[0]
  var raw: String = File(input).readText()
  var secondLine: String = raw.split("\n")[1]

  // Part 1
  var desiredDepartureTime: Long = raw.split("\n")[0].toLong()
  var waitTime = Long.MAX_VALUE
  var bestRoute: Long = 0
  for (routeLabel in secondLine.split(",")) {
    if (routeLabel.equals("x")) {
      continue
    }
    var routeNum = routeLabel.toLong()
    var remainder = desiredDepartureTime % routeNum
    var potentialWaitTime: Long
    if (remainder > 0) {
      potentialWaitTime = routeNum - remainder
    } else {
      potentialWaitTime = 0
    }
    if (potentialWaitTime < waitTime) {
      waitTime = potentialWaitTime
      bestRoute = routeNum
    }
  }
  println("Product of route num and wait time: ${bestRoute * waitTime}")

  // Part 2
  var increment: Long
  var startTime = 0L
  while (true) {
    var failedYet: Boolean = false
    var goodNums: MutableList<Long> = ArrayList()
    for ((index, routeName) in secondLine.split(",").withIndex()) {
      if (routeName.equals("x")) {
        continue
      }
      var routeNum = routeName.toInt()
      if ((startTime + index) % routeNum != 0L) {
        failedYet = true
      } else {
        goodNums.add(routeNum.toLong())
      }
    }
    if (!failedYet) {
      break
    }
    increment = lcm(goodNums)
    startTime += increment
  }
  println("Earliest timestamp: ${startTime}")
}

Compiled from "bus.kt"
public final class BusKt {
  public static final long gcf(long, long);
    Code:
       0: lconst_0
       1: lstore        4
       3: lload_0
       4: lstore        6
       6: lload_2
       7: lstore        8
       9: lload         8
      11: lconst_0
      12: lcmp
      13: ifeq          34
      16: lload         6
      18: lload         8
      20: lrem
      21: lstore        4
      23: lload         8
      25: lstore        6
      27: lload         4
      29: lstore        8
      31: goto          9
      34: lload         6
      36: lreturn

  public static final long lcm(java.util.List<java.lang.Long>);
    Code:
       0: aload_0
       1: ldc           #18                 // String vals
       3: invokestatic  #24                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #26                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      19: astore_3
      20: aload_3
      21: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      26: ifne          39
      29: new           #38                 // class java/lang/UnsupportedOperationException
      32: dup
      33: ldc           #40                 // String Empty collection can\'t be reduced.
      35: invokespecial #44                 // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
      38: athrow
      39: aload_3
      40: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      45: astore        4
      47: aload_3
      48: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          104
      56: aload         4
      58: aload_3
      59: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      64: checkcast     #50                 // class java/lang/Number
      67: invokevirtual #54                 // Method java/lang/Number.longValue:()J
      70: lstore        5
      72: checkcast     #50                 // class java/lang/Number
      75: invokevirtual #54                 // Method java/lang/Number.longValue:()J
      78: lstore        7
      80: iconst_0
      81: istore        9
      83: lload         7
      85: lload         5
      87: lmul
      88: lload         7
      90: lload         5
      92: invokestatic  #56                 // Method gcf:(JJ)J
      95: ldiv
      96: invokestatic  #62                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      99: astore        4
     101: goto          47
     104: aload         4
     106: checkcast     #50                 // class java/lang/Number
     109: invokevirtual #54                 // Method java/lang/Number.longValue:()J
     112: lreturn

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #76                 // String args
       3: invokestatic  #24                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_0
       8: aaload
       9: astore_1
      10: new           #78                 // class java/io/File
      13: dup
      14: aload_1
      15: invokespecial #79                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      18: aconst_null
      19: iconst_1
      20: aconst_null
      21: invokestatic  #85                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
      24: astore_2
      25: aload_2
      26: checkcast     #87                 // class java/lang/CharSequence
      29: iconst_1
      30: anewarray     #89                 // class java/lang/String
      33: astore        4
      35: aload         4
      37: iconst_0
      38: ldc           #91                 // String \n
      40: aastore
      41: aload         4
      43: iconst_0
      44: iconst_0
      45: bipush        6
      47: aconst_null
      48: invokestatic  #97                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      51: iconst_1
      52: invokeinterface #103,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      57: checkcast     #89                 // class java/lang/String
      60: astore_3
      61: aload_2
      62: checkcast     #87                 // class java/lang/CharSequence
      65: iconst_1
      66: anewarray     #89                 // class java/lang/String
      69: astore        6
      71: aload         6
      73: iconst_0
      74: ldc           #91                 // String \n
      76: aastore
      77: aload         6
      79: iconst_0
      80: iconst_0
      81: bipush        6
      83: aconst_null
      84: invokestatic  #97                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      87: iconst_0
      88: invokeinterface #103,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      93: checkcast     #89                 // class java/lang/String
      96: invokestatic  #107                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
      99: lstore        4
     101: ldc2_w        #108                // long 9223372036854775807l
     104: lstore        6
     106: lconst_0
     107: lstore        8
     109: aload_3
     110: checkcast     #87                 // class java/lang/CharSequence
     113: iconst_1
     114: anewarray     #89                 // class java/lang/String
     117: astore        11
     119: aload         11
     121: iconst_0
     122: ldc           #111                // String ,
     124: aastore
     125: aload         11
     127: iconst_0
     128: iconst_0
     129: bipush        6
     131: aconst_null
     132: invokestatic  #97                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     135: invokeinterface #112,  1          // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     140: astore        10
     142: aload         10
     144: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     149: ifeq          233
     152: aload         10
     154: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     159: checkcast     #89                 // class java/lang/String
     162: astore        11
     164: aload         11
     166: ldc           #114                // String x
     168: invokevirtual #118                // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     171: ifeq          177
     174: goto          142
     177: aload         11
     179: invokestatic  #107                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     182: lstore        12
     184: lload         4
     186: lload         12
     188: lrem
     189: lstore        14
     191: lconst_0
     192: lstore        16
     194: lload         14
     196: lconst_0
     197: lcmp
     198: ifle          211
     201: lload         12
     203: lload         14
     205: lsub
     206: lstore        16
     208: goto          214
     211: lconst_0
     212: lstore        16
     214: lload         16
     216: lload         6
     218: lcmp
     219: ifge          142
     222: lload         16
     224: lstore        6
     226: lload         12
     228: lstore        8
     230: goto          142
     233: new           #120                // class java/lang/StringBuilder
     236: dup
     237: invokespecial #123                // Method java/lang/StringBuilder."<init>":()V
     240: ldc           #125                // String Product of route num and wait time:
     242: invokevirtual #129                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     245: lload         8
     247: lload         6
     249: lmul
     250: invokevirtual #132                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     253: invokevirtual #136                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     256: getstatic     #142                // Field java/lang/System.out:Ljava/io/PrintStream;
     259: swap
     260: invokevirtual #148                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     263: lconst_0
     264: lstore        10
     266: lconst_0
     267: lstore        12
     269: nop
     270: iconst_0
     271: istore        14
     273: new           #150                // class java/util/ArrayList
     276: dup
     277: invokespecial #151                // Method java/util/ArrayList."<init>":()V
     280: checkcast     #99                 // class java/util/List
     283: astore        15
     285: aload_3
     286: checkcast     #87                 // class java/lang/CharSequence
     289: iconst_1
     290: anewarray     #89                 // class java/lang/String
     293: astore        17
     295: aload         17
     297: iconst_0
     298: ldc           #111                // String ,
     300: aastore
     301: aload         17
     303: iconst_0
     304: iconst_0
     305: bipush        6
     307: aconst_null
     308: invokestatic  #97                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     311: checkcast     #26                 // class java/lang/Iterable
     314: invokeinterface #30,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     319: astore        16
     321: iconst_0
     322: istore        17
     324: aload         16
     326: invokeinterface #36,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     331: ifeq          414
     334: iload         17
     336: istore        18
     338: iload         17
     340: iconst_1
     341: iadd
     342: istore        17
     344: aload         16
     346: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     351: checkcast     #89                 // class java/lang/String
     354: astore        19
     356: aload         19
     358: ldc           #114                // String x
     360: invokevirtual #118                // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     363: ifeq          369
     366: goto          324
     369: aload         19
     371: invokestatic  #157                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     374: istore        20
     376: lload         12
     378: iload         18
     380: i2l
     381: ladd
     382: iload         20
     384: i2l
     385: lrem
     386: lconst_0
     387: lcmp
     388: ifeq          397
     391: iconst_1
     392: istore        14
     394: goto          324
     397: aload         15
     399: iload         20
     401: i2l
     402: invokestatic  #62                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     405: invokeinterface #160,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     410: pop
     411: goto          324
     414: iload         14
     416: ifne          422
     419: goto          439
     422: aload         15
     424: invokestatic  #162                // Method lcm:(Ljava/util/List;)J
     427: lstore        10
     429: lload         12
     431: lload         10
     433: ladd
     434: lstore        12
     436: goto          269
     439: new           #120                // class java/lang/StringBuilder
     442: dup
     443: invokespecial #123                // Method java/lang/StringBuilder."<init>":()V
     446: ldc           #164                // String Earliest timestamp:
     448: invokevirtual #129                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     451: lload         12
     453: invokevirtual #132                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     456: invokevirtual #136                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     459: getstatic     #142                // Field java/lang/System.out:Ljava/io/PrintStream;
     462: swap
     463: invokevirtual #148                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     466: return
}


// Strategy Pattern Example

// ソートアルゴリズムのStrategyインターフェース
interface SortStrategy {
    fun sort(numbers: IntArray): IntArray
}

// バブルソートアルゴリズム
class BubbleSortStrategy : SortStrategy {
    override fun sort(numbers: IntArray): IntArray {
        val sortedArray = numbers.clone()
        val n = sortedArray.size
        for (i in 0 until n) {
            for (j in 0 until n - i - 1) {
                if (sortedArray[j] > sortedArray[j + 1]) {
                    val temp = sortedArray[j]
                    sortedArray[j] = sortedArray[j + 1]
                    sortedArray[j + 1] = temp
                }
            }
        }
        return sortedArray
    }
}

// クイックソートアルゴリズム
class QuickSortStrategy : SortStrategy {
    override fun sort(numbers: IntArray): IntArray {
        if (numbers.size <= 1) return numbers

        val pivot = numbers[numbers.size / 2]
        val equal = numbers.filter { it == pivot }.toIntArray()
        val less = numbers.filter { it < pivot }.toIntArray()
        val greater = numbers.filter { it > pivot }.toIntArray()

        return sort(less) + equal + sort(greater)
    }
}

// ソートを実行するコンテキストクラス
class SortContext(private val strategy: SortStrategy) {
    fun executeSort(numbers: IntArray): IntArray {
        return strategy.sort(numbers)
    }
}

fun main() {
    val numbers = intArrayOf(9, 3, 7, 1, 5)

    // バブルソートを用いたソート
    val bubbleSortStrategy = BubbleSortStrategy()
    val bubbleSortContext = SortContext(bubbleSortStrategy)
    val sortedWithBubbleSort = bubbleSortContext.executeSort(numbers)
    println("バブルソートの結果: ${sortedWithBubbleSort.joinToString()}")

    // クイックソートを用いたソート
    val quickSortStrategy = QuickSortStrategy()
    val quickSortContext = SortContext(quickSortStrategy)
    val sortedWithQuickSort = quickSortContext.executeSort(numbers)
    println("クイックソートの結果: ${sortedWithQuickSort.joinToString()}")
}

Compiled from "Strategy.kt"
public final class StrategyKt {
  public static final void main();
    Code:
       0: iconst_5
       1: newarray       int
       3: astore_1
       4: aload_1
       5: iconst_0
       6: bipush        9
       8: iastore
       9: aload_1
      10: iconst_1
      11: iconst_3
      12: iastore
      13: aload_1
      14: iconst_2
      15: bipush        7
      17: iastore
      18: aload_1
      19: iconst_3
      20: iconst_1
      21: iastore
      22: aload_1
      23: iconst_4
      24: iconst_5
      25: iastore
      26: aload_1
      27: astore_0
      28: new           #8                  // class BubbleSortStrategy
      31: dup
      32: invokespecial #11                 // Method BubbleSortStrategy."<init>":()V
      35: astore_1
      36: new           #13                 // class SortContext
      39: dup
      40: aload_1
      41: checkcast     #15                 // class SortStrategy
      44: invokespecial #18                 // Method SortContext."<init>":(LSortStrategy;)V
      47: astore_2
      48: aload_2
      49: aload_0
      50: invokevirtual #22                 // Method SortContext.executeSort:([I)[I
      53: astore_3
      54: new           #24                 // class java/lang/StringBuilder
      57: dup
      58: invokespecial #25                 // Method java/lang/StringBuilder."<init>":()V
      61: ldc           #27                 // String バブルソートの結果:
      63: invokevirtual #31                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      66: aload_3
      67: aconst_null
      68: aconst_null
      69: aconst_null
      70: iconst_0
      71: aconst_null
      72: aconst_null
      73: bipush        63
      75: aconst_null
      76: invokestatic  #37                 // Method kotlin/collections/ArraysKt.joinToString$default:([ILjava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
      79: invokevirtual #31                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      82: invokevirtual #41                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      85: getstatic     #47                 // Field java/lang/System.out:Ljava/io/PrintStream;
      88: swap
      89: invokevirtual #53                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      92: new           #55                 // class QuickSortStrategy
      95: dup
      96: invokespecial #56                 // Method QuickSortStrategy."<init>":()V
      99: astore        4
     101: new           #13                 // class SortContext
     104: dup
     105: aload         4
     107: checkcast     #15                 // class SortStrategy
     110: invokespecial #18                 // Method SortContext."<init>":(LSortStrategy;)V
     113: astore        5
     115: aload         5
     117: aload_0
     118: invokevirtual #22                 // Method SortContext.executeSort:([I)[I
     121: astore        6
     123: new           #24                 // class java/lang/StringBuilder
     126: dup
     127: invokespecial #25                 // Method java/lang/StringBuilder."<init>":()V
     130: ldc           #58                 // String クイックソートの結果:
     132: invokevirtual #31                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     135: aload         6
     137: aconst_null
     138: aconst_null
     139: aconst_null
     140: iconst_0
     141: aconst_null
     142: aconst_null
     143: bipush        63
     145: aconst_null
     146: invokestatic  #37                 // Method kotlin/collections/ArraysKt.joinToString$default:([ILjava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     149: invokevirtual #31                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     152: invokevirtual #41                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     155: getstatic     #47                 // Field java/lang/System.out:Ljava/io/PrintStream;
     158: swap
     159: invokevirtual #53                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     162: return

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