package com.vaclavbohac.advent2023.day3

class GearRatios(private val lines: List<String>) {
    fun getSumOfAllParts(): Int {
        val validNumbers = mutableListOf<Int>()

        lines.forEachIndexed { i, line ->
            var j = 0
            var number = StringBuffer()
            var indexStart = 0

            while (j < line.length) {
                if (line[j].isDigit()) {
                    if (number.isEmpty()) {
                        indexStart = j
                    }

                    number.append(line[j])
                }

                if (number.isNotEmpty() && (!line[j].isDigit() || j == line.length - 1)) {

                    if (isValidNumber(indexStart, j - 1, i)) {
                        validNumbers.add(number.toString().toInt())
                    }

                    number = StringBuffer()
                }

                j += 1
            }
        }

        return validNumbers.sum()
    }

    fun getSumOfGears(): Int {
        val stars: MutableMap<Pair<Int, Int>, MutableList<Int>> = mutableMapOf()

        lines.forEachIndexed { i, line ->
            var j = 0
            var number = StringBuffer()
            var indexStart = 0

            while (j < line.length) {
                if (line[j].isDigit()) {
                    if (number.isEmpty()) {
                        indexStart = j
                    }

                    number.append(line[j])
                }

                if (number.isNotEmpty() && (!line[j].isDigit() || j == line.length - 1)) {
                    val num = number.toString().toInt()
                    val star = getAdjacentStar(indexStart, j - 1, i)

                    if (star != null) {
                        if (stars[star].isNullOrEmpty()) {
                            stars[star] = mutableListOf(num)
                        } else {
                            stars[star]?.add(num)
                        }
                    }

                    number = StringBuffer()
                }

                j += 1
            }
        }

        return stars
            .filter { star -> star.value.size == 2 }
            .map { star -> star.value.fold(1) { prod, num -> prod * num } }
            .sum()
    }

    private fun isValidNumber(start: Int, end: Int, line: Int): Boolean {
        val columnRange = maxOf(start - 1, 0).rangeTo(minOf(end + 1, lines[0].length))
        val rowRange = maxOf(line - 1, 0).rangeTo(minOf(line + 1, lines.size - 1))

        for (i in columnRange) {
            for (j in rowRange) {
                val c = lines[j][i]

                if (!c.isDigit() && c != '.') {
                    return true
                }
            }
        }

        return false
    }

    private fun getAdjacentStar(start: Int, end: Int, line: Int): Pair<Int, Int>? {
        val columnRange = maxOf(start - 1, 0).rangeTo(minOf(end + 1, lines[0].length))
        val rowRange = maxOf(line - 1, 0).rangeTo(minOf(line + 1, lines.size - 1))

        for (i in columnRange) {
            for (j in rowRange) {
                val c = lines[j][i]

                if (c == '*') {
                    return Pair(j, i)
                }
            }
        }

        return null
    }
}

Compiled from "GearRatios.kt"
public final class com.vaclavbohac.advent2023.day3.GearRatios {
  private final java.util.List<java.lang.String> lines;

  public com.vaclavbohac.advent2023.day3.GearRatios(java.util.List<java.lang.String>);
    Code:
       0: aload_1
       1: ldc           #10                 // String lines
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #19                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: aload_1
      12: putfield      #22                 // Field lines:Ljava/util/List;
      15: return

  public final int getSumOfAllParts();
    Code:
       0: new           #28                 // class java/util/ArrayList
       3: dup
       4: invokespecial #29                 // Method java/util/ArrayList."<init>":()V
       7: checkcast     #31                 // class java/util/List
      10: astore_1
      11: aload_0
      12: getfield      #22                 // Field lines:Ljava/util/List;
      15: checkcast     #33                 // class java/lang/Iterable
      18: astore_2
      19: iconst_0
      20: istore_3
      21: iconst_0
      22: istore        4
      24: aload_2
      25: invokeinterface #37,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #43,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          261
      42: aload         5
      44: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      49: astore        6
      51: iload         4
      53: iinc          4, 1
      56: istore        7
      58: iload         7
      60: ifge          66
      63: invokestatic  #52                 // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
      66: iload         7
      68: aload         6
      70: checkcast     #54                 // class java/lang/String
      73: astore        8
      75: istore        9
      77: iconst_0
      78: istore        10
      80: iconst_0
      81: istore        11
      83: new           #56                 // class java/lang/StringBuffer
      86: dup
      87: invokespecial #57                 // Method java/lang/StringBuffer."<init>":()V
      90: astore        12
      92: iconst_0
      93: istore        13
      95: iload         11
      97: aload         8
      99: invokevirtual #60                 // Method java/lang/String.length:()I
     102: if_icmpge     256
     105: aload         8
     107: iload         11
     109: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     112: invokestatic  #70                 // Method java/lang/Character.isDigit:(C)Z
     115: ifeq          156
     118: aload         12
     120: checkcast     #72                 // class java/lang/CharSequence
     123: invokeinterface #73,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     128: ifne          135
     131: iconst_1
     132: goto          136
     135: iconst_0
     136: ifeq          143
     139: iload         11
     141: istore        13
     143: aload         12
     145: aload         8
     147: iload         11
     149: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     152: invokevirtual #77                 // Method java/lang/StringBuffer.append:(C)Ljava/lang/StringBuffer;
     155: pop
     156: aload         12
     158: checkcast     #72                 // class java/lang/CharSequence
     161: invokeinterface #73,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     166: ifle          173
     169: iconst_1
     170: goto          174
     173: iconst_0
     174: ifeq          250
     177: aload         8
     179: iload         11
     181: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     184: invokestatic  #70                 // Method java/lang/Character.isDigit:(C)Z
     187: ifeq          202
     190: iload         11
     192: aload         8
     194: invokevirtual #60                 // Method java/lang/String.length:()I
     197: iconst_1
     198: isub
     199: if_icmpne     250
     202: aload_0
     203: iload         13
     205: iload         11
     207: iconst_1
     208: isub
     209: iload         9
     211: invokespecial #81                 // Method isValidNumber:(III)Z
     214: ifeq          241
     217: aload_1
     218: aload         12
     220: invokevirtual #85                 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
     223: dup
     224: ldc           #87                 // String toString(...)
     226: invokestatic  #90                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     229: invokestatic  #96                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     232: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     235: invokeinterface #104,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     240: pop
     241: new           #56                 // class java/lang/StringBuffer
     244: dup
     245: invokespecial #57                 // Method java/lang/StringBuffer."<init>":()V
     248: astore        12
     250: iinc          11, 1
     253: goto          95
     256: nop
     257: nop
     258: goto          32
     261: nop
     262: aload_1
     263: checkcast     #33                 // class java/lang/Iterable
     266: invokestatic  #108                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     269: ireturn

