package datastructure.heap

class Heap {

    private val heap = arrayListOf<Int>()

    fun getHeap(): List<Int> {
        return heap.toList()
    }

    fun getLeftChild(index: Int): Int {
        return 2 * index + 1
    }

    fun getRightChild(index: Int): Int {
        return 2 * index + 2
    }

    private fun getParentIndex(index: Int): Int {
        return (index - 1) / 2
    }

    fun insert(item: Int) {
        heap.add(item)
        heapifyUp()
    }

    private fun heapifyUp() { // For max heap
        var index = heap.size - 1  // Start at the last element
        while (hasParent(index) && parent(index) < heap[index]) {  // While we have a parent and it's greater than the current node
            // Swap the current node with its parent
            swap(getParentIndex(index), index)
            // Move up the tree
            index = getParentIndex(index)
        }
    }

    private fun heapifyDown() { // for min heap
        var index = heap.size - 1  // Start at the last element
        while (hasParent(index) && parent(index) > heap[index]) {  // While we have a parent and it's greater than the current node
            // Swap the current node with its parent
            swap(getParentIndex(index), index)
            // Move up the tree
            index = getParentIndex(index)
        }
    }

    fun remove() : Int? {
        if (heap.isEmpty()) return null

        if (heap.size ==  1){
            return heap.removeAt(0)
        }

        val maxValue = heap[0]
        heap[0] = heap.removeAt(heap.size -1)
        sinkDown(0)
        return maxValue
    }

    fun findKthSmallest(nums: IntArray, k: Int): Int? {
        val heap = Heap()

        if (nums.isEmpty()) return null
        if (k < 0 || k> nums.size) return null
        if (nums.size == 1) return heap.remove()

        for (i in nums.indices) {
            heap.insert(nums[i])
        }

        val size = nums.size
        var actaulK = size - k
        var ans = -1
        while (actaulK >= 0) {
            ans = heap.remove()!!
            actaulK--
        }
        return ans
    }
    private fun sinkDown(index: Int) {
        var index = index
        var maxIndex = index
        while (true) {
            val leftIndex: Int = getLeftChild(index)
            val rightIndex: Int = getRightChild(index)
            if (leftIndex < heap.size && heap[leftIndex] > heap[maxIndex]) {
                maxIndex = leftIndex
            }
            if (rightIndex < heap.size && heap[rightIndex] > heap[maxIndex]) {
                maxIndex = rightIndex
            }
            index = if (maxIndex != index) {
                swap(index, maxIndex)
                maxIndex
            } else {
                return
            }
        }
    }

    private fun hasParent(index: Int) = getParentIndex(index) >= 0

    private fun parent(index: Int) = heap[getParentIndex(index)]
    private fun swap(i: Int, j: Int) {
        val temp = heap[i]
        heap[i] = heap[j]
        heap[j] = temp
    }

    override fun toString(): String {
        return "$heap"
    }

}

fun main() {
    val heap = Heap()
    // Test case 1
    // Test case 1
    val nums1 = intArrayOf(7, 10, 4, 3, 20, 15)
    val k1 = 3
    println("Test case 1:")
    println("Expected output: 7")
    System.out.println("Actual output: " + heap.findKthSmallest(nums1, k1))
    println()

    // Test case 2

    // Test case 2
    val nums2 = intArrayOf(2, 1, 3, 5, 6, 4)
    val k2 = 2
    println("Test case 2:")
    println("Expected output: 2")
    System.out.println("Actual output: " + heap.findKthSmallest(nums2, k2))
    println()

    // Test case 3

    // Test case 3
    val nums3 = intArrayOf(9, 3, 2, 11, 7, 10, 4, 5)
    val k3 = 5
    println("Test case 3:")
    println("Expected output: 7")
    System.out.println("Actual output: " + heap.findKthSmallest(nums3, k3))
    println()

}

Compiled from "Heap.kt"
public final class datastructure.heap.HeapKt {
  public static final void main();
    Code:
       0: new           #8                  // class datastructure/heap/Heap
       3: dup
       4: invokespecial #11                 // Method datastructure/heap/Heap."<init>":()V
       7: astore_0
       8: bipush        6
      10: newarray       int
      12: astore_2
      13: aload_2
      14: iconst_0
      15: bipush        7
      17: iastore
      18: aload_2
      19: iconst_1
      20: bipush        10
      22: iastore
      23: aload_2
      24: iconst_2
      25: iconst_4
      26: iastore
      27: aload_2
      28: iconst_3
      29: iconst_3
      30: iastore
      31: aload_2
      32: iconst_4
      33: bipush        20
      35: iastore
      36: aload_2
      37: iconst_5
      38: bipush        15
      40: iastore
      41: aload_2
      42: astore_1
      43: iconst_3
      44: istore_2
      45: ldc           #13                 // String Test case 1:
      47: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
      50: swap
      51: invokevirtual #25                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      54: ldc           #27                 // String Expected output: 7
      56: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
      59: swap
      60: invokevirtual #25                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      63: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
      66: new           #29                 // class java/lang/StringBuilder
      69: dup
      70: invokespecial #30                 // Method java/lang/StringBuilder."<init>":()V
      73: ldc           #32                 // String Actual output:
      75: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      78: aload_0
      79: aload_1
      80: iload_2
      81: invokevirtual #40                 // Method datastructure/heap/Heap.findKthSmallest:([II)Ljava/lang/Integer;
      84: invokevirtual #43                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      87: invokevirtual #47                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      90: invokevirtual #50                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      93: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
      96: invokevirtual #52                 // Method java/io/PrintStream.println:()V
      99: bipush        6
     101: newarray       int
     103: astore        4
     105: aload         4
     107: iconst_0
     108: iconst_2
     109: iastore
     110: aload         4
     112: iconst_1
     113: iconst_1
     114: iastore
     115: aload         4
     117: iconst_2
     118: iconst_3
     119: iastore
     120: aload         4
     122: iconst_3
     123: iconst_5
     124: iastore
     125: aload         4
     127: iconst_4
     128: bipush        6
     130: iastore
     131: aload         4
     133: iconst_5
     134: iconst_4
     135: iastore
     136: aload         4
     138: astore_3
     139: iconst_2
     140: istore        4
     142: ldc           #54                 // String Test case 2:
     144: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     147: swap
     148: invokevirtual #25                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     151: ldc           #56                 // String Expected output: 2
     153: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     156: swap
     157: invokevirtual #25                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     160: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     163: new           #29                 // class java/lang/StringBuilder
     166: dup
     167: invokespecial #30                 // Method java/lang/StringBuilder."<init>":()V
     170: ldc           #32                 // String Actual output:
     172: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     175: aload_0
     176: aload_3
     177: iload         4
     179: invokevirtual #40                 // Method datastructure/heap/Heap.findKthSmallest:([II)Ljava/lang/Integer;
     182: invokevirtual #43                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     185: invokevirtual #47                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     188: invokevirtual #50                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     191: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     194: invokevirtual #52                 // Method java/io/PrintStream.println:()V
     197: bipush        8
     199: newarray       int
     201: astore        6
     203: aload         6
     205: iconst_0
     206: bipush        9
     208: iastore
     209: aload         6
     211: iconst_1
     212: iconst_3
     213: iastore
     214: aload         6
     216: iconst_2
     217: iconst_2
     218: iastore
     219: aload         6
     221: iconst_3
     222: bipush        11
     224: iastore
     225: aload         6
     227: iconst_4
     228: bipush        7
     230: iastore
     231: aload         6
     233: iconst_5
     234: bipush        10
     236: iastore
     237: aload         6
     239: bipush        6
     241: iconst_4
     242: iastore
     243: aload         6
     245: bipush        7
     247: iconst_5
     248: iastore
     249: aload         6
     251: astore        5
     253: iconst_5
     254: istore        6
     256: ldc           #58                 // String Test case 3:
     258: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     261: swap
     262: invokevirtual #25                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     265: ldc           #27                 // String Expected output: 7
     267: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     270: swap
     271: invokevirtual #25                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     274: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     277: new           #29                 // class java/lang/StringBuilder
     280: dup
     281: invokespecial #30                 // Method java/lang/StringBuilder."<init>":()V
     284: ldc           #32                 // String Actual output:
     286: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     289: aload_0
     290: aload         5
     292: iload         6
     294: invokevirtual #40                 // Method datastructure/heap/Heap.findKthSmallest:([II)Ljava/lang/Integer;
     297: invokevirtual #43                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     300: invokevirtual #47                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     303: invokevirtual #50                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     306: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
     309: invokevirtual #52                 // Method java/io/PrintStream.println:()V
     312: return

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

Compiled from "Heap.kt"
public final class datastructure.heap.Heap {
  private final java.util.ArrayList<java.lang.Integer> heap;

  public datastructure.heap.Heap();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: new           #10                 // class java/util/ArrayList
       8: dup
       9: invokespecial #11                 // Method java/util/ArrayList."<init>":()V
      12: putfield      #15                 // Field heap:Ljava/util/ArrayList;
      15: return

  public final java.util.List<java.lang.Integer> getHeap();
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: checkcast     #23                 // class java/lang/Iterable
       7: invokestatic  #29                 // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
      10: areturn

