package com.igorwojda.string.issubstring

// Time complexity: O(n*m)
// Space complexity: O(1)
//
// Optimal solution using double pointer.
private object Solution1 {
    private fun isSubstring(str: String, subStr: String): Boolean {
        if (subStr.isEmpty()) return true
        if (str.length < subStr.length) return false

        var pointer1 = 0
        var pointer2 = 0

        while (pointer1 <= str.lastIndex) {
            if (str[pointer1] == subStr[pointer2]) {
                pointer1++
                pointer2++
                if (pointer2 == subStr.length) {
                    return true
                }
            } else {
                pointer1 = pointer1 - pointer2 + 1
                pointer2 = 0
            }
        }

        return false
    }
}

// Time complexity: O(n*m)
// Space complexity: ??, but more than O(1)
// Number of iterations (n) is bounded by the length of the first string
// and String.drop requires copying the entire remaining string (on it's own it has O(m) complexity)
// First of 5 chars, needs 5 iterations at most and 15 character copied (5+4+3+2+1=15). Second is copied less often.
//
// Recursive solution
private object Solution2 {
    private fun isSubstring(str: String, subStr: String): Boolean {
        fun isExactMatch(str: String, subStr: String): Boolean {
            if (subStr.length > str.length) {
                return false
            }

            return when {
                str.isEmpty() && subStr.isEmpty() -> true
                str.isNotEmpty() && subStr.isEmpty() -> true
                else -> str[0] == subStr[0] && isExactMatch(str.drop(1), subStr.drop(1))
            }
        }

        if (subStr.length > str.length) {
            return false
        }
        if (str.isEmpty() || subStr.isEmpty()) {
            return true
        }

        return isExactMatch(str, subStr) || isSubstring(str.drop(1), subStr)
    }
}

private object Solution3 {
    private fun isSubstring(str: String, subStr: String): Boolean {
        if (subStr.isEmpty()) return true

        return str
            .windowed(subStr.length)
            .any { it == subStr }
    }
}

// Time complexity: O(n*m)
// Space complexity: O(1)
// This recursive solution is faster than solution with String.drop because it uses double pointer
//
// Recursive solution
private fun isSubstring(str: String, subStr: String): Boolean {
    if (subStr.isEmpty()) {
        return true
    }

    fun helper(first: String, second: String, firstPointer1: Int = 0, secondPointer2: Int = 0): Boolean {
        if (firstPointer1 > first.lastIndex) {
            return false
        }

        return if (first[firstPointer1] == second[secondPointer2]) {
            val localPointer1 = firstPointer1 + 1
            val localPointer2 = secondPointer2 + 1

            when {
                localPointer1 <= first.lastIndex && localPointer2 <= second.lastIndex -> {
                    helper(first, second, localPointer1, localPointer2)
                }

                localPointer2 <= second.lastIndex && localPointer1 > first.lastIndex -> false
                else -> true
            }
        } else {
            val p1 = firstPointer1 - secondPointer2 + 1

            if (p1 > first.lastIndex) {
                return false
            } else {
                helper(first, second, p1, 0)
            }
        }
    }

    return helper(str, subStr)
}

Compiled from "Solution.kt"
public final class com.igorwojda.string.issubstring.SolutionKt {
  private static final boolean isSubstring(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: checkcast     #8                  // class java/lang/CharSequence
       4: invokeinterface #12,  1           // InterfaceMethod java/lang/CharSequence.length:()I
       9: ifne          16
      12: iconst_1
      13: goto          17
      16: iconst_0
      17: ifeq          22
      20: iconst_1
      21: ireturn
      22: aload_0
      23: aload_1
      24: iconst_0
      25: iconst_0
      26: bipush        12
      28: aconst_null
      29: invokestatic  #16                 // Method isSubstring$helper$default:(Ljava/lang/String;Ljava/lang/String;IIILjava/lang/Object;)Z
      32: ireturn

  private static final boolean isSubstring$helper(java.lang.String, java.lang.String, int, int);
    Code:
       0: iload_2
       1: aload_0
       2: checkcast     #8                  // class java/lang/CharSequence
       5: invokestatic  #27                 // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
       8: if_icmple     13
      11: iconst_0
      12: ireturn
      13: aload_0
      14: iload_2
      15: invokevirtual #33                 // Method java/lang/String.charAt:(I)C
      18: aload_1
      19: iload_3
      20: invokevirtual #33                 // Method java/lang/String.charAt:(I)C
      23: if_icmpne     105
      26: iload_2
      27: iconst_1
      28: iadd
      29: istore        4
      31: iload_3
      32: iconst_1
      33: iadd
      34: istore        5
      36: nop
      37: iload         4
      39: aload_0
      40: checkcast     #8                  // class java/lang/CharSequence
      43: invokestatic  #27                 // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
      46: if_icmpgt     73
      49: iload         5
      51: aload_1
      52: checkcast     #8                  // class java/lang/CharSequence
      55: invokestatic  #27                 // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
      58: if_icmpgt     73
      61: aload_0
      62: aload_1
      63: iload         4
      65: iload         5
      67: invokestatic  #35                 // Method isSubstring$helper:(Ljava/lang/String;Ljava/lang/String;II)Z
      70: goto          134
      73: iload         5
      75: aload_1
      76: checkcast     #8                  // class java/lang/CharSequence
      79: invokestatic  #27                 // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
      82: if_icmpgt     101
      85: iload         4
      87: aload_0
      88: checkcast     #8                  // class java/lang/CharSequence
      91: invokestatic  #27                 // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
      94: if_icmple     101
      97: iconst_0
      98: goto          134
     101: iconst_1
     102: goto          134
     105: iload_2
     106: iload_3
     107: isub
     108: iconst_1
     109: iadd
     110: istore        4
     112: iload         4
     114: aload_0
     115: checkcast     #8                  // class java/lang/CharSequence
     118: invokestatic  #27                 // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
     121: if_icmple     126
     124: iconst_0
     125: ireturn
     126: aload_0
     127: aload_1
     128: iload         4
     130: iconst_0
     131: invokestatic  #35                 // Method isSubstring$helper:(Ljava/lang/String;Ljava/lang/String;II)Z
     134: ireturn

  static boolean isSubstring$helper$default(java.lang.String, java.lang.String, int, int, int, java.lang.Object);
    Code:
       0: iload         4
       2: iconst_4
       3: iand
       4: ifeq          9
       7: iconst_0
       8: istore_2
       9: iload         4
      11: bipush        8
      13: iand
      14: ifeq          19
      17: iconst_0
      18: istore_3
      19: aload_0
      20: aload_1
      21: iload_2
      22: iload_3
      23: invokestatic  #35                 // Method isSubstring$helper:(Ljava/lang/String;Ljava/lang/String;II)Z
      26: ireturn
}


package Day03

import java.io.File

fun main() {

    val chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

    fun Char.toValue(): Int = chars.indexOf(this) + 1
    check('p'.toValue() == 16)
    check('L'.toValue() == 38)

    fun part1(input: String): Int {

        var commonChars = mutableListOf<Char>()
        input.lines()
            .map { it.substring(0, it.length.div(2)) to it.substring(it.length.div(2), it.length) }
            .map {
                it.first.iterator().forEach { char ->
                    if (it.second.contains(char)) {
                        commonChars.add(char)
                        return@map
                    }
                }
            }

        return commonChars.map { it.toValue() }.sum()
    }

    fun containsChar(c: Char, line:String):Boolean {
        return line.contains(c)
    }

    fun calculateResult(n: Int, input: String) : Int{

        val grouped = input
            .lines()
            .chunked(n)

        return grouped.sumOf {
            it.first()
                .toCharArray()
                .first { char -> IntRange(1, n - 1).all { n -> containsChar(char, it[n]) } }
                .toValue()
        }
    }

    fun part2(input: String): Int {
      return calculateResult(3, input)
    }

    val testInput = File("src/Day03/test_data.txt").readText()
    println(part1(testInput))
    check(part1(testInput) == 157)
    check(part2(testInput) == 70 )

    val input = File("src/Day03/data.txt").readText()
    println(part1(input))
    println(part2(input))

}

Compiled from "Day03.kt"
public final class Day03.Day03Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
       2: astore_0
       3: bipush        112
       5: aload_0
       6: invokestatic  #12                 // Method main$toValue:(CLjava/lang/String;)I
       9: bipush        16
      11: if_icmpne     18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: ifne          32
      22: new           #14                 // class java/lang/IllegalStateException
      25: dup
      26: ldc           #16                 // String Check failed.
      28: invokespecial #20                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      31: athrow
      32: bipush        76
      34: aload_0
      35: invokestatic  #12                 // Method main$toValue:(CLjava/lang/String;)I
      38: bipush        38
      40: if_icmpne     47
      43: iconst_1
      44: goto          48
      47: iconst_0
      48: ifne          61
      51: new           #14                 // class java/lang/IllegalStateException
      54: dup
      55: ldc           #16                 // String Check failed.
      57: invokespecial #20                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      60: athrow
      61: new           #22                 // class java/io/File
      64: dup
      65: ldc           #24                 // String src/Day03/test_data.txt
      67: invokespecial #25                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      70: aconst_null
      71: iconst_1
      72: aconst_null
      73: invokestatic  #31                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
      76: astore_1
      77: aload_0
      78: aload_1
      79: invokestatic  #35                 // Method main$part1:(Ljava/lang/String;Ljava/lang/String;)I
      82: istore_2
      83: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;
      86: iload_2
      87: invokevirtual #47                 // Method java/io/PrintStream.println:(I)V
      90: aload_0
      91: aload_1
      92: invokestatic  #35                 // Method main$part1:(Ljava/lang/String;Ljava/lang/String;)I
      95: sipush        157
      98: if_icmpne     105
     101: iconst_1
     102: goto          106
     105: iconst_0
     106: ifne          119
     109: new           #14                 // class java/lang/IllegalStateException
     112: dup
     113: ldc           #16                 // String Check failed.
     115: invokespecial #20                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     118: athrow
     119: aload_0
     120: aload_1
     121: invokestatic  #50                 // Method main$part2:(Ljava/lang/String;Ljava/lang/String;)I
     124: bipush        70
     126: if_icmpne     133
     129: iconst_1
     130: goto          134
     133: iconst_0
     134: ifne          147
     137: new           #14                 // class java/lang/IllegalStateException
     140: dup
     141: ldc           #16                 // String Check failed.
     143: invokespecial #20                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     146: athrow
     147: new           #22                 // class java/io/File
     150: dup
     151: ldc           #52                 // String src/Day03/data.txt
     153: invokespecial #25                 // Method java/io/File."<init>":(Ljava/lang/String;)V
     156: aconst_null
     157: iconst_1
     158: aconst_null
     159: invokestatic  #31                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
     162: astore_2
     163: aload_0
     164: aload_2
     165: invokestatic  #35                 // Method main$part1:(Ljava/lang/String;Ljava/lang/String;)I
     168: istore_3
     169: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;
     172: iload_3
     173: invokevirtual #47                 // Method java/io/PrintStream.println:(I)V
     176: aload_0
     177: aload_2
     178: invokestatic  #50                 // Method main$part2:(Ljava/lang/String;Ljava/lang/String;)I
     181: istore_3
     182: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;
     185: iload_3
     186: invokevirtual #47                 // Method java/io/PrintStream.println:(I)V
     189: return

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

