package com.anahoret.pathfinding

import java.lang.IllegalArgumentException
import java.util.*

fun addPath(map: String): String = Graph.getMapWithPath(map)

object Graph {

    private const val STRAIGHT_LENGTH = 2
    private const val DIAGONAL_LENGTH = 3

    fun getMapWithPath(map: String): String {
        val (nodes, arcs) = readGraph(map)
        val start = nodes.find { it.isStart } ?: throw IllegalArgumentException("No start point specified")
        val end = nodes.find { it.isEnd } ?: throw IllegalArgumentException("No end point specified")

        val paths = calcDistances(start, nodes, arcs)
        return map.lines()
            .map(String::toCharArray)
            .let { charGrid ->
                charGrid[start.row][start.col] = '*'
                paths.getValue(end).forEach { charGrid[it.row][it.col] = '*' }
                charGrid.joinToString(separator = "\n") { row -> row.joinToString(separator = "") }
            }
    }

    private fun calcDistances(start: Node, nodes: Collection<Node>, arcs: Map<Node, List<Arc>>): Map<Node, List<Node>> {
        val paths = nodes.map { it to emptyList<Node>() }.toMap().toMutableMap()
        val distances = nodes.map { it to if (it == start) 0 else Int.MAX_VALUE }.toMap().toMutableMap()
        val visited = mutableSetOf<Node>()

        val queue = PriorityQueue<Node>(nodes.size) { n1, n2 -> distances.getValue(n1) - distances.getValue(n2) }
        queue.addAll(nodes)

        while (queue.isNotEmpty()) {
            val node = queue.poll()
            visited.add(node)
            arcs.getValue(node)
                .filterNot { visited.contains(it.node) }
                .forEach { arc ->
                    if (distances.getValue(node) + arc.length < distances.getValue(arc.node)) {
                        distances[arc.node] = distances.getValue(node) + arc.length
                        paths[arc.node] = paths.getValue(node) + arc.node
                        queue.remove(arc.node)
                        queue.add(arc.node)
                    }
                }
        }

        return paths.toMap()
    }

    private fun readGraph(map: String): Pair<List<Node>, Map<Node, List<Arc>>> {
        val nodes = map.lines()
            .mapIndexed { row, str ->
                str.mapIndexedNotNull { col, char -> if (char == 'B') null else Node(row, col, char) }
            }
            .flatten()

        val arcs = nodes.map { node ->
            val row = nodes.filter { it.row == node.row }
            val topRow = nodes.filter { it.row == node.row - 1 }
            val bottomRow = nodes.filter { it.row == node.row + 1 }
            val nodeArcs = listOfNotNull(
                topRow.find { it.col == node.col }?.let { Arc(it, STRAIGHT_LENGTH) },
                topRow.find { it.col == node.col - 1 }?.let { Arc(it, DIAGONAL_LENGTH) },
                topRow.find { it.col == node.col + 1 }?.let { Arc(it, DIAGONAL_LENGTH) },

                bottomRow.find { it.col == node.col }?.let { Arc(it, STRAIGHT_LENGTH) },
                bottomRow.find { it.col == node.col - 1 }?.let { Arc(it, DIAGONAL_LENGTH) },
                bottomRow.find { it.col == node.col + 1 }?.let { Arc(it, DIAGONAL_LENGTH) },

                row.find { it.col == node.col - 1 }?.let { Arc(it, STRAIGHT_LENGTH) },
                row.find { it.col == node.col + 1 }?.let { Arc(it, STRAIGHT_LENGTH) }
            )
            node to nodeArcs
        }.toMap()

        return Pair(nodes, arcs)
    }

    class Node(val row: Int, val col: Int, char: Char) {

        val isStart = char == 'S'
        val isEnd = char == 'X'

        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (other !is Node) return false

            if (row != other.row) return false
            if (col != other.col) return false

            return true
        }

        override fun hashCode(): Int {
            var result = row
            result = 31 * result + col
            return result
        }

    }

    class Arc(val node: Node, val length: Int)

}

Compiled from "MarkingWayOnMap.kt"
public final class com.anahoret.pathfinding.MarkingWayOnMapKt {
  public static final java.lang.String addPath(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #9                  // String map
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #21                 // Field com/anahoret/pathfinding/Graph.INSTANCE:Lcom/anahoret/pathfinding/Graph;
       9: aload_0
      10: invokevirtual #24                 // Method com/anahoret/pathfinding/Graph.getMapWithPath:(Ljava/lang/String;)Ljava/lang/String;
      13: areturn
}


package org.redquark.conceptoftheday

/**
 * @author <NAME>
 *
 * We are given two strings "text" and "pattern" of size n and m respectively where m < n.
 * Find all the indices in text where anagrams of pattern are found.
 */
private fun findIndices(text: String, pattern: String): List<Int> {
    // Lengths of strings
    val n = text.length
    val m = pattern.length
    // List that will store the indices
    val indices: MutableList<Int> = ArrayList()
    // Frequency arrays - assuming we have a set of 256 characters
    val textCount = IntArray(256)
    val patternCount = IntArray(256)
    // Loop until m
    for (i in 0 until m) {
        textCount[text[i].toInt()]++
        patternCount[pattern[i].toInt()]++
    }
    // At this point, we have traversed m characters in both the arrays.
    // Now we will loop through the remaining characters
    for (i in m until n) {
        // Check if the counts of characters in frequency arrays are equal or not
        if (isCountEqual(textCount, patternCount)) {
            indices.add(i - m)
        }
        // Discard left most character
        textCount[text[i - m].toInt()]--
        // Include current character
        textCount[text[i].toInt()]++
    }
    // Check for the last window
    if (isCountEqual(textCount, patternCount)) {
        indices.add(n - m)
    }
    return indices
}

private fun isCountEqual(textCount: IntArray, patternCount: IntArray): Boolean {
    for (i in 0..255) {
        if (textCount[i] != patternCount[i]) {
            return false
        }
    }
    return true
}

fun main() {
    var text = "BACDGABCDA"
    var pattern = "ABCD"
    println("Anagrams are found at: " + findIndices(text, pattern))

    text = "XYYZXZYZXXYZ"
    pattern = "XYZ"
    println("Anagrams are found at: " + findIndices(text, pattern))
}

Compiled from "AnagramSubstringSearch.kt"
public final class org.redquark.conceptoftheday.AnagramSubstringSearchKt {
  private static final java.util.List<java.lang.Integer> findIndices(java.lang.String, java.lang.String);
    Code:
       0: aload_0
       1: invokevirtual #13                 // Method java/lang/String.length:()I
       4: istore_2
       5: aload_1
       6: invokevirtual #13                 // Method java/lang/String.length:()I
       9: istore_3
      10: new           #15                 // class java/util/ArrayList
      13: dup
      14: invokespecial #19                 // Method java/util/ArrayList."<init>":()V
      17: checkcast     #21                 // class java/util/List
      20: astore        4
      22: sipush        256
      25: newarray       int
      27: astore        5
      29: sipush        256
      32: newarray       int
      34: astore        6
      36: iconst_0
      37: istore        7
      39: iload         7
      41: iload_3
      42: if_icmpge     99
      45: aload_0
      46: iload         7
      48: invokevirtual #25                 // Method java/lang/String.charAt:(I)C
      51: istore        8
      53: aload         5
      55: iload         8
      57: iaload
      58: istore        9
      60: aload         5
      62: iload         8
      64: iload         9
      66: iconst_1
      67: iadd
      68: iastore
      69: aload_1
      70: iload         7
      72: invokevirtual #25                 // Method java/lang/String.charAt:(I)C
      75: istore        10
      77: aload         6
      79: iload         10
      81: iaload
      82: istore        11
      84: aload         6
      86: iload         10
      88: iload         11
      90: iconst_1
      91: iadd
      92: iastore
      93: iinc          7, 1
      96: goto          39
      99: iload_3
     100: istore        7
     102: iload         7
     104: iload_2
     105: if_icmpge     189
     108: aload         5
     110: aload         6
     112: invokestatic  #29                 // Method isCountEqual:([I[I)Z
     115: ifeq          133
     118: aload         4
     120: iload         7
     122: iload_3
     123: isub
     124: invokestatic  #35                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     127: invokeinterface #39,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     132: pop
     133: aload_0
     134: iload         7
     136: iload_3
     137: isub
     138: invokevirtual #25                 // Method java/lang/String.charAt:(I)C
     141: istore        8
     143: aload         5
     145: iload         8
     147: iaload
     148: istore        9
     150: aload         5
     152: iload         8
     154: iload         9
     156: iconst_m1
     157: iadd
     158: iastore
     159: aload_0
     160: iload         7
     162: invokevirtual #25                 // Method java/lang/String.charAt:(I)C
     165: istore        10
     167: aload         5
     169: iload         10
     171: iaload
     172: istore        11
     174: aload         5
     176: iload         10
     178: iload         11
     180: iconst_1
     181: iadd
     182: iastore
     183: iinc          7, 1
     186: goto          102
     189: aload         5
     191: aload         6
     193: invokestatic  #29                 // Method isCountEqual:([I[I)Z
     196: ifeq          213
     199: aload         4
     201: iload_2
     202: iload_3
     203: isub
     204: invokestatic  #35                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     207: invokeinterface #39,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     212: pop
     213: aload         4
     215: areturn