  public final int getSumOfGears();
    Code:
       0: new           #127                // class java/util/LinkedHashMap
       3: dup
       4: invokespecial #128                // Method java/util/LinkedHashMap."<init>":()V
       7: checkcast     #130                // class java/util/Map
      10: astore_1
      11: aload_0
      12: getfield      #22                 // Field lines:Ljava/util/List;
      15: checkcast     #33                 // class java/lang/Iterable
      18: astore_2
      19: iconst_0
      20: istore_3
      21: iconst_0
      22: istore        4
      24: aload_2
      25: invokeinterface #37,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      30: astore        5
      32: aload         5
      34: invokeinterface #43,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          363
      42: aload         5
      44: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      49: astore        6
      51: iload         4
      53: iinc          4, 1
      56: istore        7
      58: iload         7
      60: ifge          66
      63: invokestatic  #52                 // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
      66: iload         7
      68: aload         6
      70: checkcast     #54                 // class java/lang/String
      73: astore        8
      75: istore        9
      77: iconst_0
      78: istore        10
      80: iconst_0
      81: istore        11
      83: new           #56                 // class java/lang/StringBuffer
      86: dup
      87: invokespecial #57                 // Method java/lang/StringBuffer."<init>":()V
      90: astore        12
      92: iconst_0
      93: istore        13
      95: iload         11
      97: aload         8
      99: invokevirtual #60                 // Method java/lang/String.length:()I
     102: if_icmpge     358
     105: aload         8
     107: iload         11
     109: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     112: invokestatic  #70                 // Method java/lang/Character.isDigit:(C)Z
     115: ifeq          156
     118: aload         12
     120: checkcast     #72                 // class java/lang/CharSequence
     123: invokeinterface #73,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     128: ifne          135
     131: iconst_1
     132: goto          136
     135: iconst_0
     136: ifeq          143
     139: iload         11
     141: istore        13
     143: aload         12
     145: aload         8
     147: iload         11
     149: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     152: invokevirtual #77                 // Method java/lang/StringBuffer.append:(C)Ljava/lang/StringBuffer;
     155: pop
     156: aload         12
     158: checkcast     #72                 // class java/lang/CharSequence
     161: invokeinterface #73,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     166: ifle          173
     169: iconst_1
     170: goto          174
     173: iconst_0
     174: ifeq          352
     177: aload         8
     179: iload         11
     181: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     184: invokestatic  #70                 // Method java/lang/Character.isDigit:(C)Z
     187: ifeq          202
     190: iload         11
     192: aload         8
     194: invokevirtual #60                 // Method java/lang/String.length:()I
     197: iconst_1
     198: isub
     199: if_icmpne     352
     202: aload         12
     204: invokevirtual #85                 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
     207: dup
     208: ldc           #87                 // String toString(...)
     210: invokestatic  #90                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     213: invokestatic  #96                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     216: istore        14
     218: aload_0
     219: iload         13
     221: iload         11
     223: iconst_1
     224: isub
     225: iload         9
     227: invokespecial #134                // Method getAdjacentStar:(III)Lkotlin/Pair;
     230: astore        15
     232: aload         15
     234: ifnull        343
     237: aload_1
     238: aload         15
     240: invokeinterface #138,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     245: checkcast     #140                // class java/util/Collection
     248: astore        16
     250: aload         16
     252: ifnull        265
     255: aload         16
     257: invokeinterface #143,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     262: ifeq          269
     265: iconst_1
     266: goto          270
     269: iconst_0
     270: ifeq          313
     273: aload_1
     274: astore        16
     276: iconst_1
     277: anewarray     #92                 // class java/lang/Integer
     280: astore        17
     282: aload         17
     284: iconst_0
     285: iload         14
     287: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     290: aastore
     291: aload         17
     293: invokestatic  #147                // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
     296: astore        17
     298: aload         16
     300: aload         15
     302: aload         17
     304: invokeinterface #151,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     309: pop
     310: goto          343
     313: aload_1
     314: aload         15
     316: invokeinterface #138,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     321: checkcast     #31                 // class java/util/List
     324: dup
     325: ifnull        342
     328: iload         14
     330: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     333: invokeinterface #104,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     338: pop
     339: goto          343
     342: pop
     343: new           #56                 // class java/lang/StringBuffer
     346: dup
     347: invokespecial #57                 // Method java/lang/StringBuffer."<init>":()V
     350: astore        12
     352: iinc          11, 1
     355: goto          95
     358: nop
     359: nop
     360: goto          32
     363: nop
     364: aload_1
     365: astore_2
     366: nop
     367: iconst_0
     368: istore_3
     369: aload_2
     370: astore        4
     372: new           #127                // class java/util/LinkedHashMap
     375: dup
     376: invokespecial #128                // Method java/util/LinkedHashMap."<init>":()V
     379: checkcast     #130                // class java/util/Map
     382: astore        5
     384: iconst_0
     385: istore        6
     387: aload         4
     389: invokeinterface #155,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     394: invokeinterface #158,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
     399: astore        7
     401: aload         7
     403: invokeinterface #43,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     408: ifeq          482
     411: aload         7
     413: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     418: checkcast     #160                // class java/util/Map$Entry
     421: astore        8
     423: aload         8
     425: astore        9
     427: iconst_0
     428: istore        10
     430: aload         9
     432: invokeinterface #163,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     437: checkcast     #31                 // class java/util/List
     440: invokeinterface #166,  1          // InterfaceMethod java/util/List.size:()I
     445: iconst_2
     446: if_icmpne     453
     449: iconst_1
     450: goto          454
     453: iconst_0
     454: ifeq          401
     457: aload         5
     459: aload         8
     461: invokeinterface #169,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     466: aload         8
     468: invokeinterface #163,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     473: invokeinterface #151,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     478: pop
     479: goto          401
     482: aload         5
     484: nop
     485: astore_2
     486: nop
     487: iconst_0
     488: istore_3
     489: aload_2
     490: astore        4
     492: new           #28                 // class java/util/ArrayList
     495: dup
     496: aload_2
     497: invokeinterface #170,  1          // InterfaceMethod java/util/Map.size:()I
     502: invokespecial #173                // Method java/util/ArrayList."<init>":(I)V
     505: checkcast     #140                // class java/util/Collection
     508: astore        5
     510: iconst_0
     511: istore        6
     513: aload         4
     515: invokeinterface #155,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     520: invokeinterface #158,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
     525: astore        7
     527: aload         7
     529: invokeinterface #43,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     534: ifeq          655
     537: aload         7
     539: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     544: checkcast     #160                // class java/util/Map$Entry
     547: astore        8
     549: aload         5
     551: aload         8
     553: astore        9
     555: astore        20
     557: iconst_0
     558: istore        10
     560: aload         9
     562: invokeinterface #163,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     567: checkcast     #33                 // class java/lang/Iterable
     570: astore        11
     572: iconst_1
     573: istore        12
     575: iconst_0
     576: istore        13
     578: iload         12
     580: istore        14
     582: aload         11
     584: invokeinterface #37,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     589: astore        15
     591: aload         15
     593: invokeinterface #43,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     598: ifeq          637
     601: aload         15
     603: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     608: astore        16
     610: iload         14
     612: aload         16
     614: checkcast     #175                // class java/lang/Number
     617: invokevirtual #178                // Method java/lang/Number.intValue:()I
     620: istore        17
     622: istore        18
     624: iconst_0
     625: istore        19
     627: iload         18
     629: iload         17
     631: imul
     632: istore        14
     634: goto          591
     637: iload         14
     639: nop
     640: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     643: aload         20
     645: swap
     646: invokeinterface #179,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     651: pop
     652: goto          527
     655: aload         5
     657: checkcast     #31                 // class java/util/List
     660: nop
     661: checkcast     #33                 // class java/lang/Iterable
     664: invokestatic  #108                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     667: ireturn

