package com.aurelioklv.enigma.util

val alphabet = ('A'..'Z').joinToString(separator = "")
val defaultWiring: Map<Char, Char> = ('A'..'Z').associateWith { it }

fun validateWiring(wiring: Map<Char, Char>, kind: String) {
    require(wiring.isNotEmpty()) {
        "Wiring is empty"
    }

    require(wiring.all { (key, value) ->
        key.isLetter() && key.isUpperCase() && value.isLetter() && value.isUpperCase()
    }) {
        "Each character should be an uppercase letter"
    }

    when (kind) {
        in listOf("rotor", "plugboard") -> {
            require(alphabet.all { wiring.containsKey(it) && wiring.containsValue(it) })
        }

        "reflector" -> {
            require(wiring.all { (key, value) -> wiring.getOrDefault(value, ' ') == key }) {
                "Invalid wiring $wiring"
            }
        }
    }
    wiring.mapKeys { it.key.uppercaseChar() }.mapValues { it.value.uppercaseChar() }
}

fun String.toWiring(kind: String): Map<Char, Char> {
    val input = this.uppercase()
    val result = when (kind) {
        in listOf("rotor", "reflector") -> {
            require(input.length == alphabet.length) {
                "String must be ${alphabet.length} characters long. Got ${input.length}"
            }
            alphabet.zip(input).toMap()
        }

        "plugboard" -> {
            val wiring = input.chunked(2).flatMap { pair ->
                pair.map { it to pair[(pair.indexOf(it) + 1) % 2] }
            }.toMap().toMutableMap()
            val existingChar = input.toSet()
            wiring += defaultWiring.filterKeys { it !in existingChar }
            wiring
        }

        else -> {
            throw IllegalArgumentException("Unknown kind: $kind")
        }
    }
    return result
}

fun String.toListOfInt(): List<Int> {
    return map { char ->
        when {
            char.isLetter() -> char.uppercaseChar().minus('A')
            else -> throw IllegalArgumentException("Invalid character: $char")
        }
    }
}

Compiled from "Util.kt"
public final class com.aurelioklv.enigma.util.UtilKt {
  private static final java.lang.String alphabet;

  private static final java.util.Map<java.lang.Character, java.lang.Character> defaultWiring;

  public static final java.lang.String getAlphabet();
    Code:
       0: getstatic     #11                 // Field alphabet:Ljava/lang/String;
       3: areturn

  public static final java.util.Map<java.lang.Character, java.lang.Character> getDefaultWiring();
    Code:
       0: getstatic     #18                 // Field defaultWiring:Ljava/util/Map;
       3: areturn

  public static final void validateWiring(java.util.Map<java.lang.Character, java.lang.Character>, java.lang.String);
    Code:
       0: aload_0
       1: ldc           #23                 // String wiring
       3: invokestatic  #29                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #31                 // String kind
       9: invokestatic  #29                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokeinterface #37,  1           // InterfaceMethod java/util/Map.isEmpty:()Z
      18: ifne          25
      21: iconst_1
      22: goto          26
      25: iconst_0
      26: ifne          46
      29: iconst_0
      30: istore_3
      31: ldc           #39                 // String Wiring is empty
      33: astore_3
      34: new           #41                 // class java/lang/IllegalArgumentException
      37: dup
      38: aload_3
      39: invokevirtual #44                 // Method java/lang/Object.toString:()Ljava/lang/String;
      42: invokespecial #48                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
      45: athrow
      46: aload_0
      47: astore_2
      48: iconst_0
      49: istore_3
      50: aload_2
      51: invokeinterface #37,  1           // InterfaceMethod java/util/Map.isEmpty:()Z
      56: ifeq          63
      59: iconst_1
      60: goto          180
      63: aload_2
      64: invokeinterface #52,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      69: invokeinterface #58,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      74: astore        4
      76: aload         4
      78: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      83: ifeq          179
      86: aload         4
      88: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      93: checkcast     #69                 // class java/util/Map$Entry
      96: astore        5
      98: aload         5
     100: astore        6
     102: iconst_0
     103: istore        7
     105: aload         6
     107: invokeinterface #72,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     112: checkcast     #74                 // class java/lang/Character
     115: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     118: istore        8
     120: aload         6
     122: invokeinterface #81,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     127: checkcast     #74                 // class java/lang/Character
     130: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     133: istore        9
     135: iload         8
     137: invokestatic  #85                 // Method java/lang/Character.isLetter:(C)Z
     140: ifeq          171
     143: iload         8
     145: invokestatic  #88                 // Method java/lang/Character.isUpperCase:(C)Z
     148: ifeq          171
     151: iload         9
     153: invokestatic  #85                 // Method java/lang/Character.isLetter:(C)Z
     156: ifeq          171
     159: iload         9
     161: invokestatic  #88                 // Method java/lang/Character.isUpperCase:(C)Z
     164: ifeq          171
     167: iconst_1
     168: goto          172
     171: iconst_0
     172: ifne          76
     175: iconst_0
     176: goto          180
     179: iconst_1
     180: ifne          200
     183: iconst_0
     184: istore_3
     185: ldc           #90                 // String Each character should be an uppercase letter
     187: astore_3
     188: new           #41                 // class java/lang/IllegalArgumentException
     191: dup
     192: aload_3
     193: invokevirtual #44                 // Method java/lang/Object.toString:()Ljava/lang/String;
     196: invokespecial #48                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     199: athrow
     200: aload_1
     201: astore_2
     202: iconst_2
     203: anewarray     #92                 // class java/lang/String
     206: astore_3
     207: aload_3
     208: iconst_0
     209: ldc           #94                 // String rotor
     211: aastore
     212: aload_3
     213: iconst_1
     214: ldc           #96                 // String plugboard
     216: aastore
     217: aload_3
     218: invokestatic  #102                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     221: aload_2
     222: invokeinterface #108,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
     227: ifeq          338
     230: getstatic     #11                 // Field alphabet:Ljava/lang/String;
     233: checkcast     #110                // class java/lang/CharSequence
     236: astore_3
     237: iconst_0
     238: istore        4
     240: iconst_0
     241: istore        5
     243: iload         5
     245: aload_3
     246: invokeinterface #114,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     251: if_icmpge     317
     254: aload_3
     255: iload         5
     257: invokeinterface #118,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     262: istore        6
     264: iload         6
     266: istore        7
     268: iconst_0
     269: istore        8
     271: aload_0
     272: iload         7
     274: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     277: invokeinterface #125,  2          // InterfaceMethod java/util/Map.containsKey:(Ljava/lang/Object;)Z
     282: ifeq          303
     285: aload_0
     286: iload         7
     288: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     291: invokeinterface #128,  2          // InterfaceMethod java/util/Map.containsValue:(Ljava/lang/Object;)Z
     296: ifeq          303
     299: iconst_1
     300: goto          304
     303: iconst_0
     304: ifne          311
     307: iconst_0
     308: goto          318
     311: iinc          5, 1
     314: goto          243
     317: iconst_1
     318: ifne          517
     321: ldc           #130                // String Failed requirement.
     323: astore        4
     325: new           #41                 // class java/lang/IllegalArgumentException
     328: dup
     329: aload         4
     331: invokevirtual #44                 // Method java/lang/Object.toString:()Ljava/lang/String;
     334: invokespecial #48                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     337: athrow
     338: aload_2
     339: ldc           #132                // String reflector
     341: invokestatic  #136                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     344: ifeq          517
     347: aload_0
     348: astore_3
     349: iconst_0
     350: istore        4
     352: aload_3
     353: invokeinterface #37,  1           // InterfaceMethod java/util/Map.isEmpty:()Z
     358: ifeq          365
     361: iconst_1
     362: goto          477
     365: aload_3
     366: invokeinterface #52,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     371: invokeinterface #58,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
     376: astore        5
     378: aload         5
     380: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     385: ifeq          476
     388: aload         5
     390: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     395: checkcast     #69                 // class java/util/Map$Entry
     398: astore        6
     400: aload         6
     402: astore        7
     404: iconst_0
     405: istore        8
     407: aload         7
     409: invokeinterface #72,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     414: checkcast     #74                 // class java/lang/Character
     417: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     420: istore        9
     422: aload         7
     424: invokeinterface #81,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     429: checkcast     #74                 // class java/lang/Character
     432: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     435: istore        10
     437: aload_0
     438: iload         10
     440: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     443: bipush        32
     445: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     448: invokeinterface #140,  3          // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     453: checkcast     #74                 // class java/lang/Character
     456: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     459: iload         9
     461: if_icmpne     468
     464: iconst_1
     465: goto          469
     468: iconst_0
     469: ifne          378
     472: iconst_0
     473: goto          477
     476: iconst_1
     477: ifne          517
     480: iconst_0
     481: istore        4
     483: new           #142                // class java/lang/StringBuilder
     486: dup
     487: invokespecial #145                // Method java/lang/StringBuilder."<init>":()V
     490: ldc           #147                // String Invalid wiring
     492: invokevirtual #151                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     495: aload_0
     496: invokevirtual #154                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     499: invokevirtual #155                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     502: astore        4
     504: new           #41                 // class java/lang/IllegalArgumentException
     507: dup
     508: aload         4
     510: invokevirtual #44                 // Method java/lang/Object.toString:()Ljava/lang/String;
     513: invokespecial #48                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     516: athrow
     517: aload_0
     518: astore_2
     519: iconst_0
     520: istore_3
     521: aload_2
     522: astore        4
     524: new           #157                // class java/util/LinkedHashMap
     527: dup
     528: aload_2
     529: invokeinterface #160,  1          // InterfaceMethod java/util/Map.size:()I
     534: invokestatic  #166                // Method kotlin/collections/MapsKt.mapCapacity:(I)I
     537: invokespecial #169                // Method java/util/LinkedHashMap."<init>":(I)V
     540: checkcast     #33                 // class java/util/Map
     543: astore        5
     545: iconst_0
     546: istore        6
     548: aload         4
     550: invokeinterface #52,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     555: checkcast     #171                // class java/lang/Iterable
     558: astore        7
     560: iconst_0
     561: istore        8
     563: aload         7
     565: invokeinterface #172,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     570: astore        9
     572: aload         9
     574: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     579: ifeq          666
     582: aload         9
     584: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     589: astore        10
     591: aload         5
     593: aload         10
     595: checkcast     #69                 // class java/util/Map$Entry
     598: astore        11
     600: astore        17
     602: iconst_0
     603: istore        12
     605: aload         11
     607: invokeinterface #72,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     612: checkcast     #74                 // class java/lang/Character
     615: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     618: invokestatic  #176                // Method java/lang/Character.toUpperCase:(C)C
     621: nop
     622: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     625: aload         17
     627: swap
     628: aload         10
     630: checkcast     #69                 // class java/util/Map$Entry
     633: astore        13
     635: astore        14
     637: astore        15
     639: iconst_0
     640: istore        16
     642: aload         13
     644: invokeinterface #81,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     649: astore        11
     651: aload         15
     653: aload         14
     655: aload         11
     657: invokeinterface #179,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     662: pop
     663: goto          572
     666: aload         5
     668: nop
     669: nop
     670: astore_2
     671: nop
     672: iconst_0
     673: istore_3
     674: aload_2
     675: astore        4
     677: new           #157                // class java/util/LinkedHashMap
     680: dup
     681: aload_2
     682: invokeinterface #160,  1          // InterfaceMethod java/util/Map.size:()I
     687: invokestatic  #166                // Method kotlin/collections/MapsKt.mapCapacity:(I)I
     690: invokespecial #169                // Method java/util/LinkedHashMap."<init>":(I)V
     693: checkcast     #33                 // class java/util/Map
     696: astore        5
     698: iconst_0
     699: istore        6
     701: aload         4
     703: invokeinterface #52,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     708: checkcast     #171                // class java/lang/Iterable
     711: astore        7
     713: iconst_0
     714: istore        8
     716: aload         7
     718: invokeinterface #172,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     723: astore        9
     725: aload         9
     727: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     732: ifeq          819
     735: aload         9
     737: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     742: astore        10
     744: aload         5
     746: aload         10
     748: checkcast     #69                 // class java/util/Map$Entry
     751: astore        11
     753: astore        12
     755: iconst_0
     756: istore        13
     758: aload         11
     760: invokeinterface #72,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     765: aload         12
     767: swap
     768: aload         10
     770: checkcast     #69                 // class java/util/Map$Entry
     773: astore        14
     775: astore        18
     777: astore        17
     779: iconst_0
     780: istore        15
     782: aload         14
     784: invokeinterface #81,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     789: checkcast     #74                 // class java/lang/Character
     792: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     795: invokestatic  #176                // Method java/lang/Character.toUpperCase:(C)C
     798: nop
     799: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     802: astore        19
     804: aload         17
     806: aload         18
     808: aload         19
     810: invokeinterface #179,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     815: pop
     816: goto          725
     819: nop
     820: nop
     821: nop
     822: return