  private static final int main$toValue(char, java.lang.String);
    Code:
       0: aload_1
       1: checkcast     #65                 // class java/lang/CharSequence
       4: iload_0
       5: iconst_0
       6: iconst_0
       7: bipush        6
       9: aconst_null
      10: invokestatic  #71                 // Method kotlin/text/StringsKt.indexOf$default:(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
      13: iconst_1
      14: iadd
      15: ireturn

  private static final int main$part1(java.lang.String, java.lang.String);
    Code:
       0: aconst_null
       1: astore_2
       2: new           #75                 // class java/util/ArrayList
       5: dup
       6: invokespecial #77                 // Method java/util/ArrayList."<init>":()V
       9: checkcast     #79                 // class java/util/List
      12: astore_2
      13: aload_1
      14: checkcast     #65                 // class java/lang/CharSequence
      17: invokestatic  #83                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
      20: checkcast     #85                 // class java/lang/Iterable
      23: astore_3
      24: nop
      25: iconst_0
      26: istore        4
      28: aload_3
      29: astore        5
      31: new           #75                 // class java/util/ArrayList
      34: dup
      35: aload_3
      36: bipush        10
      38: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      41: invokespecial #93                 // Method java/util/ArrayList."<init>":(I)V
      44: checkcast     #95                 // class java/util/Collection
      47: astore        6
      49: iconst_0
      50: istore        7
      52: aload         5
      54: invokeinterface #99,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      59: astore        8
      61: aload         8
      63: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      68: ifeq          151
      71: aload         8
      73: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      78: astore        9
      80: aload         6
      82: aload         9
      84: checkcast     #58                 // class java/lang/String
      87: astore        10
      89: astore        18
      91: iconst_0
      92: istore        11
      94: aload         10
      96: iconst_0
      97: aload         10
      99: invokevirtual #113                // Method java/lang/String.length:()I
     102: iconst_2
     103: idiv
     104: invokevirtual #117                // Method java/lang/String.substring:(II)Ljava/lang/String;
     107: dup
     108: ldc           #119                // String substring(...)
     110: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     113: aload         10
     115: aload         10
     117: invokevirtual #113                // Method java/lang/String.length:()I
     120: iconst_2
     121: idiv
     122: aload         10
     124: invokevirtual #113                // Method java/lang/String.length:()I
     127: invokevirtual #117                // Method java/lang/String.substring:(II)Ljava/lang/String;
     130: dup
     131: ldc           #119                // String substring(...)
     133: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     136: invokestatic  #131                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     139: aload         18
     141: swap
     142: invokeinterface #135,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     147: pop
     148: goto          61
     151: aload         6
     153: checkcast     #79                 // class java/util/List
     156: nop
     157: checkcast     #85                 // class java/lang/Iterable
     160: astore_3
     161: nop
     162: iconst_0
     163: istore        4
     165: aload_3
     166: astore        5
     168: new           #75                 // class java/util/ArrayList
     171: dup
     172: aload_3
     173: bipush        10
     175: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     178: invokespecial #93                 // Method java/util/ArrayList."<init>":(I)V
     181: checkcast     #95                 // class java/util/Collection
     184: astore        6
     186: iconst_0
     187: istore        7
     189: aload         5
     191: invokeinterface #99,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     196: astore        8
     198: aload         8
     200: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     205: ifeq          341
     208: aload         8
     210: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     215: astore        9
     217: aload         6
     219: aload         9
     221: checkcast     #137                // class kotlin/Pair
     224: astore        10
     226: astore        18
     228: iconst_0
     229: istore        11
     231: aload         10
     233: invokevirtual #140                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     236: checkcast     #65                 // class java/lang/CharSequence
     239: invokestatic  #143                // Method kotlin/text/StringsKt.iterator:(Ljava/lang/CharSequence;)Lkotlin/collections/CharIterator;
     242: checkcast     #101                // class java/util/Iterator
     245: astore        12
     247: iconst_0
     248: istore        13
     250: aload         12
     252: astore        14
     254: aload         14
     256: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     261: ifeq          325
     264: aload         14
     266: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     271: astore        15
     273: aload         15
     275: checkcast     #145                // class java/lang/Character
     278: invokevirtual #149                // Method java/lang/Character.charValue:()C
     281: istore        16
     283: iconst_0
     284: istore        17
     286: aload         10
     288: invokevirtual #152                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     291: checkcast     #65                 // class java/lang/CharSequence
     294: iload         16
     296: iconst_0
     297: iconst_2
     298: aconst_null
     299: invokestatic  #156                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
     302: ifeq          320
     305: aload_2
     306: iload         16
     308: invokestatic  #160                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     311: invokeinterface #161,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     316: pop
     317: goto          327
     320: nop
     321: nop
     322: goto          254
     325: nop
     326: nop
     327: aload         18
     329: getstatic     #167                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     332: invokeinterface #135,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     337: pop
     338: goto          198
     341: aload         6
     343: checkcast     #79                 // class java/util/List
     346: nop
     347: pop
     348: aload_2
     349: checkcast     #85                 // class java/lang/Iterable
     352: astore_3
     353: iconst_0
     354: istore        4
     356: aload_3
     357: astore        5
     359: new           #75                 // class java/util/ArrayList
     362: dup
     363: aload_3
     364: bipush        10
     366: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     369: invokespecial #93                 // Method java/util/ArrayList."<init>":(I)V
     372: checkcast     #95                 // class java/util/Collection
     375: astore        6
     377: iconst_0
     378: istore        7
     380: aload         5
     382: invokeinterface #99,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     387: astore        8
     389: aload         8
     391: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     396: ifeq          446
     399: aload         8
     401: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     406: astore        9
     408: aload         6
     410: aload         9
     412: checkcast     #145                // class java/lang/Character
     415: invokevirtual #149                // Method java/lang/Character.charValue:()C
     418: istore        10
     420: astore        18
     422: iconst_0
     423: istore        11
     425: iload         10
     427: aload_0
     428: invokestatic  #12                 // Method main$toValue:(CLjava/lang/String;)I
     431: invokestatic  #172                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     434: aload         18
     436: swap
     437: invokeinterface #135,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     442: pop
     443: goto          389
     446: aload         6
     448: checkcast     #79                 // class java/util/List
     451: nop
     452: checkcast     #85                 // class java/lang/Iterable
     455: invokestatic  #176                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     458: ireturn