  private static final boolean isCountEqual(int[], int[]);
    Code:
       0: iconst_0
       1: istore_2
       2: iload_2
       3: sipush        256
       6: if_icmpge     26
       9: aload_0
      10: iload_2
      11: iaload
      12: aload_1
      13: iload_2
      14: iaload
      15: if_icmpeq     20
      18: iconst_0
      19: ireturn
      20: iinc          2, 1
      23: goto          2
      26: iconst_1
      27: ireturn

  public static final void main();
    Code:
       0: ldc           #55                 // String BACDGABCDA
       2: astore_0
       3: ldc           #57                 // String ABCD
       5: astore_1
       6: new           #59                 // class java/lang/StringBuilder
       9: dup
      10: invokespecial #60                 // Method java/lang/StringBuilder."<init>":()V
      13: ldc           #62                 // String Anagrams are found at:
      15: invokevirtual #66                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      18: aload_0
      19: aload_1
      20: invokestatic  #68                 // Method findIndices:(Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
      23: invokevirtual #71                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      26: invokevirtual #75                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      29: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
      32: swap
      33: invokevirtual #87                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      36: ldc           #89                 // String XYYZXZYZXXYZ
      38: astore_0
      39: ldc           #91                 // String XYZ
      41: astore_1
      42: new           #59                 // class java/lang/StringBuilder
      45: dup
      46: invokespecial #60                 // Method java/lang/StringBuilder."<init>":()V
      49: ldc           #62                 // String Anagrams are found at:
      51: invokevirtual #66                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      54: aload_0
      55: aload_1
      56: invokestatic  #68                 // Method findIndices:(Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
      59: invokevirtual #71                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      62: invokevirtual #75                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      65: getstatic     #81                 // Field java/lang/System.out:Ljava/io/PrintStream;
      68: swap
      69: invokevirtual #87                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      72: return

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


package org.redquark.tutorials.leetcode

class SubstringWithConcatenationOfAllWords {