  public static final java.util.Map<java.lang.Character, java.lang.Character> toWiring(java.lang.String, java.lang.String);
    Code:
       0: aload_0
       1: ldc           #221                // String <this>
       3: invokestatic  #29                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #31                 // String kind
       9: invokestatic  #29                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: getstatic     #227                // Field java/util/Locale.ROOT:Ljava/util/Locale;
      16: invokevirtual #230                // Method java/lang/String.toUpperCase:(Ljava/util/Locale;)Ljava/lang/String;
      19: dup
      20: ldc           #232                // String toUpperCase(...)
      22: invokestatic  #235                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      25: astore_2
      26: aload_1
      27: astore        4
      29: iconst_2
      30: anewarray     #92                 // class java/lang/String
      33: astore        5
      35: aload         5
      37: iconst_0
      38: ldc           #94                 // String rotor
      40: aastore
      41: aload         5
      43: iconst_1
      44: ldc           #132                // String reflector
      46: aastore
      47: aload         5
      49: invokestatic  #102                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      52: aload         4
      54: invokeinterface #108,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
      59: ifeq          159
      62: aload_2
      63: invokevirtual #236                // Method java/lang/String.length:()I
      66: getstatic     #11                 // Field alphabet:Ljava/lang/String;
      69: invokevirtual #236                // Method java/lang/String.length:()I
      72: if_icmpne     79
      75: iconst_1
      76: goto          80
      79: iconst_0
      80: ifne          137
      83: iconst_0
      84: istore        6
      86: new           #142                // class java/lang/StringBuilder
      89: dup
      90: invokespecial #145                // Method java/lang/StringBuilder."<init>":()V
      93: ldc           #238                // String String must be
      95: invokevirtual #151                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      98: getstatic     #11                 // Field alphabet:Ljava/lang/String;
     101: invokevirtual #236                // Method java/lang/String.length:()I
     104: invokevirtual #241                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     107: ldc           #243                // String  characters long. Got
     109: invokevirtual #151                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     112: aload_2
     113: invokevirtual #236                // Method java/lang/String.length:()I
     116: invokevirtual #241                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     119: invokevirtual #155                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     122: astore        6
     124: new           #41                 // class java/lang/IllegalArgumentException
     127: dup
     128: aload         6
     130: invokevirtual #44                 // Method java/lang/Object.toString:()Ljava/lang/String;
     133: invokespecial #48                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     136: athrow
     137: getstatic     #11                 // Field alphabet:Ljava/lang/String;
     140: checkcast     #110                // class java/lang/CharSequence
     143: aload_2
     144: checkcast     #110                // class java/lang/CharSequence
     147: invokestatic  #249                // Method kotlin/text/StringsKt.zip:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/List;
     150: checkcast     #171                // class java/lang/Iterable
     153: invokestatic  #253                // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
     156: goto          584
     159: aload         4
     161: ldc           #96                 // String plugboard
     163: invokestatic  #136                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     166: ifeq          556
     169: aload_2
     170: checkcast     #110                // class java/lang/CharSequence
     173: iconst_2
     174: invokestatic  #257                // Method kotlin/text/StringsKt.chunked:(Ljava/lang/CharSequence;I)Ljava/util/List;
     177: checkcast     #171                // class java/lang/Iterable
     180: astore        6
     182: iconst_0
     183: istore        7
     185: aload         6
     187: astore        8
     189: new           #259                // class java/util/ArrayList
     192: dup
     193: invokespecial #260                // Method java/util/ArrayList."<init>":()V
     196: checkcast     #262                // class java/util/Collection
     199: astore        9
     201: iconst_0
     202: istore        10
     204: aload         8
     206: invokeinterface #172,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     211: astore        11
     213: aload         11
     215: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     220: ifeq          388
     223: aload         11
     225: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     230: astore        12
     232: aload         12
     234: checkcast     #92                 // class java/lang/String
     237: astore        13
     239: iconst_0
     240: istore        14
     242: aload         13
     244: checkcast     #110                // class java/lang/CharSequence
     247: astore        15
     249: iconst_0
     250: istore        16
     252: aload         15
     254: astore        17
     256: new           #259                // class java/util/ArrayList
     259: dup
     260: aload         15
     262: invokeinterface #114,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     267: invokespecial #263                // Method java/util/ArrayList."<init>":(I)V
     270: checkcast     #262                // class java/util/Collection
     273: astore        18
     275: iconst_0
     276: istore        19
     278: iconst_0
     279: istore        20
     281: iload         20
     283: aload         17
     285: invokeinterface #114,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     290: if_icmpge     365
     293: aload         17
     295: iload         20
     297: invokeinterface #118,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     302: istore        21
     304: aload         18
     306: iload         21
     308: istore        22
     310: astore        23
     312: iconst_0
     313: istore        24
     315: iload         22
     317: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     320: aload         13
     322: aload         13
     324: checkcast     #110                // class java/lang/CharSequence
     327: iload         22
     329: iconst_0
     330: iconst_0
     331: bipush        6
     333: aconst_null
     334: invokestatic  #267                // Method kotlin/text/StringsKt.indexOf$default:(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
     337: iconst_1
     338: iadd
     339: iconst_2
     340: irem
     341: invokevirtual #268                // Method java/lang/String.charAt:(I)C
     344: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     347: invokestatic  #274                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     350: aload         23
     352: swap
     353: invokeinterface #277,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     358: pop
     359: iinc          20, 1
     362: goto          281
     365: aload         18
     367: checkcast     #104                // class java/util/List
     370: nop
     371: checkcast     #171                // class java/lang/Iterable
     374: nop
     375: astore        13
     377: aload         9
     379: aload         13
     381: invokestatic  #281                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     384: pop
     385: goto          213
     388: aload         9
     390: checkcast     #104                // class java/util/List
     393: nop
     394: checkcast     #171                // class java/lang/Iterable
     397: invokestatic  #253                // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
     400: invokestatic  #285                // Method kotlin/collections/MapsKt.toMutableMap:(Ljava/util/Map;)Ljava/util/Map;
     403: astore        5
     405: aload_2
     406: checkcast     #110                // class java/lang/CharSequence
     409: invokestatic  #289                // Method kotlin/text/StringsKt.toSet:(Ljava/lang/CharSequence;)Ljava/util/Set;
     412: astore        6
     414: aload         5
     416: astore        7
     418: getstatic     #18                 // Field defaultWiring:Ljava/util/Map;
     421: astore        8
     423: iconst_0
     424: istore        9
     426: new           #157                // class java/util/LinkedHashMap
     429: dup
     430: invokespecial #290                // Method java/util/LinkedHashMap."<init>":()V
     433: astore        10
     435: aload         8
     437: invokeinterface #52,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     442: invokeinterface #58,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
     447: astore        11
     449: aload         11
     451: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     456: ifeq          535
     459: aload         11
     461: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     466: checkcast     #69                 // class java/util/Map$Entry
     469: astore        12
     471: aload         12
     473: invokeinterface #72,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     478: checkcast     #74                 // class java/lang/Character
     481: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     484: istore        13
     486: iconst_0
     487: istore        14
     489: aload         6
     491: iload         13
     493: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     496: invokeinterface #291,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     501: ifne          508
     504: iconst_1
     505: goto          509
     508: iconst_0
     509: ifeq          449
     512: aload         10
     514: aload         12
     516: invokeinterface #72,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     521: aload         12
     523: invokeinterface #81,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     528: invokevirtual #292                // Method java/util/LinkedHashMap.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     531: pop
     532: goto          449
     535: aload         10
     537: checkcast     #33                 // class java/util/Map
     540: astore        8
     542: aload         7
     544: aload         8
     546: invokeinterface #296,  2          // InterfaceMethod java/util/Map.putAll:(Ljava/util/Map;)V
     551: aload         5
     553: goto          584
     556: new           #41                 // class java/lang/IllegalArgumentException
     559: dup
     560: new           #142                // class java/lang/StringBuilder
     563: dup
     564: invokespecial #145                // Method java/lang/StringBuilder."<init>":()V
     567: ldc_w         #298                // String Unknown kind:
     570: invokevirtual #151                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     573: aload_1
     574: invokevirtual #151                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     577: invokevirtual #155                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     580: invokespecial #48                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     583: athrow
     584: astore_3
     585: aload_3
     586: areturn