  public final int getLeftChild(int);
    Code:
       0: iconst_2
       1: iload_1
       2: imul
       3: iconst_1
       4: iadd
       5: ireturn

  public final int getRightChild(int);
    Code:
       0: iconst_2
       1: iload_1
       2: imul
       3: iconst_2
       4: iadd
       5: ireturn

  private final int getParentIndex(int);
    Code:
       0: iload_1
       1: iconst_1
       2: isub
       3: iconst_2
       4: idiv
       5: ireturn

  public final void insert(int);
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: iload_1
       5: invokestatic  #43                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       8: invokevirtual #47                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      11: pop
      12: aload_0
      13: invokespecial #50                 // Method heapifyUp:()V
      16: return

  private final void heapifyUp();
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: invokevirtual #55                 // Method java/util/ArrayList.size:()I
       7: iconst_1
       8: isub
       9: istore_1
      10: aload_0
      11: iload_1
      12: invokespecial #59                 // Method hasParent:(I)Z
      15: ifeq          59
      18: aload_0
      19: iload_1
      20: invokespecial #62                 // Method parent:(I)I
      23: aload_0
      24: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      27: iload_1
      28: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      31: checkcast     #68                 // class java/lang/Number
      34: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      37: if_icmpge     59
      40: aload_0
      41: aload_0
      42: iload_1
      43: invokespecial #73                 // Method getParentIndex:(I)I
      46: iload_1
      47: invokespecial #77                 // Method swap:(II)V
      50: aload_0
      51: iload_1
      52: invokespecial #73                 // Method getParentIndex:(I)I
      55: istore_1
      56: goto          10
      59: return

  private final void heapifyDown();
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: invokevirtual #55                 // Method java/util/ArrayList.size:()I
       7: iconst_1
       8: isub
       9: istore_1
      10: aload_0
      11: iload_1
      12: invokespecial #59                 // Method hasParent:(I)Z
      15: ifeq          59
      18: aload_0
      19: iload_1
      20: invokespecial #62                 // Method parent:(I)I
      23: aload_0
      24: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      27: iload_1
      28: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      31: checkcast     #68                 // class java/lang/Number
      34: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      37: if_icmple     59
      40: aload_0
      41: aload_0
      42: iload_1
      43: invokespecial #73                 // Method getParentIndex:(I)I
      46: iload_1
      47: invokespecial #77                 // Method swap:(II)V
      50: aload_0
      51: iload_1
      52: invokespecial #73                 // Method getParentIndex:(I)I
      55: istore_1
      56: goto          10
      59: return

  public final java.lang.Integer remove();
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: invokevirtual #85                 // Method java/util/ArrayList.isEmpty:()Z
       7: ifeq          12
      10: aconst_null
      11: areturn
      12: aload_0
      13: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      16: invokevirtual #55                 // Method java/util/ArrayList.size:()I
      19: iconst_1
      20: if_icmpne     35
      23: aload_0
      24: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      27: iconst_0
      28: invokevirtual #87                 // Method java/util/ArrayList.remove:(I)Ljava/lang/Object;
      31: checkcast     #39                 // class java/lang/Integer
      34: areturn
      35: aload_0
      36: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      39: iconst_0
      40: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      43: dup
      44: ldc           #89                 // String get(...)
      46: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      49: checkcast     #68                 // class java/lang/Number
      52: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      55: istore_1
      56: aload_0
      57: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      60: iconst_0
      61: aload_0
      62: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      65: aload_0
      66: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      69: invokevirtual #55                 // Method java/util/ArrayList.size:()I
      72: iconst_1
      73: isub
      74: invokevirtual #87                 // Method java/util/ArrayList.remove:(I)Ljava/lang/Object;
      77: invokevirtual #99                 // Method java/util/ArrayList.set:(ILjava/lang/Object;)Ljava/lang/Object;
      80: pop
      81: aload_0
      82: iconst_0
      83: invokespecial #102                // Method sinkDown:(I)V
      86: iload_1
      87: invokestatic  #43                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      90: areturn

  public final java.lang.Integer findKthSmallest(int[], int);
    Code:
       0: aload_1
       1: ldc           #107                // String nums
       3: invokestatic  #110                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #2                  // class datastructure/heap/Heap
       9: dup
      10: invokespecial #111                // Method "<init>":()V
      13: astore_3
      14: aload_1
      15: arraylength
      16: ifne          23
      19: iconst_1
      20: goto          24
      23: iconst_0
      24: ifeq          29
      27: aconst_null
      28: areturn
      29: iload_2
      30: iflt          39
      33: iload_2
      34: aload_1
      35: arraylength
      36: if_icmple     41
      39: aconst_null
      40: areturn
      41: aload_1
      42: arraylength
      43: iconst_1
      44: if_icmpne     52
      47: aload_3
      48: invokevirtual #113                // Method remove:()Ljava/lang/Integer;
      51: areturn
      52: iconst_0
      53: istore        4
      55: aload_1
      56: arraylength
      57: istore        5
      59: iload         4
      61: iload         5
      63: if_icmpge     80
      66: aload_3
      67: aload_1
      68: iload         4
      70: iaload
      71: invokevirtual #115                // Method insert:(I)V
      74: iinc          4, 1
      77: goto          59
      80: aload_1
      81: arraylength
      82: istore        4
      84: iload         4
      86: iload_2
      87: isub
      88: istore        5
      90: iconst_m1
      91: istore        6
      93: iload         5
      95: iflt          117
      98: aload_3
      99: invokevirtual #113                // Method remove:()Ljava/lang/Integer;
     102: dup
     103: invokestatic  #119                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     106: invokevirtual #120                // Method java/lang/Integer.intValue:()I
     109: istore        6
     111: iinc          5, -1
     114: goto          93
     117: iload         6
     119: invokestatic  #43                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     122: areturn

  private final void sinkDown(int);
    Code:
       0: iload_1
       1: istore_2
       2: iload_2
       3: istore_3
       4: nop
       5: aload_0
       6: iload_2
       7: invokevirtual #127                // Method getLeftChild:(I)I
      10: istore        4
      12: aload_0
      13: iload_2
      14: invokevirtual #129                // Method getRightChild:(I)I
      17: istore        5
      19: iload         4
      21: aload_0
      22: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      25: invokevirtual #55                 // Method java/util/ArrayList.size:()I
      28: if_icmpge     66
      31: aload_0
      32: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      35: iload         4
      37: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      40: checkcast     #68                 // class java/lang/Number
      43: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      46: aload_0
      47: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      50: iload_3
      51: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      54: checkcast     #68                 // class java/lang/Number
      57: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      60: if_icmple     66
      63: iload         4
      65: istore_3
      66: iload         5
      68: aload_0
      69: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      72: invokevirtual #55                 // Method java/util/ArrayList.size:()I
      75: if_icmpge     113
      78: aload_0
      79: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      82: iload         5
      84: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      87: checkcast     #68                 // class java/lang/Number
      90: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      93: aload_0
      94: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      97: iload_3
      98: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     101: checkcast     #68                 // class java/lang/Number
     104: invokevirtual #71                 // Method java/lang/Number.intValue:()I
     107: if_icmple     113
     110: iload         5
     112: istore_3
     113: iload_3
     114: iload_2
     115: if_icmpeq     128
     118: aload_0
     119: iload_2
     120: iload_3
     121: invokespecial #77                 // Method swap:(II)V
     124: iload_3
     125: goto          129
     128: return
     129: istore_2
     130: goto          4

  private final boolean hasParent(int);
    Code:
       0: aload_0
       1: iload_1
       2: invokespecial #73                 // Method getParentIndex:(I)I
       5: iflt          12
       8: iconst_1
       9: goto          13
      12: iconst_0
      13: ireturn

  private final int parent(int);
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: aload_0
       5: iload_1
       6: invokespecial #73                 // Method getParentIndex:(I)I
       9: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      12: dup
      13: ldc           #89                 // String get(...)
      15: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      18: checkcast     #68                 // class java/lang/Number
      21: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      24: ireturn

  private final void swap(int, int);
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: iload_1
       5: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
       8: dup
       9: ldc           #89                 // String get(...)
      11: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      14: checkcast     #68                 // class java/lang/Number
      17: invokevirtual #71                 // Method java/lang/Number.intValue:()I
      20: istore_3
      21: aload_0
      22: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      25: iload_1
      26: aload_0
      27: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      30: iload_2
      31: invokevirtual #66                 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
      34: invokevirtual #99                 // Method java/util/ArrayList.set:(ILjava/lang/Object;)Ljava/lang/Object;
      37: pop
      38: aload_0
      39: getfield      #15                 // Field heap:Ljava/util/ArrayList;
      42: iload_2
      43: iload_3
      44: invokestatic  #43                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      47: invokevirtual #99                 // Method java/util/ArrayList.set:(ILjava/lang/Object;)Ljava/lang/Object;
      50: pop
      51: return

  public java.lang.String toString();
    Code:
       0: aload_0
       1: getfield      #15                 // Field heap:Ljava/util/ArrayList;
       4: invokestatic  #141                // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
       7: areturn
}


package datastructure.graphs

import java.util.LinkedList
import java.util.PriorityQueue

data class Edge(val source: Int, val destination: Int, val weight: Int)

class Graphs(private val nodes: Int) {