  private final boolean isValidNumber(int, int, int);
    Code:
       0: new           #211                // class kotlin/ranges/IntRange
       3: dup
       4: iload_1
       5: iconst_1
       6: isub
       7: iconst_0
       8: invokestatic  #217                // Method java/lang/Math.max:(II)I
      11: iload_2
      12: iconst_1
      13: iadd
      14: aload_0
      15: getfield      #22                 // Field lines:Ljava/util/List;
      18: iconst_0
      19: invokeinterface #220,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      24: checkcast     #54                 // class java/lang/String
      27: invokevirtual #60                 // Method java/lang/String.length:()I
      30: invokestatic  #223                // Method java/lang/Math.min:(II)I
      33: invokespecial #226                // Method kotlin/ranges/IntRange."<init>":(II)V
      36: astore        4
      38: new           #211                // class kotlin/ranges/IntRange
      41: dup
      42: iload_3
      43: iconst_1
      44: isub
      45: iconst_0
      46: invokestatic  #217                // Method java/lang/Math.max:(II)I
      49: iload_3
      50: iconst_1
      51: iadd
      52: aload_0
      53: getfield      #22                 // Field lines:Ljava/util/List;
      56: invokeinterface #166,  1          // InterfaceMethod java/util/List.size:()I
      61: iconst_1
      62: isub
      63: invokestatic  #223                // Method java/lang/Math.min:(II)I
      66: invokespecial #226                // Method kotlin/ranges/IntRange."<init>":(II)V
      69: astore        5
      71: aload         4
      73: invokevirtual #229                // Method kotlin/ranges/IntRange.getFirst:()I
      76: istore        6
      78: aload         4
      80: invokevirtual #232                // Method kotlin/ranges/IntRange.getLast:()I
      83: istore        7
      85: iload         6
      87: iload         7
      89: if_icmpgt     177
      92: aload         5
      94: invokevirtual #229                // Method kotlin/ranges/IntRange.getFirst:()I
      97: istore        8
      99: aload         5
     101: invokevirtual #232                // Method kotlin/ranges/IntRange.getLast:()I
     104: istore        9
     106: iload         8
     108: iload         9
     110: if_icmpgt     164
     113: aload_0
     114: getfield      #22                 // Field lines:Ljava/util/List;
     117: iload         8
     119: invokeinterface #220,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     124: checkcast     #54                 // class java/lang/String
     127: iload         6
     129: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     132: istore        10
     134: iload         10
     136: invokestatic  #70                 // Method java/lang/Character.isDigit:(C)Z
     139: ifne          151
     142: iload         10
     144: bipush        46
     146: if_icmpeq     151
     149: iconst_1
     150: ireturn
     151: iload         8
     153: iload         9
     155: if_icmpeq     164
     158: iinc          8, 1
     161: goto          113
     164: iload         6
     166: iload         7
     168: if_icmpeq     177
     171: iinc          6, 1
     174: goto          92
     177: iconst_0
     178: ireturn

  private final kotlin.Pair<java.lang.Integer, java.lang.Integer> getAdjacentStar(int, int, int);
    Code:
       0: new           #211                // class kotlin/ranges/IntRange
       3: dup
       4: iload_1
       5: iconst_1
       6: isub
       7: iconst_0
       8: invokestatic  #217                // Method java/lang/Math.max:(II)I
      11: iload_2
      12: iconst_1
      13: iadd
      14: aload_0
      15: getfield      #22                 // Field lines:Ljava/util/List;
      18: iconst_0
      19: invokeinterface #220,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      24: checkcast     #54                 // class java/lang/String
      27: invokevirtual #60                 // Method java/lang/String.length:()I
      30: invokestatic  #223                // Method java/lang/Math.min:(II)I
      33: invokespecial #226                // Method kotlin/ranges/IntRange."<init>":(II)V
      36: astore        4
      38: new           #211                // class kotlin/ranges/IntRange
      41: dup
      42: iload_3
      43: iconst_1
      44: isub
      45: iconst_0
      46: invokestatic  #217                // Method java/lang/Math.max:(II)I
      49: iload_3
      50: iconst_1
      51: iadd
      52: aload_0
      53: getfield      #22                 // Field lines:Ljava/util/List;
      56: invokeinterface #166,  1          // InterfaceMethod java/util/List.size:()I
      61: iconst_1
      62: isub
      63: invokestatic  #223                // Method java/lang/Math.min:(II)I
      66: invokespecial #226                // Method kotlin/ranges/IntRange."<init>":(II)V
      69: astore        5
      71: aload         4
      73: invokevirtual #229                // Method kotlin/ranges/IntRange.getFirst:()I
      76: istore        6
      78: aload         4
      80: invokevirtual #232                // Method kotlin/ranges/IntRange.getLast:()I
      83: istore        7
      85: iload         6
      87: iload         7
      89: if_icmpgt     185
      92: aload         5
      94: invokevirtual #229                // Method kotlin/ranges/IntRange.getFirst:()I
      97: istore        8
      99: aload         5
     101: invokevirtual #232                // Method kotlin/ranges/IntRange.getLast:()I
     104: istore        9
     106: iload         8
     108: iload         9
     110: if_icmpgt     172
     113: aload_0
     114: getfield      #22                 // Field lines:Ljava/util/List;
     117: iload         8
     119: invokeinterface #220,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     124: checkcast     #54                 // class java/lang/String
     127: iload         6
     129: invokevirtual #64                 // Method java/lang/String.charAt:(I)C
     132: istore        10
     134: iload         10
     136: bipush        42
     138: if_icmpne     159
     141: new           #209                // class kotlin/Pair
     144: dup
     145: iload         8
     147: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     150: iload         6
     152: invokestatic  #100                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     155: invokespecial #243                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     158: areturn
     159: iload         8
     161: iload         9
     163: if_icmpeq     172
     166: iinc          8, 1
     169: goto          113
     172: iload         6
     174: iload         7
     176: if_icmpeq     185
     179: iinc          6, 1
     182: goto          92
     185: aconst_null
     186: areturn
}


package com.vaclavbohac.advent2023.day1

class Trebuchet(private val lines: List<String>) {
    fun sumCalibratedValues(): Int =
        lines.fold(0) { sum, line -> sum + (line.getFirstDigit() * 10 + line.reversed().getFirstDigit()) }