  public static final java.util.List<java.lang.Integer> toListOfInt(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #221                // String <this>
       3: invokestatic  #29                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #110                // class java/lang/CharSequence
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #259                // class java/util/ArrayList
      18: dup
      19: aload_1
      20: invokeinterface #114,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      25: invokespecial #263                // Method java/util/ArrayList."<init>":(I)V
      28: checkcast     #262                // class java/util/Collection
      31: astore        4
      33: iconst_0
      34: istore        5
      36: iconst_0
      37: istore        6
      39: iload         6
      41: aload_3
      42: invokeinterface #114,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      47: if_icmpge     139
      50: aload_3
      51: iload         6
      53: invokeinterface #118,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      58: istore        7
      60: aload         4
      62: iload         7
      64: istore        8
      66: astore        10
      68: iconst_0
      69: istore        9
      71: nop
      72: iload         8
      74: invokestatic  #85                 // Method java/lang/Character.isLetter:(C)Z
      77: ifeq          91
      80: iload         8
      82: invokestatic  #176                // Method java/lang/Character.toUpperCase:(C)C
      85: bipush        65
      87: isub
      88: goto          120
      91: new           #41                 // class java/lang/IllegalArgumentException
      94: dup
      95: new           #142                // class java/lang/StringBuilder
      98: dup
      99: invokespecial #145                // Method java/lang/StringBuilder."<init>":()V
     102: ldc_w         #330                // String Invalid character:
     105: invokevirtual #151                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     108: iload         8
     110: invokevirtual #333                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     113: invokevirtual #155                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     116: invokespecial #48                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     119: athrow
     120: nop
     121: invokestatic  #338                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     124: aload         10
     126: swap
     127: invokeinterface #277,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     132: pop
     133: iinc          6, 1
     136: goto          39
     139: aload         4
     141: checkcast     #104                // class java/util/List
     144: nop
     145: areturn

  static {};
    Code:
       0: new           #344                // class kotlin/ranges/CharRange
       3: dup
       4: bipush        65
       6: bipush        90
       8: invokespecial #347                // Method kotlin/ranges/CharRange."<init>":(CC)V
      11: checkcast     #171                // class java/lang/Iterable
      14: ldc_w         #349                // String
      17: checkcast     #110                // class java/lang/CharSequence
      20: aconst_null
      21: aconst_null
      22: iconst_0
      23: aconst_null
      24: aconst_null
      25: bipush        62
      27: aconst_null
      28: invokestatic  #353                // 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;
      31: putstatic     #11                 // Field alphabet:Ljava/lang/String;
      34: new           #344                // class kotlin/ranges/CharRange
      37: dup
      38: bipush        65
      40: bipush        90
      42: invokespecial #347                // Method kotlin/ranges/CharRange."<init>":(CC)V
      45: checkcast     #171                // class java/lang/Iterable
      48: astore_0
      49: iconst_0
      50: istore_1
      51: new           #157                // class java/util/LinkedHashMap
      54: dup
      55: aload_0
      56: bipush        10
      58: invokestatic  #357                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      61: invokestatic  #166                // Method kotlin/collections/MapsKt.mapCapacity:(I)I
      64: bipush        16
      66: invokestatic  #363                // Method kotlin/ranges/RangesKt.coerceAtLeast:(II)I
      69: invokespecial #169                // Method java/util/LinkedHashMap."<init>":(I)V
      72: astore_2
      73: aload_0
      74: astore_3
      75: iconst_0
      76: istore        4
      78: aload_3
      79: invokeinterface #172,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      84: astore        5
      86: aload         5
      88: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      93: ifeq          150
      96: aload         5
      98: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     103: astore        6
     105: aload_2
     106: checkcast     #33                 // class java/util/Map
     109: aload         6
     111: aload         6
     113: checkcast     #74                 // class java/lang/Character
     116: invokevirtual #78                 // Method java/lang/Character.charValue:()C
     119: istore        7
     121: astore        10
     123: astore        9
     125: iconst_0
     126: istore        8
     128: iload         7
     130: invokestatic  #122                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     133: astore        11
     135: aload         9
     137: aload         10
     139: aload         11
     141: invokeinterface #179,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     146: pop
     147: goto          86
     150: aload_2
     151: checkcast     #33                 // class java/util/Map
     154: nop
     155: putstatic     #18                 // Field defaultWiring:Ljava/util/Map;
     158: return
}


package chapter07

import java.lang.IndexOutOfBoundsException
import java.math.BigDecimal
import java.time.LocalDate
import kotlin.ranges.ClosedRange as ClosedRange1

/**
 *
 *运算符重载
 * BigDecimal运算
 *  约定 operator
 *
 *  a * b   |   times
 *  a / b   |   div
 *  a % b   |   mod
 *  a + b   |   plus
 *  a - b   |   minus
 *
 */
fun main(args: Array<String>) {
    BigDecimal.ZERO

    var p1 = Point(10, 20)
    val p2 = Point(30, 40)

    println(p1 + p2)
    println(p1.plus(p2))
    p1 += p2
    println(p1)
    println(p2 * 5.toDouble())

    var bd = BigDecimal.ZERO
    println(++bd)

    val a = Point(10, 20) == Point(10, 20)
    println("equal: $a")

    val p111 = Person722("Alice", "Smith")
    val p222 = Person722("Bob", "Johnson")
    println(p111 < p222)

    println(p2[1])

    println('a' in "abc")

}

data class Point(val x: Int, val y: Int) {
    operator fun plus(other: Point): Point {
        return Point(x + other.x, y + other.y)
    }