    private val graph = Array(nodes) { ArrayList<Edge>() } // Fixed array size to 'nodes'

    fun createGraph() {
        graph[0].add(Edge(0, 2, 2))
        graph[0].add(Edge(0, 3, 4))
        graph[1].add(Edge(1, 0, 7))
        graph[2].add(Edge(2, 1, 3))
        graph[3].add(Edge(3, 4, 1))
    }

    fun bfs() {
        if (graph.isEmpty()) {
            return
        }

        val queue = LinkedList<Int>()
        val visited = BooleanArray(nodes)

        // Initialize the queue with the first vertex (you can choose any starting vertex)
        queue.add(graph[0].first().source) // Starting vertex with source and destination as 0

        while (queue.isNotEmpty()) {
            val curr = queue.poll()
            if (!visited[curr]) {
                visited[curr] = true
                println(curr)

                // Find neighbors of the current edge's destination
                val neighbours = findNeighbours(curr)

                // Enqueue unvisited neighbors
                for (neighbor in neighbours) {
                    if (!visited[neighbor]) {
                        queue.add(neighbor)
                    }
                }
            }
        }
    }

    fun dfs(inputGraph: Array<ArrayList<Edge>>, curr: Int, visited: BooleanArray) { // O(V+E)

        // Step - 1 - Print the node
        print("$curr ")

        //Step 2- Mark visited true
        visited[curr] = true

        // Step 3 - Explore neighbour nodes
        val neighbours = findNeighbours(curr)

        for (n in neighbours) {
            if (!visited[n]) {
                dfs(inputGraph, n, visited)
                println()
            }
        }
    }

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

    private fun findNeighbours(vertex: Int): List<Int> {
        val neighbours = mutableListOf<Int>()

        // Implement your logic to find neighbors of 'vertex' here
        // You can iterate through 'graph' and identify edges connected to 'vertex'
        graph[vertex].forEach {
            neighbours.add(it.destination)
        }

        return neighbours
    }

    fun detectCycle(curr: Int, visited: BooleanArray, recurStack: BooleanArray): Boolean { // Works for directed nodes

        visited[curr] = true
        recurStack[curr] = true

        val neighbours = findNeighbours(curr)
        for (n in neighbours) {
            if (recurStack[n]) {
                return true // There is a cycle
            } else if (!visited[n]) {
                if (detectCycle(n, visited, recurStack)) {
                    return true
                }
            }
        }

        recurStack[curr] = false
        return false
    }

    fun cycleDetectionInUndirectedGraph(curr: Int, visited: BooleanArray, parent: Int): Boolean {
        visited[curr] = true

        val neighbours = findNeighbours(curr)
        for (n in neighbours) {
            if (visited[n] && parent != n) {
                return true
            } else if (!visited[n]) {
                if (cycleDetectionInUndirectedGraph(n, visited, curr)) {
                    return true
                }
            }
        }

        return false
    }

    fun printAllPaths(curr: Int, visited: BooleanArray, target: Int, path: String) { // O(V^V)

        // Base condition
        if (curr == target) {
            println(path)
            return
        }

        val neighbours = findNeighbours(curr)
        for (n in neighbours) {
            if (!visited[n]) {
                visited[curr] = true
                printAllPaths(n, visited, target, path.plus(n))
                visited[curr] = false // Important
            }
        }
    }

    fun dijkstraAlgorithm(src: Int) {
        val pq = PriorityQueue<VertexPair>()
        val visited = BooleanArray(graph.size) { false }
        // Here we are tricking which will work in case starting node is zero but won't work for others.
        pq.add(VertexPair(src, 0))
        val distance = IntArray(graph.size)
        for (i in distance.indices) {
            if (i != src) {
                distance[i] = Int.MAX_VALUE
            }
        }

        while (pq.isNotEmpty()) {
            val curr: VertexPair = pq.remove()
            if (!visited[curr.node]) {
                visited[curr.node] = true
            }
            for (i in graph[curr.node].indices) {
                val edge: Edge = graph[curr.node][i]
                val u = edge.source
                val v = edge.destination

                // Relaxation step
                if (distance[u] + edge.weight < distance[v]) {
                    distance[v] = distance[u] + edge.weight
                    pq.add(VertexPair(v, distance[v]))
                }
            }
        }

        for (d in distance) {
            print("$d ->")
        }
    }

    fun bellmanfordAlgo(src: Int) {
        val V = graph.size
        val dist = IntArray(V)
        for (i in graph.indices) {
            if (src != i) {
                dist[i] = Int.MAX_VALUE
            }
        }

        for (k in 0 until V - 1) {
            for (i in 0 until V) {
                for (j in graph[i].indices) {
                    val edge = graph[i][j]
                    val u = edge.source
                    val v = edge.destination
                    if (dist[u] != Int.MAX_VALUE && dist[u] + edge.weight < dist[v]) {
                        dist[v] = dist[u] + edge.weight
                    }
                }
            }
        }

        for (d in dist) {
            print("$d ->")
        }

    }

    fun primsMst(src: Int) {
        val pq = PriorityQueue<VertexPair>()
        pq.add(VertexPair(0, 0)) // Non mst
        val visited = BooleanArray(graph.size) { false }
        var cost = 0
        while (pq.isNotEmpty()) {
            val curr = pq.poll()
            if (!visited[curr.node]) {
                visited[curr.node] = true
                cost += curr.distance

                for (i in graph[curr.node].indices) {
                    val edge = graph[curr.node][i]
                    if (!visited[edge.destination]) {
                        pq.add(VertexPair(edge.destination, edge.weight))
                    }
                }
            }
        }

        println("\nTotal path cost = $cost")
    }

    fun topSort(): LinkedList<Int> {
        val visited = BooleanArray(6) { false }
        val stack = LinkedList<Int>()

        for (node in graph.indices) {
            if (!visited[node]) {
                topologicalSort(node, visited, stack)
            }
        }
        return stack
    }

    private fun topologicalSort(curr: Int, visited: BooleanArray, stack: LinkedList<Int>) {
        visited[curr] = true

        val neighbours = findNeighbours(curr)
        for (n in neighbours) {
            if (!visited[n]) {
                topologicalSort(n, visited, stack)
            }
        }
        stack.push(curr) // DFS + push to stack
    }

    /**
     * This algorithm is used to find the strongly connected components inside a graph.
     * A graph is called strongly connected if all the nodes can be reached from each of the nodes.
     *
     * There are three steps to find the SCC.
     *
     * 1. Get nodes in stack(Topological sort)
     * 2. Transpose the graph
     * 3. Do DFS according to stack nodes on the transpose graph.
     * */
    fun kosarajuAlgorithm() {
        val visited = BooleanArray(graph.size) { false }

        // Step 1
        val stack = topSort()

        // Step 2 -- Transpose the graph

        val transposeGraph = Array(graph.size) { ArrayList<Edge>() }
        for (i in graph.indices) {
            for (j in graph[i].indices) {
                val edge = graph[i][j]
                transposeGraph[edge.destination].add(
                    Edge(
                        source = edge.destination,
                        destination = edge.source,
                        weight = edge.weight
                    )
                )
            }
        }

        println("Graph")
        graph.forEach {
            println(it)
        }
        println("Transpose")
        transposeGraph.forEach {
            println(it)
        }
        // Step 3 -- Do DFS on stack nodes

        println("Stack")
        println(stack)
        while (stack.isNotEmpty()) {
            val node = stack.pop()
            if (!visited[node]) {
                dfs(transposeGraph, node, visited)
                println()
            }
        }

    }
}

class VertexPair(val node: Int, val distance: Int) : Comparable<VertexPair> {
    override fun compareTo(other: VertexPair): Int {
        return distance - other.distance
    }

    override fun toString(): String {
        return "[$node, $distance]"
    }
}

fun main() {

    val graph = Graphs(5)
    graph.createGraph()
//    graph.bfs()
//    val visited = BooleanArray(graph.size()) { false }
//    visited.forEachIndexed { index, value ->
//        if (!value) {
//            graph.dfs(index, visited)
//        }
//    }

//    val visitedCycles = BooleanArray(graph.size()) { false }
//    val recurStack = BooleanArray(graph.size()) { false }
//    println(graph.detectCycle(0, visitedCycles, recurStack))

//    val startNode = 0
//    val pathVisited = BooleanArray(graph.size())
//    println("\nAll paths are : ")
//    graph.printAllPaths(startNode, pathVisited, 4, "$startNode")

//    println("Topological sort ")
//    topSort(graph)

//    println("Cycle detection in undirected graph")
//    val visited = BooleanArray(4){false}
//    println(graph.cycleDetectionInUndirectedGraph(0, visited, -1))

//    graph.bellmanfordAlgo(0)
//    graph.primsMst(0)
    graph.kosarajuAlgorithm()
}

Compiled from "Graphs.kt"
public final class datastructure.graphs.GraphsKt {
  public static final void main();
    Code:
       0: new           #8                  // class datastructure/graphs/Graphs
       3: dup
       4: iconst_5
       5: invokespecial #12                 // Method datastructure/graphs/Graphs."<init>":(I)V
       8: astore_0
       9: aload_0
      10: invokevirtual #15                 // Method datastructure/graphs/Graphs.createGraph:()V
      13: aload_0
      14: invokevirtual #18                 // Method datastructure/graphs/Graphs.kosarajuAlgorithm:()V
      17: return

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

Compiled from "Graphs.kt"
public final class datastructure.graphs.Graphs {
  private final int nodes;