  private static final boolean main$containsChar(char, java.lang.String);
    Code:
       0: aload_1
       1: checkcast     #65                 // class java/lang/CharSequence
       4: iload_0
       5: iconst_0
       6: iconst_2
       7: aconst_null
       8: invokestatic  #156                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
      11: ireturn

  private static final int main$calculateResult(java.lang.String, int, java.lang.String);
    Code:
       0: aload_2
       1: checkcast     #65                 // class java/lang/CharSequence
       4: invokestatic  #83                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
       7: checkcast     #85                 // class java/lang/Iterable
      10: iload_1
      11: invokestatic  #208                // Method kotlin/collections/CollectionsKt.chunked:(Ljava/lang/Iterable;I)Ljava/util/List;
      14: astore_3
      15: aload_3
      16: checkcast     #85                 // class java/lang/Iterable
      19: astore        4
      21: iconst_0
      22: istore        5
      24: aload         4
      26: invokeinterface #99,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      31: astore        6
      33: aload         6
      35: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      40: ifeq          265
      43: aload         6
      45: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      50: astore        7
      52: iload         5
      54: aload         7
      56: checkcast     #79                 // class java/util/List
      59: astore        8
      61: istore        23
      63: iconst_0
      64: istore        9
      66: nop
      67: aload         8
      69: invokestatic  #212                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      72: checkcast     #58                 // class java/lang/String
      75: invokevirtual #216                // Method java/lang/String.toCharArray:()[C
      78: dup
      79: ldc           #218                // String toCharArray(...)
      81: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      84: astore        10
      86: nop
      87: iconst_0
      88: istore        11
      90: iconst_0
      91: istore        12
      93: aload         10
      95: arraylength
      96: istore        13
      98: iload         12
     100: iload         13
     102: if_icmpge     239
     105: aload         10
     107: iload         12
     109: caload
     110: istore        14
     112: iload         14
     114: istore        15
     116: iconst_0
     117: istore        16
     119: new           #220                // class kotlin/ranges/IntRange
     122: dup
     123: iconst_1
     124: iload_1
     125: iconst_1
     126: isub
     127: invokespecial #223                // Method kotlin/ranges/IntRange."<init>":(II)V
     130: checkcast     #85                 // class java/lang/Iterable
     133: astore        17
     135: iconst_0
     136: istore        18
     138: aload         17
     140: instanceof    #95                 // class java/util/Collection
     143: ifeq          163
     146: aload         17
     148: checkcast     #95                 // class java/util/Collection
     151: invokeinterface #226,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     156: ifeq          163
     159: iconst_1
     160: goto          224
     163: aload         17
     165: invokeinterface #99,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     170: astore        19
     172: aload         19
     174: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     179: ifeq          223
     182: aload         19
     184: checkcast     #228                // class kotlin/collections/IntIterator
     187: invokevirtual #231                // Method kotlin/collections/IntIterator.nextInt:()I
     190: istore        20
     192: iload         20
     194: istore        21
     196: iconst_0
     197: istore        22
     199: iload         15
     201: aload         8
     203: iload         21
     205: invokeinterface #235,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     210: checkcast     #58                 // class java/lang/String
     213: invokestatic  #237                // Method main$containsChar:(CLjava/lang/String;)Z
     216: ifne          172
     219: iconst_0
     220: goto          224
     223: iconst_1
     224: nop
     225: ifeq          233
     228: iload         14
     230: goto          249
     233: iinc          12, 1
     236: goto          98
     239: new           #239                // class java/util/NoSuchElementException
     242: dup
     243: ldc           #241                // String Array contains no element matching the predicate.
     245: invokespecial #242                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
     248: athrow
     249: aload_0
     250: invokestatic  #12                 // Method main$toValue:(CLjava/lang/String;)I
     253: istore        24
     255: iload         23
     257: iload         24
     259: iadd
     260: istore        5
     262: goto          33
     265: iload         5
     267: ireturn

  private static final int main$part2(java.lang.String, java.lang.String);
    Code:
       0: aload_0
       1: iconst_3
       2: aload_1
       3: invokestatic  #256                // Method main$calculateResult:(Ljava/lang/String;ILjava/lang/String;)I
       6: ireturn
}


package Day02

import java.io.File

fun main() {

    fun playResult(play: String): Int {
        val splitPlay = play.split(" ")
        val play = Play(splitPlay[0], splitPlay[1]);
        return play.selScore() + play.resScore()
    }

    fun playResultPart2(play: String): Int {
        val splitPlay = play.split(" ")
        val play = Play(splitPlay[0], splitPlay[1]);
        return play.selAndEndScore()
    }

    fun part1(input: String): Int {
        return input
            .lines()
            .fold(0) { acc, play -> acc + playResult(play) }
    }

    fun part2(input: String): Int {
        return input
            .lines()
            .fold(0) { acc, play -> acc + playResultPart2(play) }
    }

    // test if implementation meets criteria from the description, like:
    val testInput = File("src/Day02/Day02_test.txt").readText()
    check(part1(testInput) == 15)
    check(part2(testInput) == 12)

    val input = File("src/Day02/data.txt").readText()
    println(part1(input))
    println(part2(input))
}

class Play(val opponent: String, val you: String) {

    fun selScore(): Int {

        return when (you) {
            in "X" -> 1
            in "Y" -> 2
            in "Z" -> 3
            else -> 0
        }

    }

    fun resScore(): Int {

        return when (you) {
            in "X" -> when (opponent) {
                "A" -> 3
                "B" -> 0
                else -> 6
            }
            in "Y" -> when (opponent) {
                "A" -> 6
                "B" -> 3
                else -> 0
            }
            else -> when (opponent) {
                "A" -> 0
                "B" -> 6
                else -> 3
            }
        }
    }

    fun recScore(op: String, you: String): Int {
        val play = Play(op, you);
        return return play.selScore() + play.resScore()
    }

    fun selAndEndScore(): Int {

        return when (opponent) {

            in "A" -> when (you) {
                "X" -> recScore("A", "Z")
                "Y" -> recScore("A", "X")
                else -> recScore("A", "Y")
            }

            in "B" -> when (you) {
                "X" -> recScore("B", "X")
                "Y" -> recScore("B", "Y")
                else -> recScore("B", "Z")
            }

            else -> when (you) {
                "X" -> recScore("C", "Y")
                "Y" -> recScore("C", "Z")
                else -> recScore("C", "X")
            }
        }
    }
}