    fun and(other: Point): Point {
        return Point(x + other.x, y + other.y)
    }

    /**
     * Point(10,20) == Point(10,20)
     */
    override fun equals(obj: Any?): Boolean {
        if (obj === this) return true
        if (obj !is Point) return false
        return obj.x == x && obj.y == y
    }

}

operator fun Point.times(scale: Double): Point {
    return Point((x * scale).toInt(), (y * scale).toInt())
}

/**
 *
 * 重载一元运算符
 *
 * +a           |   unaryPlus
 * -a           |   unaryMinus
 * !a           |   not
 * ++a,a++      |   inc
 * --a,a--      |   dec
 *
 */
operator fun Point.unaryMinus(): Point {
    return Point(-x, -y)
}

operator fun BigDecimal.inc() = this + BigDecimal.ONE

/**
 * 比较运算符
 *
 * equals
 * == 运算符
 *
 */

/**
 *
 * 排序运算符
 * compareTo 接口
 *
 */
class Person722(val firstName: String, val lastName: String) : Comparable<Person722> {
    override fun compareTo(other: Person722): Int {
        return compareValuesBy(this, other, Person722::lastName, Person722::firstName)
    }
}

/**
 * 集合与区别的约定
 *  a[b]    下标运算符 "get"和"set"
 *
 *
 */
operator fun Point.get(index: Int): Int {
    return when (index) {
        0 -> x
        1 -> y
        else ->
            throw IndexOutOfBoundsException("Invalid coordinate $index")
    }
}

/**
 * "in"的约定
 * contains
 *
 *
 */

data class Rectangle732(val upperLeft: Point, val lowerRight: Point)

operator fun Rectangle732.contains(p: Point): Boolean {
    return p.x in upperLeft.x until lowerRight.x &&
            p.y in upperLeft.y until lowerRight.y
}

/**
 * rangeTo 约定
 * ".."符号 1..10
 *实现了Comparable 接口就不需要实现rangeTo了～因为标准库已经实现
 */
//operator fun<T:Comparable<T>> T.rangeTo(that:T) : kotlin.ranges.ClosedRange<T> {
//    1..10
//}

/**
 * for循环中使用iterator的约定
 *
 *
 *
 */

Compiled from "Intro_运算符重载.kt"
public final class chapter07.Intro_运算符重载Kt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #21                 // Field java/math/BigDecimal.ZERO:Ljava/math/BigDecimal;
       9: pop
      10: new           #23                 // class chapter07/Point
      13: dup
      14: bipush        10
      16: bipush        20
      18: invokespecial #27                 // Method chapter07/Point."<init>":(II)V
      21: astore_1
      22: new           #23                 // class chapter07/Point
      25: dup
      26: bipush        30
      28: bipush        40
      30: invokespecial #27                 // Method chapter07/Point."<init>":(II)V
      33: astore_2
      34: aload_1
      35: aload_2
      36: invokevirtual #31                 // Method chapter07/Point.plus:(Lchapter07/Point;)Lchapter07/Point;
      39: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
      42: swap
      43: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      46: aload_1
      47: aload_2
      48: invokevirtual #31                 // Method chapter07/Point.plus:(Lchapter07/Point;)Lchapter07/Point;
      51: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
      54: swap
      55: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      58: aload_1
      59: aload_2
      60: invokevirtual #31                 // Method chapter07/Point.plus:(Lchapter07/Point;)Lchapter07/Point;
      63: astore_1
      64: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
      67: aload_1
      68: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      71: aload_2
      72: ldc2_w        #44                 // double 5.0d
      75: invokestatic  #49                 // Method times:(Lchapter07/Point;D)Lchapter07/Point;
      78: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
      81: swap
      82: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      85: getstatic     #21                 // Field java/math/BigDecimal.ZERO:Ljava/math/BigDecimal;
      88: astore_3
      89: aload_3
      90: astore        4
      92: aload         4
      94: invokestatic  #52                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      97: aload         4
      99: invokestatic  #56                 // Method inc:(Ljava/math/BigDecimal;)Ljava/math/BigDecimal;
     102: astore_3
     103: aload_3
     104: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     107: swap
     108: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     111: new           #23                 // class chapter07/Point
     114: dup
     115: bipush        10
     117: bipush        20
     119: invokespecial #27                 // Method chapter07/Point."<init>":(II)V
     122: new           #23                 // class chapter07/Point
     125: dup
     126: bipush        10
     128: bipush        20
     130: invokespecial #27                 // Method chapter07/Point."<init>":(II)V
     133: invokestatic  #60                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     136: istore        4
     138: new           #62                 // class java/lang/StringBuilder
     141: dup
     142: invokespecial #65                 // Method java/lang/StringBuilder."<init>":()V
     145: ldc           #67                 // String equal:
     147: invokevirtual #71                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     150: iload         4
     152: invokevirtual #74                 // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder;
     155: invokevirtual #78                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     158: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     161: swap
     162: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     165: new           #80                 // class chapter07/Person722
     168: dup
     169: ldc           #82                 // String Alice
     171: ldc           #84                 // String Smith
     173: invokespecial #87                 // Method chapter07/Person722."<init>":(Ljava/lang/String;Ljava/lang/String;)V
     176: astore        5
     178: new           #80                 // class chapter07/Person722
     181: dup
     182: ldc           #89                 // String Bob
     184: ldc           #91                 // String Johnson
     186: invokespecial #87                 // Method chapter07/Person722."<init>":(Ljava/lang/String;Ljava/lang/String;)V
     189: astore        6
     191: aload         5
     193: aload         6
     195: invokevirtual #95                 // Method chapter07/Person722.compareTo:(Lchapter07/Person722;)I
     198: ifge          205
     201: iconst_1
     202: goto          206
     205: iconst_0
     206: istore        7
     208: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     211: iload         7
     213: invokevirtual #98                 // Method java/io/PrintStream.println:(Z)V
     216: aload_2
     217: iconst_1
     218: invokestatic  #102                // Method get:(Lchapter07/Point;I)I
     221: istore        7
     223: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     226: iload         7
     228: invokevirtual #105                // Method java/io/PrintStream.println:(I)V
     231: ldc           #107                // String abc
     233: checkcast     #109                // class java/lang/CharSequence
     236: bipush        97
     238: iconst_0
     239: iconst_2
     240: aconst_null
     241: invokestatic  #115                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
     244: istore        7
     246: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     249: iload         7
     251: invokevirtual #98                 // Method java/io/PrintStream.println:(Z)V
     254: return