  private final java.util.ArrayList<datastructure.graphs.Edge>[] graph;

  public datastructure.graphs.Graphs(int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field nodes:I
       9: aload_0
      10: iconst_0
      11: istore_2
      12: aload_0
      13: getfield      #13                 // Field nodes:I
      16: istore_3
      17: iload_3
      18: anewarray     #15                 // class java/util/ArrayList
      21: astore        4
      23: astore        6
      25: iload_2
      26: iload_3
      27: if_icmpge     51
      30: iload_2
      31: istore        5
      33: aload         4
      35: iload         5
      37: new           #15                 // class java/util/ArrayList
      40: dup
      41: invokespecial #16                 // Method java/util/ArrayList."<init>":()V
      44: aastore
      45: iinc          2, 1
      48: goto          25
      51: aload         6
      53: aload         4
      55: putfield      #20                 // Field graph:[Ljava/util/ArrayList;
      58: return

  public final void createGraph();
    Code:
       0: aload_0
       1: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
       4: iconst_0
       5: aaload
       6: new           #26                 // class datastructure/graphs/Edge
       9: dup
      10: iconst_0
      11: iconst_2
      12: iconst_2
      13: invokespecial #29                 // Method datastructure/graphs/Edge."<init>":(III)V
      16: invokevirtual #33                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      19: pop
      20: aload_0
      21: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      24: iconst_0
      25: aaload
      26: new           #26                 // class datastructure/graphs/Edge
      29: dup
      30: iconst_0
      31: iconst_3
      32: iconst_4
      33: invokespecial #29                 // Method datastructure/graphs/Edge."<init>":(III)V
      36: invokevirtual #33                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      39: pop
      40: aload_0
      41: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      44: iconst_1
      45: aaload
      46: new           #26                 // class datastructure/graphs/Edge
      49: dup
      50: iconst_1
      51: iconst_0
      52: bipush        7
      54: invokespecial #29                 // Method datastructure/graphs/Edge."<init>":(III)V
      57: invokevirtual #33                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      60: pop
      61: aload_0
      62: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      65: iconst_2
      66: aaload
      67: new           #26                 // class datastructure/graphs/Edge
      70: dup
      71: iconst_2
      72: iconst_1
      73: iconst_3
      74: invokespecial #29                 // Method datastructure/graphs/Edge."<init>":(III)V
      77: invokevirtual #33                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      80: pop
      81: aload_0
      82: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      85: iconst_3
      86: aaload
      87: new           #26                 // class datastructure/graphs/Edge
      90: dup
      91: iconst_3
      92: iconst_4
      93: iconst_1
      94: invokespecial #29                 // Method datastructure/graphs/Edge."<init>":(III)V
      97: invokevirtual #33                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     100: pop
     101: return

  public final void bfs();
    Code:
       0: aload_0
       1: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
       4: arraylength
       5: ifne          12
       8: iconst_1
       9: goto          13
      12: iconst_0
      13: ifeq          17
      16: return
      17: new           #36                 // class java/util/LinkedList
      20: dup
      21: invokespecial #37                 // Method java/util/LinkedList."<init>":()V
      24: astore_1
      25: aload_0
      26: getfield      #13                 // Field nodes:I
      29: newarray       boolean
      31: astore_2
      32: aload_1
      33: aload_0
      34: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      37: iconst_0
      38: aaload
      39: checkcast     #39                 // class java/util/List
      42: invokestatic  #45                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      45: checkcast     #26                 // class datastructure/graphs/Edge
      48: invokevirtual #49                 // Method datastructure/graphs/Edge.getSource:()I
      51: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      54: invokevirtual #56                 // Method java/util/LinkedList.add:(Ljava/lang/Object;)Z
      57: pop
      58: aload_1
      59: checkcast     #58                 // class java/util/Collection
      62: invokeinterface #62,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      67: ifne          74
      70: iconst_1
      71: goto          75
      74: iconst_0
      75: ifeq          184
      78: aload_1
      79: invokevirtual #66                 // Method java/util/LinkedList.poll:()Ljava/lang/Object;
      82: checkcast     #51                 // class java/lang/Integer
      85: astore_3
      86: aload_2
      87: aload_3
      88: invokestatic  #72                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      91: aload_3
      92: invokevirtual #75                 // Method java/lang/Integer.intValue:()I
      95: baload
      96: ifne          58
      99: aload_2
     100: aload_3
     101: invokevirtual #75                 // Method java/lang/Integer.intValue:()I
     104: iconst_1
     105: bastore
     106: aload_3
     107: invokevirtual #75                 // Method java/lang/Integer.intValue:()I
     110: istore        4
     112: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     115: iload         4
     117: invokevirtual #86                 // Method java/io/PrintStream.println:(I)V
     120: aload_0
     121: aload_3
     122: invokevirtual #75                 // Method java/lang/Integer.intValue:()I
     125: invokespecial #90                 // Method findNeighbours:(I)Ljava/util/List;
     128: astore        4
     130: aload         4
     132: invokeinterface #94,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     137: astore        5
     139: aload         5
     141: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     146: ifeq          58
     149: aload         5
     151: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     156: checkcast     #104                // class java/lang/Number
     159: invokevirtual #105                // Method java/lang/Number.intValue:()I
     162: istore        6
     164: aload_2
     165: iload         6
     167: baload
     168: ifne          139
     171: aload_1
     172: iload         6
     174: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     177: invokevirtual #56                 // Method java/util/LinkedList.add:(Ljava/lang/Object;)Z
     180: pop
     181: goto          139
     184: return

  public final void dfs(java.util.ArrayList<datastructure.graphs.Edge>[], int, boolean[]);
    Code:
       0: aload_1
       1: ldc           #121                // String inputGraph
       3: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_3
       7: ldc           #126                // String visited
       9: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: new           #128                // class java/lang/StringBuilder
      15: dup
      16: invokespecial #129                // Method java/lang/StringBuilder."<init>":()V
      19: iload_2
      20: invokevirtual #133                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      23: bipush        32
      25: invokevirtual #136                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      28: invokevirtual #140                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      31: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
      34: swap
      35: invokevirtual #143                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      38: aload_3
      39: iload_2
      40: iconst_1
      41: bastore
      42: aload_0
      43: iload_2
      44: invokespecial #90                 // Method findNeighbours:(I)Ljava/util/List;
      47: astore        4
      49: aload         4
      51: invokeinterface #94,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      56: astore        5
      58: aload         5
      60: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      65: ifeq          107
      68: aload         5
      70: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      75: checkcast     #104                // class java/lang/Number
      78: invokevirtual #105                // Method java/lang/Number.intValue:()I
      81: istore        6
      83: aload_3
      84: iload         6
      86: baload
      87: ifne          58
      90: aload_0
      91: aload_1
      92: iload         6
      94: aload_3
      95: invokevirtual #145                // Method dfs:([Ljava/util/ArrayList;I[Z)V
      98: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     101: invokevirtual #147                // Method java/io/PrintStream.println:()V
     104: goto          58
     107: return

  public final int size();
    Code:
       0: aload_0
       1: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
       4: arraylength
       5: ireturn

  private final java.util.List<java.lang.Integer> findNeighbours(int);
    Code:
       0: new           #15                 // class java/util/ArrayList
       3: dup
       4: invokespecial #16                 // Method java/util/ArrayList."<init>":()V
       7: checkcast     #39                 // class java/util/List
      10: astore_2
      11: aload_0
      12: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      15: iload_1
      16: aaload
      17: checkcast     #152                // class java/lang/Iterable
      20: astore_3
      21: iconst_0
      22: istore        4
      24: aload_3
      25: invokeinterface #153,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          81
      42: aload         5
      44: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      49: astore        6
      51: aload         6
      53: checkcast     #26                 // class datastructure/graphs/Edge
      56: astore        7
      58: iconst_0
      59: istore        8
      61: aload_2
      62: aload         7
      64: invokevirtual #156                // Method datastructure/graphs/Edge.getDestination:()I
      67: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      70: invokeinterface #157,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      75: pop
      76: nop
      77: nop
      78: goto          32
      81: nop
      82: aload_2
      83: areturn

  public final boolean detectCycle(int, boolean[], boolean[]);
    Code:
       0: aload_2
       1: ldc           #126                // String visited
       3: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_3
       7: ldc           #170                // String recurStack
       9: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: iload_1
      14: iconst_1
      15: bastore
      16: aload_3
      17: iload_1
      18: iconst_1
      19: bastore
      20: aload_0
      21: iload_1
      22: invokespecial #90                 // Method findNeighbours:(I)Ljava/util/List;
      25: astore        4
      27: aload         4
      29: invokeinterface #94,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      34: astore        5
      36: aload         5
      38: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      43: ifeq          90
      46: aload         5
      48: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      53: checkcast     #104                // class java/lang/Number
      56: invokevirtual #105                // Method java/lang/Number.intValue:()I
      59: istore        6
      61: aload_3
      62: iload         6
      64: baload
      65: ifeq          70
      68: iconst_1
      69: ireturn
      70: aload_2
      71: iload         6
      73: baload
      74: ifne          36
      77: aload_0
      78: iload         6
      80: aload_2
      81: aload_3
      82: invokevirtual #172                // Method detectCycle:(I[Z[Z)Z
      85: ifeq          36
      88: iconst_1
      89: ireturn
      90: aload_3
      91: iload_1
      92: iconst_0
      93: bastore
      94: iconst_0
      95: ireturn

  public final boolean cycleDetectionInUndirectedGraph(int, boolean[], int);
    Code:
       0: aload_2
       1: ldc           #126                // String visited
       3: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: iload_1
       8: iconst_1
       9: bastore
      10: aload_0
      11: iload_1
      12: invokespecial #90                 // Method findNeighbours:(I)Ljava/util/List;
      15: astore        4
      17: aload         4
      19: invokeinterface #94,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      24: astore        5
      26: aload         5
      28: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      33: ifeq          86
      36: aload         5
      38: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      43: checkcast     #104                // class java/lang/Number
      46: invokevirtual #105                // Method java/lang/Number.intValue:()I
      49: istore        6
      51: aload_2
      52: iload         6
      54: baload
      55: ifeq          66
      58: iload_3
      59: iload         6
      61: if_icmpeq     66
      64: iconst_1
      65: ireturn
      66: aload_2
      67: iload         6
      69: baload
      70: ifne          26
      73: aload_0
      74: iload         6
      76: aload_2
      77: iload_1
      78: invokevirtual #176                // Method cycleDetectionInUndirectedGraph:(I[ZI)Z
      81: ifeq          26
      84: iconst_1
      85: ireturn
      86: iconst_0
      87: ireturn

  public final void printAllPaths(int, boolean[], int, java.lang.String);
    Code:
       0: aload_2
       1: ldc           #126                // String visited
       3: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload         4
       8: ldc           #181                // String path
      10: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      13: iload_1
      14: iload_3
      15: if_icmpne     27
      18: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
      21: aload         4
      23: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      26: return
      27: aload_0
      28: iload_1
      29: invokespecial #90                 // Method findNeighbours:(I)Ljava/util/List;
      32: astore        5
      34: aload         5
      36: invokeinterface #94,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      41: astore        6
      43: aload         6
      45: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      50: ifeq          114
      53: aload         6
      55: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      60: checkcast     #104                // class java/lang/Number
      63: invokevirtual #105                // Method java/lang/Number.intValue:()I
      66: istore        7
      68: aload_2
      69: iload         7
      71: baload
      72: ifne          43
      75: aload_2
      76: iload_1
      77: iconst_1
      78: bastore
      79: aload_0
      80: iload         7
      82: aload_2
      83: iload_3
      84: new           #128                // class java/lang/StringBuilder
      87: dup
      88: invokespecial #129                // Method java/lang/StringBuilder."<init>":()V
      91: aload         4
      93: invokevirtual #186                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      96: iload         7
      98: invokevirtual #133                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     101: invokevirtual #140                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     104: invokevirtual #188                // Method printAllPaths:(I[ZILjava/lang/String;)V
     107: aload_2
     108: iload_1
     109: iconst_0
     110: bastore
     111: goto          43
     114: return

  public final void dijkstraAlgorithm(int);
    Code:
       0: new           #193                // class java/util/PriorityQueue
       3: dup
       4: invokespecial #194                // Method java/util/PriorityQueue."<init>":()V
       7: astore_2
       8: iconst_0
       9: istore        4
      11: aload_0
      12: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      15: arraylength
      16: istore        5
      18: iload         5
      20: newarray       boolean
      22: astore        6
      24: iload         4
      26: iload         5
      28: if_icmpge     47
      31: iload         4
      33: istore        7
      35: aload         6
      37: iload         7
      39: iconst_0
      40: bastore
      41: iinc          4, 1
      44: goto          24
      47: aload         6
      49: astore_3
      50: aload_2
      51: new           #196                // class datastructure/graphs/VertexPair
      54: dup
      55: iload_1
      56: iconst_0
      57: invokespecial #199                // Method datastructure/graphs/VertexPair."<init>":(II)V
      60: invokevirtual #200                // Method java/util/PriorityQueue.add:(Ljava/lang/Object;)Z
      63: pop
      64: aload_0
      65: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      68: arraylength
      69: newarray       int
      71: astore        4
      73: iconst_0
      74: istore        5
      76: aload         4
      78: arraylength
      79: istore        6
      81: iload         5
      83: iload         6
      85: if_icmpge     107
      88: iload         5
      90: iload_1
      91: if_icmpeq     101
      94: aload         4
      96: iload         5
      98: ldc           #201                // int 2147483647
     100: iastore
     101: iinc          5, 1
     104: goto          81
     107: aload_2
     108: checkcast     #58                 // class java/util/Collection
     111: invokeinterface #62,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     116: ifne          123
     119: iconst_1
     120: goto          124
     123: iconst_0
     124: ifeq          290
     127: aload_2
     128: invokevirtual #204                // Method java/util/PriorityQueue.remove:()Ljava/lang/Object;
     131: dup
     132: ldc           #206                // String remove(...)
     134: invokestatic  #209                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     137: checkcast     #196                // class datastructure/graphs/VertexPair
     140: astore        5
     142: aload_3
     143: aload         5
     145: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     148: baload
     149: ifne          160
     152: aload_3
     153: aload         5
     155: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     158: iconst_1
     159: bastore
     160: iconst_0
     161: istore        6
     163: aload_0
     164: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     167: aload         5
     169: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     172: aaload
     173: checkcast     #58                 // class java/util/Collection
     176: invokeinterface #214,  1          // InterfaceMethod java/util/Collection.size:()I
     181: istore        7
     183: iload         6
     185: iload         7
     187: if_icmpge     107
     190: aload_0
     191: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     194: aload         5
     196: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     199: aaload
     200: iload         6
     202: invokevirtual #218                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     205: dup
     206: ldc           #220                // String get(...)
     208: invokestatic  #209                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     211: checkcast     #26                 // class datastructure/graphs/Edge
     214: astore        8
     216: aload         8
     218: invokevirtual #49                 // Method datastructure/graphs/Edge.getSource:()I
     221: istore        9
     223: aload         8
     225: invokevirtual #156                // Method datastructure/graphs/Edge.getDestination:()I
     228: istore        10
     230: aload         4
     232: iload         9
     234: iaload
     235: aload         8
     237: invokevirtual #223                // Method datastructure/graphs/Edge.getWeight:()I
     240: iadd
     241: aload         4
     243: iload         10
     245: iaload
     246: if_icmpge     284
     249: aload         4
     251: iload         10
     253: aload         4
     255: iload         9
     257: iaload
     258: aload         8
     260: invokevirtual #223                // Method datastructure/graphs/Edge.getWeight:()I
     263: iadd
     264: iastore
     265: aload_2
     266: new           #196                // class datastructure/graphs/VertexPair
     269: dup
     270: iload         10
     272: aload         4
     274: iload         10
     276: iaload
     277: invokespecial #199                // Method datastructure/graphs/VertexPair."<init>":(II)V
     280: invokevirtual #200                // Method java/util/PriorityQueue.add:(Ljava/lang/Object;)Z
     283: pop
     284: iinc          6, 1
     287: goto          183
     290: iconst_0
     291: istore        5
     293: aload         4
     295: arraylength
     296: istore        6
     298: iload         5
     300: iload         6
     302: if_icmpge     345
     305: aload         4
     307: iload         5
     309: iaload
     310: istore        7
     312: new           #128                // class java/lang/StringBuilder
     315: dup
     316: invokespecial #129                // Method java/lang/StringBuilder."<init>":()V
     319: iload         7
     321: invokevirtual #133                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     324: ldc           #225                // String  ->
     326: invokevirtual #186                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     329: invokevirtual #140                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     332: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     335: swap
     336: invokevirtual #143                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     339: iinc          5, 1
     342: goto          298
     345: return

  public final void bellmanfordAlgo(int);
    Code:
       0: aload_0
       1: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
       4: arraylength
       5: istore_2
       6: iload_2
       7: newarray       int
       9: astore_3
      10: iconst_0
      11: istore        4
      13: aload_0
      14: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      17: arraylength
      18: istore        5
      20: iload         4
      22: iload         5
      24: if_icmpge     45
      27: iload_1
      28: iload         4
      30: if_icmpeq     39
      33: aload_3
      34: iload         4
      36: ldc           #201                // int 2147483647
      38: iastore
      39: iinc          4, 1
      42: goto          20
      45: iconst_0
      46: istore        4
      48: iload_2
      49: iconst_1
      50: isub
      51: istore        5
      53: iload         4
      55: iload         5
      57: if_icmpge     191
      60: iconst_0
      61: istore        6
      63: iload         6
      65: iload_2
      66: if_icmpge     185
      69: iconst_0
      70: istore        7
      72: aload_0
      73: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      76: iload         6
      78: aaload
      79: checkcast     #58                 // class java/util/Collection
      82: invokeinterface #214,  1          // InterfaceMethod java/util/Collection.size:()I
      87: istore        8
      89: iload         7
      91: iload         8
      93: if_icmpge     179
      96: aload_0
      97: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     100: iload         6
     102: aaload
     103: iload         7
     105: invokevirtual #218                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     108: dup
     109: ldc           #220                // String get(...)
     111: invokestatic  #209                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     114: checkcast     #26                 // class datastructure/graphs/Edge
     117: astore        9
     119: aload         9
     121: invokevirtual #49                 // Method datastructure/graphs/Edge.getSource:()I
     124: istore        10
     126: aload         9
     128: invokevirtual #156                // Method datastructure/graphs/Edge.getDestination:()I
     131: istore        11
     133: aload_3
     134: iload         10
     136: iaload
     137: ldc           #201                // int 2147483647
     139: if_icmpeq     173
     142: aload_3
     143: iload         10
     145: iaload
     146: aload         9
     148: invokevirtual #223                // Method datastructure/graphs/Edge.getWeight:()I
     151: iadd
     152: aload_3
     153: iload         11
     155: iaload
     156: if_icmpge     173
     159: aload_3
     160: iload         11
     162: aload_3
     163: iload         10
     165: iaload
     166: aload         9
     168: invokevirtual #223                // Method datastructure/graphs/Edge.getWeight:()I
     171: iadd
     172: iastore
     173: iinc          7, 1
     176: goto          89
     179: iinc          6, 1
     182: goto          63
     185: iinc          4, 1
     188: goto          53
     191: iconst_0
     192: istore        4
     194: aload_3
     195: arraylength
     196: istore        5
     198: iload         4
     200: iload         5
     202: if_icmpge     244
     205: aload_3
     206: iload         4
     208: iaload
     209: istore        6
     211: new           #128                // class java/lang/StringBuilder
     214: dup
     215: invokespecial #129                // Method java/lang/StringBuilder."<init>":()V
     218: iload         6
     220: invokevirtual #133                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     223: ldc           #225                // String  ->
     225: invokevirtual #186                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     228: invokevirtual #140                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     231: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     234: swap
     235: invokevirtual #143                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     238: iinc          4, 1
     241: goto          198
     244: return

  public final void primsMst(int);
    Code:
       0: new           #193                // class java/util/PriorityQueue
       3: dup
       4: invokespecial #194                // Method java/util/PriorityQueue."<init>":()V
       7: astore_2
       8: aload_2
       9: new           #196                // class datastructure/graphs/VertexPair
      12: dup
      13: iconst_0
      14: iconst_0
      15: invokespecial #199                // Method datastructure/graphs/VertexPair."<init>":(II)V
      18: invokevirtual #200                // Method java/util/PriorityQueue.add:(Ljava/lang/Object;)Z
      21: pop
      22: iconst_0
      23: istore        4
      25: aload_0
      26: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      29: arraylength
      30: istore        5
      32: iload         5
      34: newarray       boolean
      36: astore        6
      38: iload         4
      40: iload         5
      42: if_icmpge     61
      45: iload         4
      47: istore        7
      49: aload         6
      51: iload         7
      53: iconst_0
      54: bastore
      55: iinc          4, 1
      58: goto          38
      61: aload         6
      63: astore_3
      64: iconst_0
      65: istore        4
      67: aload_2
      68: checkcast     #58                 // class java/util/Collection
      71: invokeinterface #62,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      76: ifne          83
      79: iconst_1
      80: goto          84
      83: iconst_0
      84: ifeq          218
      87: aload_2
      88: invokevirtual #244                // Method java/util/PriorityQueue.poll:()Ljava/lang/Object;
      91: checkcast     #196                // class datastructure/graphs/VertexPair
      94: astore        5
      96: aload_3
      97: aload         5
      99: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     102: baload
     103: ifne          67
     106: aload_3
     107: aload         5
     109: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     112: iconst_1
     113: bastore
     114: iload         4
     116: aload         5
     118: invokevirtual #247                // Method datastructure/graphs/VertexPair.getDistance:()I
     121: iadd
     122: istore        4
     124: iconst_0
     125: istore        6
     127: aload_0
     128: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     131: aload         5
     133: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     136: aaload
     137: checkcast     #58                 // class java/util/Collection
     140: invokeinterface #214,  1          // InterfaceMethod java/util/Collection.size:()I
     145: istore        7
     147: iload         6
     149: iload         7
     151: if_icmpge     67
     154: aload_0
     155: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     158: aload         5
     160: invokevirtual #212                // Method datastructure/graphs/VertexPair.getNode:()I
     163: aaload
     164: iload         6
     166: invokevirtual #218                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     169: dup
     170: ldc           #220                // String get(...)
     172: invokestatic  #209                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     175: checkcast     #26                 // class datastructure/graphs/Edge
     178: astore        8
     180: aload_3
     181: aload         8
     183: invokevirtual #156                // Method datastructure/graphs/Edge.getDestination:()I
     186: baload
     187: ifne          212
     190: aload_2
     191: new           #196                // class datastructure/graphs/VertexPair
     194: dup
     195: aload         8
     197: invokevirtual #156                // Method datastructure/graphs/Edge.getDestination:()I
     200: aload         8
     202: invokevirtual #223                // Method datastructure/graphs/Edge.getWeight:()I
     205: invokespecial #199                // Method datastructure/graphs/VertexPair."<init>":(II)V
     208: invokevirtual #200                // Method java/util/PriorityQueue.add:(Ljava/lang/Object;)Z
     211: pop
     212: iinc          6, 1
     215: goto          147
     218: new           #128                // class java/lang/StringBuilder
     221: dup
     222: invokespecial #129                // Method java/lang/StringBuilder."<init>":()V
     225: ldc           #249                // String \nTotal path cost =
     227: invokevirtual #186                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     230: iload         4
     232: invokevirtual #133                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     235: invokevirtual #140                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     238: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     241: swap
     242: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     245: return

  public final java.util.LinkedList<java.lang.Integer> topSort();
    Code:
       0: iconst_0
       1: istore_2
       2: bipush        6
       4: newarray       boolean
       6: astore_3
       7: iload_2
       8: bipush        6
      10: if_icmpge     27
      13: iload_2
      14: istore        4
      16: aload_3
      17: iload         4
      19: iconst_0
      20: bastore
      21: iinc          2, 1
      24: goto          7
      27: aload_3
      28: astore_1
      29: new           #36                 // class java/util/LinkedList
      32: dup
      33: invokespecial #37                 // Method java/util/LinkedList."<init>":()V
      36: astore_2
      37: iconst_0
      38: istore_3
      39: aload_0
      40: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      43: arraylength
      44: istore        4
      46: iload_3
      47: iload         4
      49: if_icmpge     71
      52: aload_1
      53: iload_3
      54: baload
      55: ifne          65
      58: aload_0
      59: iload_3
      60: aload_1
      61: aload_2
      62: invokespecial #257                // Method topologicalSort:(I[ZLjava/util/LinkedList;)V
      65: iinc          3, 1
      68: goto          46
      71: aload_2
      72: areturn

  private final void topologicalSort(int, boolean[], java.util.LinkedList<java.lang.Integer>);
    Code:
       0: aload_2
       1: iload_1
       2: iconst_1
       3: bastore
       4: aload_0
       5: iload_1
       6: invokespecial #90                 // Method findNeighbours:(I)Ljava/util/List;
       9: astore        4
      11: aload         4
      13: invokeinterface #94,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      18: astore        5
      20: aload         5
      22: invokeinterface #99,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      27: ifeq          63
      30: aload         5
      32: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      37: checkcast     #104                // class java/lang/Number
      40: invokevirtual #105                // Method java/lang/Number.intValue:()I
      43: istore        6
      45: aload_2
      46: iload         6
      48: baload
      49: ifne          20
      52: aload_0
      53: iload         6
      55: aload_2
      56: aload_3
      57: invokespecial #257                // Method topologicalSort:(I[ZLjava/util/LinkedList;)V
      60: goto          20
      63: aload_3
      64: iload_1
      65: invokestatic  #55                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      68: invokevirtual #263                // Method java/util/LinkedList.push:(Ljava/lang/Object;)V
      71: return

  public final void kosarajuAlgorithm();
    Code:
       0: iconst_0
       1: istore_2
       2: aload_0
       3: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
       6: arraylength
       7: istore_3
       8: iload_3
       9: newarray       boolean
      11: astore        4
      13: iload_2
      14: iload_3
      15: if_icmpge     33
      18: iload_2
      19: istore        5
      21: aload         4
      23: iload         5
      25: iconst_0
      26: bastore
      27: iinc          2, 1
      30: goto          13
      33: aload         4
      35: astore_1
      36: aload_0
      37: invokevirtual #266                // Method topSort:()Ljava/util/LinkedList;
      40: astore_2
      41: iconst_0
      42: istore        4
      44: aload_0
      45: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      48: arraylength
      49: istore        5
      51: iload         5
      53: anewarray     #15                 // class java/util/ArrayList
      56: astore        6
      58: iload         4
      60: iload         5
      62: if_icmpge     87
      65: iload         4
      67: istore        7
      69: aload         6
      71: iload         7
      73: new           #15                 // class java/util/ArrayList
      76: dup
      77: invokespecial #16                 // Method java/util/ArrayList."<init>":()V
      80: aastore
      81: iinc          4, 1
      84: goto          58
      87: aload         6
      89: astore_3
      90: iconst_0
      91: istore        4
      93: aload_0
      94: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
      97: arraylength
      98: istore        5
     100: iload         4
     102: iload         5
     104: if_icmpge     202
     107: iconst_0
     108: istore        6
     110: aload_0
     111: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     114: iload         4
     116: aaload
     117: checkcast     #58                 // class java/util/Collection
     120: invokeinterface #214,  1          // InterfaceMethod java/util/Collection.size:()I
     125: istore        7
     127: iload         6
     129: iload         7
     131: if_icmpge     196
     134: aload_0
     135: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     138: iload         4
     140: aaload
     141: iload         6
     143: invokevirtual #218                // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
     146: dup
     147: ldc           #220                // String get(...)
     149: invokestatic  #209                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     152: checkcast     #26                 // class datastructure/graphs/Edge
     155: astore        8
     157: aload_3
     158: aload         8
     160: invokevirtual #156                // Method datastructure/graphs/Edge.getDestination:()I
     163: aaload
     164: new           #26                 // class datastructure/graphs/Edge
     167: dup
     168: aload         8
     170: invokevirtual #156                // Method datastructure/graphs/Edge.getDestination:()I
     173: aload         8
     175: invokevirtual #49                 // Method datastructure/graphs/Edge.getSource:()I
     178: aload         8
     180: invokevirtual #223                // Method datastructure/graphs/Edge.getWeight:()I
     183: invokespecial #29                 // Method datastructure/graphs/Edge."<init>":(III)V
     186: invokevirtual #33                 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     189: pop
     190: iinc          6, 1
     193: goto          127
     196: iinc          4, 1
     199: goto          100
     202: ldc_w         #268                // String Graph
     205: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     208: swap
     209: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     212: aload_0
     213: getfield      #20                 // Field graph:[Ljava/util/ArrayList;
     216: astore        4
     218: iconst_0
     219: istore        5
     221: iconst_0
     222: istore        6
     224: aload         4
     226: arraylength
     227: istore        7
     229: iload         6
     231: iload         7
     233: if_icmpge     266
     236: aload         4
     238: iload         6
     240: aaload
     241: astore        8
     243: aload         8
     245: astore        9
     247: iconst_0
     248: istore        10
     250: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     253: aload         9
     255: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     258: nop
     259: nop
     260: iinc          6, 1
     263: goto          229
     266: nop
     267: ldc_w         #270                // String Transpose
     270: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     273: swap
     274: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     277: aload_3
     278: astore        4
     280: iconst_0
     281: istore        5
     283: iconst_0
     284: istore        6
     286: aload         4
     288: arraylength
     289: istore        7
     291: iload         6
     293: iload         7
     295: if_icmpge     328
     298: aload         4
     300: iload         6
     302: aaload
     303: astore        8
     305: aload         8
     307: astore        9
     309: iconst_0
     310: istore        10
     312: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     315: aload         9
     317: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     320: nop
     321: nop
     322: iinc          6, 1
     325: goto          291
     328: nop
     329: ldc_w         #272                // String Stack
     332: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     335: swap
     336: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     339: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     342: aload_2
     343: invokevirtual #183                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     346: aload_2
     347: checkcast     #58                 // class java/util/Collection
     350: invokeinterface #62,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     355: ifne          362
     358: iconst_1
     359: goto          363
     362: iconst_0
     363: ifeq          410
     366: aload_2
     367: invokevirtual #275                // Method java/util/LinkedList.pop:()Ljava/lang/Object;
     370: checkcast     #51                 // class java/lang/Integer
     373: astore        4
     375: aload_1
     376: aload         4
     378: invokestatic  #72                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     381: aload         4
     383: invokevirtual #75                 // Method java/lang/Integer.intValue:()I
     386: baload
     387: ifne          346
     390: aload_0
     391: aload_3
     392: aload         4
     394: invokevirtual #75                 // Method java/lang/Integer.intValue:()I
     397: aload_1
     398: invokevirtual #145                // Method dfs:([Ljava/util/ArrayList;I[Z)V
     401: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
     404: invokevirtual #147                // Method java/io/PrintStream.println:()V
     407: goto          346
     410: return
}


package datastructure.graphs

/**
 * You are given an m x n grid where each cell can have one of three values: ● 0 representing an empty cell, ● 1 representing a fresh orange,
 * or ● 2 representing a rotten orange. Every minute, any fresh orange that is 4-directionally adjacent to a rotten orange becomes rotten.
 * Return the minimum number of minutes that must elapse until no cell has a fresh orange.
 * If this is impossible, return -1.
 *
 * Example 1 Input: grid = [[2,1,1],[1,1,0],[0,1,1]]
 * Output: 4
 *
 * Example 2 Input: grid = [[2,1,1],[0,1,1],[1,0,1]]
 * Output: -1 Explanation:
 *
 * The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally
 * */

import java.util.LinkedList
import java.util.Queue

fun orangesRotting(grid: Array<IntArray>): Int {
    val rows = grid.size
    val cols = grid[0].size

    // Define four possible directions (up, down, left, right)
    val directions = arrayOf(intArrayOf(-1, 0), intArrayOf(1, 0), intArrayOf(0, -1), intArrayOf(0, 1))

    // Initialize a queue to perform BFS
    val queue: Queue<kotlin.Pair<Int, Int>> = LinkedList()

    // Initialize variables to keep track of time and fresh oranges
    var minutes = 0
    var freshOranges = 0

    // Enqueue all rotten oranges and count fresh oranges
    // This step also ensure to handle multiple rotten oranges at same time.
    for (i in 0 until rows) {
        for (j in 0 until cols) {
            if (grid[i][j] == 2) {
                queue.offer(Pair(i, j))
            } else if (grid[i][j] == 1) {
                freshOranges++
            }
        }
    }

    // Perform BFS
    while (queue.isNotEmpty()) {
        val size = queue.size
        for (i in 0 until size) {
            val (x, y) = queue.poll()

            for (direction in directions) {
                val newX = x + direction[0]
                val newY = y + direction[1]

                if (newX in 0 until rows && newY in 0 until cols && grid[newX][newY] == 1) {
                    grid[newX][newY] = 2
                    freshOranges--
                    queue.offer(Pair(newX, newY))
                }
            }
        }
        minutes++
    }

    // If there are still fresh oranges left, it's impossible to rot them all
    return if (freshOranges == 0) minutes else -1
}

fun main() {
    val grid1 = arrayOf(
        intArrayOf(2, 1, 1),
        intArrayOf(1, 1, 0),
        intArrayOf(0, 1, 2)
    )

    val grid2 = arrayOf(
        intArrayOf(2, 1, 1),
        intArrayOf(0, 1, 1),
        intArrayOf(1, 0, 1)
    )

    println(orangesRotting(grid1)) // Output: 4
    println(orangesRotting(grid2)) // Output: -1
}

fun printMatrix(matrix: Array<IntArray>){
    for (i in matrix.indices) {
        for (j in matrix[i].indices) {
            print("${matrix[i][j]} \t")
        }
        println()
    }
}

Compiled from "RootenOranges.kt"
public final class datastructure.graphs.RootenOrangesKt {
  public static final int orangesRotting(int[][]);
    Code:
       0: aload_0
       1: ldc           #9                  // String grid
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #17                 // class "[Ljava/lang/Object;"
      10: arraylength
      11: istore_1
      12: aload_0
      13: iconst_0
      14: aaload
      15: arraylength
      16: istore_2
      17: iconst_4
      18: anewarray     #19                 // class "[I"
      21: astore        4
      23: aload         4
      25: iconst_0
      26: iconst_2
      27: newarray       int
      29: astore        5
      31: aload         5
      33: iconst_0
      34: iconst_m1
      35: iastore
      36: aload         5
      38: iconst_1
      39: iconst_0
      40: iastore
      41: aload         5
      43: aastore
      44: aload         4
      46: iconst_1
      47: iconst_2
      48: newarray       int
      50: astore        5
      52: aload         5
      54: iconst_0
      55: iconst_1
      56: iastore
      57: aload         5
      59: iconst_1
      60: iconst_0
      61: iastore
      62: aload         5
      64: aastore
      65: aload         4
      67: iconst_2
      68: iconst_2
      69: newarray       int
      71: astore        5
      73: aload         5
      75: iconst_0
      76: iconst_0
      77: iastore
      78: aload         5
      80: iconst_1
      81: iconst_m1
      82: iastore
      83: aload         5
      85: aastore
      86: aload         4
      88: iconst_3
      89: iconst_2
      90: newarray       int
      92: astore        5
      94: aload         5
      96: iconst_0
      97: iconst_0
      98: iastore
      99: aload         5
     101: iconst_1
     102: iconst_1
     103: iastore
     104: aload         5
     106: aastore
     107: aload         4
     109: astore_3
     110: new           #21                 // class java/util/LinkedList
     113: dup
     114: invokespecial #25                 // Method java/util/LinkedList."<init>":()V
     117: checkcast     #27                 // class java/util/Queue
     120: astore        4
     122: iconst_0
     123: istore        5
     125: iconst_0
     126: istore        6
     128: iconst_0
     129: istore        7
     131: iload         7
     133: iload_1
     134: if_icmpge     211
     137: iconst_0
     138: istore        8
     140: iload         8
     142: iload_2
     143: if_icmpge     205
     146: aload_0
     147: iload         7
     149: aaload
     150: iload         8
     152: iaload
     153: iconst_2
     154: if_icmpne     185
     157: aload         4
     159: new           #29                 // class kotlin/Pair
     162: dup
     163: iload         7
     165: invokestatic  #35                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     168: iload         8
     170: invokestatic  #35                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     173: invokespecial #38                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     176: invokeinterface #42,  2           // InterfaceMethod java/util/Queue.offer:(Ljava/lang/Object;)Z
     181: pop
     182: goto          199
     185: aload_0
     186: iload         7
     188: aaload
     189: iload         8
     191: iaload
     192: iconst_1
     193: if_icmpne     199
     196: iinc          6, 1
     199: iinc          8, 1
     202: goto          140
     205: iinc          7, 1
     208: goto          131
     211: aload         4
     213: checkcast     #44                 // class java/util/Collection
     216: invokeinterface #48,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     221: ifne          228
     224: iconst_1
     225: goto          229
     228: iconst_0
     229: ifeq          443
     232: aload         4
     234: invokeinterface #52,  1           // InterfaceMethod java/util/Queue.size:()I
     239: istore        7
     241: iconst_0
     242: istore        8
     244: iload         8
     246: iload         7
     248: if_icmpge     437
     251: aload         4
     253: invokeinterface #56,  1           // InterfaceMethod java/util/Queue.poll:()Ljava/lang/Object;
     258: checkcast     #29                 // class kotlin/Pair
     261: astore        9
     263: aload         9
     265: invokevirtual #59                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
     268: checkcast     #61                 // class java/lang/Number
     271: invokevirtual #64                 // Method java/lang/Number.intValue:()I
     274: istore        10
     276: aload         9
     278: invokevirtual #67                 // Method kotlin/Pair.component2:()Ljava/lang/Object;
     281: checkcast     #61                 // class java/lang/Number
     284: invokevirtual #64                 // Method java/lang/Number.intValue:()I
     287: istore        11
     289: iconst_0
     290: istore        12
     292: aload_3
     293: checkcast     #17                 // class "[Ljava/lang/Object;"
     296: arraylength
     297: istore        13
     299: iload         12
     301: iload         13
     303: if_icmpge     431
     306: aload_3
     307: iload         12
     309: aaload
     310: astore        14
     312: iload         10
     314: aload         14
     316: iconst_0
     317: iaload
     318: iadd
     319: istore        15
     321: iload         11
     323: aload         14
     325: iconst_1
     326: iaload
     327: iadd
     328: istore        16
     330: iconst_0
     331: iload         15
     333: if_icmpgt     350
     336: iload         15
     338: iload_1
     339: if_icmpge     346
     342: iconst_1
     343: goto          351
     346: iconst_0
     347: goto          351
     350: iconst_0
     351: ifeq          425
     354: iconst_0
     355: iload         16
     357: if_icmpgt     374
     360: iload         16
     362: iload_2
     363: if_icmpge     370
     366: iconst_1
     367: goto          375
     370: iconst_0
     371: goto          375
     374: iconst_0
     375: ifeq          425
     378: aload_0
     379: iload         15
     381: aaload
     382: iload         16
     384: iaload
     385: iconst_1
     386: if_icmpne     425
     389: aload_0
     390: iload         15
     392: aaload
     393: iload         16
     395: iconst_2
     396: iastore
     397: iinc          6, -1
     400: aload         4
     402: new           #29                 // class kotlin/Pair
     405: dup
     406: iload         15
     408: invokestatic  #35                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     411: iload         16
     413: invokestatic  #35                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     416: invokespecial #38                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     419: invokeinterface #42,  2           // InterfaceMethod java/util/Queue.offer:(Ljava/lang/Object;)Z
     424: pop
     425: iinc          12, 1
     428: goto          299
     431: iinc          8, 1
     434: goto          244
     437: iinc          5, 1
     440: goto          211
     443: iload         6
     445: ifne          453
     448: iload         5
     450: goto          454
     453: iconst_m1
     454: ireturn