    fun sumCalibratedValuesAfterInterpolation(): Int =
        lines.fold(0) { sum, line -> sum + (line.getFirstInterpolatedNumber(INTERPOLATION_TABLE) * 10 + line.getLastInterpolatedNumber(INTERPOLATION_TABLE)) }

    companion object {
        val INTERPOLATION_TABLE = mapOf("one" to 1, "two" to 2, "three" to 3, "four" to 4, "five" to 5, "six" to 6, "seven" to 7, "eight" to 8, "nine" to 9)
    }
}

private fun String.getFirstDigit(): Int = this.first { c -> c.isDigit() }.digitToInt()

private fun String.getFirstInterpolatedNumber(numbers: Map<String, Int>): Int {
    this.forEachIndexed { i, c ->
        if (c.isDigit()) {
            return c.digitToInt()
        }

        for (number in numbers) {
            if (this.startsWith(number.key, i)) {
                return number.value
            }
        }
    }

    return -1
}

private fun String.getLastInterpolatedNumber(numbers: Map<String, Int>): Int =
    this.reversed().getFirstInterpolatedNumber(numbers.mapKeys { it.key.reversed() } )

Compiled from "Trebuchet.kt"
public final class com.vaclavbohac.advent2023.day1.TrebuchetKt {
  private static final int getFirstDigit(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #8                  // class java/lang/CharSequence
       4: astore_1
       5: iconst_0
       6: istore_2
       7: iconst_0
       8: istore_3
       9: iload_3
      10: aload_1
      11: invokeinterface #12,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      16: if_icmpge     55
      19: aload_1
      20: iload_3
      21: invokeinterface #16,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      26: istore        4
      28: iload         4
      30: istore        5
      32: iconst_0
      33: istore        6
      35: iload         5
      37: invokestatic  #22                 // Method java/lang/Character.isDigit:(C)Z
      40: nop
      41: ifeq          49
      44: iload         4
      46: goto          65
      49: iinc          3, 1
      52: goto          9
      55: new           #24                 // class java/util/NoSuchElementException
      58: dup
      59: ldc           #26                 // String Char sequence contains no character matching the predicate.
      61: invokespecial #30                 // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
      64: athrow
      65: invokestatic  #36                 // Method kotlin/text/CharsKt.digitToInt:(C)I
      68: ireturn

  private static final int getFirstInterpolatedNumber(java.lang.String, java.util.Map<java.lang.String, java.lang.Integer>);
    Code:
       0: aload_0
       1: checkcast     #8                  // class java/lang/CharSequence
       4: astore_2
       5: iconst_0
       6: istore_3
       7: iconst_0
       8: istore        4
      10: iconst_0
      11: istore        5
      13: iload         5
      15: aload_2
      16: invokeinterface #12,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      21: if_icmpge     141
      24: aload_2
      25: iload         5
      27: invokeinterface #16,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      32: istore        6
      34: iload         4
      36: iinc          4, 1
      39: iload         6
      41: istore        7
      43: istore        8
      45: iconst_0
      46: istore        9
      48: iload         7
      50: invokestatic  #22                 // Method java/lang/Character.isDigit:(C)Z
      53: ifeq          62
      56: iload         7
      58: invokestatic  #36                 // Method kotlin/text/CharsKt.digitToInt:(C)I
      61: ireturn
      62: aload_1
      63: invokeinterface #57,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      68: invokeinterface #63,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      73: astore        10
      75: aload         10
      77: invokeinterface #69,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      82: ifeq          133
      85: aload         10
      87: invokeinterface #73,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      92: checkcast     #75                 // class java/util/Map$Entry
      95: astore        11
      97: aload_0
      98: aload         11
     100: invokeinterface #78,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     105: checkcast     #48                 // class java/lang/String
     108: iload         8
     110: iconst_0
     111: iconst_4
     112: aconst_null
     113: invokestatic  #84                 // Method kotlin/text/StringsKt.startsWith$default:(Ljava/lang/String;Ljava/lang/String;IZILjava/lang/Object;)Z
     116: ifeq          75
     119: aload         11
     121: invokeinterface #87,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     126: checkcast     #89                 // class java/lang/Number
     129: invokevirtual #92                 // Method java/lang/Number.intValue:()I
     132: ireturn
     133: nop
     134: nop
     135: iinc          5, 1
     138: goto          13
     141: nop
     142: iconst_m1
     143: ireturn

  private static final int getLastInterpolatedNumber(java.lang.String, java.util.Map<java.lang.String, java.lang.Integer>);
    Code:
       0: aload_0
       1: checkcast     #8                  // class java/lang/CharSequence
       4: invokestatic  #108                // Method kotlin/text/StringsKt.reversed:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
       7: invokevirtual #112                // Method java/lang/Object.toString:()Ljava/lang/String;
      10: aload_1
      11: astore_2
      12: astore        17
      14: iconst_0
      15: istore_3
      16: aload_2
      17: astore        4
      19: new           #114                // class java/util/LinkedHashMap
      22: dup
      23: aload_2
      24: invokeinterface #117,  1          // InterfaceMethod java/util/Map.size:()I
      29: invokestatic  #123                // Method kotlin/collections/MapsKt.mapCapacity:(I)I
      32: invokespecial #126                // Method java/util/LinkedHashMap."<init>":(I)V
      35: checkcast     #53                 // class java/util/Map
      38: astore        5
      40: iconst_0
      41: istore        6
      43: aload         4
      45: invokeinterface #57,  1           // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      50: checkcast     #128                // class java/lang/Iterable
      53: astore        7
      55: iconst_0
      56: istore        8
      58: aload         7
      60: invokeinterface #129,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      65: astore        9
      67: aload         9
      69: invokeinterface #69,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      74: ifeq          161
      77: aload         9
      79: invokeinterface #73,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      84: astore        10
      86: aload         5
      88: aload         10
      90: checkcast     #75                 // class java/util/Map$Entry
      93: astore        11
      95: astore        18
      97: iconst_0
      98: istore        12
     100: aload         11
     102: invokeinterface #78,  1           // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     107: checkcast     #48                 // class java/lang/String
     110: checkcast     #8                  // class java/lang/CharSequence
     113: invokestatic  #108                // Method kotlin/text/StringsKt.reversed:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     116: invokevirtual #112                // Method java/lang/Object.toString:()Ljava/lang/String;
     119: nop
     120: aload         18
     122: swap
     123: aload         10
     125: checkcast     #75                 // class java/util/Map$Entry
     128: astore        13
     130: astore        14
     132: astore        15
     134: iconst_0
     135: istore        16
     137: aload         13
     139: invokeinterface #87,  1           // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     144: astore        11
     146: aload         15
     148: aload         14
     150: aload         11
     152: invokeinterface #133,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     157: pop
     158: goto          67
     161: aload         5
     163: nop
     164: nop
     165: aload         17
     167: swap
     168: invokestatic  #135                // Method getFirstInterpolatedNumber:(Ljava/lang/String;Ljava/util/Map;)I
     171: ireturn

  public static final int access$getFirstDigit(java.lang.String);
    Code:
       0: aload_0
       1: invokestatic  #153                // Method getFirstDigit:(Ljava/lang/String;)I
       4: ireturn

  public static final int access$getFirstInterpolatedNumber(java.lang.String, java.util.Map);
    Code:
       0: aload_0
       1: aload_1
       2: invokestatic  #135                // Method getFirstInterpolatedNumber:(Ljava/lang/String;Ljava/util/Map;)I
       5: ireturn

  public static final int access$getLastInterpolatedNumber(java.lang.String, java.util.Map);
    Code:
       0: aload_0
       1: aload_1
       2: invokestatic  #158                // Method getLastInterpolatedNumber:(Ljava/lang/String;Ljava/util/Map;)I
       5: ireturn
}

Compiled from "Trebuchet.kt"
public final class com.vaclavbohac.advent2023.day1.Trebuchet {
  public static final com.vaclavbohac.advent2023.day1.Trebuchet$Companion Companion;