  public static final chapter07.Point times(chapter07.Point, double);
    Code:
       0: aload_0
       1: ldc           #128                // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #23                 // class chapter07/Point
       9: dup
      10: aload_0
      11: invokevirtual #132                // Method chapter07/Point.getX:()I
      14: i2d
      15: dload_1
      16: dmul
      17: d2i
      18: aload_0
      19: invokevirtual #135                // Method chapter07/Point.getY:()I
      22: i2d
      23: dload_1
      24: dmul
      25: d2i
      26: invokespecial #27                 // Method chapter07/Point."<init>":(II)V
      29: areturn

  public static final chapter07.Point unaryMinus(chapter07.Point);
    Code:
       0: aload_0
       1: ldc           #128                // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #23                 // class chapter07/Point
       9: dup
      10: aload_0
      11: invokevirtual #132                // Method chapter07/Point.getX:()I
      14: ineg
      15: aload_0
      16: invokevirtual #135                // Method chapter07/Point.getY:()I
      19: ineg
      20: invokespecial #27                 // Method chapter07/Point."<init>":(II)V
      23: areturn

  public static final java.math.BigDecimal inc(java.math.BigDecimal);
    Code:
       0: aload_0
       1: ldc           #128                // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: astore_1
       8: getstatic     #143                // Field java/math/BigDecimal.ONE:Ljava/math/BigDecimal;
      11: dup
      12: ldc           #144                // String ONE
      14: invokestatic  #147                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      17: aload_1
      18: swap
      19: invokevirtual #150                // Method java/math/BigDecimal.add:(Ljava/math/BigDecimal;)Ljava/math/BigDecimal;
      22: dup
      23: ldc           #152                // String add(...)
      25: invokestatic  #147                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      28: areturn

  public static final int get(chapter07.Point, int);
    Code:
       0: aload_0
       1: ldc           #128                // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: tableswitch   { // 0 to 1
                     0: 28
                     1: 35
               default: 42
          }
      28: aload_0
      29: invokevirtual #132                // Method chapter07/Point.getX:()I
      32: goto          69
      35: aload_0
      36: invokevirtual #135                // Method chapter07/Point.getY:()I
      39: goto          69
      42: new           #155                // class java/lang/IndexOutOfBoundsException
      45: dup
      46: new           #62                 // class java/lang/StringBuilder
      49: dup
      50: invokespecial #65                 // Method java/lang/StringBuilder."<init>":()V
      53: ldc           #157                // String Invalid coordinate
      55: invokevirtual #71                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      58: iload_1
      59: invokevirtual #160                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      62: invokevirtual #78                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      65: invokespecial #163                // Method java/lang/IndexOutOfBoundsException."<init>":(Ljava/lang/String;)V
      68: athrow
      69: ireturn

  public static final boolean contains(chapter07.Rectangle732, chapter07.Point);
    Code:
       0: aload_0
       1: ldc           #128                // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #170                // String p
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokevirtual #176                // Method chapter07/Rectangle732.getUpperLeft:()Lchapter07/Point;
      16: invokevirtual #132                // Method chapter07/Point.getX:()I
      19: istore_2
      20: aload_0
      21: invokevirtual #179                // Method chapter07/Rectangle732.getLowerRight:()Lchapter07/Point;
      24: invokevirtual #132                // Method chapter07/Point.getX:()I
      27: istore_3
      28: aload_1
      29: invokevirtual #132                // Method chapter07/Point.getX:()I
      32: istore        4
      34: iload_2
      35: iload         4
      37: if_icmpgt     54
      40: iload         4
      42: iload_3
      43: if_icmpge     50
      46: iconst_1
      47: goto          55
      50: iconst_0
      51: goto          55
      54: iconst_0
      55: ifeq          108
      58: aload_0
      59: invokevirtual #176                // Method chapter07/Rectangle732.getUpperLeft:()Lchapter07/Point;
      62: invokevirtual #135                // Method chapter07/Point.getY:()I
      65: istore_2
      66: aload_0
      67: invokevirtual #179                // Method chapter07/Rectangle732.getLowerRight:()Lchapter07/Point;
      70: invokevirtual #135                // Method chapter07/Point.getY:()I
      73: istore_3
      74: aload_1
      75: invokevirtual #135                // Method chapter07/Point.getY:()I
      78: istore        4
      80: iload_2
      81: iload         4
      83: if_icmpgt     100
      86: iload         4
      88: iload_3
      89: if_icmpge     96
      92: iconst_1
      93: goto          101
      96: iconst_0
      97: goto          101
     100: iconst_0
     101: ifeq          108
     104: iconst_1
     105: goto          109
     108: iconst_0
     109: ireturn
}


package chapter08._8_1_2

data class SiteVisit(
        val path: String,
        val dutation: Double,
        val os: OS
)

//函数类型和lambda 一起去除重复代码
enum class OS { WINDOWS, LINUX, MAC, IOS, ANDROID }

fun main(args: Array<String>) {
    val log = listOf(
            SiteVisit("/", 34.0, OS.WINDOWS),
            SiteVisit("/", 22.0, OS.MAC),
            SiteVisit("/login", 12.0, OS.WINDOWS),
            SiteVisit("/signup", 8.0, OS.IOS),
            SiteVisit("/", 16.3, OS.ANDROID)
    )

    println(log.filter { it.os == OS.WINDOWS }
            .map(SiteVisit::dutation))

    //计算windows平均时间
    val averageWindows = log.filter { it.os == OS.WINDOWS }
            .map(SiteVisit::dutation)
            .average()
    println(averageWindows)

//    println(log.filter { it.os == OS.WINDOWS }
//            .map(SiteVisit::dutation))

    val averageMobile = log.filter {
        it.os in setOf(OS.IOS, OS.ANDROID)
    }
            .map(SiteVisit::dutation)
            .average()
    println(averageMobile)

    /**
     * 普通去重方法
     */
    println()
    println("log.averageDuration(OS.ANDROID)")
    println(log.averageDuration(OS.ANDROID))
    println("------------------------")
    /**
     * 将需要的条件抽到函数类型参数中
     */
    println(log.averageDurationFor {
        it.os in setOf(OS.ANDROID, OS.IOS)
    })
    println(log.averageDurationFor {
        it.os == OS.IOS && it.path == "/signup"
    })

}