Compiled from "Day02.kt"
public final class Day02.Day02Kt {
  public static final void main();
    Code:
       0: new           #8                  // class java/io/File
       3: dup
       4: ldc           #10                 // String src/Day02/Day02_test.txt
       6: invokespecial #14                 // Method java/io/File."<init>":(Ljava/lang/String;)V
       9: aconst_null
      10: iconst_1
      11: aconst_null
      12: invokestatic  #20                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
      15: astore_0
      16: aload_0
      17: invokestatic  #24                 // Method main$part1:(Ljava/lang/String;)I
      20: bipush        15
      22: if_icmpne     29
      25: iconst_1
      26: goto          30
      29: iconst_0
      30: ifne          43
      33: new           #26                 // class java/lang/IllegalStateException
      36: dup
      37: ldc           #28                 // String Check failed.
      39: invokespecial #29                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      42: athrow
      43: aload_0
      44: invokestatic  #32                 // Method main$part2:(Ljava/lang/String;)I
      47: bipush        12
      49: if_icmpne     56
      52: iconst_1
      53: goto          57
      56: iconst_0
      57: ifne          70
      60: new           #26                 // class java/lang/IllegalStateException
      63: dup
      64: ldc           #28                 // String Check failed.
      66: invokespecial #29                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      69: athrow
      70: new           #8                  // class java/io/File
      73: dup
      74: ldc           #34                 // String src/Day02/data.txt
      76: invokespecial #14                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      79: aconst_null
      80: iconst_1
      81: aconst_null
      82: invokestatic  #20                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
      85: astore_1
      86: aload_1
      87: invokestatic  #24                 // Method main$part1:(Ljava/lang/String;)I
      90: istore_2
      91: getstatic     #40                 // Field java/lang/System.out:Ljava/io/PrintStream;
      94: iload_2
      95: invokevirtual #46                 // Method java/io/PrintStream.println:(I)V
      98: aload_1
      99: invokestatic  #32                 // Method main$part2:(Ljava/lang/String;)I
     102: istore_2
     103: getstatic     #40                 // Field java/lang/System.out:Ljava/io/PrintStream;
     106: iload_2
     107: invokevirtual #46                 // Method java/io/PrintStream.println:(I)V
     110: return

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