  public static final void main();
    Code:
       0: iconst_3
       1: anewarray     #19                 // class "[I"
       4: astore_1
       5: aload_1
       6: iconst_0
       7: iconst_3
       8: newarray       int
      10: astore_2
      11: aload_2
      12: iconst_0
      13: iconst_2
      14: iastore
      15: aload_2
      16: iconst_1
      17: iconst_1
      18: iastore
      19: aload_2
      20: iconst_2
      21: iconst_1
      22: iastore
      23: aload_2
      24: aastore
      25: aload_1
      26: iconst_1
      27: iconst_3
      28: newarray       int
      30: astore_2
      31: aload_2
      32: iconst_0
      33: iconst_1
      34: iastore
      35: aload_2
      36: iconst_1
      37: iconst_1
      38: iastore
      39: aload_2
      40: iconst_2
      41: iconst_0
      42: iastore
      43: aload_2
      44: aastore
      45: aload_1
      46: iconst_2
      47: iconst_3
      48: newarray       int
      50: astore_2
      51: aload_2
      52: iconst_0
      53: iconst_0
      54: iastore
      55: aload_2
      56: iconst_1
      57: iconst_1
      58: iastore
      59: aload_2
      60: iconst_2
      61: iconst_2
      62: iastore
      63: aload_2
      64: aastore
      65: aload_1
      66: astore_0
      67: iconst_3
      68: anewarray     #19                 // class "[I"
      71: astore_2
      72: aload_2
      73: iconst_0
      74: iconst_3
      75: newarray       int
      77: astore_3
      78: aload_3
      79: iconst_0
      80: iconst_2
      81: iastore
      82: aload_3
      83: iconst_1
      84: iconst_1
      85: iastore
      86: aload_3
      87: iconst_2
      88: iconst_1
      89: iastore
      90: aload_3
      91: aastore
      92: aload_2
      93: iconst_1
      94: iconst_3
      95: newarray       int
      97: astore_3
      98: aload_3
      99: iconst_0
     100: iconst_0
     101: iastore
     102: aload_3
     103: iconst_1
     104: iconst_1
     105: iastore
     106: aload_3
     107: iconst_2
     108: iconst_1
     109: iastore
     110: aload_3
     111: aastore
     112: aload_2
     113: iconst_2
     114: iconst_3
     115: newarray       int
     117: astore_3
     118: aload_3
     119: iconst_0
     120: iconst_1
     121: iastore
     122: aload_3
     123: iconst_1
     124: iconst_0
     125: iastore
     126: aload_3
     127: iconst_2
     128: iconst_1
     129: iastore
     130: aload_3
     131: aastore
     132: aload_2
     133: astore_1
     134: aload_0
     135: invokestatic  #87                 // Method orangesRotting:([[I)I
     138: istore_2
     139: getstatic     #93                 // Field java/lang/System.out:Ljava/io/PrintStream;
     142: iload_2
     143: invokevirtual #99                 // Method java/io/PrintStream.println:(I)V
     146: aload_1
     147: invokestatic  #87                 // Method orangesRotting:([[I)I
     150: istore_2
     151: getstatic     #93                 // Field java/lang/System.out:Ljava/io/PrintStream;
     154: iload_2
     155: invokevirtual #99                 // Method java/io/PrintStream.println:(I)V
     158: return