/**
 * 普通方法去重
 */
fun List<SiteVisit>.averageDuration(os: OS) = filter { it.os == os }
        .map(SiteVisit::dutation)
        .average()

/**
 * 将需要的条件抽到函数类型参数中
 * 不仅抽取重复数据，也能抽取重复行为
 */
fun List<SiteVisit>.averageDurationFor(predicate: (SiteVisit) -> Boolean) =
        filter(predicate)
                .map(SiteVisit::dutation)
                .average()

Compiled from "_8_1_6_去除重复代码.kt"
public final class chapter08._8_1_2._8_1_6_去除重复代码Kt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_5
       7: anewarray     #17                 // class chapter08/_8_1_2/SiteVisit
      10: astore_2
      11: aload_2
      12: iconst_0
      13: new           #17                 // class chapter08/_8_1_2/SiteVisit
      16: dup
      17: ldc           #19                 // String /
      19: ldc2_w        #20                 // double 34.0d
      22: getstatic     #27                 // Field chapter08/_8_1_2/OS.WINDOWS:Lchapter08/_8_1_2/OS;
      25: invokespecial #31                 // Method chapter08/_8_1_2/SiteVisit."<init>":(Ljava/lang/String;DLchapter08/_8_1_2/OS;)V
      28: aastore
      29: aload_2
      30: iconst_1
      31: new           #17                 // class chapter08/_8_1_2/SiteVisit
      34: dup
      35: ldc           #19                 // String /
      37: ldc2_w        #32                 // double 22.0d
      40: getstatic     #36                 // Field chapter08/_8_1_2/OS.MAC:Lchapter08/_8_1_2/OS;
      43: invokespecial #31                 // Method chapter08/_8_1_2/SiteVisit."<init>":(Ljava/lang/String;DLchapter08/_8_1_2/OS;)V
      46: aastore
      47: aload_2
      48: iconst_2
      49: new           #17                 // class chapter08/_8_1_2/SiteVisit
      52: dup
      53: ldc           #38                 // String /login
      55: ldc2_w        #39                 // double 12.0d
      58: getstatic     #27                 // Field chapter08/_8_1_2/OS.WINDOWS:Lchapter08/_8_1_2/OS;
      61: invokespecial #31                 // Method chapter08/_8_1_2/SiteVisit."<init>":(Ljava/lang/String;DLchapter08/_8_1_2/OS;)V
      64: aastore
      65: aload_2
      66: iconst_3
      67: new           #17                 // class chapter08/_8_1_2/SiteVisit
      70: dup
      71: ldc           #42                 // String /signup
      73: ldc2_w        #43                 // double 8.0d
      76: getstatic     #47                 // Field chapter08/_8_1_2/OS.IOS:Lchapter08/_8_1_2/OS;
      79: invokespecial #31                 // Method chapter08/_8_1_2/SiteVisit."<init>":(Ljava/lang/String;DLchapter08/_8_1_2/OS;)V
      82: aastore
      83: aload_2
      84: iconst_4
      85: new           #17                 // class chapter08/_8_1_2/SiteVisit
      88: dup
      89: ldc           #19                 // String /
      91: ldc2_w        #48                 // double 16.3d
      94: getstatic     #52                 // Field chapter08/_8_1_2/OS.ANDROID:Lchapter08/_8_1_2/OS;
      97: invokespecial #31                 // Method chapter08/_8_1_2/SiteVisit."<init>":(Ljava/lang/String;DLchapter08/_8_1_2/OS;)V
     100: aastore
     101: aload_2
     102: invokestatic  #58                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     105: astore_1
     106: aload_1
     107: checkcast     #60                 // class java/lang/Iterable
     110: astore_2
     111: iconst_0
     112: istore_3
     113: aload_2
     114: astore        4
     116: new           #62                 // class java/util/ArrayList
     119: dup
     120: invokespecial #65                 // Method java/util/ArrayList."<init>":()V
     123: checkcast     #67                 // class java/util/Collection
     126: astore        5
     128: iconst_0
     129: istore        6
     131: aload         4
     133: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     138: astore        7
     140: aload         7
     142: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     147: ifeq          201
     150: aload         7
     152: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     157: astore        8
     159: aload         8
     161: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     164: astore        9
     166: iconst_0
     167: istore        10
     169: aload         9
     171: invokevirtual #85                 // Method chapter08/_8_1_2/SiteVisit.getOs:()Lchapter08/_8_1_2/OS;
     174: getstatic     #27                 // Field chapter08/_8_1_2/OS.WINDOWS:Lchapter08/_8_1_2/OS;
     177: if_acmpne     184
     180: iconst_1
     181: goto          185
     184: iconst_0
     185: ifeq          140
     188: aload         5
     190: aload         8
     192: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     197: pop
     198: goto          140
     201: aload         5
     203: checkcast     #91                 // class java/util/List
     206: nop
     207: checkcast     #60                 // class java/lang/Iterable
     210: astore_2
     211: nop
     212: iconst_0
     213: istore_3
     214: aload_2
     215: astore        4
     217: new           #62                 // class java/util/ArrayList
     220: dup
     221: aload_2
     222: bipush        10
     224: invokestatic  #95                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     227: invokespecial #98                 // Method java/util/ArrayList."<init>":(I)V
     230: checkcast     #67                 // class java/util/Collection
     233: astore        5
     235: iconst_0
     236: istore        6
     238: aload         4
     240: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     245: astore        7
     247: aload         7
     249: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     254: ifeq          300
     257: aload         7
     259: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     264: astore        8
     266: aload         5
     268: aload         8
     270: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     273: astore        9
     275: astore        16
     277: iconst_0
     278: istore        10
     280: aload         9
     282: invokevirtual #102                // Method chapter08/_8_1_2/SiteVisit.getDutation:()D
     285: invokestatic  #108                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     288: aload         16
     290: swap
     291: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     296: pop
     297: goto          247
     300: aload         5
     302: checkcast     #91                 // class java/util/List
     305: nop
     306: astore_2
     307: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     310: aload_2
     311: invokevirtual #120                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     314: aload_1
     315: checkcast     #60                 // class java/lang/Iterable
     318: astore        4
     320: iconst_0
     321: istore        5
     323: aload         4
     325: astore        6
     327: new           #62                 // class java/util/ArrayList
     330: dup
     331: invokespecial #65                 // Method java/util/ArrayList."<init>":()V
     334: checkcast     #67                 // class java/util/Collection
     337: astore        7
     339: iconst_0
     340: istore        8
     342: aload         6
     344: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     349: astore        9
     351: aload         9
     353: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     358: ifeq          412
     361: aload         9
     363: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     368: astore        10
     370: aload         10
     372: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     375: astore        11
     377: iconst_0
     378: istore        12
     380: aload         11
     382: invokevirtual #85                 // Method chapter08/_8_1_2/SiteVisit.getOs:()Lchapter08/_8_1_2/OS;
     385: getstatic     #27                 // Field chapter08/_8_1_2/OS.WINDOWS:Lchapter08/_8_1_2/OS;
     388: if_acmpne     395
     391: iconst_1
     392: goto          396
     395: iconst_0
     396: ifeq          351
     399: aload         7
     401: aload         10
     403: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     408: pop
     409: goto          351
     412: aload         7
     414: checkcast     #91                 // class java/util/List
     417: nop
     418: checkcast     #60                 // class java/lang/Iterable
     421: astore        4
     423: nop
     424: iconst_0
     425: istore        5
     427: aload         4
     429: astore        6
     431: new           #62                 // class java/util/ArrayList
     434: dup
     435: aload         4
     437: bipush        10
     439: invokestatic  #95                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     442: invokespecial #98                 // Method java/util/ArrayList."<init>":(I)V
     445: checkcast     #67                 // class java/util/Collection
     448: astore        7
     450: iconst_0
     451: istore        8
     453: aload         6
     455: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     460: astore        9
     462: aload         9
     464: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     469: ifeq          515
     472: aload         9
     474: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     479: astore        10
     481: aload         7
     483: aload         10
     485: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     488: astore        11
     490: astore        16
     492: iconst_0
     493: istore        12
     495: aload         11
     497: invokevirtual #102                // Method chapter08/_8_1_2/SiteVisit.getDutation:()D
     500: invokestatic  #108                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     503: aload         16
     505: swap
     506: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     511: pop
     512: goto          462
     515: aload         7
     517: checkcast     #91                 // class java/util/List
     520: nop
     521: checkcast     #60                 // class java/lang/Iterable
     524: invokestatic  #124                // Method kotlin/collections/CollectionsKt.averageOfDouble:(Ljava/lang/Iterable;)D
     527: dstore_2
     528: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     531: dload_2
     532: invokevirtual #127                // Method java/io/PrintStream.println:(D)V
     535: aload_1
     536: checkcast     #60                 // class java/lang/Iterable
     539: astore        6
     541: iconst_0
     542: istore        7
     544: aload         6
     546: astore        8
     548: new           #62                 // class java/util/ArrayList
     551: dup
     552: invokespecial #65                 // Method java/util/ArrayList."<init>":()V
     555: checkcast     #67                 // class java/util/Collection
     558: astore        9
     560: iconst_0
     561: istore        10
     563: aload         8
     565: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     570: astore        11
     572: aload         11
     574: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     579: ifeq          652
     582: aload         11
     584: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     589: astore        12
     591: aload         12
     593: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     596: astore        13
     598: iconst_0
     599: istore        14
     601: iconst_2
     602: anewarray     #23                 // class chapter08/_8_1_2/OS
     605: astore        15
     607: aload         15
     609: iconst_0
     610: getstatic     #47                 // Field chapter08/_8_1_2/OS.IOS:Lchapter08/_8_1_2/OS;
     613: aastore
     614: aload         15
     616: iconst_1
     617: getstatic     #52                 // Field chapter08/_8_1_2/OS.ANDROID:Lchapter08/_8_1_2/OS;
     620: aastore
     621: aload         15
     623: invokestatic  #133                // Method kotlin/collections/SetsKt.setOf:([Ljava/lang/Object;)Ljava/util/Set;
     626: aload         13
     628: invokevirtual #85                 // Method chapter08/_8_1_2/SiteVisit.getOs:()Lchapter08/_8_1_2/OS;
     631: invokeinterface #138,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     636: ifeq          572
     639: aload         9
     641: aload         12
     643: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     648: pop
     649: goto          572
     652: aload         9
     654: checkcast     #91                 // class java/util/List
     657: nop
     658: checkcast     #60                 // class java/lang/Iterable
     661: astore        6
     663: nop
     664: iconst_0
     665: istore        7
     667: aload         6
     669: astore        8
     671: new           #62                 // class java/util/ArrayList
     674: dup
     675: aload         6
     677: bipush        10
     679: invokestatic  #95                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     682: invokespecial #98                 // Method java/util/ArrayList."<init>":(I)V
     685: checkcast     #67                 // class java/util/Collection
     688: astore        9
     690: iconst_0
     691: istore        10
     693: aload         8
     695: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     700: astore        11
     702: aload         11
     704: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     709: ifeq          755
     712: aload         11
     714: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     719: astore        12
     721: aload         9
     723: aload         12
     725: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     728: astore        13
     730: astore        16
     732: iconst_0
     733: istore        14
     735: aload         13
     737: invokevirtual #102                // Method chapter08/_8_1_2/SiteVisit.getDutation:()D
     740: invokestatic  #108                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     743: aload         16
     745: swap
     746: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     751: pop
     752: goto          702
     755: aload         9
     757: checkcast     #91                 // class java/util/List
     760: nop
     761: checkcast     #60                 // class java/lang/Iterable
     764: invokestatic  #124                // Method kotlin/collections/CollectionsKt.averageOfDouble:(Ljava/lang/Iterable;)D
     767: dstore        4
     769: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     772: dload         4
     774: invokevirtual #127                // Method java/io/PrintStream.println:(D)V
     777: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     780: invokevirtual #140                // Method java/io/PrintStream.println:()V
     783: ldc           #142                // String log.averageDuration(OS.ANDROID)
     785: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     788: swap
     789: invokevirtual #120                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     792: aload_1
     793: getstatic     #52                 // Field chapter08/_8_1_2/OS.ANDROID:Lchapter08/_8_1_2/OS;
     796: invokestatic  #146                // Method averageDuration:(Ljava/util/List;Lchapter08/_8_1_2/OS;)D
     799: dstore        6
     801: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     804: dload         6
     806: invokevirtual #127                // Method java/io/PrintStream.println:(D)V
     809: ldc           #148                // String ------------------------
     811: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     814: swap
     815: invokevirtual #120                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     818: aload_1
     819: invokedynamic #168,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     824: invokestatic  #172                // Method averageDurationFor:(Ljava/util/List;Lkotlin/jvm/functions/Function1;)D
     827: dstore        6
     829: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     832: dload         6
     834: invokevirtual #127                // Method java/io/PrintStream.println:(D)V
     837: aload_1
     838: invokedynamic #177,  0            // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function1;
     843: invokestatic  #172                // Method averageDurationFor:(Ljava/util/List;Lkotlin/jvm/functions/Function1;)D
     846: dstore        6
     848: getstatic     #114                // Field java/lang/System.out:Ljava/io/PrintStream;
     851: dload         6
     853: invokevirtual #127                // Method java/io/PrintStream.println:(D)V
     856: return

  public static final double averageDuration(java.util.List<chapter08._8_1_2.SiteVisit>, chapter08._8_1_2.OS);
    Code:
       0: aload_0
       1: ldc           #211                // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #213                // String os
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #60                 // class java/lang/Iterable
      16: astore_2
      17: iconst_0
      18: istore_3
      19: aload_2
      20: astore        4
      22: new           #62                 // class java/util/ArrayList
      25: dup
      26: invokespecial #65                 // Method java/util/ArrayList."<init>":()V
      29: checkcast     #67                 // class java/util/Collection
      32: astore        5
      34: iconst_0
      35: istore        6
      37: aload         4
      39: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      44: astore        7
      46: aload         7
      48: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          105
      56: aload         7
      58: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: astore        8
      65: aload         8
      67: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
      70: astore        9
      72: iconst_0
      73: istore        10
      75: aload         9
      77: invokevirtual #85                 // Method chapter08/_8_1_2/SiteVisit.getOs:()Lchapter08/_8_1_2/OS;
      80: aload_1
      81: if_acmpne     88
      84: iconst_1
      85: goto          89
      88: iconst_0
      89: ifeq          46
      92: aload         5
      94: aload         8
      96: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     101: pop
     102: goto          46
     105: aload         5
     107: checkcast     #91                 // class java/util/List
     110: nop
     111: checkcast     #60                 // class java/lang/Iterable
     114: astore_2
     115: nop
     116: iconst_0
     117: istore_3
     118: aload_2
     119: astore        4
     121: new           #62                 // class java/util/ArrayList
     124: dup
     125: aload_2
     126: bipush        10
     128: invokestatic  #95                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     131: invokespecial #98                 // Method java/util/ArrayList."<init>":(I)V
     134: checkcast     #67                 // class java/util/Collection
     137: astore        5
     139: iconst_0
     140: istore        6
     142: aload         4
     144: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     149: astore        7
     151: aload         7
     153: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     158: ifeq          204
     161: aload         7
     163: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     168: astore        8
     170: aload         5
     172: aload         8
     174: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     177: astore        9
     179: astore        11
     181: iconst_0
     182: istore        10
     184: aload         9
     186: invokevirtual #102                // Method chapter08/_8_1_2/SiteVisit.getDutation:()D
     189: invokestatic  #108                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     192: aload         11
     194: swap
     195: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     200: pop
     201: goto          151
     204: aload         5
     206: checkcast     #91                 // class java/util/List
     209: nop
     210: checkcast     #60                 // class java/lang/Iterable
     213: invokestatic  #124                // Method kotlin/collections/CollectionsKt.averageOfDouble:(Ljava/lang/Iterable;)D
     216: dreturn

  public static final double averageDurationFor(java.util.List<chapter08._8_1_2.SiteVisit>, kotlin.jvm.functions.Function1<? super chapter08._8_1_2.SiteVisit, java.lang.Boolean>);
    Code:
       0: aload_0
       1: ldc           #211                // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #219                // String predicate
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #60                 // class java/lang/Iterable
      16: astore_2
      17: iconst_0
      18: istore_3
      19: aload_2
      20: astore        4
      22: new           #62                 // class java/util/ArrayList
      25: dup
      26: invokespecial #65                 // Method java/util/ArrayList."<init>":()V
      29: checkcast     #67                 // class java/util/Collection
      32: astore        5
      34: iconst_0
      35: istore        6
      37: aload         4
      39: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      44: astore        7
      46: aload         7
      48: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          95
      56: aload         7
      58: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: astore        8
      65: aload_1
      66: aload         8
      68: invokeinterface #223,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
      73: checkcast     #225                // class java/lang/Boolean
      76: invokevirtual #228                // Method java/lang/Boolean.booleanValue:()Z
      79: ifeq          46
      82: aload         5
      84: aload         8
      86: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      91: pop
      92: goto          46
      95: aload         5
      97: checkcast     #91                 // class java/util/List
     100: nop
     101: checkcast     #60                 // class java/lang/Iterable
     104: astore_2
     105: nop
     106: iconst_0
     107: istore_3
     108: aload_2
     109: astore        4
     111: new           #62                 // class java/util/ArrayList
     114: dup
     115: aload_2
     116: bipush        10
     118: invokestatic  #95                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     121: invokespecial #98                 // Method java/util/ArrayList."<init>":(I)V
     124: checkcast     #67                 // class java/util/Collection
     127: astore        5
     129: iconst_0
     130: istore        6
     132: aload         4
     134: invokeinterface #71,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     139: astore        7
     141: aload         7
     143: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     148: ifeq          194
     151: aload         7
     153: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     158: astore        8
     160: aload         5
     162: aload         8
     164: checkcast     #17                 // class chapter08/_8_1_2/SiteVisit
     167: astore        9
     169: astore        11
     171: iconst_0
     172: istore        10
     174: aload         9
     176: invokevirtual #102                // Method chapter08/_8_1_2/SiteVisit.getDutation:()D
     179: invokestatic  #108                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     182: aload         11
     184: swap
     185: invokeinterface #89,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     190: pop
     191: goto          141
     194: aload         5
     196: checkcast     #91                 // class java/util/List
     199: nop
     200: checkcast     #60                 // class java/lang/Iterable
     203: invokestatic  #124                // Method kotlin/collections/CollectionsKt.averageOfDouble:(Ljava/lang/Iterable;)D
     206: dreturn

  private static final boolean main$lambda$5(chapter08._8_1_2.SiteVisit);
    Code:
       0: aload_0
       1: ldc           #232                // String it
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_2
       7: anewarray     #23                 // class chapter08/_8_1_2/OS
      10: astore_1
      11: aload_1
      12: iconst_0
      13: getstatic     #52                 // Field chapter08/_8_1_2/OS.ANDROID:Lchapter08/_8_1_2/OS;
      16: aastore
      17: aload_1
      18: iconst_1
      19: getstatic     #47                 // Field chapter08/_8_1_2/OS.IOS:Lchapter08/_8_1_2/OS;
      22: aastore
      23: aload_1
      24: invokestatic  #133                // Method kotlin/collections/SetsKt.setOf:([Ljava/lang/Object;)Ljava/util/Set;
      27: aload_0
      28: invokevirtual #85                 // Method chapter08/_8_1_2/SiteVisit.getOs:()Lchapter08/_8_1_2/OS;
      31: invokeinterface #138,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
      36: ireturn

  private static final boolean main$lambda$6(chapter08._8_1_2.SiteVisit);
    Code:
       0: aload_0
       1: ldc           #232                // String it
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #85                 // Method chapter08/_8_1_2/SiteVisit.getOs:()Lchapter08/_8_1_2/OS;
      10: getstatic     #47                 // Field chapter08/_8_1_2/OS.IOS:Lchapter08/_8_1_2/OS;
      13: if_acmpne     32
      16: aload_0
      17: invokevirtual #236                // Method chapter08/_8_1_2/SiteVisit.getPath:()Ljava/lang/String;
      20: ldc           #42                 // String /signup
      22: invokestatic  #240                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      25: ifeq          32
      28: iconst_1
      29: goto          33
      32: iconst_0
      33: ireturn
}


