package com.heerkirov.hedge.server.library.compiler.grammar.definintion

//文法产生式的定义，作用是和syntax.txt中的定义对应。

/**
 * 被定义的文法产生式。
 */
data class SyntaxExpression(val index: Int, val key: KeyNotation, val sequence: List<Notation>)

/**
 * 文法产生式中的文法符号。
 */
interface Notation

/**
 * 终结符。
 */
interface TerminalNotation : Notation

/**
 * 用户定义的非终结符。
 */
class KeyNotation private constructor(val key: String) : Notation {
    companion object {
        private val cache = HashMap<String, KeyNotation>()

        fun of(key: String): KeyNotation {
            return cache.computeIfAbsent(key) { KeyNotation(it) }
        }
    }

    override fun equals(other: Any?) = other === this || (other is KeyNotation && other.key == key)

    override fun hashCode() = key.hashCode()

    override fun toString() = key
}

/**
 * 用户定义的终结符。
 */
class SyntaxNotation private constructor(val symbol: String) : TerminalNotation {
    companion object {
        private val cache = HashMap<String, SyntaxNotation>()

        fun of(symbol: String): SyntaxNotation {
            return cache.computeIfAbsent(symbol) { SyntaxNotation(it) }
        }
    }

    override fun equals(other: Any?) = other === this || (other is SyntaxNotation && other.symbol == symbol)

    override fun hashCode() = symbol.hashCode()

    override fun toString() = symbol
}

/**
 * 读取并生成原始的文法产生式定义。
 * 原始文法定义没有序号，自动添加序号，从1开始。
 */
fun readSyntaxExpression(text: String): List<SyntaxExpression> {
    val lines = text.split("\n")
        .asSequence().filter { it.isNotBlank() }.map { it.split(Regex("\\s+")) }
        .map {
            if(it.size < 2 || it[1] != "->") throw RuntimeException("Expression [${it.joinToString(" ")}] is incorrect.")
            it[0] to it.subList(2, it.size)
        }.toList()

    val nonTerminals = lines.asSequence().map { (left, _) -> left }.toSet()

    return lines.mapIndexed { i, (left, right) ->
        SyntaxExpression(i + 1, KeyNotation.of(left), right.map { if(it in nonTerminals) KeyNotation.of(it) else SyntaxNotation.of(it) })
    }
}

Compiled from "SyntaxExpression.kt"
public final class com.heerkirov.hedge.server.library.compiler.grammar.definintion.SyntaxExpression {
  private final int index;

  private final com.heerkirov.hedge.server.library.compiler.grammar.definintion.KeyNotation key;

  private final java.util.List<com.heerkirov.hedge.server.library.compiler.grammar.definintion.Notation> sequence;

  public com.heerkirov.hedge.server.library.compiler.grammar.definintion.SyntaxExpression(int, com.heerkirov.hedge.server.library.compiler.grammar.definintion.KeyNotation, java.util.List<? extends com.heerkirov.hedge.server.library.compiler.grammar.definintion.Notation>);
    Code:
       0: aload_2
       1: ldc           #10                 // String key
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_3
       7: ldc           #18                 // String sequence
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokespecial #21                 // Method java/lang/Object."<init>":()V
      16: aload_0
      17: iload_1
      18: putfield      #25                 // Field index:I
      21: aload_0
      22: aload_2
      23: putfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
      26: aload_0
      27: aload_3
      28: putfield      #31                 // Field sequence:Ljava/util/List;
      31: return

  public final int getIndex();
    Code:
       0: aload_0
       1: getfield      #25                 // Field index:I
       4: ireturn

  public final com.heerkirov.hedge.server.library.compiler.grammar.definintion.KeyNotation getKey();
    Code:
       0: aload_0
       1: getfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
       4: areturn

  public final java.util.List<com.heerkirov.hedge.server.library.compiler.grammar.definintion.Notation> getSequence();
    Code:
       0: aload_0
       1: getfield      #31                 // Field sequence:Ljava/util/List;
       4: areturn

  public final int component1();
    Code:
       0: aload_0
       1: getfield      #25                 // Field index:I
       4: ireturn

  public final com.heerkirov.hedge.server.library.compiler.grammar.definintion.KeyNotation component2();
    Code:
       0: aload_0
       1: getfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
       4: areturn

  public final java.util.List<com.heerkirov.hedge.server.library.compiler.grammar.definintion.Notation> component3();
    Code:
       0: aload_0
       1: getfield      #31                 // Field sequence:Ljava/util/List;
       4: areturn

  public final com.heerkirov.hedge.server.library.compiler.grammar.definintion.SyntaxExpression copy(int, com.heerkirov.hedge.server.library.compiler.grammar.definintion.KeyNotation, java.util.List<? extends com.heerkirov.hedge.server.library.compiler.grammar.definintion.Notation>);
    Code:
       0: aload_2
       1: ldc           #10                 // String key
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_3
       7: ldc           #18                 // String sequence
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: new           #2                  // class com/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxExpression
      15: dup
      16: iload_1
      17: aload_2
      18: aload_3
      19: invokespecial #48                 // Method "<init>":(ILcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;Ljava/util/List;)V
      22: areturn

  public static com.heerkirov.hedge.server.library.compiler.grammar.definintion.SyntaxExpression copy$default(com.heerkirov.hedge.server.library.compiler.grammar.definintion.SyntaxExpression, int, com.heerkirov.hedge.server.library.compiler.grammar.definintion.KeyNotation, java.util.List, int, java.lang.Object);
    Code:
       0: iload         4
       2: iconst_1
       3: iand
       4: ifeq          12
       7: aload_0
       8: getfield      #25                 // Field index:I
      11: istore_1
      12: iload         4
      14: iconst_2
      15: iand
      16: ifeq          24
      19: aload_0
      20: getfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
      23: astore_2
      24: iload         4
      26: iconst_4
      27: iand
      28: ifeq          36
      31: aload_0
      32: getfield      #31                 // Field sequence:Ljava/util/List;
      35: astore_3
      36: aload_0
      37: iload_1
      38: aload_2
      39: aload_3
      40: invokevirtual #52                 // Method copy:(ILcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;Ljava/util/List;)Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxExpression;
      43: areturn