  private final java.util.List<java.lang.String> lines;

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

  public com.vaclavbohac.advent2023.day1.Trebuchet(java.util.List<java.lang.String>);
    Code:
       0: aload_1
       1: ldc           #10                 // String lines
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokespecial #19                 // Method java/lang/Object."<init>":()V
      10: aload_0
      11: aload_1
      12: putfield      #22                 // Field lines:Ljava/util/List;
      15: return

  public final int sumCalibratedValues();
    Code:
       0: aload_0
       1: getfield      #22                 // Field lines:Ljava/util/List;
       4: checkcast     #28                 // class java/lang/Iterable
       7: astore_1
       8: iconst_0
       9: istore_2
      10: iconst_0
      11: istore_3
      12: iload_2
      13: istore        4
      15: aload_1
      16: invokeinterface #32,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      21: astore        5
      23: aload         5
      25: invokeinterface #38,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      30: ifeq          87
      33: aload         5
      35: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      40: astore        6
      42: iload         4
      44: aload         6
      46: checkcast     #44                 // class java/lang/String
      49: astore        7
      51: istore        8
      53: iconst_0
      54: istore        9
      56: iload         8
      58: aload         7
      60: invokestatic  #50                 // Method com/vaclavbohac/advent2023/day1/TrebuchetKt.access$getFirstDigit:(Ljava/lang/String;)I
      63: bipush        10
      65: imul
      66: aload         7
      68: checkcast     #52                 // class java/lang/CharSequence
      71: invokestatic  #58                 // Method kotlin/text/StringsKt.reversed:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      74: invokevirtual #62                 // Method java/lang/Object.toString:()Ljava/lang/String;
      77: invokestatic  #50                 // Method com/vaclavbohac/advent2023/day1/TrebuchetKt.access$getFirstDigit:(Ljava/lang/String;)I
      80: iadd
      81: iadd
      82: istore        4
      84: goto          23
      87: iload         4
      89: ireturn

  public final int sumCalibratedValuesAfterInterpolation();
    Code:
       0: aload_0
       1: getfield      #22                 // Field lines:Ljava/util/List;
       4: checkcast     #28                 // class java/lang/Iterable
       7: astore_1
       8: iconst_0
       9: istore_2
      10: iconst_0
      11: istore_3
      12: iload_2
      13: istore        4
      15: aload_1
      16: invokeinterface #32,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      21: astore        5
      23: aload         5
      25: invokeinterface #38,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      30: ifeq          84
      33: aload         5
      35: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      40: astore        6
      42: iload         4
      44: aload         6
      46: checkcast     #44                 // class java/lang/String
      49: astore        7
      51: istore        8
      53: iconst_0
      54: istore        9
      56: iload         8
      58: aload         7
      60: getstatic     #79                 // Field INTERPOLATION_TABLE:Ljava/util/Map;
      63: invokestatic  #83                 // Method com/vaclavbohac/advent2023/day1/TrebuchetKt.access$getFirstInterpolatedNumber:(Ljava/lang/String;Ljava/util/Map;)I
      66: bipush        10
      68: imul
      69: aload         7
      71: getstatic     #79                 // Field INTERPOLATION_TABLE:Ljava/util/Map;
      74: invokestatic  #86                 // Method com/vaclavbohac/advent2023/day1/TrebuchetKt.access$getLastInterpolatedNumber:(Ljava/lang/String;Ljava/util/Map;)I
      77: iadd
      78: iadd
      79: istore        4
      81: goto          23
      84: iload         4
      86: ireturn

  public static final java.util.Map access$getINTERPOLATION_TABLE$cp();
    Code:
       0: getstatic     #79                 // Field INTERPOLATION_TABLE:Ljava/util/Map;
       3: areturn

  static {};
    Code:
       0: new           #92                 // class com/vaclavbohac/advent2023/day1/Trebuchet$Companion
       3: dup
       4: aconst_null
       5: invokespecial #95                 // Method com/vaclavbohac/advent2023/day1/Trebuchet$Companion."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #99                 // Field Companion:Lcom/vaclavbohac/advent2023/day1/Trebuchet$Companion;
      11: bipush        9
      13: anewarray     #101                // class kotlin/Pair
      16: astore_0
      17: aload_0
      18: iconst_0
      19: ldc           #103                // String one
      21: iconst_1
      22: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      25: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      28: aastore
      29: aload_0
      30: iconst_1
      31: ldc           #117                // String two
      33: iconst_2
      34: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      37: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      40: aastore
      41: aload_0
      42: iconst_2
      43: ldc           #119                // String three
      45: iconst_3
      46: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      49: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      52: aastore
      53: aload_0
      54: iconst_3
      55: ldc           #121                // String four
      57: iconst_4
      58: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      61: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      64: aastore
      65: aload_0
      66: iconst_4
      67: ldc           #123                // String five
      69: iconst_5
      70: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      73: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      76: aastore
      77: aload_0
      78: iconst_5
      79: ldc           #125                // String six
      81: bipush        6
      83: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      86: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      89: aastore
      90: aload_0
      91: bipush        6
      93: ldc           #127                // String seven
      95: bipush        7
      97: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     100: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     103: aastore
     104: aload_0
     105: bipush        7
     107: ldc           #129                // String eight
     109: bipush        8
     111: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     114: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     117: aastore
     118: aload_0
     119: bipush        8
     121: ldc           #131                // String nine
     123: bipush        9
     125: invokestatic  #109                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     128: invokestatic  #115                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     131: aastore
     132: aload_0
     133: invokestatic  #137                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     136: putstatic     #79                 // Field INTERPOLATION_TABLE:Ljava/util/Map;
     139: return
}

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

  public final java.util.Map<java.lang.String, java.lang.Integer> getINTERPOLATION_TABLE();
    Code:
       0: invokestatic  #19                 // Method com/vaclavbohac/advent2023/day1/Trebuchet.access$getINTERPOLATION_TABLE$cp:()Ljava/util/Map;
       3: areturn