package homework_5

import java.io.File

fun String.isNumber() = this.toIntOrNull() != null

enum class OperationType(val operation: String) {
    Addition("+"),
    Multiplication("*"),
    Subtraction("-"),
    Division("/")
}

interface ArithmeticTreeNode {
    fun getValue(): Int
    override fun toString(): String
}

class Operand(private val value: Int) : ArithmeticTreeNode {
    override fun getValue() = value
    override fun toString() = value.toString()
}

class Operation(
    private val type: OperationType,
    private val leftNode: ArithmeticTreeNode,
    private val rightNode: ArithmeticTreeNode
) : ArithmeticTreeNode {
    override fun getValue(): Int {
        return when (type) {
            OperationType.Addition -> leftNode.getValue() + rightNode.getValue()
            OperationType.Multiplication -> leftNode.getValue() * rightNode.getValue()
            OperationType.Subtraction -> leftNode.getValue() - rightNode.getValue()
            OperationType.Division -> leftNode.getValue() / rightNode.getValue()
        }
    }

    override fun toString(): String = "(${type.operation} $leftNode $rightNode)"
}

class ArithmeticTree(path: String) {
    private val root: ArithmeticTreeNode

    init {
        val input = File(path).readText().replace("(", "").replace(")", "").split(" ")
        root = parseRecursive(input).node
    }