  public java.lang.String toString();
    Code:
       0: new           #56                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #57                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #59                 // String SyntaxExpression(index=
       9: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #25                 // Field index:I
      16: invokevirtual #66                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      19: ldc           #68                 // String , key=
      21: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
      28: invokevirtual #71                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      31: ldc           #73                 // String , sequence=
      33: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      36: aload_0
      37: getfield      #31                 // Field sequence:Ljava/util/List;
      40: invokevirtual #71                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      43: bipush        41
      45: invokevirtual #76                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      48: invokevirtual #78                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      51: areturn

  public int hashCode();
    Code:
       0: aload_0
       1: getfield      #25                 // Field index:I
       4: invokestatic  #84                 // Method java/lang/Integer.hashCode:(I)I
       7: istore_1
       8: iload_1
       9: bipush        31
      11: imul
      12: aload_0
      13: getfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
      16: invokevirtual #88                 // Method com/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation.hashCode:()I
      19: iadd
      20: istore_1
      21: iload_1
      22: bipush        31
      24: imul
      25: aload_0
      26: getfield      #31                 // Field sequence:Ljava/util/List;
      29: invokevirtual #89                 // Method java/lang/Object.hashCode:()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/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxExpression
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class com/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxExpression
      20: astore_2
      21: aload_0
      22: getfield      #25                 // Field index:I
      25: aload_2
      26: getfield      #25                 // Field index:I
      29: if_icmpeq     34
      32: iconst_0
      33: ireturn
      34: aload_0
      35: getfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
      38: aload_2
      39: getfield      #28                 // Field key:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
      42: invokestatic  #97                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      45: ifne          50
      48: iconst_0
      49: ireturn
      50: aload_0
      51: getfield      #31                 // Field sequence:Ljava/util/List;
      54: aload_2
      55: getfield      #31                 // Field sequence:Ljava/util/List;
      58: invokestatic  #97                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      61: ifne          66
      64: iconst_0
      65: ireturn
      66: iconst_1
      67: ireturn
}