  public com.vaclavbohac.advent2023.day1.Trebuchet$Companion(kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: aload_0
       1: invokespecial #21                 // Method "<init>":()V
       4: return
}


package com.liueq.leetcode.easy

import java.util.*

/**
 * 问题描述：给定两个数组 nums1, nums2。其中 1 是 2的子集。求nums1 每一个element 在 nums2 中的位置，往后最大的数字。如果不存在，用 -1 代替。
 * 比如： [4, 1, 2]
 *       [1, 3, 4, 2]
 *       =
 *       [-1, 3, -1] 因为 4 在 nums2 中往后只有一个 2，不比4大，所以不存在；1在 nums2 中，往后第一个比 1 大的是3，所以返回3。同理。
 *
 * 解：先求出 nums2 每一个 element 往后的第一个更大的值，保存在 map 中。遍历 nums1，从 map 取出即可，如果不存在，说明是 -1
 */
class NextGreaterElementI

fun main(args: Array<String>) {
    nextGreaterElement(intArrayOf(4, 1, 2), intArrayOf(1, 3, 4, 2)).apply {
        for (i in this) {
            print("$i,")
        }
        println()
    }

    nextGreaterElement(intArrayOf(2, 4), intArrayOf(1, 2, 3, 4)).apply {
        for (i in this) {
            print("$i,")
        }
        println()
    }
}

fun nextGreaterElement(nums1: IntArray, nums2: IntArray): IntArray {
    var map = HashMap<Int, Int>()
    for (i in 0.until(nums2.size)) {
        var nextGreater = -1
        for (j in (i + 1).until(nums2.size)) {
            if (nums2[i] < nums2[j]) {
                nextGreater = nums2[j]
                map[nums2[i]] = nextGreater
                break
            }
        }
    }

    nums1.mapIndexed { index, value ->
        if (map[value] == null)
            nums1[index] = -1
        else
            nums1[index] = map[value]!!
    }

    return nums1
}

Compiled from "NextGreaterElementI.kt"
public final class com.liueq.leetcode.easy.NextGreaterElementI {
  public com.liueq.leetcode.easy.NextGreaterElementI();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return
}

Compiled from "NextGreaterElementI.kt"
public final class com.liueq.leetcode.easy.NextGreaterElementIKt {
  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_3
       7: newarray       int
       9: astore_1
      10: aload_1
      11: iconst_0
      12: iconst_4
      13: iastore
      14: aload_1
      15: iconst_1
      16: iconst_1
      17: iastore
      18: aload_1
      19: iconst_2
      20: iconst_2
      21: iastore
      22: aload_1
      23: iconst_4
      24: newarray       int
      26: astore_1
      27: aload_1
      28: iconst_0
      29: iconst_1
      30: iastore
      31: aload_1
      32: iconst_1
      33: iconst_3
      34: iastore
      35: aload_1
      36: iconst_2
      37: iconst_4
      38: iastore
      39: aload_1
      40: iconst_3
      41: iconst_2
      42: iastore
      43: aload_1
      44: invokestatic  #19                 // Method nextGreaterElement:([I[I)[I
      47: astore_1
      48: aload_1
      49: astore_2
      50: iconst_0
      51: istore_3
      52: iconst_0
      53: istore        4
      55: aload_2
      56: arraylength
      57: istore        5
      59: iload         4
      61: iload         5
      63: if_icmpge     105
      66: aload_2
      67: iload         4
      69: iaload
      70: istore        6
      72: new           #21                 // class java/lang/StringBuilder
      75: dup
      76: invokespecial #25                 // Method java/lang/StringBuilder."<init>":()V
      79: iload         6
      81: invokevirtual #29                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      84: bipush        44
      86: invokevirtual #32                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      89: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      92: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
      95: swap
      96: invokevirtual #48                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
      99: iinc          4, 1
     102: goto          59
     105: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     108: invokevirtual #51                 // Method java/io/PrintStream.println:()V
     111: nop
     112: nop
     113: iconst_2
     114: newarray       int
     116: astore_1
     117: aload_1
     118: iconst_0
     119: iconst_2
     120: iastore
     121: aload_1
     122: iconst_1
     123: iconst_4
     124: iastore
     125: aload_1
     126: iconst_4
     127: newarray       int
     129: astore_1
     130: aload_1
     131: iconst_0
     132: iconst_1
     133: iastore
     134: aload_1
     135: iconst_1
     136: iconst_2
     137: iastore
     138: aload_1
     139: iconst_2
     140: iconst_3
     141: iastore
     142: aload_1
     143: iconst_3
     144: iconst_4
     145: iastore
     146: aload_1
     147: invokestatic  #19                 // Method nextGreaterElement:([I[I)[I
     150: astore_1
     151: aload_1
     152: astore_2
     153: iconst_0
     154: istore_3
     155: iconst_0
     156: istore        4
     158: aload_2
     159: arraylength
     160: istore        5
     162: iload         4
     164: iload         5
     166: if_icmpge     208
     169: aload_2
     170: iload         4
     172: iaload
     173: istore        6
     175: new           #21                 // class java/lang/StringBuilder
     178: dup
     179: invokespecial #25                 // Method java/lang/StringBuilder."<init>":()V
     182: iload         6
     184: invokevirtual #29                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     187: bipush        44
     189: invokevirtual #32                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     192: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     195: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     198: swap
     199: invokevirtual #48                 // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     202: iinc          4, 1
     205: goto          162
     208: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
     211: invokevirtual #51                 // Method java/io/PrintStream.println:()V
     214: nop
     215: nop
     216: return