    data class RecursiveResult(val node: ArithmeticTreeNode, val newList: List<String>)

    private fun parseRecursive(list: List<String>): RecursiveResult {
        if (list.first().isNumber()) {
            return RecursiveResult(Operand(list.first().toInt()), list.slice(1..list.lastIndex))
        } else {
            val type = when (list.first()) {
                "+" -> OperationType.Addition
                "*" -> OperationType.Multiplication
                "-" -> OperationType.Subtraction
                "/" -> OperationType.Division
                else -> throw IllegalArgumentException("arithmetic expression is not correct")
            }
            var result = parseRecursive(list.slice(1..list.lastIndex))
            val leftNode = result.node
            result = parseRecursive(result.newList)
            val rightNode = result.node
            return RecursiveResult(Operation(type, leftNode, rightNode), result.newList)
        }
    }

    override fun toString() = root.toString()
    fun getValue() = root.getValue()
}

Compiled from "Task1.kt"
public final class homework_5.Task1Kt {
  public static final boolean isNumber(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #9                  // String <this>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #21                 // Method kotlin/text/StringsKt.toIntOrNull:(Ljava/lang/String;)Ljava/lang/Integer;
      10: ifnull        17
      13: iconst_1
      14: goto          18
      17: iconst_0
      18: ireturn
}