  private static final int main$playResult(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #59                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #51                 // class java/lang/String
       8: astore_2
       9: aload_2
      10: iconst_0
      11: ldc           #61                 // String
      13: aastore
      14: aload_2
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #67                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: astore_1
      24: new           #69                 // class Day02/Play
      27: dup
      28: aload_1
      29: iconst_0
      30: invokeinterface #75,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      35: checkcast     #51                 // class java/lang/String
      38: aload_1
      39: iconst_1
      40: invokeinterface #75,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      45: checkcast     #51                 // class java/lang/String
      48: invokespecial #78                 // Method Day02/Play."<init>":(Ljava/lang/String;Ljava/lang/String;)V
      51: astore_2
      52: aload_2
      53: invokevirtual #82                 // Method Day02/Play.selScore:()I
      56: aload_2
      57: invokevirtual #85                 // Method Day02/Play.resScore:()I
      60: iadd
      61: ireturn

  private static final int main$playResultPart2(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #59                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #51                 // class java/lang/String
       8: astore_2
       9: aload_2
      10: iconst_0
      11: ldc           #61                 // String
      13: aastore
      14: aload_2
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #67                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: astore_1
      24: new           #69                 // class Day02/Play
      27: dup
      28: aload_1
      29: iconst_0
      30: invokeinterface #75,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      35: checkcast     #51                 // class java/lang/String
      38: aload_1
      39: iconst_1
      40: invokeinterface #75,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      45: checkcast     #51                 // class java/lang/String
      48: invokespecial #78                 // Method Day02/Play."<init>":(Ljava/lang/String;Ljava/lang/String;)V
      51: astore_2
      52: aload_2
      53: invokevirtual #93                 // Method Day02/Play.selAndEndScore:()I
      56: ireturn

  private static final int main$part1(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #59                 // class java/lang/CharSequence
       4: invokestatic  #97                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
       7: checkcast     #99                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: iconst_0
      14: istore_3
      15: iload_2
      16: istore        4
      18: aload_1
      19: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      24: astore        5
      26: aload         5
      28: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      33: ifeq          72
      36: aload         5
      38: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      43: astore        6
      45: iload         4
      47: aload         6
      49: checkcast     #51                 // class java/lang/String
      52: astore        7
      54: istore        8
      56: iconst_0
      57: istore        9
      59: iload         8
      61: aload         7
      63: invokestatic  #115                // Method main$playResult:(Ljava/lang/String;)I
      66: iadd
      67: istore        4
      69: goto          26
      72: iload         4
      74: ireturn

  private static final int main$part2(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #59                 // class java/lang/CharSequence
       4: invokestatic  #97                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
       7: checkcast     #99                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: iconst_0
      14: istore_3
      15: iload_2
      16: istore        4
      18: aload_1
      19: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      24: astore        5
      26: aload         5
      28: invokeinterface #109,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      33: ifeq          72
      36: aload         5
      38: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      43: astore        6
      45: iload         4
      47: aload         6
      49: checkcast     #51                 // class java/lang/String
      52: astore        7
      54: istore        8
      56: iconst_0
      57: istore        9
      59: iload         8
      61: aload         7
      63: invokestatic  #127                // Method main$playResultPart2:(Ljava/lang/String;)I
      66: iadd
      67: istore        4
      69: goto          26
      72: iload         4
      74: ireturn
}


package ch.sbb.functionalkotlin.basics

// 2.1 Given the function prepend, write a recursive function concat that concatenates a list of chars to a string
fun prepend(c: Char, s: String): String = "$c$s"

fun concat(chars: List<Char>): String =
        if (chars.isEmpty()) "" else prepend(chars.first(), concat(chars.takeLast(chars.size - 1)))

// 2.2 Create a recursive version of a function that computes the n-th number in the Fibonacci sequence
// Hint: the Fibonacci series is 0, 1, 1, 2, 3, 5, 8, 13, 21; hence the n-th number in the sequence is the sum of the (n-2)th and (n-1)th numbers
fun fibRec(n: Int): Int =
        when (n) {
            0 -> 0
            1 -> 1
            else -> fibRec(n - 1) + fibRec(n - 2)
        }

// 2.3 (HARD) Create a tail-recursive version of the function in 2.2
fun fibCorec(n: Int): Int {
    tailrec fun _fib(n: Int, prev2: Int, prev1: Int): Int =
            when (n) {
                0 -> prev2
                1 -> prev1
                else -> _fib(n - 1, prev1, prev2 + prev1)
            }
    return _fib(n, 0, 1)
}

// 2.4 (Extra) Write a binary search function which takes a sorted list of ints and checks whether an element is present
fun binarySearch(value: Int, list: List<Int>): Boolean =
        when {
            list.isEmpty() -> false
            list[middle(list)] < value -> binarySearch(value, list.subList(0, middle(list)))
            list[middle(list)] > value -> binarySearch(value, list.subList(middle(list) + 1, list.size))
            else -> true // list[middle(list)] == value
        }

fun middle(list: List<Int>) = list.size / 2

Compiled from "Recursion.kt"
public final class ch.sbb.functionalkotlin.basics.RecursionKt {
  public static final java.lang.String prepend(char, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #9                  // String s
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class java/lang/StringBuilder
       9: dup
      10: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      13: iload_0
      14: invokevirtual #25                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      17: aload_1
      18: invokevirtual #28                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      21: invokevirtual #32                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      24: areturn

  public static final java.lang.String concat(java.util.List<java.lang.Character>);
    Code:
       0: aload_0
       1: ldc           #40                 // String chars
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #46,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      12: ifeq          20
      15: ldc           #48                 // String
      17: goto          48
      20: aload_0
      21: invokestatic  #54                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      24: checkcast     #56                 // class java/lang/Character
      27: invokevirtual #60                 // Method java/lang/Character.charValue:()C
      30: aload_0
      31: aload_0
      32: invokeinterface #64,  1           // InterfaceMethod java/util/List.size:()I
      37: iconst_1
      38: isub
      39: invokestatic  #68                 // Method kotlin/collections/CollectionsKt.takeLast:(Ljava/util/List;I)Ljava/util/List;
      42: invokestatic  #70                 // Method concat:(Ljava/util/List;)Ljava/lang/String;
      45: invokestatic  #72                 // Method prepend:(CLjava/lang/String;)Ljava/lang/String;
      48: areturn

  public static final int fibRec(int);
    Code:
       0: iload_0
       1: tableswitch   { // 0 to 1
                     0: 24
                     1: 28
               default: 32
          }
      24: iconst_0
      25: goto          45
      28: iconst_1
      29: goto          45
      32: iload_0
      33: iconst_1
      34: isub
      35: invokestatic  #79                 // Method fibRec:(I)I
      38: iload_0
      39: iconst_2
      40: isub
      41: invokestatic  #79                 // Method fibRec:(I)I
      44: iadd
      45: ireturn

  public static final int fibCorec(int);
    Code:
       0: iload_0
       1: iconst_0
       2: iconst_1
       3: invokestatic  #86                 // Method fibCorec$_fib:(III)I
       6: ireturn

  public static final boolean binarySearch(int, java.util.List<java.lang.Integer>);
    Code:
       0: aload_1
       1: ldc           #91                 // String list
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: nop
       7: aload_1
       8: invokeinterface #46,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      13: ifeq          20
      16: iconst_0
      17: goto          104
      20: aload_1
      21: aload_1
      22: invokestatic  #95                 // Method middle:(Ljava/util/List;)I
      25: invokeinterface #99,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      30: checkcast     #101                // class java/lang/Number
      33: invokevirtual #104                // Method java/lang/Number.intValue:()I
      36: iload_0
      37: if_icmpge     58
      40: iload_0
      41: aload_1
      42: iconst_0
      43: aload_1
      44: invokestatic  #95                 // Method middle:(Ljava/util/List;)I
      47: invokeinterface #108,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
      52: invokestatic  #110                // Method binarySearch:(ILjava/util/List;)Z
      55: goto          104
      58: aload_1
      59: aload_1
      60: invokestatic  #95                 // Method middle:(Ljava/util/List;)I
      63: invokeinterface #99,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      68: checkcast     #101                // class java/lang/Number
      71: invokevirtual #104                // Method java/lang/Number.intValue:()I
      74: iload_0
      75: if_icmple     103
      78: iload_0
      79: aload_1
      80: aload_1
      81: invokestatic  #95                 // Method middle:(Ljava/util/List;)I
      84: iconst_1
      85: iadd
      86: aload_1
      87: invokeinterface #64,  1           // InterfaceMethod java/util/List.size:()I
      92: invokeinterface #108,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
      97: invokestatic  #110                // Method binarySearch:(ILjava/util/List;)Z
     100: goto          104
     103: iconst_1
     104: ireturn

  public static final int middle(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #91                 // String list
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #64,  1           // InterfaceMethod java/util/List.size:()I
      12: iconst_2
      13: idiv
      14: ireturn

  private static final int fibCorec$_fib(int, int, int);
    Code:
       0: iload_0
       1: tableswitch   { // 0 to 1
                     0: 24
                     1: 28
               default: 32
          }
      24: iload_1
      25: goto          55
      28: iload_2
      29: goto          55
      32: iload_0
      33: iconst_1
      34: isub
      35: istore_3
      36: iload_2
      37: istore        4
      39: iload_1
      40: iload_2
      41: iadd
      42: istore        5
      44: iload_3
      45: istore_0
      46: iload         4
      48: istore_1
      49: iload         5
      51: istore_2
      52: goto          0
      55: ireturn
}


package com.arcadan.util.math

import java.lang.Math.*
import kotlin.math.pow

data class QuadraticEquation(val a: Double, val b: Double, val c: Double) {
    data class Complex(val r: Double, val i: Double) {
        override fun toString() = when {
            i == 0.0 -> r.toString()
            r == 0.0 -> "${i}i"
            else -> "$r + ${i}i"
        }
    }

    data class Solution(val x1: Any, val x2: Any) {
        override fun toString() = when(x1) {
            x2 -> "X1,2 = $x1"
            else -> "X1 = $x1, X2 = $x2"
        }
    }

    val quadraticRoots by lazy {
        val _2a = a + a
        val d = b * b - 4.0 * a * c  // discriminant
        if (d < 0.0) {
            val r = -b / _2a
            val i = kotlin.math.sqrt(-d) / _2a
            Solution(Complex(r, i), Complex(r, -i))
        } else {
            // avoid calculating -b +/- sqrt(d), to avoid any
            // subtractive cancellation when it is near zero.
            val r = if (b < 0.0) (-b + kotlin.math.sqrt(d)) / _2a else (-b - kotlin.math.sqrt(d)) / _2a
            Solution(r, c / (a * r))
        }
    }

    fun obtainYForXValue(x: Double) : Double = ((x.pow(2) * a) + (x * b) + c)
}

Compiled from "QuadraticEquation.kt"
public final class com.arcadan.util.math.QuadraticEquation$Solution {
  private final java.lang.Object x1;

  private final java.lang.Object x2;

  public com.arcadan.util.math.QuadraticEquation$Solution(java.lang.Object, java.lang.Object);
    Code:
       0: aload_1
       1: ldc           #9                  // String x1
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #17                 // String x2
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokespecial #20                 // Method java/lang/Object."<init>":()V
      16: aload_0
      17: aload_1
      18: putfield      #23                 // Field x1:Ljava/lang/Object;
      21: aload_0
      22: aload_2
      23: putfield      #25                 // Field x2:Ljava/lang/Object;
      26: return

  public final java.lang.Object getX1();
    Code:
       0: aload_0
       1: getfield      #23                 // Field x1:Ljava/lang/Object;
       4: areturn

  public final java.lang.Object getX2();
    Code:
       0: aload_0
       1: getfield      #25                 // Field x2:Ljava/lang/Object;
       4: areturn

  public java.lang.String toString();
    Code:
       0: aload_0
       1: getfield      #23                 // Field x1:Ljava/lang/Object;
       4: aload_0
       5: getfield      #25                 // Field x2:Ljava/lang/Object;
       8: invokestatic  #36                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      11: ifeq          39
      14: new           #38                 // class java/lang/StringBuilder
      17: dup
      18: invokespecial #39                 // Method java/lang/StringBuilder."<init>":()V
      21: ldc           #41                 // String X1,2 =
      23: invokevirtual #45                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      26: aload_0
      27: getfield      #23                 // Field x1:Ljava/lang/Object;
      30: invokevirtual #48                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      33: invokevirtual #50                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      36: goto          73
      39: new           #38                 // class java/lang/StringBuilder
      42: dup
      43: invokespecial #39                 // Method java/lang/StringBuilder."<init>":()V
      46: ldc           #52                 // String X1 =
      48: invokevirtual #45                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      51: aload_0
      52: getfield      #23                 // Field x1:Ljava/lang/Object;
      55: invokevirtual #48                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      58: ldc           #54                 // String , X2 =
      60: invokevirtual #45                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      63: aload_0
      64: getfield      #25                 // Field x2:Ljava/lang/Object;
      67: invokevirtual #48                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      70: invokevirtual #50                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      73: areturn

  public final java.lang.Object component1();
    Code:
       0: aload_0
       1: getfield      #23                 // Field x1:Ljava/lang/Object;
       4: areturn

  public final java.lang.Object component2();
    Code:
       0: aload_0
       1: getfield      #25                 // Field x2:Ljava/lang/Object;
       4: areturn

  public final com.arcadan.util.math.QuadraticEquation$Solution copy(java.lang.Object, java.lang.Object);
    Code:
       0: aload_1
       1: ldc           #9                  // String x1
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #17                 // String x2
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: new           #2                  // class com/arcadan/util/math/QuadraticEquation$Solution
      15: dup
      16: aload_1
      17: aload_2
      18: invokespecial #62                 // Method "<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      21: areturn

  public static com.arcadan.util.math.QuadraticEquation$Solution copy$default(com.arcadan.util.math.QuadraticEquation$Solution, java.lang.Object, java.lang.Object, int, java.lang.Object);
    Code:
       0: iload_3
       1: iconst_1
       2: iand
       3: ifeq          11
       6: aload_0
       7: getfield      #23                 // Field x1:Ljava/lang/Object;
      10: astore_1
      11: iload_3
      12: iconst_2
      13: iand
      14: ifeq          22
      17: aload_0
      18: getfield      #25                 // Field x2:Ljava/lang/Object;
      21: astore_2
      22: aload_0
      23: aload_1
      24: aload_2
      25: invokevirtual #66                 // Method copy:(Ljava/lang/Object;Ljava/lang/Object;)Lcom/arcadan/util/math/QuadraticEquation$Solution;
      28: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #23                 // Field x1:Ljava/lang/Object;
       4: invokevirtual #70                 // Method java/lang/Object.hashCode:()I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #25                 // Field x2:Ljava/lang/Object;
      16: invokevirtual #70                 // Method java/lang/Object.hashCode:()I
      19: iadd
      20: istore_1
      21: iload_1
      22: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class com/arcadan/util/math/QuadraticEquation$Solution
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class com/arcadan/util/math/QuadraticEquation$Solution
      20: astore_2
      21: aload_0
      22: getfield      #23                 // Field x1:Ljava/lang/Object;
      25: aload_2
      26: getfield      #23                 // Field x1:Ljava/lang/Object;
      29: invokestatic  #36                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      32: ifne          37
      35: iconst_0
      36: ireturn
      37: aload_0
      38: getfield      #25                 // Field x2:Ljava/lang/Object;
      41: aload_2
      42: getfield      #25                 // Field x2:Ljava/lang/Object;
      45: invokestatic  #36                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      48: ifne          53
      51: iconst_0
      52: ireturn
      53: iconst_1
      54: ireturn
}

Compiled from "QuadraticEquation.kt"
public final class com.arcadan.util.math.QuadraticEquation$Complex {
  private final double r;

  private final double i;

  public com.arcadan.util.math.QuadraticEquation$Complex(double, double);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: dload_1
       6: putfield      #13                 // Field r:D
       9: aload_0
      10: dload_3
      11: putfield      #16                 // Field i:D
      14: return

  public final double getR();
    Code:
       0: aload_0
       1: getfield      #13                 // Field r:D
       4: dreturn

  public final double getI();
    Code:
       0: aload_0
       1: getfield      #16                 // Field i:D
       4: dreturn

  public java.lang.String toString();
    Code:
       0: nop
       1: aload_0
       2: getfield      #16                 // Field i:D
       5: dconst_0
       6: dcmpg
       7: ifne          14
      10: iconst_1
      11: goto          15
      14: iconst_0
      15: ifeq          28
      18: aload_0
      19: getfield      #13                 // Field r:D
      22: invokestatic  #30                 // Method java/lang/String.valueOf:(D)Ljava/lang/String;
      25: goto          104
      28: aload_0
      29: getfield      #13                 // Field r:D
      32: dconst_0
      33: dcmpg
      34: ifne          41
      37: iconst_1
      38: goto          42
      41: iconst_0
      42: ifeq          70
      45: new           #32                 // class java/lang/StringBuilder
      48: dup
      49: invokespecial #33                 // Method java/lang/StringBuilder."<init>":()V
      52: aload_0
      53: getfield      #16                 // Field i:D
      56: invokevirtual #37                 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
      59: bipush        105
      61: invokevirtual #40                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      64: invokevirtual #42                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      67: goto          104
      70: new           #32                 // class java/lang/StringBuilder
      73: dup
      74: invokespecial #33                 // Method java/lang/StringBuilder."<init>":()V
      77: aload_0
      78: getfield      #13                 // Field r:D
      81: invokevirtual #37                 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
      84: ldc           #44                 // String  +
      86: invokevirtual #47                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      89: aload_0
      90: getfield      #16                 // Field i:D
      93: invokevirtual #37                 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
      96: bipush        105
      98: invokevirtual #40                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     101: invokevirtual #42                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     104: areturn

  public final double component1();
    Code:
       0: aload_0
       1: getfield      #13                 // Field r:D
       4: dreturn

  public final double component2();
    Code:
       0: aload_0
       1: getfield      #16                 // Field i:D
       4: dreturn

  public final com.arcadan.util.math.QuadraticEquation$Complex copy(double, double);
    Code:
       0: new           #2                  // class com/arcadan/util/math/QuadraticEquation$Complex
       3: dup
       4: dload_1
       5: dload_3
       6: invokespecial #53                 // Method "<init>":(DD)V
       9: areturn

  public static com.arcadan.util.math.QuadraticEquation$Complex copy$default(com.arcadan.util.math.QuadraticEquation$Complex, double, double, int, java.lang.Object);
    Code:
       0: iload         5
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #13                 // Field r:D
      11: dstore_1
      12: iload         5
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #16                 // Field i:D
      23: dstore_3
      24: aload_0
      25: dload_1
      26: dload_3
      27: invokevirtual #57                 // Method copy:(DD)Lcom/arcadan/util/math/QuadraticEquation$Complex;
      30: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #13                 // Field r:D
       4: invokestatic  #64                 // Method java/lang/Double.hashCode:(D)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #16                 // Field i:D
      16: invokestatic  #64                 // Method java/lang/Double.hashCode:(D)I
      19: iadd
      20: istore_1
      21: iload_1
      22: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class com/arcadan/util/math/QuadraticEquation$Complex
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class com/arcadan/util/math/QuadraticEquation$Complex
      20: astore_2
      21: aload_0
      22: getfield      #13                 // Field r:D
      25: aload_2
      26: getfield      #13                 // Field r:D
      29: invokestatic  #73                 // Method java/lang/Double.compare:(DD)I
      32: ifeq          37
      35: iconst_0
      36: ireturn
      37: aload_0
      38: getfield      #16                 // Field i:D
      41: aload_2
      42: getfield      #16                 // Field i:D
      45: invokestatic  #73                 // Method java/lang/Double.compare:(DD)I
      48: ifeq          53
      51: iconst_0
      52: ireturn
      53: iconst_1
      54: ireturn
}

Compiled from "QuadraticEquation.kt"
public final class com.arcadan.util.math.QuadraticEquation {
  private final double a;

  private final double b;

  private final double c;

  private final kotlin.Lazy quadraticRoots$delegate;

  public com.arcadan.util.math.QuadraticEquation(double, double, double);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: dload_1
       6: putfield      #13                 // Field a:D
       9: aload_0
      10: dload_3
      11: putfield      #16                 // Field b:D
      14: aload_0
      15: dload         5
      17: putfield      #19                 // Field c:D
      20: aload_0
      21: aload_0
      22: invokedynamic #39,  0             // InvokeDynamic #0:invoke:(Lcom/arcadan/util/math/QuadraticEquation;)Lkotlin/jvm/functions/Function0;
      27: invokestatic  #45                 // Method kotlin/LazyKt.lazy:(Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;
      30: putfield      #49                 // Field quadraticRoots$delegate:Lkotlin/Lazy;
      33: return

  public final double getA();
    Code:
       0: aload_0
       1: getfield      #13                 // Field a:D
       4: dreturn

  public final double getB();
    Code:
       0: aload_0
       1: getfield      #16                 // Field b:D
       4: dreturn

  public final double getC();
    Code:
       0: aload_0
       1: getfield      #19                 // Field c:D
       4: dreturn

  public final com.arcadan.util.math.QuadraticEquation$Solution getQuadraticRoots();
    Code:
       0: aload_0
       1: getfield      #49                 // Field quadraticRoots$delegate:Lkotlin/Lazy;
       4: astore_1
       5: aload_1
       6: invokeinterface #62,  1           // InterfaceMethod kotlin/Lazy.getValue:()Ljava/lang/Object;
      11: checkcast     #64                 // class com/arcadan/util/math/QuadraticEquation$Solution
      14: areturn

  public final double obtainYForXValue(double);
    Code:
       0: dload_1
       1: iconst_2
       2: i2d
       3: invokestatic  #72                 // Method java/lang/Math.pow:(DD)D
       6: aload_0
       7: getfield      #13                 // Field a:D
      10: dmul
      11: dload_1
      12: aload_0
      13: getfield      #16                 // Field b:D
      16: dmul
      17: dadd
      18: aload_0
      19: getfield      #19                 // Field c:D
      22: dadd
      23: dreturn

  public final double component1();
    Code:
       0: aload_0
       1: getfield      #13                 // Field a:D
       4: dreturn

  public final double component2();
    Code:
       0: aload_0
       1: getfield      #16                 // Field b:D
       4: dreturn

  public final double component3();
    Code:
       0: aload_0
       1: getfield      #19                 // Field c:D
       4: dreturn

  public final com.arcadan.util.math.QuadraticEquation copy(double, double, double);
    Code:
       0: new           #2                  // class com/arcadan/util/math/QuadraticEquation
       3: dup
       4: dload_1
       5: dload_3
       6: dload         5
       8: invokespecial #80                 // Method "<init>":(DDD)V
      11: areturn

  public static com.arcadan.util.math.QuadraticEquation copy$default(com.arcadan.util.math.QuadraticEquation, double, double, double, int, java.lang.Object);
    Code:
       0: iload         7
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #13                 // Field a:D
      11: dstore_1
      12: iload         7
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #16                 // Field b:D
      23: dstore_3
      24: iload         7
      26: iconst_4
      27: iand
      28: ifeq          37
      31: aload_0
      32: getfield      #19                 // Field c:D
      35: dstore        5
      37: aload_0
      38: dload_1
      39: dload_3
      40: dload         5
      42: invokevirtual #84                 // Method copy:(DDD)Lcom/arcadan/util/math/QuadraticEquation;
      45: areturn

  public java.lang.String toString();
    Code:
       0: new           #88                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #89                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #91                 // String QuadraticEquation(a=
       9: invokevirtual #95                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #13                 // Field a:D
      16: invokevirtual #98                 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
      19: ldc           #100                // String , b=
      21: invokevirtual #95                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #16                 // Field b:D
      28: invokevirtual #98                 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
      31: ldc           #102                // String , c=
      33: invokevirtual #95                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      36: aload_0
      37: getfield      #19                 // Field c:D
      40: invokevirtual #98                 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
      43: bipush        41
      45: invokevirtual #105                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      48: invokevirtual #107                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      51: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #13                 // Field a:D
       4: invokestatic  #114                // Method java/lang/Double.hashCode:(D)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #16                 // Field b:D
      16: invokestatic  #114                // Method java/lang/Double.hashCode:(D)I
      19: iadd
      20: istore_1
      21: iload_1
      22: bipush        31
      24: imul
      25: aload_0
      26: getfield      #19                 // Field c:D
      29: invokestatic  #114                // Method java/lang/Double.hashCode:(D)I
      32: iadd
      33: istore_1
      34: iload_1
      35: ireturn

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class com/arcadan/util/math/QuadraticEquation
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class com/arcadan/util/math/QuadraticEquation
      20: astore_2
      21: aload_0
      22: getfield      #13                 // Field a:D
      25: aload_2
      26: getfield      #13                 // Field a:D
      29: invokestatic  #123                // Method java/lang/Double.compare:(DD)I
      32: ifeq          37
      35: iconst_0
      36: ireturn
      37: aload_0
      38: getfield      #16                 // Field b:D
      41: aload_2
      42: getfield      #16                 // Field b:D
      45: invokestatic  #123                // Method java/lang/Double.compare:(DD)I
      48: ifeq          53
      51: iconst_0
      52: ireturn
      53: aload_0
      54: getfield      #19                 // Field c:D
      57: aload_2
      58: getfield      #19                 // Field c:D
      61: invokestatic  #123                // Method java/lang/Double.compare:(DD)I
      64: ifeq          69
      67: iconst_0
      68: ireturn
      69: iconst_1
      70: ireturn

  private static final com.arcadan.util.math.QuadraticEquation$Solution quadraticRoots_delegate$lambda$0(com.arcadan.util.math.QuadraticEquation);
    Code:
       0: aload_0
       1: getfield      #13                 // Field a:D
       4: aload_0
       5: getfield      #13                 // Field a:D
       8: dadd
       9: dstore_1
      10: aload_0
      11: getfield      #16                 // Field b:D
      14: aload_0
      15: getfield      #16                 // Field b:D
      18: dmul
      19: ldc2_w        #126                // double 4.0d
      22: aload_0
      23: getfield      #13                 // Field a:D
      26: dmul
      27: aload_0
      28: getfield      #19                 // Field c:D
      31: dmul
      32: dsub
      33: dstore_3
      34: dload_3
      35: dconst_0
      36: dcmpg
      37: ifge          91
      40: aload_0
      41: getfield      #16                 // Field b:D
      44: dneg
      45: dload_1
      46: ddiv
      47: dstore        5
      49: dload_3
      50: dneg
      51: invokestatic  #130                // Method java/lang/Math.sqrt:(D)D
      54: dload_1
      55: ddiv
      56: dstore        7
      58: new           #64                 // class com/arcadan/util/math/QuadraticEquation$Solution
      61: dup
      62: new           #132                // class com/arcadan/util/math/QuadraticEquation$Complex
      65: dup
      66: dload         5
      68: dload         7
      70: invokespecial #135                // Method com/arcadan/util/math/QuadraticEquation$Complex."<init>":(DD)V
      73: new           #132                // class com/arcadan/util/math/QuadraticEquation$Complex
      76: dup
      77: dload         5
      79: dload         7
      81: dneg
      82: invokespecial #135                // Method com/arcadan/util/math/QuadraticEquation$Complex."<init>":(DD)V
      85: invokespecial #138                // Method com/arcadan/util/math/QuadraticEquation$Solution."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      88: goto          156
      91: aload_0
      92: getfield      #16                 // Field b:D
      95: dconst_0
      96: dcmpg
      97: ifge          115
     100: aload_0
     101: getfield      #16                 // Field b:D
     104: dneg
     105: dload_3
     106: invokestatic  #130                // Method java/lang/Math.sqrt:(D)D
     109: dadd
     110: dload_1
     111: ddiv
     112: goto          127
     115: aload_0
     116: getfield      #16                 // Field b:D
     119: dneg
     120: dload_3
     121: invokestatic  #130                // Method java/lang/Math.sqrt:(D)D
     124: dsub
     125: dload_1
     126: ddiv
     127: dstore        5
     129: new           #64                 // class com/arcadan/util/math/QuadraticEquation$Solution
     132: dup
     133: dload         5
     135: invokestatic  #142                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     138: aload_0
     139: getfield      #19                 // Field c:D
     142: aload_0
     143: getfield      #13                 // Field a:D
     146: dload         5
     148: dmul
     149: ddiv
     150: invokestatic  #142                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     153: invokespecial #138                // Method com/arcadan/util/math/QuadraticEquation$Solution."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     156: areturn
}


package com.github.dmstocking.levenshtein

import kotlin.math.min

class Levenshtein(private var height: Int = 16, private var width: Int = 16) {

    private var distance = Array(height) { Array(width) { 0 } }

    init {
        for (i in 0 until width) {
            distance[i][0] = i
        }

        for (j in 0 until height) {
            distance[0][j] = j
        }
    }

    fun distance(a: String, b: String): Int {
        val rows = a.length
        val columns = b.length

        growToFit(rows, columns)

        for (j in 1..columns) {
            for (i in 1..rows) {
                val substitutionCost = if (a[i-1] == b[j-1]) 0 else 1
                distance[i][j] = min(
                    distance[i-1][j  ] + 1, // delete
                    distance[i  ][j-1] + 1, // insert
                    distance[i-1][j-1] + substitutionCost  // substitution
                )
            }
        }
        return distance[rows][columns]
    }

    private fun growToFit(rows: Int, columns: Int) {
        while (width < rows + 2 || height < columns + 2) {
            height *= 2
            width *= 2
        }

        distance = Array(height) { Array(width) { 0 } }

        for (i in 0 until width) {
            distance[i][0] = i
        }

        for (j in 0 until height) {
            distance[0][j] = j
        }
    }
}

fun min(vararg values: Int): Int {
    return values.reduce { current, next -> min(current, next) }
}

Compiled from "Levenshtein.kt"
public final class com.github.dmstocking.levenshtein.LevenshteinKt {
  public static final int min(int...);
    Code:
       0: aload_0
       1: ldc           #9                  // String values
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: astore_1
       8: iconst_0
       9: istore_2
      10: aload_1
      11: arraylength
      12: ifne          19
      15: iconst_1
      16: goto          20
      19: iconst_0
      20: ifeq          33
      23: new           #17                 // class java/lang/UnsupportedOperationException
      26: dup
      27: ldc           #19                 // String Empty array can\'t be reduced.
      29: invokespecial #23                 // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
      32: athrow
      33: aload_1
      34: iconst_0
      35: iaload
      36: istore_3
      37: iconst_1
      38: istore        4
      40: aload_1
      41: invokestatic  #28                 // Method kotlin/collections/ArraysKt.getLastIndex:([I)I
      44: istore        5
      46: iload         4
      48: iload         5
      50: if_icmpgt     87
      53: iload_3
      54: aload_1
      55: iload         4
      57: iaload
      58: istore        6
      60: istore        7
      62: iconst_0
      63: istore        8
      65: iload         7
      67: iload         6
      69: invokestatic  #33                 // Method java/lang/Math.min:(II)I
      72: nop
      73: istore_3
      74: iload         4
      76: iload         5
      78: if_icmpeq     87
      81: iinc          4, 1
      84: goto          53
      87: iload_3
      88: ireturn
}

Compiled from "Levenshtein.kt"
public final class com.github.dmstocking.levenshtein.Levenshtein {
  private int height;

  private int width;

  private java.lang.Integer[][] distance;

  public com.github.dmstocking.levenshtein.Levenshtein(int, int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field height:I
       9: aload_0
      10: iload_2
      11: putfield      #16                 // Field width:I
      14: aload_0
      15: iconst_0
      16: istore_3
      17: aload_0
      18: getfield      #13                 // Field height:I
      21: istore        4
      23: iload         4
      25: anewarray     #18                 // class "[Ljava/lang/Integer;"
      28: astore        5
      30: astore        11
      32: iload_3
      33: iload         4
      35: if_icmpge     104
      38: iload_3
      39: istore        6
      41: aload         5
      43: iload         6
      45: iconst_0
      46: istore        7
      48: aload_0
      49: getfield      #16                 // Field width:I
      52: istore        8
      54: iload         8
      56: anewarray     #20                 // class java/lang/Integer
      59: astore        9
      61: istore        13
      63: astore        12
      65: iload         7
      67: iload         8
      69: if_icmpge     91
      72: iload         7
      74: istore        10
      76: aload         9
      78: iload         10
      80: iconst_0
      81: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      84: aastore
      85: iinc          7, 1
      88: goto          65
      91: aload         12
      93: iload         13
      95: aload         9
      97: aastore
      98: iinc          3, 1
     101: goto          32
     104: aload         11
     106: aload         5
     108: putfield      #28                 // Field distance:[[Ljava/lang/Integer;
     111: nop
     112: iconst_0
     113: istore_3
     114: aload_0
     115: getfield      #16                 // Field width:I
     118: istore        4
     120: iload_3
     121: iload         4
     123: if_icmpge     144
     126: aload_0
     127: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
     130: iload_3
     131: aaload
     132: iconst_0
     133: iload_3
     134: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     137: aastore
     138: iinc          3, 1
     141: goto          120
     144: iconst_0
     145: istore_3
     146: aload_0
     147: getfield      #13                 // Field height:I
     150: istore        4
     152: iload_3
     153: iload         4
     155: if_icmpge     176
     158: aload_0
     159: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
     162: iconst_0
     163: aaload
     164: iload_3
     165: iload_3
     166: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     169: aastore
     170: iinc          3, 1
     173: goto          152
     176: nop
     177: return

  public com.github.dmstocking.levenshtein.Levenshtein(int, int, int, kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: iload_3
       1: iconst_1
       2: iand
       3: ifeq          9
       6: bipush        16
       8: istore_1
       9: iload_3
      10: iconst_2
      11: iand
      12: ifeq          18
      15: bipush        16
      17: istore_2
      18: aload_0
      19: iload_1
      20: iload_2
      21: invokespecial #36                 // Method "<init>":(II)V
      24: return

  public final int distance(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #40                 // String a
       3: invokestatic  #46                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #48                 // String b
       9: invokestatic  #46                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: invokevirtual #54                 // Method java/lang/String.length:()I
      16: istore_3
      17: aload_2
      18: invokevirtual #54                 // Method java/lang/String.length:()I
      21: istore        4
      23: aload_0
      24: iload_3
      25: iload         4
      27: invokespecial #57                 // Method growToFit:(II)V
      30: iconst_1
      31: istore        5
      33: iload         5
      35: iload         4
      37: if_icmpgt     189
      40: iconst_1
      41: istore        6
      43: iload         6
      45: iload_3
      46: if_icmpgt     176
      49: aload_1
      50: iload         6
      52: iconst_1
      53: isub
      54: invokevirtual #61                 // Method java/lang/String.charAt:(I)C
      57: aload_2
      58: iload         5
      60: iconst_1
      61: isub
      62: invokevirtual #61                 // Method java/lang/String.charAt:(I)C
      65: if_icmpne     72
      68: iconst_0
      69: goto          73
      72: iconst_1
      73: istore        7
      75: aload_0
      76: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
      79: iload         6
      81: aaload
      82: iload         5
      84: iconst_3
      85: newarray       int
      87: astore        8
      89: aload         8
      91: iconst_0
      92: aload_0
      93: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
      96: iload         6
      98: iconst_1
      99: isub
     100: aaload
     101: iload         5
     103: aaload
     104: invokevirtual #64                 // Method java/lang/Integer.intValue:()I
     107: iconst_1
     108: iadd
     109: iastore
     110: aload         8
     112: iconst_1
     113: aload_0
     114: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
     117: iload         6
     119: aaload
     120: iload         5
     122: iconst_1
     123: isub
     124: aaload
     125: invokevirtual #64                 // Method java/lang/Integer.intValue:()I
     128: iconst_1
     129: iadd
     130: iastore
     131: aload         8
     133: iconst_2
     134: aload_0
     135: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
     138: iload         6
     140: iconst_1
     141: isub
     142: aaload
     143: iload         5
     145: iconst_1
     146: isub
     147: aaload
     148: invokevirtual #64                 // Method java/lang/Integer.intValue:()I
     151: iload         7
     153: iadd
     154: iastore
     155: aload         8
     157: invokestatic  #70                 // Method com/github/dmstocking/levenshtein/LevenshteinKt.min:([I)I
     160: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     163: aastore
     164: iload         6
     166: iload_3
     167: if_icmpeq     176
     170: iinc          6, 1
     173: goto          49
     176: iload         5
     178: iload         4
     180: if_icmpeq     189
     183: iinc          5, 1
     186: goto          40
     189: aload_0
     190: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
     193: iload_3
     194: aaload
     195: iload         4
     197: aaload
     198: invokevirtual #64                 // Method java/lang/Integer.intValue:()I
     201: ireturn

  private final void growToFit(int, int);
    Code:
       0: aload_0
       1: getfield      #16                 // Field width:I
       4: iload_1
       5: iconst_2
       6: iadd
       7: if_icmplt     20
      10: aload_0
      11: getfield      #13                 // Field height:I
      14: iload_2
      15: iconst_2
      16: iadd
      17: if_icmpge     43
      20: aload_0
      21: aload_0
      22: getfield      #13                 // Field height:I
      25: iconst_2
      26: imul
      27: putfield      #13                 // Field height:I
      30: aload_0
      31: aload_0
      32: getfield      #16                 // Field width:I
      35: iconst_2
      36: imul
      37: putfield      #16                 // Field width:I
      40: goto          0
      43: aload_0
      44: iconst_0
      45: istore_3
      46: aload_0
      47: getfield      #13                 // Field height:I
      50: istore        4
      52: iload         4
      54: anewarray     #18                 // class "[Ljava/lang/Integer;"
      57: astore        5
      59: astore        11
      61: iload_3
      62: iload         4
      64: if_icmpge     133
      67: iload_3
      68: istore        6
      70: aload         5
      72: iload         6
      74: iconst_0
      75: istore        7
      77: aload_0
      78: getfield      #16                 // Field width:I
      81: istore        8
      83: iload         8
      85: anewarray     #20                 // class java/lang/Integer
      88: astore        9
      90: istore        13
      92: astore        12
      94: iload         7
      96: iload         8
      98: if_icmpge     120
     101: iload         7
     103: istore        10
     105: aload         9
     107: iload         10
     109: iconst_0
     110: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     113: aastore
     114: iinc          7, 1
     117: goto          94
     120: aload         12
     122: iload         13
     124: aload         9
     126: aastore
     127: iinc          3, 1
     130: goto          61
     133: aload         11
     135: aload         5
     137: putfield      #28                 // Field distance:[[Ljava/lang/Integer;
     140: iconst_0
     141: istore_3
     142: aload_0
     143: getfield      #16                 // Field width:I
     146: istore        4
     148: iload_3
     149: iload         4
     151: if_icmpge     172
     154: aload_0
     155: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
     158: iload_3
     159: aaload
     160: iconst_0
     161: iload_3
     162: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     165: aastore
     166: iinc          3, 1
     169: goto          148
     172: iconst_0
     173: istore_3
     174: aload_0
     175: getfield      #13                 // Field height:I
     178: istore        4
     180: iload_3
     181: iload         4
     183: if_icmpge     204
     186: aload_0
     187: getfield      #28                 // Field distance:[[Ljava/lang/Integer;
     190: iconst_0
     191: aaload
     192: iload_3
     193: iload_3
     194: invokestatic  #24                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     197: aastore
     198: iinc          3, 1
     201: goto          180
     204: return

  public com.github.dmstocking.levenshtein.Levenshtein();
    Code:
       0: aload_0
       1: iconst_0
       2: iconst_0
       3: iconst_3
       4: aconst_null
       5: invokespecial #76                 // Method "<init>":(IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: return
}