  public static final int[] nextGreaterElement(int[], int[]);
    Code:
       0: aload_0
       1: ldc           #63                 // String nums1
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #65                 // String nums2
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aconst_null
      13: astore_2
      14: new           #67                 // class java/util/HashMap
      17: dup
      18: invokespecial #68                 // Method java/util/HashMap."<init>":()V
      21: astore_2
      22: iconst_0
      23: istore_3
      24: aload_1
      25: arraylength
      26: istore        4
      28: iload_3
      29: iload         4
      31: if_icmpge     109
      34: iconst_m1
      35: istore        5
      37: iload_3
      38: iconst_1
      39: iadd
      40: istore        6
      42: aload_1
      43: arraylength
      44: istore        7
      46: iload         6
      48: iload         7
      50: if_icmpge     103
      53: aload_1
      54: iload_3
      55: iaload
      56: aload_1
      57: iload         6
      59: iaload
      60: if_icmpge     97
      63: aload_1
      64: iload         6
      66: iaload
      67: istore        5
      69: iload         5
      71: invokestatic  #74                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      74: astore        10
      76: aload_2
      77: checkcast     #76                 // class java/util/Map
      80: aload_1
      81: iload_3
      82: iaload
      83: invokestatic  #74                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      86: aload         10
      88: invokeinterface #80,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      93: pop
      94: goto          103
      97: iinc          6, 1
     100: goto          46
     103: iinc          3, 1
     106: goto          28
     109: aload_0
     110: astore_3
     111: iconst_0
     112: istore        4
     114: aload_3
     115: astore        5
     117: new           #82                 // class java/util/ArrayList
     120: dup
     121: aload_3
     122: arraylength
     123: invokespecial #85                 // Method java/util/ArrayList."<init>":(I)V
     126: checkcast     #87                 // class java/util/Collection
     129: astore        6
     131: iconst_0
     132: istore        7
     134: iconst_0
     135: istore        8
     137: iconst_0
     138: istore        9
     140: aload         5
     142: arraylength
     143: istore        10
     145: iload         9
     147: iload         10
     149: if_icmpge     238
     152: aload         5
     154: iload         9
     156: iaload
     157: istore        11
     159: aload         6
     161: iload         8
     163: iinc          8, 1
     166: iload         11
     168: istore        12
     170: istore        13
     172: astore        15
     174: iconst_0
     175: istore        14
     177: aload_2
     178: iload         12
     180: invokestatic  #74                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     183: invokevirtual #91                 // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     186: ifnonnull     197
     189: aload_0
     190: iload         13
     192: iconst_m1
     193: iastore
     194: goto          220
     197: aload_0
     198: iload         13
     200: aload_2
     201: iload         12
     203: invokestatic  #74                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     206: invokevirtual #91                 // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     209: dup
     210: invokestatic  #94                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     213: checkcast     #96                 // class java/lang/Number
     216: invokevirtual #100                // Method java/lang/Number.intValue:()I
     219: iastore
     220: nop
     221: aload         15
     223: getstatic     #106                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     226: invokeinterface #110,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     231: pop
     232: iinc          9, 1
     235: goto          145
     238: aload         6
     240: checkcast     #112                // class java/util/List
     243: nop
     244: pop
     245: aload_0
     246: areturn
}


package lain

import kotlin.math.abs

data class Range(val min:Int, val max: Int) {
    init {
        if (min > max) {
            throw Exception("Range created with min greater than max, min: $min max: $max")
        }
    }

    companion object {
        fun and(a:Range, b:Range):Range {
            val min = if (a.min <= b.min) b.min
            else a.min

            val max = if (a.max >= b.max) b.max
            else a.max

            return Range(min, max)
        }

        fun or(a:Range, b:Range):Range {
            // lowest min, highest max
            val min = if (a.min <= b.min) a.min
            else b.min

            val max = if (a.max <= b.max) b.max
            else a.max

            return Range(min, max)
        }

        // subtract b from a, will return values that are in a but not in b
        fun subtract (a: Range, b: Range): List<Range> {
            if (!overlaps(a, b)) return listOf(a)

            // if b is completely inside a, eg it will split a into two ranges
            if (b.min > a.min &&  b.max < a.max) {
                return listOf(
                        Range(a.min, b.min - 1),
                        Range(b.max + 1, a.max)
                )
            }

            // if b is overlapping the top of a
            if (b.max >= a.max) return listOf(Range(a.min, b.min - 1))

            // else, b is overlapping the bottom  of a
            return listOf(Range(b.max + 1, a.max))
        }

        // returns true if the two input ranges overlap, false if they don't
        fun overlaps(a: Range, b:Range):Boolean {
            if (a.min > b.max) return false
            if (b.min > a.max) return false
            return true
        }
    }

    fun isEmpty():Boolean {
        if (this.min >= this.max) return true
        return false
    }

    // returns the difference between min and max
    fun width(): Int {
        return (abs(this.min - this.max))
    }
}

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

  public final lain.Range and(lain.Range, lain.Range);
    Code:
       0: aload_1
       1: ldc           #15                 // String a
       3: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #23                 // String b
       9: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: invokevirtual #29                 // Method lain/Range.getMin:()I
      16: aload_2
      17: invokevirtual #29                 // Method lain/Range.getMin:()I
      20: if_icmpgt     30
      23: aload_2
      24: invokevirtual #29                 // Method lain/Range.getMin:()I
      27: goto          34
      30: aload_1
      31: invokevirtual #29                 // Method lain/Range.getMin:()I
      34: istore_3
      35: aload_1
      36: invokevirtual #32                 // Method lain/Range.getMax:()I
      39: aload_2
      40: invokevirtual #32                 // Method lain/Range.getMax:()I
      43: if_icmplt     53
      46: aload_2
      47: invokevirtual #32                 // Method lain/Range.getMax:()I
      50: goto          57
      53: aload_1
      54: invokevirtual #32                 // Method lain/Range.getMax:()I
      57: istore        4
      59: new           #25                 // class lain/Range
      62: dup
      63: iload_3
      64: iload         4
      66: invokespecial #35                 // Method lain/Range."<init>":(II)V
      69: areturn

  public final lain.Range or(lain.Range, lain.Range);
    Code:
       0: aload_1
       1: ldc           #15                 // String a
       3: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #23                 // String b
       9: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: invokevirtual #29                 // Method lain/Range.getMin:()I
      16: aload_2
      17: invokevirtual #29                 // Method lain/Range.getMin:()I
      20: if_icmpgt     30
      23: aload_1
      24: invokevirtual #29                 // Method lain/Range.getMin:()I
      27: goto          34
      30: aload_2
      31: invokevirtual #29                 // Method lain/Range.getMin:()I
      34: istore_3
      35: aload_1
      36: invokevirtual #32                 // Method lain/Range.getMax:()I
      39: aload_2
      40: invokevirtual #32                 // Method lain/Range.getMax:()I
      43: if_icmpgt     53
      46: aload_2
      47: invokevirtual #32                 // Method lain/Range.getMax:()I
      50: goto          57
      53: aload_1
      54: invokevirtual #32                 // Method lain/Range.getMax:()I
      57: istore        4
      59: new           #25                 // class lain/Range
      62: dup
      63: iload_3
      64: iload         4
      66: invokespecial #35                 // Method lain/Range."<init>":(II)V
      69: areturn