Compiled from "SyntaxExpression.kt"
public final class com.heerkirov.hedge.server.library.compiler.grammar.definintion.SyntaxExpressionKt {
  public static final java.util.List<com.heerkirov.hedge.server.library.compiler.grammar.definintion.SyntaxExpression> readSyntaxExpression(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String text
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #18                 // class java/lang/CharSequence
      10: iconst_1
      11: anewarray     #20                 // class java/lang/String
      14: astore_2
      15: aload_2
      16: iconst_0
      17: ldc           #22                 // String \n
      19: aastore
      20: aload_2
      21: iconst_0
      22: iconst_0
      23: bipush        6
      25: aconst_null
      26: invokestatic  #28                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      29: checkcast     #30                 // class java/lang/Iterable
      32: invokestatic  #36                 // Method kotlin/collections/CollectionsKt.asSequence:(Ljava/lang/Iterable;)Lkotlin/sequences/Sequence;
      35: invokedynamic #56,  0             // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
      40: invokestatic  #62                 // Method kotlin/sequences/SequencesKt.filter:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      43: invokedynamic #68,  0             // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function1;
      48: invokestatic  #71                 // Method kotlin/sequences/SequencesKt.map:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      51: invokedynamic #78,  0             // InvokeDynamic #2:invoke:()Lkotlin/jvm/functions/Function1;
      56: invokestatic  #71                 // Method kotlin/sequences/SequencesKt.map:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      59: invokestatic  #82                 // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
      62: astore_1
      63: aload_1
      64: checkcast     #30                 // class java/lang/Iterable
      67: invokestatic  #36                 // Method kotlin/collections/CollectionsKt.asSequence:(Ljava/lang/Iterable;)Lkotlin/sequences/Sequence;
      70: invokedynamic #89,  0             // InvokeDynamic #3:invoke:()Lkotlin/jvm/functions/Function1;
      75: invokestatic  #71                 // Method kotlin/sequences/SequencesKt.map:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      78: invokestatic  #93                 // Method kotlin/sequences/SequencesKt.toSet:(Lkotlin/sequences/Sequence;)Ljava/util/Set;
      81: astore_2
      82: aload_1
      83: checkcast     #30                 // class java/lang/Iterable
      86: astore_3
      87: iconst_0
      88: istore        4
      90: aload_3
      91: astore        5
      93: new           #95                 // class java/util/ArrayList
      96: dup
      97: aload_3
      98: bipush        10
     100: invokestatic  #99                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     103: invokespecial #103                // Method java/util/ArrayList."<init>":(I)V
     106: checkcast     #105                // class java/util/Collection
     109: astore        6
     111: iconst_0
     112: istore        7
     114: iconst_0
     115: istore        8
     117: aload         5
     119: invokeinterface #109,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     124: astore        9
     126: aload         9
     128: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     133: ifeq          385
     136: aload         9
     138: invokeinterface #119,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     143: astore        10
     145: aload         6
     147: iload         8
     149: iinc          8, 1
     152: istore        11
     154: iload         11
     156: ifge          162
     159: invokestatic  #123                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     162: iload         11
     164: aload         10
     166: checkcast     #125                // class kotlin/Pair
     169: astore        12
     171: istore        13
     173: astore        29
     175: iconst_0
     176: istore        14
     178: aload         12
     180: invokevirtual #128                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     183: checkcast     #20                 // class java/lang/String
     186: astore        15
     188: aload         12
     190: invokevirtual #131                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     193: checkcast     #133                // class java/util/List
     196: astore        16
     198: iload         13
     200: iconst_1
     201: iadd
     202: getstatic     #139                // Field com/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation.Companion:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation$Companion;
     205: aload         15
     207: invokevirtual #145                // Method com/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation$Companion.of:(Ljava/lang/String;)Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
     210: aload         16
     212: checkcast     #30                 // class java/lang/Iterable
     215: astore        17
     217: astore        18
     219: istore        19
     221: iconst_0
     222: istore        20
     224: aload         17
     226: astore        21
     228: new           #95                 // class java/util/ArrayList
     231: dup
     232: aload         17
     234: bipush        10
     236: invokestatic  #99                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     239: invokespecial #103                // Method java/util/ArrayList."<init>":(I)V
     242: checkcast     #105                // class java/util/Collection
     245: astore        22
     247: iconst_0
     248: istore        23
     250: aload         21
     252: invokeinterface #109,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     257: astore        24
     259: aload         24
     261: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     266: ifeq          340
     269: aload         24
     271: invokeinterface #119,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     276: astore        25
     278: aload         22
     280: aload         25
     282: checkcast     #20                 // class java/lang/String
     285: astore        26
     287: astore        27
     289: iconst_0
     290: istore        28
     292: aload_2
     293: aload         26
     295: invokeinterface #151,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     300: ifeq          317
     303: getstatic     #139                // Field com/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation.Companion:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation$Companion;
     306: aload         26
     308: invokevirtual #145                // Method com/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation$Companion.of:(Ljava/lang/String;)Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;
     311: checkcast     #153                // class com/heerkirov/hedge/server/library/compiler/grammar/definintion/Notation
     314: goto          328
     317: getstatic     #158                // Field com/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxNotation.Companion:Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxNotation$Companion;
     320: aload         26
     322: invokevirtual #163                // Method com/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxNotation$Companion.of:(Ljava/lang/String;)Lcom/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxNotation;
     325: checkcast     #153                // class com/heerkirov/hedge/server/library/compiler/grammar/definintion/Notation
     328: aload         27
     330: swap
     331: invokeinterface #166,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     336: pop
     337: goto          259
     340: aload         22
     342: checkcast     #133                // class java/util/List
     345: nop
     346: astore        27
     348: iload         19
     350: aload         18
     352: aload         27
     354: astore        30
     356: astore        31
     358: istore        32
     360: new           #168                // class com/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxExpression
     363: dup
     364: iload         32
     366: aload         31
     368: aload         30
     370: invokespecial #171                // Method com/heerkirov/hedge/server/library/compiler/grammar/definintion/SyntaxExpression."<init>":(ILcom/heerkirov/hedge/server/library/compiler/grammar/definintion/KeyNotation;Ljava/util/List;)V
     373: aload         29
     375: swap
     376: invokeinterface #166,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     381: pop
     382: goto          126
     385: aload         6
     387: checkcast     #133                // class java/util/List
     390: nop
     391: areturn

  private static final boolean readSyntaxExpression$lambda$0(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #198                // String it
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #18                 // class java/lang/CharSequence
      10: invokestatic  #202                // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
      13: ifne          20
      16: iconst_1
      17: goto          21
      20: iconst_0
      21: ireturn

  private static final java.util.List readSyntaxExpression$lambda$1(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #198                // String it
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #18                 // class java/lang/CharSequence
      10: astore_1
      11: new           #204                // class kotlin/text/Regex
      14: dup
      15: ldc           #206                // String \\s+
      17: invokespecial #209                // Method kotlin/text/Regex."<init>":(Ljava/lang/String;)V
      20: astore_2
      21: iconst_0
      22: istore_3
      23: aload_2
      24: aload_1
      25: iload_3
      26: invokevirtual #213                // Method kotlin/text/Regex.split:(Ljava/lang/CharSequence;I)Ljava/util/List;
      29: areturn

  private static final kotlin.Pair readSyntaxExpression$lambda$2(java.util.List);
    Code:
       0: aload_0
       1: ldc           #198                // String it
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #217,  1          // InterfaceMethod java/util/List.size:()I
      12: iconst_2
      13: if_icmplt     31
      16: aload_0
      17: iconst_1
      18: invokeinterface #221,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      23: ldc           #223                // String ->
      25: invokestatic  #227                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      28: ifne          82
      31: new           #229                // class java/lang/RuntimeException
      34: dup
      35: new           #231                // class java/lang/StringBuilder
      38: dup
      39: invokespecial #233                // Method java/lang/StringBuilder."<init>":()V
      42: ldc           #235                // String Expression [
      44: invokevirtual #239                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      47: aload_0
      48: checkcast     #30                 // class java/lang/Iterable
      51: ldc           #241                // String
      53: checkcast     #18                 // class java/lang/CharSequence
      56: aconst_null
      57: aconst_null
      58: iconst_0
      59: aconst_null
      60: aconst_null
      61: bipush        62
      63: aconst_null
      64: invokestatic  #245                // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
      67: invokevirtual #239                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      70: ldc           #247                // String ] is incorrect.
      72: invokevirtual #239                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      75: invokevirtual #251                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      78: invokespecial #252                // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
      81: athrow
      82: aload_0
      83: iconst_0
      84: invokeinterface #221,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      89: aload_0
      90: iconst_2
      91: aload_0
      92: invokeinterface #217,  1          // InterfaceMethod java/util/List.size:()I
      97: invokeinterface #256,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
     102: invokestatic  #262                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     105: areturn

  private static final java.lang.String readSyntaxExpression$lambda$3(kotlin.Pair);
    Code:
       0: aload_0
       1: ldc_w         #264                // String <destruct>
       4: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #128                // Method kotlin/Pair.component1:()Ljava/lang/Object;
      11: checkcast     #20                 // class java/lang/String
      14: astore_1
      15: aload_1
      16: areturn
}


package ch02

import java.util.*

/* fizzbuzz:
* - if any number is divisible by 3 = Fizz
* - if any number is divisible by 5 = Buzz
* - if number is divisible by both 3 and 5 = FizzBuzz */

fun fizzBuzz(i: Int) = when {
    i % 15 == 0 -> "FizzBuzz "
    i % 3 == 0 -> "Fizz "
    i % 5 == 0 -> "Buzz "
    else -> "$i "
}

fun exampleOne() {
    /*  kotlin doesn't bring anything new to the 'while' and 'do while' loops
     *  Kotlin has the 'for-each' loop
     */

    var count = 1
    while (count < 10) {
        println("count $count")
        count += 1
    }

    do {
         println("count $count")
         count -= 1
    } while (count > 0)
}

fun exampleTwo() {
    /* to define a range in kotlin, use the .. operator
    *  start..stop
    *
    * stop is always part of the range
    * */
    for (i in 1..100) {
        print(fizzBuzz(i))
    }
}

fun exampleThree() {
    /* for loop with a step */
    for (i in 100 downTo 1 step 2) {
        print(fizzBuzz(i))
    }
}

fun exampleFour() {
    /* you can use 'until'
    * for (x in number until size)
    *
    * Key difference between 1..10 and 1 until 10 is that
    *
    *   - 1..10 includes the stop number
    *   - 1 until 10 does not include the stop number
    *
    * */
    for (i in 1 until 30) {
        print(fizzBuzz(i))
    }
}

fun exampleFive() {
    /* iterating over maps */
    val binaryReps = TreeMap<Char, String>()

    /* the .. syntax for creating ranges works not only for numbers by for
     * characters as well
     */
    for (c in 'A'..'F') {
        val binary = Integer.toBinaryString(c.toInt())
        binaryReps[c] = binary
    }

    for ((letter, binary) in binaryReps) {
        println("$letter = $binary")
    }
}

fun exampleSix(){
    val list = arrayListOf("10", "11", "1001")
    for ((index, element) in list.withIndex()) {
        println("$index: $element")
    }
}

fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
fun isNotDigt(c: Char) = c !in '0'..'9'

fun exampleSeven() {
    println(isLetter('q'))
    println(isNotDigt('x'))
}

fun recognize(c: Char): String {
    var s = when (c) {
        in '0'..'9' -> "It's a digit!"
        in 'a'..'z' -> "It's a lowercase letter!"
        in 'A'..'Z' -> "It's a uppercase letter!"
        else -> "I don't know ..."
    }
    return s
}

fun main(args: Array<String>) {
   println(recognize('Z'))
}

Compiled from "iterations.kt"
public final class ch02.IterationsKt {
  public static final java.lang.String fizzBuzz(int);
    Code:
       0: nop
       1: iload_0
       2: bipush        15
       4: irem
       5: ifne          13
       8: ldc           #9                  // String FizzBuzz
      10: goto          54
      13: iload_0
      14: iconst_3
      15: irem
      16: ifne          24
      19: ldc           #11                 // String Fizz
      21: goto          54
      24: iload_0
      25: iconst_5
      26: irem
      27: ifne          35
      30: ldc           #13                 // String Buzz
      32: goto          54
      35: new           #15                 // class java/lang/StringBuilder
      38: dup
      39: invokespecial #19                 // Method java/lang/StringBuilder."<init>":()V
      42: iload_0
      43: invokevirtual #23                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      46: bipush        32
      48: invokevirtual #26                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      51: invokevirtual #30                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      54: areturn

  public static final void exampleOne();
    Code:
       0: iconst_1
       1: istore_0
       2: iload_0
       3: bipush        10
       5: if_icmpge     40
       8: new           #15                 // class java/lang/StringBuilder
      11: dup
      12: invokespecial #19                 // Method java/lang/StringBuilder."<init>":()V
      15: ldc           #37                 // String count
      17: invokevirtual #40                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      20: iload_0
      21: invokevirtual #23                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      24: invokevirtual #30                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      27: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      30: swap
      31: invokevirtual #52                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      34: iinc          0, 1
      37: goto          2
      40: new           #15                 // class java/lang/StringBuilder
      43: dup
      44: invokespecial #19                 // Method java/lang/StringBuilder."<init>":()V
      47: ldc           #37                 // String count
      49: invokevirtual #40                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      52: iload_0
      53: invokevirtual #23                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      56: invokevirtual #30                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      59: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      62: swap
      63: invokevirtual #52                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      66: iinc          0, -1
      69: iload_0
      70: ifgt          40
      73: return

  public static final void exampleTwo();
    Code:
       0: iconst_1
       1: istore_0
       2: iload_0
       3: bipush        101
       5: if_icmpge     25
       8: iload_0
       9: invokestatic  #56                 // Method fizzBuzz:(I)Ljava/lang/String;
      12: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      15: swap
      16: invokevirtual #59                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      19: iinc          0, 1
      22: goto          2
      25: return

  public static final void exampleThree();
    Code:
       0: bipush        100
       2: istore_0
       3: bipush        100
       5: iconst_1
       6: bipush        -2
       8: invokestatic  #66                 // Method kotlin/internal/ProgressionUtilKt.getProgressionLastElement:(III)I
      11: istore_1
      12: iload_1
      13: iload_0
      14: if_icmpgt     39
      17: iload_0
      18: invokestatic  #56                 // Method fizzBuzz:(I)Ljava/lang/String;
      21: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      24: swap
      25: invokevirtual #59                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      28: iload_0
      29: iload_1
      30: if_icmpeq     39
      33: iinc          0, -2
      36: goto          17
      39: return

  public static final void exampleFour();
    Code:
       0: iconst_1
       1: istore_0
       2: iload_0
       3: bipush        30
       5: if_icmpge     25
       8: iload_0
       9: invokestatic  #56                 // Method fizzBuzz:(I)Ljava/lang/String;
      12: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      15: swap
      16: invokevirtual #59                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      19: iinc          0, 1
      22: goto          2
      25: return

  public static final void exampleFive();
    Code:
       0: new           #70                 // class java/util/TreeMap
       3: dup
       4: invokespecial #71                 // Method java/util/TreeMap."<init>":()V
       7: astore_0
       8: bipush        65
      10: istore_1
      11: iload_1
      12: bipush        71
      14: if_icmpge     49
      17: iload_1
      18: invokestatic  #76                 // Method java/lang/Integer.toBinaryString:(I)Ljava/lang/String;
      21: astore_2
      22: iload_1
      23: invokestatic  #82                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      26: astore        4
      28: aload_0
      29: checkcast     #84                 // class java/util/Map
      32: aload         4
      34: aload_2
      35: invokeinterface #88,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      40: pop
      41: iload_1
      42: iconst_1
      43: iadd
      44: i2c
      45: istore_1
      46: goto          11
      49: aload_0
      50: checkcast     #84                 // class java/util/Map
      53: invokeinterface #92,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      58: invokeinterface #98,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      63: astore_1
      64: aload_1
      65: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      70: ifeq          141
      73: aload_1
      74: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      79: checkcast     #110                // class java/util/Map$Entry
      82: astore_2
      83: aload_2
      84: invokeinterface #113,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
      89: checkcast     #78                 // class java/lang/Character
      92: invokevirtual #117                // Method java/lang/Character.charValue:()C
      95: istore_3
      96: aload_2
      97: invokeinterface #120,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     102: checkcast     #34                 // class java/lang/String
     105: astore        4
     107: new           #15                 // class java/lang/StringBuilder
     110: dup
     111: invokespecial #19                 // Method java/lang/StringBuilder."<init>":()V
     114: iload_3
     115: invokevirtual #26                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     118: ldc           #122                // String  =
     120: invokevirtual #40                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     123: aload         4
     125: invokevirtual #40                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     128: invokevirtual #30                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     131: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
     134: swap
     135: invokevirtual #52                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     138: goto          64
     141: return

  public static final void exampleSix();
    Code:
       0: iconst_3
       1: anewarray     #34                 // class java/lang/String
       4: astore_1
       5: aload_1
       6: iconst_0
       7: ldc           #132                // String 10
       9: aastore
      10: aload_1
      11: iconst_1
      12: ldc           #134                // String 11
      14: aastore
      15: aload_1
      16: iconst_2
      17: ldc           #136                // String 1001
      19: aastore
      20: aload_1
      21: invokestatic  #142                // Method kotlin/collections/CollectionsKt.arrayListOf:([Ljava/lang/Object;)Ljava/util/ArrayList;
      24: astore_0
      25: aload_0
      26: checkcast     #144                // class java/lang/Iterable
      29: invokeinterface #145,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      34: astore_1
      35: iconst_0
      36: istore_2
      37: aload_1
      38: invokeinterface #104,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      43: ifeq          97
      46: iload_2
      47: istore_3
      48: iload_2
      49: iconst_1
      50: iadd
      51: istore_2
      52: aload_1
      53: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      58: checkcast     #34                 // class java/lang/String
      61: astore        4
      63: new           #15                 // class java/lang/StringBuilder
      66: dup
      67: invokespecial #19                 // Method java/lang/StringBuilder."<init>":()V
      70: iload_3
      71: invokevirtual #23                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      74: ldc           #147                // String :
      76: invokevirtual #40                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      79: aload         4
      81: invokevirtual #40                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      84: invokevirtual #30                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      87: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      90: swap
      91: invokevirtual #52                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      94: goto          37
      97: return

  public static final boolean isLetter(char);
    Code:
       0: bipush        97
       2: iload_0
       3: if_icmpgt     20
       6: iload_0
       7: bipush        123
       9: if_icmpge     16
      12: iconst_1
      13: goto          21
      16: iconst_0
      17: goto          21
      20: iconst_0
      21: ifne          48
      24: bipush        65
      26: iload_0
      27: if_icmpgt     44
      30: iload_0
      31: bipush        91
      33: if_icmpge     40
      36: iconst_1
      37: goto          45
      40: iconst_0
      41: goto          45
      44: iconst_0
      45: ifeq          52
      48: iconst_1
      49: goto          53
      52: iconst_0
      53: ireturn

  public static final boolean isNotDigt(char);
    Code:
       0: bipush        48
       2: iload_0
       3: if_icmpgt     20
       6: iload_0
       7: bipush        58
       9: if_icmpge     16
      12: iconst_1
      13: goto          21
      16: iconst_0
      17: goto          21
      20: iconst_0
      21: ifne          28
      24: iconst_1
      25: goto          29
      28: iconst_0
      29: ireturn

  public static final void exampleSeven();
    Code:
       0: bipush        113
       2: invokestatic  #159                // Method isLetter:(C)Z
       5: istore_0
       6: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: iload_0
      10: invokevirtual #162                // Method java/io/PrintStream.println:(Z)V
      13: bipush        120
      15: invokestatic  #164                // Method isNotDigt:(C)Z
      18: istore_0
      19: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      22: iload_0
      23: invokevirtual #162                // Method java/io/PrintStream.println:(Z)V
      26: return

  public static final java.lang.String recognize(char);
    Code:
       0: iload_0
       1: istore_2
       2: bipush        48
       4: iload_2
       5: if_icmpgt     22
       8: iload_2
       9: bipush        58
      11: if_icmpge     18
      14: iconst_1
      15: goto          23
      18: iconst_0
      19: goto          23
      22: iconst_0
      23: ifeq          31
      26: ldc           #168                // String It\'s a digit!
      28: goto          91
      31: bipush        97
      33: iload_2
      34: if_icmpgt     51
      37: iload_2
      38: bipush        123
      40: if_icmpge     47
      43: iconst_1
      44: goto          52
      47: iconst_0
      48: goto          52
      51: iconst_0
      52: ifeq          60
      55: ldc           #170                // String It\'s a lowercase letter!
      57: goto          91
      60: bipush        65
      62: iload_2
      63: if_icmpgt     80
      66: iload_2
      67: bipush        91
      69: if_icmpge     76
      72: iconst_1
      73: goto          81
      76: iconst_0
      77: goto          81
      80: iconst_0
      81: ifeq          89
      84: ldc           #172                // String It\'s a uppercase letter!
      86: goto          91
      89: ldc           #174                // String I don\'t know ...
      91: astore_1
      92: aload_1
      93: areturn

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #179                // String args
       3: invokestatic  #185                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: bipush        90
       8: invokestatic  #187                // Method recognize:(C)Ljava/lang/String;
      11: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      14: swap
      15: invokevirtual #52                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      18: return
}


package com.github.brpeterman.advent2022

class RpsSim {
    fun simulateAndScore(plays: List<Pair<String, String>>): Int {
        return plays.fold(0, { total, play ->
            total + scorePlay(play.first, toPlay(play.second))
        })
    }

    fun strategizeAndScore(plays: List<Pair<String, String>>): Int {
        return plays.fold(0, {total, play ->
            total + scorePlay(play.first, choosePlay(play.first, play.second))
        })
    }

    fun toPlay(play: String): String {
        return when (play) {
            ME_ROCK -> ROCK
            ME_PAPER -> PAPER
            ME_SCISSORS -> SCISSORS
            else -> throw IllegalStateException("Unexpected play: ${play}")
        }
    }

    fun choosePlay(opponent: String, outcome: String): String {
        if (outcome == WIN) {
            return when (opponent) {
                ROCK -> PAPER
                PAPER -> SCISSORS
                SCISSORS -> ROCK
                else -> throw IllegalStateException("Unexpected move: ${opponent}")
            }
        }
        if (outcome == LOSE) {
            return when (opponent) {
                ROCK -> SCISSORS
                PAPER -> ROCK
                SCISSORS -> PAPER
                else -> throw IllegalStateException("Unexpected move: ${opponent}")
            }
        }
        return opponent
    }

    fun scorePlay(opponent: String, me: String): Int {
        var score = SCORES[me]!!
        if (opponent == me) {
            score += 3
        } else if ((opponent == ROCK && me == PAPER) ||
            (opponent == PAPER && me == SCISSORS) ||
            (opponent == SCISSORS && me == ROCK)) {
            score += 6
        }
        return score
    }

    companion object {
        // I had these in nice typesafe enums and then part 2 showed up 😐
        val ROCK = "A"
        val PAPER = "B"
        val SCISSORS = "C"
        val ME_ROCK = "X"
        val ME_PAPER = "Y"
        val ME_SCISSORS = "Z"
        val LOSE = "X"
        val WIN = "Z"
        val SCORES = mapOf(
            Pair(ROCK, 1),
            Pair(PAPER, 2),
            Pair(SCISSORS, 3))

        fun parseInput(input: String): List<Pair<String, String>> {
            return input.split("\n")
                .filter { it.isNotBlank() }
                .map { line ->
                    val (left, right) = line.split(" ")
                    Pair(left, right)
                }
        }
    }
}

Compiled from "RpsSim.kt"
public final class com.github.brpeterman.advent2022.RpsSim {
  public static final com.github.brpeterman.advent2022.RpsSim$Companion Companion;

  private static final java.lang.String ROCK;

  private static final java.lang.String PAPER;

  private static final java.lang.String SCISSORS;

  private static final java.lang.String ME_ROCK;

  private static final java.lang.String ME_PAPER;

  private static final java.lang.String ME_SCISSORS;

  private static final java.lang.String LOSE;

  private static final java.lang.String WIN;

  private static final java.util.Map<java.lang.String, java.lang.Integer> SCORES;

  public com.github.brpeterman.advent2022.RpsSim();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final int simulateAndScore(java.util.List<kotlin.Pair<java.lang.String, java.lang.String>>);
    Code:
       0: aload_1
       1: ldc           #16                 // String plays
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: checkcast     #24                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: iconst_0
      14: istore        4
      16: iload_3
      17: istore        5
      19: aload_2
      20: invokeinterface #28,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      25: astore        6
      27: aload         6
      29: invokeinterface #34,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      34: ifeq          92
      37: aload         6
      39: invokeinterface #38,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      44: astore        7
      46: iload         5
      48: aload         7
      50: checkcast     #40                 // class kotlin/Pair
      53: astore        8
      55: istore        9
      57: iconst_0
      58: istore        10
      60: iload         9
      62: aload_0
      63: aload         8
      65: invokevirtual #43                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      68: checkcast     #45                 // class java/lang/String
      71: aload_0
      72: aload         8
      74: invokevirtual #48                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      77: checkcast     #45                 // class java/lang/String
      80: invokevirtual #52                 // Method toPlay:(Ljava/lang/String;)Ljava/lang/String;
      83: invokevirtual #56                 // Method scorePlay:(Ljava/lang/String;Ljava/lang/String;)I
      86: iadd
      87: istore        5
      89: goto          27
      92: iload         5
      94: ireturn

  public final int strategizeAndScore(java.util.List<kotlin.Pair<java.lang.String, java.lang.String>>);
    Code:
       0: aload_1
       1: ldc           #16                 // String plays
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: checkcast     #24                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: iconst_0
      14: istore        4
      16: iload_3
      17: istore        5
      19: aload_2
      20: invokeinterface #28,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      25: astore        6
      27: aload         6
      29: invokeinterface #34,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      34: ifeq          100
      37: aload         6
      39: invokeinterface #38,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      44: astore        7
      46: iload         5
      48: aload         7
      50: checkcast     #40                 // class kotlin/Pair
      53: astore        8
      55: istore        9
      57: iconst_0
      58: istore        10
      60: iload         9
      62: aload_0
      63: aload         8
      65: invokevirtual #43                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      68: checkcast     #45                 // class java/lang/String
      71: aload_0
      72: aload         8
      74: invokevirtual #43                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      77: checkcast     #45                 // class java/lang/String
      80: aload         8
      82: invokevirtual #48                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      85: checkcast     #45                 // class java/lang/String
      88: invokevirtual #76                 // Method choosePlay:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
      91: invokevirtual #56                 // Method scorePlay:(Ljava/lang/String;Ljava/lang/String;)I
      94: iadd
      95: istore        5
      97: goto          27
     100: iload         5
     102: ireturn

  public final java.lang.String toPlay(java.lang.String);
    Code:
       0: aload_1
       1: ldc           #78                 // String play
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: astore_2
       8: aload_2
       9: getstatic     #82                 // Field ME_ROCK:Ljava/lang/String;
      12: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      15: ifeq          24
      18: getstatic     #89                 // Field ROCK:Ljava/lang/String;
      21: goto          83
      24: aload_2
      25: getstatic     #92                 // Field ME_PAPER:Ljava/lang/String;
      28: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      31: ifeq          40
      34: getstatic     #95                 // Field PAPER:Ljava/lang/String;
      37: goto          83
      40: aload_2
      41: getstatic     #98                 // Field ME_SCISSORS:Ljava/lang/String;
      44: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      47: ifeq          56
      50: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
      53: goto          83
      56: new           #103                // class java/lang/IllegalStateException
      59: dup
      60: new           #105                // class java/lang/StringBuilder
      63: dup
      64: invokespecial #106                // Method java/lang/StringBuilder."<init>":()V
      67: ldc           #108                // String Unexpected play:
      69: invokevirtual #112                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      72: aload_1
      73: invokevirtual #112                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      76: invokevirtual #116                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      79: invokespecial #119                // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      82: athrow
      83: areturn

  public final java.lang.String choosePlay(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #121                // String opponent
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #123                // String outcome
       9: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_2
      13: getstatic     #126                // Field WIN:Ljava/lang/String;
      16: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      19: ifeq          100
      22: aload_1
      23: astore_3
      24: aload_3
      25: getstatic     #89                 // Field ROCK:Ljava/lang/String;
      28: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      31: ifeq          40
      34: getstatic     #95                 // Field PAPER:Ljava/lang/String;
      37: goto          99
      40: aload_3
      41: getstatic     #95                 // Field PAPER:Ljava/lang/String;
      44: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      47: ifeq          56
      50: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
      53: goto          99
      56: aload_3
      57: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
      60: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      63: ifeq          72
      66: getstatic     #89                 // Field ROCK:Ljava/lang/String;
      69: goto          99
      72: new           #103                // class java/lang/IllegalStateException
      75: dup
      76: new           #105                // class java/lang/StringBuilder
      79: dup
      80: invokespecial #106                // Method java/lang/StringBuilder."<init>":()V
      83: ldc           #128                // String Unexpected move:
      85: invokevirtual #112                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      88: aload_1
      89: invokevirtual #112                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      92: invokevirtual #116                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      95: invokespecial #119                // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      98: athrow
      99: areturn
     100: aload_2
     101: getstatic     #131                // Field LOSE:Ljava/lang/String;
     104: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     107: ifeq          188
     110: aload_1
     111: astore_3
     112: aload_3
     113: getstatic     #89                 // Field ROCK:Ljava/lang/String;
     116: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     119: ifeq          128
     122: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
     125: goto          187
     128: aload_3
     129: getstatic     #95                 // Field PAPER:Ljava/lang/String;
     132: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     135: ifeq          144
     138: getstatic     #89                 // Field ROCK:Ljava/lang/String;
     141: goto          187
     144: aload_3
     145: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
     148: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     151: ifeq          160
     154: getstatic     #95                 // Field PAPER:Ljava/lang/String;
     157: goto          187
     160: new           #103                // class java/lang/IllegalStateException
     163: dup
     164: new           #105                // class java/lang/StringBuilder
     167: dup
     168: invokespecial #106                // Method java/lang/StringBuilder."<init>":()V
     171: ldc           #128                // String Unexpected move:
     173: invokevirtual #112                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     176: aload_1
     177: invokevirtual #112                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     180: invokevirtual #116                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     183: invokespecial #119                // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     186: athrow
     187: areturn
     188: aload_1
     189: areturn

  public final int scorePlay(java.lang.String, java.lang.String);
    Code:
       0: aload_1
       1: ldc           #121                // String opponent
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #133                // String me
       9: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: getstatic     #137                // Field SCORES:Ljava/util/Map;
      15: aload_2
      16: invokeinterface #143,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      21: dup
      22: invokestatic  #147                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      25: checkcast     #149                // class java/lang/Number
      28: invokevirtual #153                // Method java/lang/Number.intValue:()I
      31: istore_3
      32: aload_1
      33: aload_2
      34: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      37: ifeq          46
      40: iinc          3, 3
      43: goto          109
      46: aload_1
      47: getstatic     #89                 // Field ROCK:Ljava/lang/String;
      50: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      53: ifeq          66
      56: aload_2
      57: getstatic     #95                 // Field PAPER:Ljava/lang/String;
      60: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      63: ifne          106
      66: aload_1
      67: getstatic     #95                 // Field PAPER:Ljava/lang/String;
      70: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      73: ifeq          86
      76: aload_2
      77: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
      80: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      83: ifne          106
      86: aload_1
      87: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
      90: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      93: ifeq          109
      96: aload_2
      97: getstatic     #89                 // Field ROCK:Ljava/lang/String;
     100: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     103: ifeq          109
     106: iinc          3, 6
     109: iload_3
     110: ireturn

  public static final java.lang.String access$getROCK$cp();
    Code:
       0: getstatic     #89                 // Field ROCK:Ljava/lang/String;
       3: areturn

  public static final java.lang.String access$getPAPER$cp();
    Code:
       0: getstatic     #95                 // Field PAPER:Ljava/lang/String;
       3: areturn

  public static final java.lang.String access$getSCISSORS$cp();
    Code:
       0: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
       3: areturn

  public static final java.lang.String access$getME_ROCK$cp();
    Code:
       0: getstatic     #82                 // Field ME_ROCK:Ljava/lang/String;
       3: areturn

  public static final java.lang.String access$getME_PAPER$cp();
    Code:
       0: getstatic     #92                 // Field ME_PAPER:Ljava/lang/String;
       3: areturn

  public static final java.lang.String access$getME_SCISSORS$cp();
    Code:
       0: getstatic     #98                 // Field ME_SCISSORS:Ljava/lang/String;
       3: areturn

  public static final java.lang.String access$getLOSE$cp();
    Code:
       0: getstatic     #131                // Field LOSE:Ljava/lang/String;
       3: areturn

  public static final java.lang.String access$getWIN$cp();
    Code:
       0: getstatic     #126                // Field WIN:Ljava/lang/String;
       3: areturn

  public static final java.util.Map access$getSCORES$cp();
    Code:
       0: getstatic     #137                // Field SCORES:Ljava/util/Map;
       3: areturn

  static {};
    Code:
       0: new           #167                // class com/github/brpeterman/advent2022/RpsSim$Companion
       3: dup
       4: aconst_null
       5: invokespecial #170                // Method com/github/brpeterman/advent2022/RpsSim$Companion."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #174                // Field Companion:Lcom/github/brpeterman/advent2022/RpsSim$Companion;
      11: ldc           #176                // String A
      13: putstatic     #89                 // Field ROCK:Ljava/lang/String;
      16: ldc           #178                // String B
      18: putstatic     #95                 // Field PAPER:Ljava/lang/String;
      21: ldc           #180                // String C
      23: putstatic     #101                // Field SCISSORS:Ljava/lang/String;
      26: ldc           #182                // String X
      28: putstatic     #82                 // Field ME_ROCK:Ljava/lang/String;
      31: ldc           #184                // String Y
      33: putstatic     #92                 // Field ME_PAPER:Ljava/lang/String;
      36: ldc           #186                // String Z
      38: putstatic     #98                 // Field ME_SCISSORS:Ljava/lang/String;
      41: ldc           #182                // String X
      43: putstatic     #131                // Field LOSE:Ljava/lang/String;
      46: ldc           #186                // String Z
      48: putstatic     #126                // Field WIN:Ljava/lang/String;
      51: iconst_3
      52: anewarray     #40                 // class kotlin/Pair
      55: astore_0
      56: aload_0
      57: iconst_0
      58: new           #40                 // class kotlin/Pair
      61: dup
      62: getstatic     #89                 // Field ROCK:Ljava/lang/String;
      65: iconst_1
      66: invokestatic  #192                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      69: invokespecial #195                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      72: aastore
      73: aload_0
      74: iconst_1
      75: new           #40                 // class kotlin/Pair
      78: dup
      79: getstatic     #95                 // Field PAPER:Ljava/lang/String;
      82: iconst_2
      83: invokestatic  #192                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      86: invokespecial #195                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      89: aastore
      90: aload_0
      91: iconst_2
      92: new           #40                 // class kotlin/Pair
      95: dup
      96: getstatic     #101                // Field SCISSORS:Ljava/lang/String;
      99: iconst_3
     100: invokestatic  #192                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     103: invokespecial #195                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     106: aastore
     107: aload_0
     108: invokestatic  #201                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     111: putstatic     #137                // Field SCORES:Ljava/util/Map;
     114: return
}

Compiled from "RpsSim.kt"
public final class com.github.brpeterman.advent2022.RpsSim$Companion {
  private com.github.brpeterman.advent2022.RpsSim$Companion();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final java.lang.String getROCK();
    Code:
       0: invokestatic  #18                 // Method com/github/brpeterman/advent2022/RpsSim.access$getROCK$cp:()Ljava/lang/String;
       3: areturn

  public final java.lang.String getPAPER();
    Code:
       0: invokestatic  #22                 // Method com/github/brpeterman/advent2022/RpsSim.access$getPAPER$cp:()Ljava/lang/String;
       3: areturn

  public final java.lang.String getSCISSORS();
    Code:
       0: invokestatic  #26                 // Method com/github/brpeterman/advent2022/RpsSim.access$getSCISSORS$cp:()Ljava/lang/String;
       3: areturn

  public final java.lang.String getME_ROCK();
    Code:
       0: invokestatic  #30                 // Method com/github/brpeterman/advent2022/RpsSim.access$getME_ROCK$cp:()Ljava/lang/String;
       3: areturn

  public final java.lang.String getME_PAPER();
    Code:
       0: invokestatic  #34                 // Method com/github/brpeterman/advent2022/RpsSim.access$getME_PAPER$cp:()Ljava/lang/String;
       3: areturn

  public final java.lang.String getME_SCISSORS();
    Code:
       0: invokestatic  #38                 // Method com/github/brpeterman/advent2022/RpsSim.access$getME_SCISSORS$cp:()Ljava/lang/String;
       3: areturn

  public final java.lang.String getLOSE();
    Code:
       0: invokestatic  #42                 // Method com/github/brpeterman/advent2022/RpsSim.access$getLOSE$cp:()Ljava/lang/String;
       3: areturn

  public final java.lang.String getWIN();
    Code:
       0: invokestatic  #46                 // Method com/github/brpeterman/advent2022/RpsSim.access$getWIN$cp:()Ljava/lang/String;
       3: areturn

  public final java.util.Map<java.lang.String, java.lang.Integer> getSCORES();
    Code:
       0: invokestatic  #52                 // Method com/github/brpeterman/advent2022/RpsSim.access$getSCORES$cp:()Ljava/util/Map;
       3: areturn

  public final java.util.List<kotlin.Pair<java.lang.String, java.lang.String>> parseInput(java.lang.String);
    Code:
       0: aload_1
       1: ldc           #57                 // String input
       3: invokestatic  #63                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: checkcast     #65                 // class java/lang/CharSequence
      10: iconst_1
      11: anewarray     #67                 // class java/lang/String
      14: astore_2
      15: aload_2
      16: iconst_0
      17: ldc           #69                 // String \n
      19: aastore
      20: aload_2
      21: iconst_0
      22: iconst_0
      23: bipush        6
      25: aconst_null
      26: invokestatic  #75                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      29: checkcast     #77                 // class java/lang/Iterable
      32: astore_2
      33: nop
      34: iconst_0
      35: istore_3
      36: aload_2
      37: astore        4
      39: new           #79                 // class java/util/ArrayList
      42: dup
      43: invokespecial #80                 // Method java/util/ArrayList."<init>":()V
      46: checkcast     #82                 // class java/util/Collection
      49: astore        5
      51: iconst_0
      52: istore        6
      54: aload         4
      56: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      61: astore        7
      63: aload         7
      65: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      70: ifeq          125
      73: aload         7
      75: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      80: astore        8
      82: aload         8
      84: checkcast     #67                 // class java/lang/String
      87: astore        9
      89: iconst_0
      90: istore        10
      92: aload         9
      94: checkcast     #65                 // class java/lang/CharSequence
      97: invokestatic  #100                // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
     100: ifne          107
     103: iconst_1
     104: goto          108
     107: iconst_0
     108: nop
     109: ifeq          63
     112: aload         5
     114: aload         8
     116: invokeinterface #104,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     121: pop
     122: goto          63
     125: aload         5
     127: checkcast     #106                // class java/util/List
     130: nop
     131: checkcast     #77                 // class java/lang/Iterable
     134: astore_2
     135: nop
     136: iconst_0
     137: istore_3
     138: aload_2
     139: astore        4
     141: new           #79                 // class java/util/ArrayList
     144: dup
     145: aload_2
     146: bipush        10
     148: invokestatic  #112                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     151: invokespecial #115                // Method java/util/ArrayList."<init>":(I)V
     154: checkcast     #82                 // class java/util/Collection
     157: astore        5
     159: iconst_0
     160: istore        6
     162: aload         4
     164: invokeinterface #86,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     169: astore        7
     171: aload         7
     173: invokeinterface #92,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     178: ifeq          282
     181: aload         7
     183: invokeinterface #96,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     188: astore        8
     190: aload         5
     192: aload         8
     194: checkcast     #67                 // class java/lang/String
     197: astore        9
     199: astore        14
     201: iconst_0
     202: istore        10
     204: aload         9
     206: checkcast     #65                 // class java/lang/CharSequence
     209: iconst_1
     210: anewarray     #67                 // class java/lang/String
     213: astore        11
     215: aload         11
     217: iconst_0
     218: ldc           #117                // String
     220: aastore
     221: aload         11
     223: iconst_0
     224: iconst_0
     225: bipush        6
     227: aconst_null
     228: invokestatic  #75                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     231: astore        12
     233: aload         12
     235: iconst_0
     236: invokeinterface #121,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     241: checkcast     #67                 // class java/lang/String
     244: astore        11
     246: aload         12
     248: iconst_1
     249: invokeinterface #121,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     254: checkcast     #67                 // class java/lang/String
     257: astore        13
     259: new           #123                // class kotlin/Pair
     262: dup
     263: aload         11
     265: aload         13
     267: invokespecial #126                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     270: aload         14
     272: swap
     273: invokeinterface #104,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     278: pop
     279: goto          171
     282: aload         5
     284: checkcast     #106                // class java/util/List
     287: nop
     288: areturn

  public com.github.brpeterman.advent2022.RpsSim$Companion(kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: aload_0
       1: invokespecial #150                // Method "<init>":()V
       4: return
}