  public static final void printMatrix(int[][]);
    Code:
       0: aload_0
       1: ldc           #105                // String matrix
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: istore_1
       8: aload_0
       9: checkcast     #17                 // class "[Ljava/lang/Object;"
      12: arraylength
      13: istore_2
      14: iload_1
      15: iload_2
      16: if_icmpge     81
      19: iconst_0
      20: istore_3
      21: aload_0
      22: iload_1
      23: aaload
      24: arraylength
      25: istore        4
      27: iload_3
      28: iload         4
      30: if_icmpge     69
      33: new           #107                // class java/lang/StringBuilder
      36: dup
      37: invokespecial #108                // Method java/lang/StringBuilder."<init>":()V
      40: aload_0
      41: iload_1
      42: aaload
      43: iload_3
      44: iaload
      45: invokevirtual #112                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      48: ldc           #114                // String  \t
      50: invokevirtual #117                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      53: invokevirtual #121                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      56: getstatic     #93                 // Field java/lang/System.out:Ljava/io/PrintStream;
      59: swap
      60: invokevirtual #125                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      63: iinc          3, 1
      66: goto          27
      69: getstatic     #93                 // Field java/lang/System.out:Ljava/io/PrintStream;
      72: invokevirtual #127                // Method java/io/PrintStream.println:()V
      75: iinc          1, 1
      78: goto          14
      81: return

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