  public final java.util.List<lain.Range> subtract(lain.Range, lain.Range);
    Code:
       0: aload_1
       1: ldc           #15                 // String a
       3: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #23                 // String b
       9: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: aload_1
      14: aload_2
      15: invokevirtual #47                 // Method overlaps:(Llain/Range;Llain/Range;)Z
      18: ifne          26
      21: aload_1
      22: invokestatic  #53                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      25: areturn
      26: aload_2
      27: invokevirtual #29                 // Method lain/Range.getMin:()I
      30: aload_1
      31: invokevirtual #29                 // Method lain/Range.getMin:()I
      34: if_icmple     98
      37: aload_2
      38: invokevirtual #32                 // Method lain/Range.getMax:()I
      41: aload_1
      42: invokevirtual #32                 // Method lain/Range.getMax:()I
      45: if_icmpge     98
      48: iconst_2
      49: anewarray     #25                 // class lain/Range
      52: astore_3
      53: aload_3
      54: iconst_0
      55: new           #25                 // class lain/Range
      58: dup
      59: aload_1
      60: invokevirtual #29                 // Method lain/Range.getMin:()I
      63: aload_2
      64: invokevirtual #29                 // Method lain/Range.getMin:()I
      67: iconst_1
      68: isub
      69: invokespecial #35                 // Method lain/Range."<init>":(II)V
      72: aastore
      73: aload_3
      74: iconst_1
      75: new           #25                 // class lain/Range
      78: dup
      79: aload_2
      80: invokevirtual #32                 // Method lain/Range.getMax:()I
      83: iconst_1
      84: iadd
      85: aload_1
      86: invokevirtual #32                 // Method lain/Range.getMax:()I
      89: invokespecial #35                 // Method lain/Range."<init>":(II)V
      92: aastore
      93: aload_3
      94: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      97: areturn
      98: aload_2
      99: invokevirtual #32                 // Method lain/Range.getMax:()I
     102: aload_1
     103: invokevirtual #32                 // Method lain/Range.getMax:()I
     106: if_icmplt     130
     109: new           #25                 // class lain/Range
     112: dup
     113: aload_1
     114: invokevirtual #29                 // Method lain/Range.getMin:()I
     117: aload_2
     118: invokevirtual #29                 // Method lain/Range.getMin:()I
     121: iconst_1
     122: isub
     123: invokespecial #35                 // Method lain/Range."<init>":(II)V
     126: invokestatic  #53                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
     129: areturn
     130: new           #25                 // class lain/Range
     133: dup
     134: aload_2
     135: invokevirtual #32                 // Method lain/Range.getMax:()I
     138: iconst_1
     139: iadd
     140: aload_1
     141: invokevirtual #32                 // Method lain/Range.getMax:()I
     144: invokespecial #35                 // Method lain/Range."<init>":(II)V
     147: invokestatic  #53                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
     150: areturn

  public final boolean overlaps(lain.Range, lain.Range);
    Code:
       0: aload_1
       1: ldc           #15                 // String a
       3: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #23                 // String b
       9: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: invokevirtual #29                 // Method lain/Range.getMin:()I
      16: aload_2
      17: invokevirtual #32                 // Method lain/Range.getMax:()I
      20: if_icmple     25
      23: iconst_0
      24: ireturn
      25: aload_2
      26: invokevirtual #29                 // Method lain/Range.getMin:()I
      29: aload_1
      30: invokevirtual #32                 // Method lain/Range.getMax:()I
      33: if_icmple     38
      36: iconst_0
      37: ireturn
      38: iconst_1
      39: ireturn

  public lain.Range$Companion(kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: aload_0
       1: invokespecial #58                 // Method "<init>":()V
       4: return
}

Compiled from "Range.kt"
public final class lain.Range {
  public static final lain.Range$Companion Companion;

  private final int min;

  private final int max;

  public lain.Range(int, int);
    Code:
       0: aload_0
       1: invokespecial #9                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iload_1
       6: putfield      #13                 // Field min:I
       9: aload_0
      10: iload_2
      11: putfield      #16                 // Field max:I
      14: nop
      15: aload_0
      16: getfield      #13                 // Field min:I
      19: aload_0
      20: getfield      #16                 // Field max:I
      23: if_icmple     68
      26: new           #18                 // class java/lang/Exception
      29: dup
      30: new           #20                 // class java/lang/StringBuilder
      33: dup
      34: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      37: ldc           #23                 // String Range created with min greater than max, min:
      39: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      42: aload_0
      43: getfield      #13                 // Field min:I
      46: invokevirtual #30                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      49: ldc           #32                 // String  max:
      51: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      54: aload_0
      55: getfield      #16                 // Field max:I
      58: invokevirtual #30                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      61: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      64: invokespecial #39                 // Method java/lang/Exception."<init>":(Ljava/lang/String;)V
      67: athrow
      68: nop
      69: return

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

  public final int getMax();
    Code:
       0: aload_0
       1: getfield      #16                 // Field max:I
       4: ireturn

  public final boolean isEmpty();
    Code:
       0: aload_0
       1: getfield      #13                 // Field min:I
       4: aload_0
       5: getfield      #16                 // Field max:I
       8: if_icmplt     13
      11: iconst_1
      12: ireturn
      13: iconst_0
      14: ireturn

  public final int width();
    Code:
       0: aload_0
       1: getfield      #13                 // Field min:I
       4: aload_0
       5: getfield      #16                 // Field max:I
       8: isub
       9: invokestatic  #53                 // Method java/lang/Math.abs:(I)I
      12: ireturn

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

  public final int component2();
    Code:
       0: aload_0
       1: getfield      #16                 // Field max:I
       4: ireturn

  public final lain.Range copy(int, int);
    Code:
       0: new           #2                  // class lain/Range
       3: dup
       4: iload_1
       5: iload_2
       6: invokespecial #60                 // Method "<init>":(II)V
       9: areturn

  public static lain.Range copy$default(lain.Range, int, int, int, java.lang.Object);
    Code:
       0: iload_3
       1: iconst_1
       2: iand
       3: ifeq          11
       6: aload_0
       7: getfield      #13                 // Field min:I
      10: istore_1
      11: iload_3
      12: iconst_2
      13: iand
      14: ifeq          22
      17: aload_0
      18: getfield      #16                 // Field max:I
      21: istore_2
      22: aload_0
      23: iload_1
      24: iload_2
      25: invokevirtual #64                 // Method copy:(II)Llain/Range;
      28: areturn

  public java.lang.String toString();
    Code:
       0: new           #20                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #66                 // String Range(min=
       9: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #13                 // Field min:I
      16: invokevirtual #30                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      19: ldc           #68                 // String , max=
      21: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #16                 // Field max:I
      28: invokevirtual #30                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      31: bipush        41
      33: invokevirtual #71                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      36: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn

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

  public boolean equals(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: if_acmpne     7
       5: iconst_1
       6: ireturn
       7: aload_1
       8: instanceof    #2                  // class lain/Range
      11: ifne          16
      14: iconst_0
      15: ireturn
      16: aload_1
      17: checkcast     #2                  // class lain/Range
      20: astore_2
      21: aload_0
      22: getfield      #13                 // Field min:I
      25: aload_2
      26: getfield      #13                 // Field min:I
      29: if_icmpeq     34
      32: iconst_0
      33: ireturn
      34: aload_0
      35: getfield      #16                 // Field max:I
      38: aload_2
      39: getfield      #16                 // Field max:I
      42: if_icmpeq     47
      45: iconst_0
      46: ireturn
      47: iconst_1
      48: ireturn

  static {};
    Code:
       0: new           #85                 // class lain/Range$Companion
       3: dup
       4: aconst_null
       5: invokespecial #88                 // Method lain/Range$Companion."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #92                 // Field Companion:Llain/Range$Companion;
      11: return
}