    fun findSubstring(s: String, words: Array<String>): List<Int> {
        // Resultant list
        val indices: MutableList<Int> = ArrayList()
        // Base conditions
        if (s.isEmpty() || words.isEmpty()) {
            return indices
        }
        // Store the words and their counts in a hash map
        val wordCount: MutableMap<String, Int> = HashMap()
        for (word in words) {
            wordCount[word] = wordCount.getOrDefault(word, 0) + 1
        }
        // Length of each word in the words array
        val wordLength = words[0].length
        // Length of all the words combined in the array
        val wordArrayLength = wordLength * words.size
        // Loop for the entire string
        for (i in 0..s.length - wordArrayLength) {
            // Get the substring of length equal to wordArrayLength
            val current = s.substring(i, i + wordArrayLength)
            // Map to store each word of the substring
            val wordMap: MutableMap<String, Int> = HashMap()
            // Index to loop through the words array
            var index = 0
            // Index to get each word in the current
            var j = 0
            // Loop through each word of the words array
            while (index < words.size) {
                // Divide the current string into strings of length of
                // each word in the array
                val part = current.substring(j, j + wordLength)
                // Put this string into the wordMap
                wordMap[part] = wordMap.getOrDefault(part, 0) + 1
                // Update j and index
                j += wordLength
                index++
            }
            // At this point compare the maps
            if (wordCount == wordMap) {
                indices.add(i)
            }
        }
        return indices
    }
}

fun main() {
    val sObject = SubstringWithConcatenationOfAllWords()
    var s = "barfoothefoobarman"
    var words = arrayOf("foo", "bar")
    println(sObject.findSubstring(s, words))

    s = "wordgoodgoodgoodbestword"
    words = arrayOf("word", "good", "best", "word")
    println(sObject.findSubstring(s, words))

    s = "barfoofoobarthefoobarman"
    words = arrayOf("bar", "foo", "the")
    println(sObject.findSubstring(s, words))

    s = "wordgoodgoodgoodbestword"
    words = arrayOf("word", "good", "best", "good")
    println(sObject.findSubstring(s, words))
}

Compiled from "SubstringWithConcatenationOfAllWords.kt"
public final class org.redquark.tutorials.leetcode.SubstringWithConcatenationOfAllWords {
  public org.redquark.tutorials.leetcode.SubstringWithConcatenationOfAllWords();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final java.util.List<java.lang.Integer> findSubstring(java.lang.String, java.lang.String[]);
    Code:
       0: aload_1
       1: ldc           #16                 // String s
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #24                 // String words
       9: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: new           #26                 // class java/util/ArrayList
      15: dup
      16: invokespecial #27                 // Method java/util/ArrayList."<init>":()V
      19: checkcast     #29                 // class java/util/List
      22: astore_3
      23: aload_1
      24: checkcast     #31                 // class java/lang/CharSequence
      27: invokeinterface #35,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      32: ifne          39
      35: iconst_1
      36: goto          40
      39: iconst_0
      40: ifne          56
      43: aload_2
      44: arraylength
      45: ifne          52
      48: iconst_1
      49: goto          53
      52: iconst_0
      53: ifeq          58
      56: aload_3
      57: areturn
      58: new           #37                 // class java/util/HashMap
      61: dup
      62: invokespecial #38                 // Method java/util/HashMap."<init>":()V
      65: checkcast     #40                 // class java/util/Map
      68: astore        4
      70: iconst_0
      71: istore        5
      73: aload_2
      74: arraylength
      75: istore        6
      77: iload         5
      79: iload         6
      81: if_icmpge     130
      84: aload_2
      85: iload         5
      87: aaload
      88: astore        7
      90: aload         4
      92: aload         7
      94: aload         4
      96: aload         7
      98: iconst_0
      99: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     102: invokeinterface #50,  3           // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     107: checkcast     #52                 // class java/lang/Number
     110: invokevirtual #55                 // Method java/lang/Number.intValue:()I
     113: iconst_1
     114: iadd
     115: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     118: invokeinterface #58,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     123: pop
     124: iinc          5, 1
     127: goto          77
     130: aload_2
     131: iconst_0
     132: aaload
     133: invokevirtual #61                 // Method java/lang/String.length:()I
     136: istore        5
     138: iload         5
     140: aload_2
     141: arraylength
     142: imul
     143: istore        6
     145: iconst_0
     146: istore        7
     148: aload_1
     149: invokevirtual #61                 // Method java/lang/String.length:()I
     152: iload         6
     154: isub
     155: istore        8
     157: iload         7
     159: iload         8
     161: if_icmpgt     310
     164: aload_1
     165: iload         7
     167: iload         7
     169: iload         6
     171: iadd
     172: invokevirtual #65                 // Method java/lang/String.substring:(II)Ljava/lang/String;
     175: dup
     176: ldc           #67                 // String substring(...)
     178: invokestatic  #70                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     181: astore        9
     183: new           #37                 // class java/util/HashMap
     186: dup
     187: invokespecial #38                 // Method java/util/HashMap."<init>":()V
     190: checkcast     #40                 // class java/util/Map
     193: astore        10
     195: iconst_0
     196: istore        11
     198: iconst_0
     199: istore        12
     201: iload         11
     203: aload_2
     204: arraylength
     205: if_icmpge     275
     208: aload         9
     210: iload         12
     212: iload         12
     214: iload         5
     216: iadd
     217: invokevirtual #65                 // Method java/lang/String.substring:(II)Ljava/lang/String;
     220: dup
     221: ldc           #67                 // String substring(...)
     223: invokestatic  #70                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     226: astore        13
     228: aload         10
     230: aload         13
     232: aload         10
     234: aload         13
     236: iconst_0
     237: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     240: invokeinterface #50,  3           // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     245: checkcast     #52                 // class java/lang/Number
     248: invokevirtual #55                 // Method java/lang/Number.intValue:()I
     251: iconst_1
     252: iadd
     253: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     256: invokeinterface #58,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     261: pop
     262: iload         12
     264: iload         5
     266: iadd
     267: istore        12
     269: iinc          11, 1
     272: goto          201
     275: aload         4
     277: aload         10
     279: invokestatic  #74                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     282: ifeq          297
     285: aload_3
     286: iload         7
     288: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     291: invokeinterface #78,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     296: pop
     297: iload         7
     299: iload         8
     301: if_icmpeq     310
     304: iinc          7, 1
     307: goto          164
     310: aload_3
     311: areturn
}

Compiled from "SubstringWithConcatenationOfAllWords.kt"
public final class org.redquark.tutorials.leetcode.SubstringWithConcatenationOfAllWordsKt {
  public static final void main();
    Code:
       0: new           #8                  // class org/redquark/tutorials/leetcode/SubstringWithConcatenationOfAllWords
       3: dup
       4: invokespecial #11                 // Method org/redquark/tutorials/leetcode/SubstringWithConcatenationOfAllWords."<init>":()V
       7: astore_0
       8: ldc           #13                 // String barfoothefoobarman
      10: astore_1
      11: iconst_2
      12: anewarray     #15                 // class java/lang/String
      15: astore_3
      16: aload_3
      17: iconst_0
      18: ldc           #17                 // String foo
      20: aastore
      21: aload_3
      22: iconst_1
      23: ldc           #19                 // String bar
      25: aastore
      26: aload_3
      27: astore_2
      28: aload_0
      29: aload_1
      30: aload_2
      31: invokevirtual #23                 // Method org/redquark/tutorials/leetcode/SubstringWithConcatenationOfAllWords.findSubstring:(Ljava/lang/String;[Ljava/lang/String;)Ljava/util/List;
      34: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;
      37: swap
      38: invokevirtual #35                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      41: ldc           #37                 // String wordgoodgoodgoodbestword
      43: astore_1
      44: iconst_4
      45: anewarray     #15                 // class java/lang/String
      48: astore_3
      49: aload_3
      50: iconst_0
      51: ldc           #39                 // String word
      53: aastore
      54: aload_3
      55: iconst_1
      56: ldc           #41                 // String good
      58: aastore
      59: aload_3
      60: iconst_2
      61: ldc           #43                 // String best
      63: aastore
      64: aload_3
      65: iconst_3
      66: ldc           #39                 // String word
      68: aastore
      69: aload_3
      70: astore_2
      71: aload_0
      72: aload_1
      73: aload_2
      74: invokevirtual #23                 // Method org/redquark/tutorials/leetcode/SubstringWithConcatenationOfAllWords.findSubstring:(Ljava/lang/String;[Ljava/lang/String;)Ljava/util/List;
      77: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;
      80: swap
      81: invokevirtual #35                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      84: ldc           #45                 // String barfoofoobarthefoobarman
      86: astore_1
      87: iconst_3
      88: anewarray     #15                 // class java/lang/String
      91: astore_3
      92: aload_3
      93: iconst_0
      94: ldc           #19                 // String bar
      96: aastore
      97: aload_3
      98: iconst_1
      99: ldc           #17                 // String foo
     101: aastore
     102: aload_3
     103: iconst_2
     104: ldc           #47                 // String the
     106: aastore
     107: aload_3
     108: astore_2
     109: aload_0
     110: aload_1
     111: aload_2
     112: invokevirtual #23                 // Method org/redquark/tutorials/leetcode/SubstringWithConcatenationOfAllWords.findSubstring:(Ljava/lang/String;[Ljava/lang/String;)Ljava/util/List;
     115: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;
     118: swap
     119: invokevirtual #35                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     122: ldc           #37                 // String wordgoodgoodgoodbestword
     124: astore_1
     125: iconst_4
     126: anewarray     #15                 // class java/lang/String
     129: astore_3
     130: aload_3
     131: iconst_0
     132: ldc           #39                 // String word
     134: aastore
     135: aload_3
     136: iconst_1
     137: ldc           #41                 // String good
     139: aastore
     140: aload_3
     141: iconst_2
     142: ldc           #43                 // String best
     144: aastore
     145: aload_3
     146: iconst_3
     147: ldc           #41                 // String good
     149: aastore
     150: aload_3
     151: astore_2
     152: aload_0
     153: aload_1
     154: aload_2
     155: invokevirtual #23                 // Method org/redquark/tutorials/leetcode/SubstringWithConcatenationOfAllWords.findSubstring:(Ljava/lang/String;[Ljava/lang/String;)Ljava/util/List;
     158: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;
     161: swap
     162: invokevirtual #35                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     165: return

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


package org.redquark.tutorials.leetcode

fun letterCombinations(digits: String): List<String> {
    // Resultant list
    val combinations: MutableList<String> = mutableListOf()
    // Base condition
    if (digits.isEmpty()) {
        return combinations
    }
    // Mappings of letters and numbers
    val lettersAndNumbersMappings = arrayOf(
            "Anirudh",
            "is awesome",
            "abc",
            "def",
            "ghi",
            "jkl",
            "mno",
            "pqrs",
            "tuv",
            "wxyz"
    )
    findCombinations(combinations, digits, StringBuilder(), 0, lettersAndNumbersMappings)
    return combinations
}

fun findCombinations(combinations: MutableList<String>, digits: String, previous: StringBuilder, index: Int, lettersAndNumbersMappings: Array<String>) {
    // Base condition for recursion to stop
    if (index == digits.length) {
        combinations.add(previous.toString())
        return
    }
    // Get the letters corresponding to the current index of digits string
    val letters = lettersAndNumbersMappings[digits[index] - '0']
    // Loop through all the characters in the current combination of letters
    for (c in letters.toCharArray()) {
        findCombinations(combinations, digits, previous.append(c), index + 1, lettersAndNumbersMappings)
        previous.deleteCharAt(previous.length - 1)
    }
}

fun main() {
    println(letterCombinations("23"))
    println(letterCombinations(""))
    println(letterCombinations("2"))
}

Compiled from "LetterCombinationsOfAPhoneNumber.kt"
public final class org.redquark.tutorials.leetcode.LetterCombinationsOfAPhoneNumberKt {
  public static final java.util.List<java.lang.String> letterCombinations(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String digits
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #18                 // class java/util/ArrayList
       9: dup
      10: invokespecial #22                 // Method java/util/ArrayList."<init>":()V
      13: checkcast     #24                 // class java/util/List
      16: astore_1
      17: aload_0
      18: checkcast     #26                 // class java/lang/CharSequence
      21: invokeinterface #30,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      26: ifne          33
      29: iconst_1
      30: goto          34
      33: iconst_0
      34: ifeq          39
      37: aload_1
      38: areturn
      39: bipush        10
      41: anewarray     #32                 // class java/lang/String
      44: astore_3
      45: aload_3
      46: iconst_0
      47: ldc           #34                 // String Anirudh
      49: aastore
      50: aload_3
      51: iconst_1
      52: ldc           #36                 // String is awesome
      54: aastore
      55: aload_3
      56: iconst_2
      57: ldc           #38                 // String abc
      59: aastore
      60: aload_3
      61: iconst_3
      62: ldc           #40                 // String def
      64: aastore
      65: aload_3
      66: iconst_4
      67: ldc           #42                 // String ghi
      69: aastore
      70: aload_3
      71: iconst_5
      72: ldc           #44                 // String jkl
      74: aastore
      75: aload_3
      76: bipush        6
      78: ldc           #46                 // String mno
      80: aastore
      81: aload_3
      82: bipush        7
      84: ldc           #48                 // String pqrs
      86: aastore
      87: aload_3
      88: bipush        8
      90: ldc           #50                 // String tuv
      92: aastore
      93: aload_3
      94: bipush        9
      96: ldc           #52                 // String wxyz
      98: aastore
      99: aload_3
     100: astore_2
     101: aload_1
     102: aload_0
     103: new           #54                 // class java/lang/StringBuilder
     106: dup
     107: invokespecial #55                 // Method java/lang/StringBuilder."<init>":()V
     110: iconst_0
     111: aload_2
     112: invokestatic  #59                 // Method findCombinations:(Ljava/util/List;Ljava/lang/String;Ljava/lang/StringBuilder;I[Ljava/lang/String;)V
     115: aload_1
     116: areturn

  public static final void findCombinations(java.util.List<java.lang.String>, java.lang.String, java.lang.StringBuilder, int, java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #66                 // String combinations
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #10                 // String digits
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: ldc           #68                 // String previous
      15: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      18: aload         4
      20: ldc           #69                 // String lettersAndNumbersMappings
      22: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      25: iload_3
      26: aload_1
      27: invokevirtual #70                 // Method java/lang/String.length:()I
      30: if_icmpne     51
      33: aload_0
      34: aload_2
      35: invokevirtual #74                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      38: dup
      39: ldc           #76                 // String toString(...)
      41: invokestatic  #79                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      44: invokeinterface #83,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      49: pop
      50: return
      51: aload         4
      53: aload_1
      54: iload_3
      55: invokevirtual #87                 // Method java/lang/String.charAt:(I)C
      58: bipush        48
      60: isub
      61: aaload
      62: astore        5
      64: aload         5
      66: invokevirtual #91                 // Method java/lang/String.toCharArray:()[C
      69: dup
      70: ldc           #93                 // String toCharArray(...)
      72: invokestatic  #79                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      75: astore        6
      77: iconst_0
      78: istore        7
      80: aload         6
      82: arraylength
      83: istore        8
      85: iload         7
      87: iload         8
      89: if_icmpge     138
      92: aload         6
      94: iload         7
      96: caload
      97: istore        9
      99: aload_0
     100: aload_1
     101: aload_2
     102: iload         9
     104: invokevirtual #97                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     107: dup
     108: ldc           #99                 // String append(...)
     110: invokestatic  #79                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     113: iload_3
     114: iconst_1
     115: iadd
     116: aload         4
     118: invokestatic  #59                 // Method findCombinations:(Ljava/util/List;Ljava/lang/String;Ljava/lang/StringBuilder;I[Ljava/lang/String;)V
     121: aload_2
     122: aload_2
     123: invokevirtual #100                // Method java/lang/StringBuilder.length:()I
     126: iconst_1
     127: isub
     128: invokevirtual #104                // Method java/lang/StringBuilder.deleteCharAt:(I)Ljava/lang/StringBuilder;
     131: pop
     132: iinc          7, 1
     135: goto          85
     138: return

  public static final void main();
    Code:
       0: ldc           #116                // String 23
       2: invokestatic  #118                // Method letterCombinations:(Ljava/lang/String;)Ljava/util/List;
       5: getstatic     #124                // Field java/lang/System.out:Ljava/io/PrintStream;
       8: swap
       9: invokevirtual #130                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      12: ldc           #132                // String
      14: invokestatic  #118                // Method letterCombinations:(Ljava/lang/String;)Ljava/util/List;
      17: getstatic     #124                // Field java/lang/System.out:Ljava/io/PrintStream;
      20: swap
      21: invokevirtual #130                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      24: ldc           #134                // String 2
      26: invokestatic  #118                // Method letterCombinations:(Ljava/lang/String;)Ljava/util/List;
      29: getstatic     #124                // Field java/lang/System.out:Ljava/io/PrintStream;
      32: swap
      33: invokevirtual #130                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      36: return

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


package org.redquark.tutorials.leetcode

class MergeKSortedLists {

    internal fun mergeKLists(lists: Array<ListNode?>): ListNode? {
        // Base condition
        return if (lists.isEmpty()) {
            null
        } else mergeKLists(lists, 0, lists.size - 1)
    }

    private fun mergeKLists(lists: Array<ListNode?>, start: Int, end: Int): ListNode? {
        if (start == end) {
            return lists[start]
        }
        // Mid of list of lists
        val mid = start + (end - start) / 2
        // Recursive call for left sublist
        val left = mergeKLists(lists, start, mid)
        // Recursive call for right sublist
        val right = mergeKLists(lists, mid + 1, end)
        // Merge the left and right sublist
        return merge(left, right)
    }

    private fun merge(left: ListNode?, right: ListNode?): ListNode? {
        // Create a dummy node
        var leftNode = left
        var rightNode = right
        val head = ListNode(-1)
        // Temp node
        var temp: ListNode? = head
        // Loop until any of the list becomes null
        while (leftNode != null && rightNode != null) {
            // Choose the value from the left and right which is smaller
            if (leftNode.`val` < rightNode.`val`) {
                temp!!.next = leftNode
                leftNode = leftNode.next
            } else {
                temp!!.next = rightNode
                rightNode = rightNode.next
            }
            temp = temp.next
        }
        // Take all nodes from left list if remaining
        while (leftNode != null) {
            temp!!.next = leftNode
            leftNode = leftNode.next
            temp = temp.next
        }
        // Take all nodes from right list if remaining
        while (rightNode != null) {
            temp!!.next = rightNode
            rightNode = rightNode.next
            temp = temp.next
        }
        return head.next
    }

    internal class ListNode(val `val`: Int) {
        var next: ListNode? = null
    }
}

fun main() {
    val m = MergeKSortedLists()
    val head1 = MergeKSortedLists.ListNode(1)
    head1.next = MergeKSortedLists.ListNode(4)
    head1.next!!.next = MergeKSortedLists.ListNode(5)
    val head2 = MergeKSortedLists.ListNode(1)
    head2.next = MergeKSortedLists.ListNode(3)
    head2.next!!.next = MergeKSortedLists.ListNode(4)
    val head3 = MergeKSortedLists.ListNode(2)
    head3.next = MergeKSortedLists.ListNode(6)
    var result = m.mergeKLists(arrayOf(head1, head2, head3))
    while (result != null) {
        print(result.`val`.toString() + " ")
        result = result.next
    }
}

Compiled from "MergeKSortedLists.kt"
public final class org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode {
  private final int val;

  private org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode next;

  public org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode(int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field val:I
       9: return

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

  public final org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode getNext();
    Code:
       0: aload_0
       1: getfield      #23                 // Field next:Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
       4: areturn

  public final void setNext(org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #23                 // Field next:Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
       5: return
}

Compiled from "MergeKSortedLists.kt"
public final class org.redquark.tutorials.leetcode.MergeKSortedLists {
  public org.redquark.tutorials.leetcode.MergeKSortedLists();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode mergeKLists$main(org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode[]);
    Code:
       0: aload_1
       1: ldc           #16                 // String lists
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: arraylength
       8: ifne          15
      11: iconst_1
      12: goto          16
      15: iconst_0
      16: ifeq          23
      19: aconst_null
      20: goto          33
      23: aload_0
      24: aload_1
      25: iconst_0
      26: aload_1
      27: arraylength
      28: iconst_1
      29: isub
      30: invokespecial #26                 // Method mergeKLists:([Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;II)Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      33: areturn

  private final org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode mergeKLists(org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode[], int, int);
    Code:
       0: iload_2
       1: iload_3
       2: if_icmpne     9
       5: aload_1
       6: iload_2
       7: aaload
       8: areturn
       9: iload_2
      10: iload_3
      11: iload_2
      12: isub
      13: iconst_2
      14: idiv
      15: iadd
      16: istore        4
      18: aload_0
      19: aload_1
      20: iload_2
      21: iload         4
      23: invokespecial #26                 // Method mergeKLists:([Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;II)Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      26: astore        5
      28: aload_0
      29: aload_1
      30: iload         4
      32: iconst_1
      33: iadd
      34: iload_3
      35: invokespecial #26                 // Method mergeKLists:([Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;II)Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      38: astore        6
      40: aload_0
      41: aload         5
      43: aload         6
      45: invokespecial #33                 // Method merge:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      48: areturn

  private final org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode merge(org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode, org.redquark.tutorials.leetcode.MergeKSortedLists$ListNode);
    Code:
       0: aload_1
       1: astore_3
       2: aload_2
       3: astore        4
       5: new           #29                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
       8: dup
       9: iconst_m1
      10: invokespecial #43                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      13: astore        5
      15: aload         5
      17: astore        6
      19: aload_3
      20: ifnull        86
      23: aload         4
      25: ifnull        86
      28: aload_3
      29: invokevirtual #47                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getVal:()I
      32: aload         4
      34: invokevirtual #47                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getVal:()I
      37: if_icmpge     58
      40: aload         6
      42: dup
      43: invokestatic  #51                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      46: aload_3
      47: invokevirtual #55                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
      50: aload_3
      51: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      54: astore_3
      55: goto          76
      58: aload         6
      60: dup
      61: invokestatic  #51                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      64: aload         4
      66: invokevirtual #55                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
      69: aload         4
      71: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      74: astore        4
      76: aload         6
      78: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      81: astore        6
      83: goto          19
      86: aload_3
      87: ifnull        115
      90: aload         6
      92: dup
      93: invokestatic  #51                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      96: aload_3
      97: invokevirtual #55                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
     100: aload_3
     101: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
     104: astore_3
     105: aload         6
     107: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
     110: astore        6
     112: goto          86
     115: aload         4
     117: ifnull        148
     120: aload         6
     122: dup
     123: invokestatic  #51                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     126: aload         4
     128: invokevirtual #55                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
     131: aload         4
     133: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
     136: astore        4
     138: aload         6
     140: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
     143: astore        6
     145: goto          115
     148: aload         5
     150: invokevirtual #59                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
     153: areturn
}

Compiled from "MergeKSortedLists.kt"
public final class org.redquark.tutorials.leetcode.MergeKSortedListsKt {
  public static final void main();
    Code:
       0: new           #8                  // class org/redquark/tutorials/leetcode/MergeKSortedLists
       3: dup
       4: invokespecial #11                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists."<init>":()V
       7: astore_0
       8: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
      11: dup
      12: iconst_1
      13: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      16: astore_1
      17: aload_1
      18: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
      21: dup
      22: iconst_4
      23: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      26: invokevirtual #20                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
      29: aload_1
      30: invokevirtual #24                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      33: dup
      34: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      37: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
      40: dup
      41: iconst_5
      42: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      45: invokevirtual #20                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
      48: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
      51: dup
      52: iconst_1
      53: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      56: astore_2
      57: aload_2
      58: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
      61: dup
      62: iconst_3
      63: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      66: invokevirtual #20                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
      69: aload_2
      70: invokevirtual #24                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
      73: dup
      74: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      77: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
      80: dup
      81: iconst_4
      82: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      85: invokevirtual #20                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
      88: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
      91: dup
      92: iconst_2
      93: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
      96: astore_3
      97: aload_3
      98: new           #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
     101: dup
     102: bipush        6
     104: invokespecial #16                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode."<init>":(I)V
     107: invokevirtual #20                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.setNext:(Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)V
     110: aload_0
     111: iconst_3
     112: anewarray     #13                 // class org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode
     115: astore        5
     117: aload         5
     119: iconst_0
     120: aload_1
     121: aastore
     122: aload         5
     124: iconst_1
     125: aload_2
     126: aastore
     127: aload         5
     129: iconst_2
     130: aload_3
     131: aastore
     132: aload         5
     134: invokevirtual #34                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists.mergeKLists$main:([Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;)Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
     137: astore        4
     139: aload         4
     141: ifnull        184
     144: new           #36                 // class java/lang/StringBuilder
     147: dup
     148: invokespecial #37                 // Method java/lang/StringBuilder."<init>":()V
     151: aload         4
     153: invokevirtual #41                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getVal:()I
     156: invokevirtual #45                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     159: bipush        32
     161: invokevirtual #48                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     164: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     167: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
     170: swap
     171: invokevirtual #63                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     174: aload         4
     176: invokevirtual #24                 // Method org/redquark/tutorials/leetcode/MergeKSortedLists$ListNode.getNext:()Lorg/redquark/tutorials/leetcode/MergeKSortedLists$ListNode;
     179: astore        4
     181: goto          139
     184: return

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


package org.redquark.tutorials.leetcode

import java.util.*
import kotlin.collections.ArrayList

fun fourSum(nums: IntArray, target: Int): List<List<Int>> {
    // Resultant list
    val quadruplets: MutableList<List<Int>> = ArrayList()
    // Base condition
    if (nums.size < 4) {
        return quadruplets
    }
    // Sort the array
    Arrays.sort(nums)
    // Length of the array
    val n = nums.size
    // Loop for each element in the array
    for (i in 0 until n - 3) {
        // Check for skipping duplicates
        if (i > 0 && nums[i] == nums[i - 1]) {
            continue
        }
        // Reducing problem to 3Sum problem
        for (j in i + 1 until n - 2) {
            // Check for skipping duplicates
            if (j != i + 1 && nums[j] == nums[j - 1]) {
                continue
            }
            // Left and right pointers
            var k = j + 1
            var l = n - 1
            // Reducing to two sum problem
            while (k < l) {
                val currentSum = nums[i] + nums[j] + nums[k] + nums[l]
                when {
                    currentSum < target -> {
                        k++
                    }
                    currentSum > target -> {
                        l--
                    }
                    else -> {
                        quadruplets.add(listOf(nums[i], nums[j], nums[k], nums[l]))
                        k++
                        l--
                        // Check for skipping duplicates
                        while (k < l && nums[k] == nums[k - 1]) {
                            k++
                        }
                        while (k < l && nums[l] == nums[l + 1]) {
                            l--
                        }
                    }
                }
            }
        }
    }
    return quadruplets
}

fun main() {
    println(fourSum(intArrayOf(1, 0, -1, 0, -2, 2), 0))
    println(fourSum(intArrayOf(), 0))
    println(fourSum(intArrayOf(1, 2, 3, 4), 10))
    println(fourSum(intArrayOf(0, 0, 0, 0), 0))
}

Compiled from "FourSum.kt"
public final class org.redquark.tutorials.leetcode.FourSumKt {
  public static final java.util.List<java.util.List<java.lang.Integer>> fourSum(int[], int);
    Code:
       0: aload_0
       1: ldc           #10                 // String nums
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #18                 // class java/util/ArrayList
       9: dup
      10: invokespecial #22                 // Method java/util/ArrayList."<init>":()V
      13: checkcast     #24                 // class java/util/List
      16: astore_2
      17: aload_0
      18: arraylength
      19: iconst_4
      20: if_icmpge     25
      23: aload_2
      24: areturn
      25: aload_0
      26: invokestatic  #30                 // Method java/util/Arrays.sort:([I)V
      29: aload_0
      30: arraylength
      31: istore_3
      32: iconst_0
      33: istore        4
      35: iload_3
      36: iconst_3
      37: isub
      38: istore        5
      40: iload         4
      42: iload         5
      44: if_icmpge     313
      47: iload         4
      49: ifle          68
      52: aload_0
      53: iload         4
      55: iaload
      56: aload_0
      57: iload         4
      59: iconst_1
      60: isub
      61: iaload
      62: if_icmpne     68
      65: goto          307
      68: iload         4
      70: iconst_1
      71: iadd
      72: istore        6
      74: iload_3
      75: iconst_2
      76: isub
      77: istore        7
      79: iload         6
      81: iload         7
      83: if_icmpge     307
      86: iload         6
      88: iload         4
      90: iconst_1
      91: iadd
      92: if_icmpeq     111
      95: aload_0
      96: iload         6
      98: iaload
      99: aload_0
     100: iload         6
     102: iconst_1
     103: isub
     104: iaload
     105: if_icmpne     111
     108: goto          301
     111: iload         6
     113: iconst_1
     114: iadd
     115: istore        8
     117: iload_3
     118: iconst_1
     119: isub
     120: istore        9
     122: iload         8
     124: iload         9
     126: if_icmpge     301
     129: aload_0
     130: iload         4
     132: iaload
     133: aload_0
     134: iload         6
     136: iaload
     137: iadd
     138: aload_0
     139: iload         8
     141: iaload
     142: iadd
     143: aload_0
     144: iload         9
     146: iaload
     147: iadd
     148: istore        10
     150: nop
     151: iload         10
     153: iload_1
     154: if_icmpge     166
     157: iload         8
     159: iinc          8, 1
     162: pop
     163: goto          122
     166: iload         10
     168: iload_1
     169: if_icmple     181
     172: iload         9
     174: iinc          9, -1
     177: pop
     178: goto          122
     181: aload_2
     182: iconst_4
     183: anewarray     #32                 // class java/lang/Integer
     186: astore        11
     188: aload         11
     190: iconst_0
     191: aload_0
     192: iload         4
     194: iaload
     195: invokestatic  #36                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     198: aastore
     199: aload         11
     201: iconst_1
     202: aload_0
     203: iload         6
     205: iaload
     206: invokestatic  #36                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     209: aastore
     210: aload         11
     212: iconst_2
     213: aload_0
     214: iload         8
     216: iaload
     217: invokestatic  #36                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     220: aastore
     221: aload         11
     223: iconst_3
     224: aload_0
     225: iload         9
     227: iaload
     228: invokestatic  #36                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     231: aastore
     232: aload         11
     234: invokestatic  #42                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     237: invokeinterface #46,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     242: pop
     243: iinc          8, 1
     246: iinc          9, -1
     249: iload         8
     251: iload         9
     253: if_icmpge     275
     256: aload_0
     257: iload         8
     259: iaload
     260: aload_0
     261: iload         8
     263: iconst_1
     264: isub
     265: iaload
     266: if_icmpne     275
     269: iinc          8, 1
     272: goto          249
     275: iload         8
     277: iload         9
     279: if_icmpge     122
     282: aload_0
     283: iload         9
     285: iaload
     286: aload_0
     287: iload         9
     289: iconst_1
     290: iadd
     291: iaload
     292: if_icmpne     122
     295: iinc          9, -1
     298: goto          275
     301: iinc          6, 1
     304: goto          79
     307: iinc          4, 1
     310: goto          40
     313: aload_2
     314: areturn

  public static final void main();
    Code:
       0: bipush        6
       2: newarray       int
       4: astore_0
       5: aload_0
       6: iconst_0
       7: iconst_1
       8: iastore
       9: aload_0
      10: iconst_1
      11: iconst_0
      12: iastore
      13: aload_0
      14: iconst_2
      15: iconst_m1
      16: iastore
      17: aload_0
      18: iconst_3
      19: iconst_0
      20: iastore
      21: aload_0
      22: iconst_4
      23: bipush        -2
      25: iastore
      26: aload_0
      27: iconst_5
      28: iconst_2
      29: iastore
      30: aload_0
      31: iconst_0
      32: invokestatic  #63                 // Method fourSum:([II)Ljava/util/List;
      35: getstatic     #69                 // Field java/lang/System.out:Ljava/io/PrintStream;
      38: swap
      39: invokevirtual #75                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      42: iconst_0
      43: newarray       int
      45: iconst_0
      46: invokestatic  #63                 // Method fourSum:([II)Ljava/util/List;
      49: getstatic     #69                 // Field java/lang/System.out:Ljava/io/PrintStream;
      52: swap
      53: invokevirtual #75                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      56: iconst_4
      57: newarray       int
      59: astore_0
      60: aload_0
      61: iconst_0
      62: iconst_1
      63: iastore
      64: aload_0
      65: iconst_1
      66: iconst_2
      67: iastore
      68: aload_0
      69: iconst_2
      70: iconst_3
      71: iastore
      72: aload_0
      73: iconst_3
      74: iconst_4
      75: iastore
      76: aload_0
      77: bipush        10
      79: invokestatic  #63                 // Method fourSum:([II)Ljava/util/List;
      82: getstatic     #69                 // Field java/lang/System.out:Ljava/io/PrintStream;
      85: swap
      86: invokevirtual #75                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      89: iconst_4
      90: newarray       int
      92: astore_0
      93: aload_0
      94: iconst_0
      95: iconst_0
      96: iastore
      97: aload_0
      98: iconst_1
      99: iconst_0
     100: iastore
     101: aload_0
     102: iconst_2
     103: iconst_0
     104: iastore
     105: aload_0
     106: iconst_3
     107: iconst_0
     108: iastore
     109: aload_0
     110: iconst_0
     111: invokestatic  #63                 // Method fourSum:([II)Ljava/util/List;
     114: getstatic     #69                 // Field java/lang/System.out:Ljava/io/PrintStream;
     117: swap
     118: invokevirtual #75                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     121: return

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


package org.redquark.tutorials.leetcode

fun findMedianSortedArrays(nums1: IntArray, nums2: IntArray): Double {
    // Check if num1 is smaller than num2
    // If not, then we will swap num1 with num2
    if (nums1.size > nums2.size) {
        return findMedianSortedArrays(nums2, nums1)
    }
    // Lengths of two arrays
    val m = nums1.size
    val n = nums2.size
    // Pointers for binary search
    var start = 0
    var end = m
    // Binary search starts from here
    while (start <= end) {
        // Partitions of both the array
        val partitionNums1 = (start + end) / 2
        val partitionNums2 = (m + n + 1) / 2 - partitionNums1
        // Edge cases
        // If there are no elements left on the left side after partition
        val maxLeftNums1 = if (partitionNums1 == 0) Int.MIN_VALUE else nums1[partitionNums1 - 1]
        // If there are no elements left on the right side after partition
        val minRightNums1 = if (partitionNums1 == m) Int.MAX_VALUE else nums1[partitionNums1]
        // Similarly for nums2
        val maxLeftNums2 = if (partitionNums2 == 0) Int.MIN_VALUE else nums2[partitionNums2 - 1]
        val minRightNums2 = if (partitionNums2 == n) Int.MAX_VALUE else nums2[partitionNums2]
        // Check if we have found the match
        if (maxLeftNums1 <= minRightNums2 && maxLeftNums2 <= minRightNums1) {
            // Check if the combined array is of even/odd length
            return if ((m + n) % 2 == 0) {
                (maxLeftNums1.coerceAtLeast(maxLeftNums2) + minRightNums1.coerceAtMost(minRightNums2)) / 2.0
            } else {
                maxLeftNums1.coerceAtLeast(maxLeftNums2).toDouble()
            }
        } else if (maxLeftNums1 > minRightNums2) {
            end = partitionNums1 - 1
        } else {
            start = partitionNums1 + 1
        }
    }
    throw IllegalArgumentException()
}

fun main() {
    var nums1 = intArrayOf(1, 3)
    var nums2 = intArrayOf(2)
    println(findMedianSortedArrays(nums1, nums2))
    nums1 = intArrayOf(1, 2)
    nums2 = intArrayOf(3, 4)
    println(findMedianSortedArrays(nums1, nums2))
    nums1 = intArrayOf(0, 0)
    nums2 = intArrayOf(0, 0)
    println(findMedianSortedArrays(nums1, nums2))
    nums1 = intArrayOf()
    nums2 = intArrayOf(1)
    println(findMedianSortedArrays(nums1, nums2))
    nums1 = intArrayOf(2)
    nums2 = intArrayOf()
    println(findMedianSortedArrays(nums1, nums2))
}

Compiled from "MedianOfTwoSortedArrays.kt"
public final class org.redquark.tutorials.leetcode.MedianOfTwoSortedArraysKt {
  public static final double findMedianSortedArrays(int[], int[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String nums1
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #17                 // String nums2
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: arraylength
      14: aload_1
      15: arraylength
      16: if_icmple     25
      19: aload_1
      20: aload_0
      21: invokestatic  #19                 // Method findMedianSortedArrays:([I[I)D
      24: dreturn
      25: aload_0
      26: arraylength
      27: istore_2
      28: aload_1
      29: arraylength
      30: istore_3
      31: iconst_0
      32: istore        4
      34: iload_2
      35: istore        5
      37: iload         4
      39: iload         5
      41: if_icmpgt     214
      44: iload         4
      46: iload         5
      48: iadd
      49: iconst_2
      50: idiv
      51: istore        6
      53: iload_2
      54: iload_3
      55: iadd
      56: iconst_1
      57: iadd
      58: iconst_2
      59: idiv
      60: iload         6
      62: isub
      63: istore        7
      65: iload         6
      67: ifne          75
      70: ldc           #20                 // int -2147483648
      72: goto          81
      75: aload_0
      76: iload         6
      78: iconst_1
      79: isub
      80: iaload
      81: istore        8
      83: iload         6
      85: iload_2
      86: if_icmpne     94
      89: ldc           #21                 // int 2147483647
      91: goto          98
      94: aload_0
      95: iload         6
      97: iaload
      98: istore        9
     100: iload         7
     102: ifne          110
     105: ldc           #20                 // int -2147483648
     107: goto          116
     110: aload_1
     111: iload         7
     113: iconst_1
     114: isub
     115: iaload
     116: istore        10
     118: iload         7
     120: iload_3
     121: if_icmpne     129
     124: ldc           #21                 // int 2147483647
     126: goto          133
     129: aload_1
     130: iload         7
     132: iaload
     133: istore        11
     135: iload         8
     137: iload         11
     139: if_icmpgt     189
     142: iload         10
     144: iload         9
     146: if_icmpgt     189
     149: iload_2
     150: iload_3
     151: iadd
     152: iconst_2
     153: irem
     154: ifne          180
     157: iload         8
     159: iload         10
     161: invokestatic  #27                 // Method kotlin/ranges/RangesKt.coerceAtLeast:(II)I
     164: iload         9
     166: iload         11
     168: invokestatic  #30                 // Method kotlin/ranges/RangesKt.coerceAtMost:(II)I
     171: iadd
     172: i2d
     173: ldc2_w        #31                 // double 2.0d
     176: ddiv
     177: goto          188
     180: iload         8
     182: iload         10
     184: invokestatic  #27                 // Method kotlin/ranges/RangesKt.coerceAtLeast:(II)I
     187: i2d
     188: dreturn
     189: iload         8
     191: iload         11
     193: if_icmple     205
     196: iload         6
     198: iconst_1
     199: isub
     200: istore        5
     202: goto          37
     205: iload         6
     207: iconst_1
     208: iadd
     209: istore        4
     211: goto          37
     214: new           #34                 // class java/lang/IllegalArgumentException
     217: dup
     218: invokespecial #38                 // Method java/lang/IllegalArgumentException."<init>":()V
     221: athrow

  public static final void main();
    Code:
       0: iconst_2
       1: newarray       int
       3: astore_1
       4: aload_1
       5: iconst_0
       6: iconst_1
       7: iastore
       8: aload_1
       9: iconst_1
      10: iconst_3
      11: iastore
      12: aload_1
      13: astore_0
      14: iconst_1
      15: newarray       int
      17: astore_2
      18: aload_2
      19: iconst_0
      20: iconst_2
      21: iastore
      22: aload_2
      23: astore_1
      24: aload_0
      25: aload_1
      26: invokestatic  #19                 // Method findMedianSortedArrays:([I[I)D
      29: dstore_2
      30: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
      33: dload_2
      34: invokevirtual #64                 // Method java/io/PrintStream.println:(D)V
      37: iconst_2
      38: newarray       int
      40: astore_2
      41: aload_2
      42: iconst_0
      43: iconst_1
      44: iastore
      45: aload_2
      46: iconst_1
      47: iconst_2
      48: iastore
      49: aload_2
      50: astore_0
      51: iconst_2
      52: newarray       int
      54: astore_2
      55: aload_2
      56: iconst_0
      57: iconst_3
      58: iastore
      59: aload_2
      60: iconst_1
      61: iconst_4
      62: iastore
      63: aload_2
      64: astore_1
      65: aload_0
      66: aload_1
      67: invokestatic  #19                 // Method findMedianSortedArrays:([I[I)D
      70: dstore_2
      71: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
      74: dload_2
      75: invokevirtual #64                 // Method java/io/PrintStream.println:(D)V
      78: iconst_2
      79: newarray       int
      81: astore_2
      82: aload_2
      83: iconst_0
      84: iconst_0
      85: iastore
      86: aload_2
      87: iconst_1
      88: iconst_0
      89: iastore
      90: aload_2
      91: astore_0
      92: iconst_2
      93: newarray       int
      95: astore_2
      96: aload_2
      97: iconst_0
      98: iconst_0
      99: iastore
     100: aload_2
     101: iconst_1
     102: iconst_0
     103: iastore
     104: aload_2
     105: astore_1
     106: aload_0
     107: aload_1
     108: invokestatic  #19                 // Method findMedianSortedArrays:([I[I)D
     111: dstore_2
     112: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
     115: dload_2
     116: invokevirtual #64                 // Method java/io/PrintStream.println:(D)V
     119: iconst_0
     120: newarray       int
     122: astore_0
     123: iconst_1
     124: newarray       int
     126: astore_2
     127: aload_2
     128: iconst_0
     129: iconst_1
     130: iastore
     131: aload_2
     132: astore_1
     133: aload_0
     134: aload_1
     135: invokestatic  #19                 // Method findMedianSortedArrays:([I[I)D
     138: dstore_2
     139: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
     142: dload_2
     143: invokevirtual #64                 // Method java/io/PrintStream.println:(D)V
     146: iconst_1
     147: newarray       int
     149: astore_2
     150: aload_2
     151: iconst_0
     152: iconst_2
     153: iastore
     154: aload_2
     155: astore_0
     156: iconst_0
     157: newarray       int
     159: astore_1
     160: aload_0
     161: aload_1
     162: invokestatic  #19                 // Method findMedianSortedArrays:([I[I)D
     165: dstore_2
     166: getstatic     #58                 // Field java/lang/System.out:Ljava/io/PrintStream;
     169: dload_2
     170: invokevirtual #64                 // Method java/io/PrintStream.println:(D)V
     173: return

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


package org.redquark.tutorials.leetcode

fun isMatch(s: String, p: String): Boolean {
    val rows = s.length
    val columns = p.length
    /// Base conditions
    if (rows == 0 && columns == 0) {
        return true
    }
    if (columns == 0) {
        return false
    }
    // DP array
    val dp = Array(rows + 1) { BooleanArray(columns + 1) }
    // Empty string and empty pattern are a match
    dp[0][0] = true
    // Deals with patterns with *
    for (i in 2 until columns + 1) {
        if (p[i - 1] == '*') {
            dp[0][i] = dp[0][i - 2]
        }
    }
    // For remaining characters
    for (i in 1 until rows + 1) {
        for (j in 1 until columns + 1) {
            if (s[i - 1] == p[j - 1] || p[j - 1] == '.') {
                dp[i][j] = dp[i - 1][j - 1]
            } else if (j > 1 && p[j - 1] == '*') {
                dp[i][j] = dp[i][j - 2]
                if (p[j - 2] == '.' || p[j - 2] == s[i - 1]) {
                    dp[i][j] = dp[i][j] or dp[i - 1][j]
                }
            }
        }
    }
    return dp[rows][columns]
}

fun main() {
    println(isMatch("aa", "a"))
    println(isMatch("aa", "a*"))
    println(isMatch("ab", "."))
    println(isMatch("aab", "c*a*b"))
    println(isMatch("mississippi", "mis*is*p*."))
    println(isMatch("", ".*"))
}

Compiled from "RegularExpressionMatching.kt"
public final class org.redquark.tutorials.leetcode.RegularExpressionMatchingKt {
  public static final boolean isMatch(java.lang.String, java.lang.String);
    Code:
       0: aload_0
       1: ldc           #9                  // String s
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #17                 // String p
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokevirtual #23                 // Method java/lang/String.length:()I
      16: istore_2
      17: aload_1
      18: invokevirtual #23                 // Method java/lang/String.length:()I
      21: istore_3
      22: iload_2
      23: ifne          32
      26: iload_3
      27: ifne          32
      30: iconst_1
      31: ireturn
      32: iload_3
      33: ifne          38
      36: iconst_0
      37: ireturn
      38: iconst_0
      39: istore        5
      41: iload_2
      42: iconst_1
      43: iadd
      44: istore        6
      46: iload         6
      48: anewarray     #25                 // class "[Z"
      51: astore        7
      53: iload         5
      55: iload         6
      57: if_icmpge     80
      60: iload         5
      62: istore        8
      64: aload         7
      66: iload         8
      68: iload_3
      69: iconst_1
      70: iadd
      71: newarray       boolean
      73: aastore
      74: iinc          5, 1
      77: goto          53
      80: aload         7
      82: astore        4
      84: aload         4
      86: iconst_0
      87: aaload
      88: iconst_0
      89: iconst_1
      90: bastore
      91: iconst_2
      92: istore        5
      94: iload_3
      95: iconst_1
      96: iadd
      97: istore        6
      99: iload         5
     101: iload         6
     103: if_icmpge     141
     106: aload_1
     107: iload         5
     109: iconst_1
     110: isub
     111: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     114: bipush        42
     116: if_icmpne     135
     119: aload         4
     121: iconst_0
     122: aaload
     123: iload         5
     125: aload         4
     127: iconst_0
     128: aaload
     129: iload         5
     131: iconst_2
     132: isub
     133: baload
     134: bastore
     135: iinc          5, 1
     138: goto          99
     141: iconst_1
     142: istore        5
     144: iload_2
     145: iconst_1
     146: iadd
     147: istore        6
     149: iload         5
     151: iload         6
     153: if_icmpge     334
     156: iconst_1
     157: istore        7
     159: iload_3
     160: iconst_1
     161: iadd
     162: istore        8
     164: iload         7
     166: iload         8
     168: if_icmpge     328
     171: aload_0
     172: iload         5
     174: iconst_1
     175: isub
     176: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     179: aload_1
     180: iload         7
     182: iconst_1
     183: isub
     184: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     187: if_icmpeq     203
     190: aload_1
     191: iload         7
     193: iconst_1
     194: isub
     195: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     198: bipush        46
     200: if_icmpne     226
     203: aload         4
     205: iload         5
     207: aaload
     208: iload         7
     210: aload         4
     212: iload         5
     214: iconst_1
     215: isub
     216: aaload
     217: iload         7
     219: iconst_1
     220: isub
     221: baload
     222: bastore
     223: goto          322
     226: iload         7
     228: iconst_1
     229: if_icmple     322
     232: aload_1
     233: iload         7
     235: iconst_1
     236: isub
     237: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     240: bipush        42
     242: if_icmpne     322
     245: aload         4
     247: iload         5
     249: aaload
     250: iload         7
     252: aload         4
     254: iload         5
     256: aaload
     257: iload         7
     259: iconst_2
     260: isub
     261: baload
     262: bastore
     263: aload_1
     264: iload         7
     266: iconst_2
     267: isub
     268: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     271: bipush        46
     273: if_icmpeq     295
     276: aload_1
     277: iload         7
     279: iconst_2
     280: isub
     281: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     284: aload_0
     285: iload         5
     287: iconst_1
     288: isub
     289: invokevirtual #29                 // Method java/lang/String.charAt:(I)C
     292: if_icmpne     322
     295: aload         4
     297: iload         5
     299: aaload
     300: iload         7
     302: aload         4
     304: iload         5
     306: aaload
     307: iload         7
     309: baload
     310: aload         4
     312: iload         5
     314: iconst_1
     315: isub
     316: aaload
     317: iload         7
     319: baload
     320: ior
     321: bastore
     322: iinc          7, 1
     325: goto          164
     328: iinc          5, 1
     331: goto          149
     334: aload         4
     336: iload_2
     337: aaload
     338: iload_3
     339: baload
     340: ireturn

  public static final void main();
    Code:
       0: ldc           #42                 // String aa
       2: ldc           #44                 // String a
       4: invokestatic  #46                 // Method isMatch:(Ljava/lang/String;Ljava/lang/String;)Z
       7: istore_0
       8: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: iload_0
      12: invokevirtual #58                 // Method java/io/PrintStream.println:(Z)V
      15: ldc           #42                 // String aa
      17: ldc           #60                 // String a*
      19: invokestatic  #46                 // Method isMatch:(Ljava/lang/String;Ljava/lang/String;)Z
      22: istore_0
      23: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: iload_0
      27: invokevirtual #58                 // Method java/io/PrintStream.println:(Z)V
      30: ldc           #62                 // String ab
      32: ldc           #64                 // String .
      34: invokestatic  #46                 // Method isMatch:(Ljava/lang/String;Ljava/lang/String;)Z
      37: istore_0
      38: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
      41: iload_0
      42: invokevirtual #58                 // Method java/io/PrintStream.println:(Z)V
      45: ldc           #66                 // String aab
      47: ldc           #68                 // String c*a*b
      49: invokestatic  #46                 // Method isMatch:(Ljava/lang/String;Ljava/lang/String;)Z
      52: istore_0
      53: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
      56: iload_0
      57: invokevirtual #58                 // Method java/io/PrintStream.println:(Z)V
      60: ldc           #70                 // String mississippi
      62: ldc           #72                 // String mis*is*p*.
      64: invokestatic  #46                 // Method isMatch:(Ljava/lang/String;Ljava/lang/String;)Z
      67: istore_0
      68: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
      71: iload_0
      72: invokevirtual #58                 // Method java/io/PrintStream.println:(Z)V
      75: ldc           #74                 // String
      77: ldc           #76                 // String .*
      79: invokestatic  #46                 // Method isMatch:(Ljava/lang/String;Ljava/lang/String;)Z
      82: istore_0
      83: getstatic     #52                 // Field java/lang/System.out:Ljava/io/PrintStream;
      86: iload_0
      87: invokevirtual #58                 // Method java/io/PrintStream.println:(Z)V
      90: return

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


package org.redquark.tutorials.leetcode

fun longestPalindrome(s: String): String {
    // Update the string to put hash "#" at the beginning, end and in between each character
    val updatedString = getUpdatedString(s)
    // Length of the array that will store the window of palindromic substring
    val length = 2 * s.length + 1
    // Array to store the length of each palindrome centered at each element
    val p = IntArray(length)
    // Current center of the longest palindromic string
    var c = 0
    // Right boundary of the longest palindromic string
    var r = 0
    // Maximum length of the substring
    var maxLength = 0
    // Position index
    var position = -1
    for (i in 0 until length) {
        // Mirror of the current index
        val mirror = 2 * c - i
        // Check if the mirror is outside the left boundary of current longest palindrome
        if (i < r) {
            p[i] = (r - i).coerceAtMost(p[mirror])
        }
        // Indices of the characters to be compared
        var a = i + (1 + p[i])
        var b = i - (1 + p[i])
        // Expand the window
        while (a < length && b >= 0 && updatedString[a] == updatedString[b]) {
            p[i]++
            a++
            b--
        }
        // If the expanded palindrome is expanding beyond the right boundary of
        // the current longest palindrome, then update c and r
        if (i + p[i] > r) {
            c = i
            r = i + p[i]
        }
        if (maxLength < p[i]) {
            maxLength = p[i]
            position = i
        }
    }
    val offset = p[position]
    val result = StringBuilder()
    for (i in position - offset + 1 until position + offset) {
        if (updatedString[i] != '#') {
            result.append(updatedString[i])
        }
    }
    return result.toString()
}

fun getUpdatedString(s: String): String {
    val sb = StringBuilder()
    for (element in s) {
        sb.append("#").append(element)
    }
    sb.append("#")
    return sb.toString()
}

fun main() {
    println(longestPalindrome("babad"))
    println(longestPalindrome("cbbd"))
    println(longestPalindrome("a"))
    println(longestPalindrome("ac"))
    println(longestPalindrome("abb"))
}

Compiled from "LongestPalindromeSubstring.kt"
public final class org.redquark.tutorials.leetcode.LongestPalindromeSubstringKt {
  public static final java.lang.String longestPalindrome(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #9                  // String s
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #18                 // Method getUpdatedString:(Ljava/lang/String;)Ljava/lang/String;
      10: astore_1
      11: iconst_2
      12: aload_0
      13: invokevirtual #24                 // Method java/lang/String.length:()I
      16: imul
      17: iconst_1
      18: iadd
      19: istore_2
      20: iload_2
      21: newarray       int
      23: astore_3
      24: iconst_0
      25: istore        4
      27: iconst_0
      28: istore        5
      30: iconst_0
      31: istore        6
      33: iconst_m1
      34: istore        7
      36: iconst_0
      37: istore        8
      39: iload         8
      41: iload_2
      42: if_icmpge     202
      45: iconst_2
      46: iload         4
      48: imul
      49: iload         8
      51: isub
      52: istore        9
      54: iload         8
      56: iload         5
      58: if_icmpge     77
      61: aload_3
      62: iload         8
      64: iload         5
      66: iload         8
      68: isub
      69: aload_3
      70: iload         9
      72: iaload
      73: invokestatic  #30                 // Method kotlin/ranges/RangesKt.coerceAtMost:(II)I
      76: iastore
      77: iload         8
      79: iconst_1
      80: aload_3
      81: iload         8
      83: iaload
      84: iadd
      85: iadd
      86: istore        10
      88: iload         8
      90: iconst_1
      91: aload_3
      92: iload         8
      94: iaload
      95: iadd
      96: isub
      97: istore        11
      99: iload         10
     101: iload_2
     102: if_icmpge     152
     105: iload         11
     107: iflt          152
     110: aload_1
     111: iload         10
     113: invokevirtual #34                 // Method java/lang/String.charAt:(I)C
     116: aload_1
     117: iload         11
     119: invokevirtual #34                 // Method java/lang/String.charAt:(I)C
     122: if_icmpne     152
     125: iload         8
     127: istore        12
     129: aload_3
     130: iload         12
     132: iaload
     133: istore        13
     135: aload_3
     136: iload         12
     138: iload         13
     140: iconst_1
     141: iadd
     142: iastore
     143: iinc          10, 1
     146: iinc          11, -1
     149: goto          99
     152: iload         8
     154: aload_3
     155: iload         8
     157: iaload
     158: iadd
     159: iload         5
     161: if_icmple     177
     164: iload         8
     166: istore        4
     168: iload         8
     170: aload_3
     171: iload         8
     173: iaload
     174: iadd
     175: istore        5
     177: iload         6
     179: aload_3
     180: iload         8
     182: iaload
     183: if_icmpge     196
     186: aload_3
     187: iload         8
     189: iaload
     190: istore        6
     192: iload         8
     194: istore        7
     196: iinc          8, 1
     199: goto          39
     202: aload_3
     203: iload         7
     205: iaload
     206: istore        8
     208: new           #36                 // class java/lang/StringBuilder
     211: dup
     212: invokespecial #40                 // Method java/lang/StringBuilder."<init>":()V
     215: astore        9
     217: iload         7
     219: iload         8
     221: isub
     222: iconst_1
     223: iadd
     224: istore        10
     226: iload         7
     228: iload         8
     230: iadd
     231: istore        11
     233: iload         10
     235: iload         11
     237: if_icmpge     269
     240: aload_1
     241: iload         10
     243: invokevirtual #34                 // Method java/lang/String.charAt:(I)C
     246: bipush        35
     248: if_icmpeq     263
     251: aload         9
     253: aload_1
     254: iload         10
     256: invokevirtual #34                 // Method java/lang/String.charAt:(I)C
     259: invokevirtual #44                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     262: pop
     263: iinc          10, 1
     266: goto          233
     269: aload         9
     271: invokevirtual #48                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     274: dup
     275: ldc           #50                 // String toString(...)
     277: invokestatic  #53                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     280: areturn

  public static final java.lang.String getUpdatedString(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #9                  // String s
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #36                 // class java/lang/StringBuilder
       9: dup
      10: invokespecial #40                 // Method java/lang/StringBuilder."<init>":()V
      13: astore_1
      14: iconst_0
      15: istore_2
      16: aload_0
      17: invokevirtual #24                 // Method java/lang/String.length:()I
      20: istore_3
      21: iload_2
      22: iload_3
      23: if_icmpge     51
      26: aload_0
      27: iload_2
      28: invokevirtual #34                 // Method java/lang/String.charAt:(I)C
      31: istore        4
      33: aload_1
      34: ldc           #72                 // String #
      36: invokevirtual #75                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      39: iload         4
      41: invokevirtual #44                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      44: pop
      45: iinc          2, 1
      48: goto          21
      51: aload_1
      52: ldc           #72                 // String #
      54: invokevirtual #75                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      57: pop
      58: aload_1
      59: invokevirtual #48                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      62: dup
      63: ldc           #50                 // String toString(...)
      65: invokestatic  #53                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      68: areturn

  public static final void main();
    Code:
       0: ldc           #81                 // String babad
       2: invokestatic  #83                 // Method longestPalindrome:(Ljava/lang/String;)Ljava/lang/String;
       5: getstatic     #89                 // Field java/lang/System.out:Ljava/io/PrintStream;
       8: swap
       9: invokevirtual #95                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      12: ldc           #97                 // String cbbd
      14: invokestatic  #83                 // Method longestPalindrome:(Ljava/lang/String;)Ljava/lang/String;
      17: getstatic     #89                 // Field java/lang/System.out:Ljava/io/PrintStream;
      20: swap
      21: invokevirtual #95                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      24: ldc           #98                 // String a
      26: invokestatic  #83                 // Method longestPalindrome:(Ljava/lang/String;)Ljava/lang/String;
      29: getstatic     #89                 // Field java/lang/System.out:Ljava/io/PrintStream;
      32: swap
      33: invokevirtual #95                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      36: ldc           #100                // String ac
      38: invokestatic  #83                 // Method longestPalindrome:(Ljava/lang/String;)Ljava/lang/String;
      41: getstatic     #89                 // Field java/lang/System.out:Ljava/io/PrintStream;
      44: swap
      45: invokevirtual #95                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      48: ldc           #102                // String abb
      50: invokestatic  #83                 // Method longestPalindrome:(Ljava/lang/String;)Ljava/lang/String;
      53: getstatic     #89                 // Field java/lang/System.out:Ljava/io/PrintStream;
      56: swap
      57: invokevirtual #95                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      60: return

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