package task_10

import java.io.File
import java.lang.Integer.max
import java.lang.Integer.min

class App {
    fun solveFirst(input: List<String>): Int {
        val map = Map(input)
        var (_, asteroids) = map.getBestLocation()
        return asteroids.size
    }

    fun solveSecond(input: List<String>): Int {
        return -1
    }
}

class Map(input: List<String>) {
    var map = mutableListOf<List<Int>>()
    var asteroids = mutableListOf<Point>()

    init {
        for ((y, line) in input.withIndex()) {
            val row = mutableListOf<Int>()

            for ((x, value) in line.withIndex()) {
                val fieldValue = value.getFieldValue()
                if (fieldValue.isAsteroid()) {
                    asteroids.add(Point(x, y))
                }

                row.add(fieldValue)
            }

            map.add(row)
        }
    }

    fun getBestLocation(): Pair<Point, List<Point>> {
        var bestPosition = Point(0, 0)
        var bestVisibleAsteroids = listOf<Point>()

        //TODO use channels
        for (asteroid in asteroids) {
            val visibleAsteroids = getVisibleAsteroids(asteroid, asteroids)

            if (visibleAsteroids.size > bestVisibleAsteroids.size) {
                bestPosition = asteroid
                bestVisibleAsteroids = visibleAsteroids
            }
        }

        return Pair(bestPosition, bestVisibleAsteroids)
    }

    private fun getVisibleAsteroids(asteroid: Point, asteroids: MutableList<Point>): List<Point> {
        val visibleAsteroids = mutableListOf<Point>()

        for (asteroidToCheck in asteroids) {
            if (asteroid == asteroidToCheck) {
                continue
            }

            if (hiddenByAsteroids(asteroids, asteroid, asteroidToCheck)) {
                continue
            }

            visibleAsteroids.add(asteroidToCheck)
        }

        return visibleAsteroids
    }

    private fun hiddenByAsteroids(asteroids: MutableList<Point>, fromPoint: Point, toPoint: Point): Boolean {
        for (asteroid in asteroids) {
            if (fromPoint != asteroid && toPoint != asteroid
                    && isOnSegment(asteroid, fromPoint, toPoint)) {
                return true
            }
        }

        return false
    }

    fun isOnSegment(point: Point, lineStart: Point, lineEnd: Point): Boolean {
        val isOnLine = ((lineStart.y - lineEnd.y) * point.x
                + (lineEnd.x - lineStart.x) * point.y
                + (lineStart.x * lineEnd.y - lineEnd.x * lineStart.y) == 0)

        if (!isOnLine) {
            return false
        }

        return point.x > min(lineStart.x, lineEnd.x) && point.x < max(lineStart.x, lineEnd.x)
                && point.y > min(lineStart.y, lineEnd.y) && point.y < max(lineStart.y, lineEnd.y)
    }

    fun Char.getFieldValue(): Int {
        return when (this) {
            '.' -> 0
            '#' -> 1
            else -> throw RuntimeException("unknown value of '$this'")
        }
    }

    fun Int.isAsteroid(): Boolean {
        return this == 1
    }

    data class Point(val x: Int, val y: Int)

}

fun main() {
    val app = App()
    val input = File("input.txt").readLines()

    println(app.solveFirst(input))
    println(app.solveSecond(input))
}

Compiled from "App.kt"
public final class task_10.AppKt {
  public static final void main();
    Code:
       0: new           #8                  // class task_10/App
       3: dup
       4: invokespecial #11                 // Method task_10/App."<init>":()V
       7: astore_0
       8: new           #13                 // class java/io/File
      11: dup
      12: ldc           #15                 // String input.txt
      14: invokespecial #18                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      17: aconst_null
      18: iconst_1
      19: aconst_null
      20: invokestatic  #24                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      23: astore_1
      24: aload_0
      25: aload_1
      26: invokevirtual #28                 // Method task_10/App.solveFirst:(Ljava/util/List;)I
      29: istore_2
      30: getstatic     #34                 // Field java/lang/System.out:Ljava/io/PrintStream;
      33: iload_2
      34: invokevirtual #40                 // Method java/io/PrintStream.println:(I)V
      37: aload_0
      38: aload_1
      39: invokevirtual #43                 // Method task_10/App.solveSecond:(Ljava/util/List;)I
      42: istore_2
      43: getstatic     #34                 // Field java/lang/System.out:Ljava/io/PrintStream;
      46: iload_2
      47: invokevirtual #40                 // Method java/io/PrintStream.println:(I)V
      50: return

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

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

  public final int solveFirst(java.util.List<java.lang.String>);
    Code:
       0: aload_1
       1: ldc           #16                 // String input
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #24                 // class task_10/Map
       9: dup
      10: aload_1
      11: invokespecial #27                 // Method task_10/Map."<init>":(Ljava/util/List;)V
      14: astore_2
      15: aload_2
      16: invokevirtual #31                 // Method task_10/Map.getBestLocation:()Lkotlin/Pair;
      19: invokevirtual #37                 // Method kotlin/Pair.component2:()Ljava/lang/Object;
      22: checkcast     #39                 // class java/util/List
      25: astore_3
      26: aload_3
      27: invokeinterface #43,  1           // InterfaceMethod java/util/List.size:()I
      32: ireturn

  public final int solveSecond(java.util.List<java.lang.String>);
    Code:
       0: aload_1
       1: ldc           #16                 // String input
       3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_m1
       7: ireturn
}


package sudoku

data class Grid(val given: List<List<Int>>)

data class Guess(val position: Pair<Int,Int>, val number:Int)

data class Proposal(val original:Sudoku, val proposition: List<Guess>)

fun main(args: Array<String>) {
//  val grid1 = parse()
}

typealias Sudoku = List<List<Int>>

fun parse(text: List<String>): Sudoku {
  val parsed = text.map {
    it.trim()
  }.filter {
    it.isNotEmpty()
  }.map {
    it.filter {
      it in ('0'..'9')
    }.map {
      it.toInt() - '0'.toInt()
    }
  }

  if (parsed.size != 9) {
    throw IllegalArgumentException("The grid is not 9 lines long")
  }
  if (parsed.map { it.size }.any { it != 9 }) {
    throw IllegalArgumentException("All lines must be 9 numbers long")
  }

  return parsed
}

/**
 * Lists all the values contained in the given rectangle, bounds inclusive.
 */
fun listValues(
    sudoku: Sudoku,
    startRow: Int,
    startColumn: Int,
    endRow: Int,
    endColumn: Int
): List<Int> {
  return (startRow..endRow).flatMap { row ->
    (startColumn..endColumn).map { col ->
      sudoku[row][col]
    }
  }.filter { it != 0 }
}

fun listExistingValuesInSquare(
    sudoku: Sudoku,
    row: Int,
    column: Int
): List<Int> {
  val sRow = row / 3
  val sCol = column / 3
  return listValues(
      sudoku,
      sRow * 3,
      sCol * 3,
      (sRow + 1) * 3 - 1,
      (sCol + 1) * 3 - 1
  )
}

fun listExistingValuesInRow(sudoku: Sudoku, row: Int) =
    listValues(sudoku, row, 0, row, 8)

fun listExistingValuesInColumn(sudoku: Sudoku, column: Int) =
    listValues(sudoku, 0, column, 8, column)

fun options(sudoku: Sudoku, row: Int, column: Int): List<Int> {
  val rowValues = listExistingValuesInRow(sudoku, row)
  val columnValues = listExistingValuesInColumn(sudoku, column)
  val squareValues = listExistingValuesInSquare(sudoku, row, column)
  return (1..9).filter {
    it !in rowValues && it !in columnValues && it !in squareValues
  }
}

fun reject(origin: Sudoku, proposal: Sudoku, row: Int, col: Int): Boolean {
  val opt = options(origin, row, col)
  return proposal[row][col] !in opt
}

fun accept(proposal: Sudoku) =
    proposal.flatMap {
      it.map {
        it
      }
    }.any {
      it == 0
    }.not()

fun first(original: Sudoku) = original

fun next(proposal: Sudoku, row: Int, col: Int): Sudoku {
  val current = proposal[row][col]
  val currentPosition = row to col
  val nextPosition = when (current) {
    9 -> next(row, col)
    else -> {
      currentPosition
    }
  }
  val nextNumber = when (current) {
    9 -> 1
    else -> current + 1
  }

  // TODO: change
  return proposal
}

fun next(row: Int, col: Int) =
    when (col) {
      9 -> row + 1 to 1
      else -> row to col + 1
    }

Compiled from "Sudoku.kt"
public final class sudoku.SudokuKt {
  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: return

  public static final java.util.List<java.util.List<java.lang.Integer>> parse(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #21                 // String text
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #23                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: astore        4
      16: new           #25                 // class java/util/ArrayList
      19: dup
      20: aload_2
      21: bipush        10
      23: invokestatic  #31                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      26: invokespecial #35                 // Method java/util/ArrayList."<init>":(I)V
      29: checkcast     #37                 // class java/util/Collection
      32: astore        5
      34: iconst_0
      35: istore        6
      37: aload         4
      39: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      44: astore        7
      46: aload         7
      48: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          103
      56: aload         7
      58: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: astore        8
      65: aload         5
      67: aload         8
      69: checkcast     #53                 // class java/lang/String
      72: astore        9
      74: astore        22
      76: iconst_0
      77: istore        10
      79: aload         9
      81: checkcast     #55                 // class java/lang/CharSequence
      84: invokestatic  #61                 // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      87: invokevirtual #65                 // Method java/lang/Object.toString:()Ljava/lang/String;
      90: nop
      91: aload         22
      93: swap
      94: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      99: pop
     100: goto          46
     103: aload         5
     105: checkcast     #71                 // class java/util/List
     108: nop
     109: checkcast     #23                 // class java/lang/Iterable
     112: astore_2
     113: nop
     114: iconst_0
     115: istore_3
     116: aload_2
     117: astore        4
     119: new           #25                 // class java/util/ArrayList
     122: dup
     123: invokespecial #74                 // Method java/util/ArrayList."<init>":()V
     126: checkcast     #37                 // class java/util/Collection
     129: astore        5
     131: iconst_0
     132: istore        6
     134: aload         4
     136: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     141: astore        7
     143: aload         7
     145: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     150: ifeq          207
     153: aload         7
     155: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     160: astore        8
     162: aload         8
     164: checkcast     #53                 // class java/lang/String
     167: astore        9
     169: iconst_0
     170: istore        10
     172: aload         9
     174: checkcast     #55                 // class java/lang/CharSequence
     177: invokeinterface #78,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     182: ifle          189
     185: iconst_1
     186: goto          190
     189: iconst_0
     190: nop
     191: ifeq          143
     194: aload         5
     196: aload         8
     198: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     203: pop
     204: goto          143
     207: aload         5
     209: checkcast     #71                 // class java/util/List
     212: nop
     213: checkcast     #23                 // class java/lang/Iterable
     216: astore_2
     217: nop
     218: iconst_0
     219: istore_3
     220: aload_2
     221: astore        4
     223: new           #25                 // class java/util/ArrayList
     226: dup
     227: aload_2
     228: bipush        10
     230: invokestatic  #31                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     233: invokespecial #35                 // Method java/util/ArrayList."<init>":(I)V
     236: checkcast     #37                 // class java/util/Collection
     239: astore        5
     241: iconst_0
     242: istore        6
     244: aload         4
     246: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     251: astore        7
     253: aload         7
     255: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     260: ifeq          516
     263: aload         7
     265: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     270: astore        8
     272: aload         5
     274: aload         8
     276: checkcast     #53                 // class java/lang/String
     279: astore        9
     281: astore        22
     283: iconst_0
     284: istore        10
     286: aload         9
     288: astore        11
     290: iconst_0
     291: istore        12
     293: aload         11
     295: checkcast     #55                 // class java/lang/CharSequence
     298: astore        13
     300: new           #80                 // class java/lang/StringBuilder
     303: dup
     304: invokespecial #81                 // Method java/lang/StringBuilder."<init>":()V
     307: checkcast     #83                 // class java/lang/Appendable
     310: astore        14
     312: iconst_0
     313: istore        15
     315: iconst_0
     316: istore        16
     318: aload         13
     320: invokeinterface #78,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     325: istore        17
     327: iload         16
     329: iload         17
     331: if_icmpge     394
     334: aload         13
     336: iload         16
     338: invokeinterface #87,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     343: istore        18
     345: iload         18
     347: istore        19
     349: iconst_0
     350: istore        20
     352: bipush        48
     354: iload         19
     356: if_icmpgt     374
     359: iload         19
     361: bipush        58
     363: if_icmpge     370
     366: iconst_1
     367: goto          375
     370: iconst_0
     371: goto          375
     374: iconst_0
     375: ifeq          388
     378: aload         14
     380: iload         18
     382: invokeinterface #91,  2           // InterfaceMethod java/lang/Appendable.append:(C)Ljava/lang/Appendable;
     387: pop
     388: iinc          16, 1
     391: goto          327
     394: aload         14
     396: checkcast     #80                 // class java/lang/StringBuilder
     399: invokevirtual #92                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     402: checkcast     #55                 // class java/lang/CharSequence
     405: astore        11
     407: nop
     408: iconst_0
     409: istore        12
     411: aload         11
     413: astore        13
     415: new           #25                 // class java/util/ArrayList
     418: dup
     419: aload         11
     421: invokeinterface #78,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     426: invokespecial #35                 // Method java/util/ArrayList."<init>":(I)V
     429: checkcast     #37                 // class java/util/Collection
     432: astore        14
     434: iconst_0
     435: istore        15
     437: iconst_0
     438: istore        16
     440: iload         16
     442: aload         13
     444: invokeinterface #78,  1           // InterfaceMethod java/lang/CharSequence.length:()I
     449: if_icmpge     497
     452: aload         13
     454: iload         16
     456: invokeinterface #87,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     461: istore        17
     463: aload         14
     465: iload         17
     467: istore        18
     469: astore        21
     471: iconst_0
     472: istore        19
     474: iload         18
     476: bipush        48
     478: isub
     479: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     482: aload         21
     484: swap
     485: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     490: pop
     491: iinc          16, 1
     494: goto          440
     497: aload         14
     499: checkcast     #71                 // class java/util/List
     502: nop
     503: nop
     504: aload         22
     506: swap
     507: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     512: pop
     513: goto          253
     516: aload         5
     518: checkcast     #71                 // class java/util/List
     521: nop
     522: astore_1
     523: aload_1
     524: invokeinterface #101,  1          // InterfaceMethod java/util/List.size:()I
     529: bipush        9
     531: if_icmpeq     544
     534: new           #103                // class java/lang/IllegalArgumentException
     537: dup
     538: ldc           #105                // String The grid is not 9 lines long
     540: invokespecial #108                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     543: athrow
     544: aload_1
     545: checkcast     #23                 // class java/lang/Iterable
     548: astore_2
     549: iconst_0
     550: istore_3
     551: aload_2
     552: astore        4
     554: new           #25                 // class java/util/ArrayList
     557: dup
     558: aload_2
     559: bipush        10
     561: invokestatic  #31                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     564: invokespecial #35                 // Method java/util/ArrayList."<init>":(I)V
     567: checkcast     #37                 // class java/util/Collection
     570: astore        5
     572: iconst_0
     573: istore        6
     575: aload         4
     577: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     582: astore        7
     584: aload         7
     586: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     591: ifeq          639
     594: aload         7
     596: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     601: astore        8
     603: aload         5
     605: aload         8
     607: checkcast     #71                 // class java/util/List
     610: astore        9
     612: astore        22
     614: iconst_0
     615: istore        10
     617: aload         9
     619: invokeinterface #101,  1          // InterfaceMethod java/util/List.size:()I
     624: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     627: aload         22
     629: swap
     630: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     635: pop
     636: goto          584
     639: aload         5
     641: checkcast     #71                 // class java/util/List
     644: nop
     645: checkcast     #23                 // class java/lang/Iterable
     648: astore_2
     649: iconst_0
     650: istore_3
     651: aload_2
     652: instanceof    #37                 // class java/util/Collection
     655: ifeq          674
     658: aload_2
     659: checkcast     #37                 // class java/util/Collection
     662: invokeinterface #111,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     667: ifeq          674
     670: iconst_0
     671: goto          734
     674: aload_2
     675: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     680: astore        4
     682: aload         4
     684: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     689: ifeq          733
     692: aload         4
     694: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     699: astore        5
     701: aload         5
     703: checkcast     #113                // class java/lang/Number
     706: invokevirtual #116                // Method java/lang/Number.intValue:()I
     709: istore        6
     711: iconst_0
     712: istore        7
     714: iload         6
     716: bipush        9
     718: if_icmpeq     725
     721: iconst_1
     722: goto          726
     725: iconst_0
     726: ifeq          682
     729: iconst_1
     730: goto          734
     733: iconst_0
     734: ifeq          747
     737: new           #103                // class java/lang/IllegalArgumentException
     740: dup
     741: ldc           #118                // String All lines must be 9 numbers long
     743: invokespecial #108                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     746: athrow
     747: aload_1
     748: areturn

  public static final java.util.List<java.lang.Integer> listValues(java.util.List<? extends java.util.List<java.lang.Integer>>, int, int, int, int);
    Code:
       0: aload_0
       1: ldc           #156                // String sudoku
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #158                // class kotlin/ranges/IntRange
       9: dup
      10: iload_1
      11: iload_3
      12: invokespecial #161                // Method kotlin/ranges/IntRange."<init>":(II)V
      15: checkcast     #23                 // class java/lang/Iterable
      18: astore        5
      20: iconst_0
      21: istore        6
      23: aload         5
      25: astore        7
      27: new           #25                 // class java/util/ArrayList
      30: dup
      31: invokespecial #74                 // Method java/util/ArrayList."<init>":()V
      34: checkcast     #37                 // class java/util/Collection
      37: astore        8
      39: iconst_0
      40: istore        9
      42: aload         7
      44: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      49: astore        10
      51: aload         10
      53: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      58: ifeq          224
      61: aload         10
      63: checkcast     #163                // class kotlin/collections/IntIterator
      66: invokevirtual #166                // Method kotlin/collections/IntIterator.nextInt:()I
      69: istore        11
      71: iload         11
      73: istore        12
      75: iconst_0
      76: istore        13
      78: new           #158                // class kotlin/ranges/IntRange
      81: dup
      82: iload_2
      83: iload         4
      85: invokespecial #161                // Method kotlin/ranges/IntRange."<init>":(II)V
      88: checkcast     #23                 // class java/lang/Iterable
      91: astore        14
      93: iconst_0
      94: istore        15
      96: aload         14
      98: astore        16
     100: new           #25                 // class java/util/ArrayList
     103: dup
     104: aload         14
     106: bipush        10
     108: invokestatic  #31                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     111: invokespecial #35                 // Method java/util/ArrayList."<init>":(I)V
     114: checkcast     #37                 // class java/util/Collection
     117: astore        17
     119: iconst_0
     120: istore        18
     122: aload         16
     124: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     129: astore        19
     131: aload         19
     133: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     138: ifeq          201
     141: aload         19
     143: checkcast     #163                // class kotlin/collections/IntIterator
     146: invokevirtual #166                // Method kotlin/collections/IntIterator.nextInt:()I
     149: istore        20
     151: aload         17
     153: iload         20
     155: istore        21
     157: astore        22
     159: iconst_0
     160: istore        23
     162: aload_0
     163: iload         12
     165: invokeinterface #170,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     170: checkcast     #71                 // class java/util/List
     173: iload         21
     175: invokeinterface #170,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     180: checkcast     #113                // class java/lang/Number
     183: invokevirtual #116                // Method java/lang/Number.intValue:()I
     186: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     189: aload         22
     191: swap
     192: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     197: pop
     198: goto          131
     201: aload         17
     203: checkcast     #71                 // class java/util/List
     206: nop
     207: checkcast     #23                 // class java/lang/Iterable
     210: nop
     211: astore        24
     213: aload         8
     215: aload         24
     217: invokestatic  #174                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     220: pop
     221: goto          51
     224: aload         8
     226: checkcast     #71                 // class java/util/List
     229: nop
     230: checkcast     #23                 // class java/lang/Iterable
     233: astore        5
     235: nop
     236: iconst_0
     237: istore        6
     239: aload         5
     241: astore        7
     243: new           #25                 // class java/util/ArrayList
     246: dup
     247: invokespecial #74                 // Method java/util/ArrayList."<init>":()V
     250: checkcast     #37                 // class java/util/Collection
     253: astore        8
     255: iconst_0
     256: istore        9
     258: aload         7
     260: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     265: astore        10
     267: aload         10
     269: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     274: ifeq          325
     277: aload         10
     279: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     284: astore        11
     286: aload         11
     288: checkcast     #113                // class java/lang/Number
     291: invokevirtual #116                // Method java/lang/Number.intValue:()I
     294: istore        12
     296: iconst_0
     297: istore        13
     299: iload         12
     301: ifeq          308
     304: iconst_1
     305: goto          309
     308: iconst_0
     309: ifeq          267
     312: aload         8
     314: aload         11
     316: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     321: pop
     322: goto          267
     325: aload         8
     327: checkcast     #71                 // class java/util/List
     330: nop
     331: areturn

  public static final java.util.List<java.lang.Integer> listExistingValuesInSquare(java.util.List<? extends java.util.List<java.lang.Integer>>, int, int);
    Code:
       0: aload_0
       1: ldc           #156                // String sudoku
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: iconst_3
       8: idiv
       9: istore_3
      10: iload_2
      11: iconst_3
      12: idiv
      13: istore        4
      15: aload_0
      16: iload_3
      17: iconst_3
      18: imul
      19: iload         4
      21: iconst_3
      22: imul
      23: iload_3
      24: iconst_1
      25: iadd
      26: iconst_3
      27: imul
      28: iconst_1
      29: isub
      30: iload         4
      32: iconst_1
      33: iadd
      34: iconst_3
      35: imul
      36: iconst_1
      37: isub
      38: invokestatic  #193                // Method listValues:(Ljava/util/List;IIII)Ljava/util/List;
      41: areturn

  public static final java.util.List<java.lang.Integer> listExistingValuesInRow(java.util.List<? extends java.util.List<java.lang.Integer>>, int);
    Code:
       0: aload_0
       1: ldc           #156                // String sudoku
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iload_1
       8: iconst_0
       9: iload_1
      10: bipush        8
      12: invokestatic  #193                // Method listValues:(Ljava/util/List;IIII)Ljava/util/List;
      15: areturn

  public static final java.util.List<java.lang.Integer> listExistingValuesInColumn(java.util.List<? extends java.util.List<java.lang.Integer>>, int);
    Code:
       0: aload_0
       1: ldc           #156                // String sudoku
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_0
       8: iload_1
       9: bipush        8
      11: iload_1
      12: invokestatic  #193                // Method listValues:(Ljava/util/List;IIII)Ljava/util/List;
      15: areturn

  public static final java.util.List<java.lang.Integer> options(java.util.List<? extends java.util.List<java.lang.Integer>>, int, int);
    Code:
       0: aload_0
       1: ldc           #156                // String sudoku
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iload_1
       8: invokestatic  #203                // Method listExistingValuesInRow:(Ljava/util/List;I)Ljava/util/List;
      11: astore_3
      12: aload_0
      13: iload_2
      14: invokestatic  #205                // Method listExistingValuesInColumn:(Ljava/util/List;I)Ljava/util/List;
      17: astore        4
      19: aload_0
      20: iload_1
      21: iload_2
      22: invokestatic  #207                // Method listExistingValuesInSquare:(Ljava/util/List;II)Ljava/util/List;
      25: astore        5
      27: new           #158                // class kotlin/ranges/IntRange
      30: dup
      31: iconst_1
      32: bipush        9
      34: invokespecial #161                // Method kotlin/ranges/IntRange."<init>":(II)V
      37: checkcast     #23                 // class java/lang/Iterable
      40: astore        6
      42: iconst_0
      43: istore        7
      45: aload         6
      47: astore        8
      49: new           #25                 // class java/util/ArrayList
      52: dup
      53: invokespecial #74                 // Method java/util/ArrayList."<init>":()V
      56: checkcast     #37                 // class java/util/Collection
      59: astore        9
      61: iconst_0
      62: istore        10
      64: aload         8
      66: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      71: astore        11
      73: aload         11
      75: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      80: ifeq          170
      83: aload         11
      85: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      90: astore        12
      92: aload         12
      94: checkcast     #113                // class java/lang/Number
      97: invokevirtual #116                // Method java/lang/Number.intValue:()I
     100: istore        13
     102: iconst_0
     103: istore        14
     105: aload_3
     106: iload         13
     108: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     111: invokeinterface #210,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
     116: ifne          153
     119: aload         4
     121: iload         13
     123: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     126: invokeinterface #210,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
     131: ifne          153
     134: aload         5
     136: iload         13
     138: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     141: invokeinterface #210,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
     146: ifne          153
     149: iconst_1
     150: goto          154
     153: iconst_0
     154: ifeq          73
     157: aload         9
     159: aload         12
     161: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     166: pop
     167: goto          73
     170: aload         9
     172: checkcast     #71                 // class java/util/List
     175: nop
     176: areturn

  public static final boolean reject(java.util.List<? extends java.util.List<java.lang.Integer>>, java.util.List<? extends java.util.List<java.lang.Integer>>, int, int);
    Code:
       0: aload_0
       1: ldc           #219                // String origin
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #221                // String proposal
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: iload_2
      14: iload_3
      15: invokestatic  #223                // Method options:(Ljava/util/List;II)Ljava/util/List;
      18: astore        4
      20: aload         4
      22: aload_1
      23: iload_2
      24: invokeinterface #170,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      29: checkcast     #71                 // class java/util/List
      32: iload_3
      33: invokeinterface #170,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      38: invokeinterface #210,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
      43: ifne          50
      46: iconst_1
      47: goto          51
      50: iconst_0
      51: ireturn

  public static final boolean accept(java.util.List<? extends java.util.List<java.lang.Integer>>);
    Code:
       0: aload_0
       1: ldc           #221                // String proposal
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #23                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #25                 // class java/util/ArrayList
      18: dup
      19: invokespecial #74                 // Method java/util/ArrayList."<init>":()V
      22: checkcast     #37                 // class java/util/Collection
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          188
      48: aload         6
      50: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         7
      59: checkcast     #71                 // class java/util/List
      62: astore        8
      64: iconst_0
      65: istore        9
      67: aload         8
      69: checkcast     #23                 // class java/lang/Iterable
      72: astore        10
      74: iconst_0
      75: istore        11
      77: aload         10
      79: astore        12
      81: new           #25                 // class java/util/ArrayList
      84: dup
      85: aload         10
      87: bipush        10
      89: invokestatic  #31                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      92: invokespecial #35                 // Method java/util/ArrayList."<init>":(I)V
      95: checkcast     #37                 // class java/util/Collection
      98: astore        13
     100: iconst_0
     101: istore        14
     103: aload         12
     105: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     110: astore        15
     112: aload         15
     114: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     119: ifeq          165
     122: aload         15
     124: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     129: astore        16
     131: aload         13
     133: aload         16
     135: checkcast     #113                // class java/lang/Number
     138: invokevirtual #116                // Method java/lang/Number.intValue:()I
     141: istore        17
     143: astore        18
     145: iconst_0
     146: istore        19
     148: iload         17
     150: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     153: aload         18
     155: swap
     156: invokeinterface #69,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     161: pop
     162: goto          112
     165: aload         13
     167: checkcast     #71                 // class java/util/List
     170: nop
     171: checkcast     #23                 // class java/lang/Iterable
     174: nop
     175: astore        8
     177: aload         4
     179: aload         8
     181: invokestatic  #174                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     184: pop
     185: goto          38
     188: aload         4
     190: checkcast     #71                 // class java/util/List
     193: nop
     194: checkcast     #23                 // class java/lang/Iterable
     197: astore_1
     198: nop
     199: iconst_0
     200: istore_2
     201: aload_1
     202: instanceof    #37                 // class java/util/Collection
     205: ifeq          224
     208: aload_1
     209: checkcast     #37                 // class java/util/Collection
     212: invokeinterface #111,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     217: ifeq          224
     220: iconst_0
     221: goto          279
     224: aload_1
     225: invokeinterface #41,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     230: astore_3
     231: aload_3
     232: invokeinterface #47,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     237: ifeq          278
     240: aload_3
     241: invokeinterface #51,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     246: astore        4
     248: aload         4
     250: checkcast     #113                // class java/lang/Number
     253: invokevirtual #116                // Method java/lang/Number.intValue:()I
     256: istore        5
     258: iconst_0
     259: istore        6
     261: iload         5
     263: ifne          270
     266: iconst_1
     267: goto          271
     270: iconst_0
     271: ifeq          231
     274: iconst_1
     275: goto          279
     278: iconst_0
     279: ifne          286
     282: iconst_1
     283: goto          287
     286: iconst_0
     287: ireturn

  public static final java.util.List<java.util.List<java.lang.Integer>> first(java.util.List<? extends java.util.List<java.lang.Integer>>);
    Code:
       0: aload_0
       1: ldc           #234                // String original
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: areturn

  public static final java.util.List<java.util.List<java.lang.Integer>> next(java.util.List<? extends java.util.List<java.lang.Integer>>, int, int);
    Code:
       0: aload_0
       1: ldc           #221                // String proposal
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iload_1
       8: invokeinterface #170,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      13: checkcast     #71                 // class java/util/List
      16: iload_2
      17: invokeinterface #170,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      22: checkcast     #113                // class java/lang/Number
      25: invokevirtual #116                // Method java/lang/Number.intValue:()I
      28: istore_3
      29: iload_1
      30: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      33: iload_2
      34: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      37: invokestatic  #241                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      40: astore        4
      42: iload_3
      43: bipush        9
      45: if_icmpne     56
      48: iload_1
      49: iload_2
      50: invokestatic  #244                // Method next:(II)Lkotlin/Pair;
      53: goto          58
      56: aload         4
      58: astore        5
      60: iload_3
      61: bipush        9
      63: if_icmpne     70
      66: iconst_1
      67: goto          73
      70: iload_3
      71: iconst_1
      72: iadd
      73: istore        6
      75: aload_0
      76: areturn

  public static final kotlin.Pair<java.lang.Integer, java.lang.Integer> next(int, int);
    Code:
       0: iload_1
       1: bipush        9
       3: if_icmpne     22
       6: iload_0
       7: iconst_1
       8: iadd
       9: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      12: iconst_1
      13: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: invokestatic  #241                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      19: goto          35
      22: iload_0
      23: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      26: iload_1
      27: iconst_1
      28: iadd
      29: invokestatic  #98                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      32: invokestatic  #241                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      35: areturn
}


package strassenbahn

import java.util.LinkedList
import kotlin.math.max

interface Ticket {
    fun getPrice(area: Int): Float
    val description: String
    val adultCapacity: Int
    val childrenCapacity: Int
    val allowedTrips: Int
}

data class Wanted(
    val area: Int,
    val adults: Int = 0,
    val children: Int = 0,
    val tripsPerPeople: Int = 1
) {
    fun noPassenger() = (adults + children) <= 0
}

class TicketImpl(
    override val description: String,
    val prices: Map<Int, Number>,
    override val adultCapacity: Int = 0,
    override val childrenCapacity: Int = 0,
    override val allowedTrips: Int = 1
) : Ticket {
    override fun getPrice(area: Int): Float {
        return prices[area]?.toFloat() ?: throw IllegalArgumentException("No price for area $area")
    }

    override fun toString() = description
}

data class Proposition(val tickets: Map<Ticket, Int>) {
//    constructor(pairs: List<Pair<Ticket, Int>>): this(pairs.toMap())
//    constructor(pair: Pair<Ticket, Int>): this(listOf(pair).toMap())

    companion object {
        val EMPTY = Proposition(mapOf())
    }

    fun getPrice(area: Int, trips: Int = 1) =
        tickets.map {
            // are many tickets are needed to make the desired number of trips
            val ticketsCount = Math.ceil(trips / it.key.allowedTrips.toDouble()).toInt()
            it.key.getPrice(area) * it.value * ticketsCount
        }.sum()

    val flatTickets: List<Ticket> by lazy {
        tickets.flatMap { entry ->
            List(entry.value) { entry.key }
        }
    }

    val adultSeats =
        flatTickets.sumBy {
            it.adultCapacity
        }
    val childrenSeats =
        flatTickets.sumBy {
            it.childrenCapacity
        }

    operator fun plus(ticket: Ticket): Proposition {
        val new = this.tickets.toMutableMap()
        new[ticket] = (this.tickets[ticket] ?: 0) + 1
        return Proposition(new)
    }

    fun canAccommodate(wanted: Wanted) =
        listOf(
            // strict adult and child separation
            { this.adultSeats >= wanted.adults && this.childrenSeats >= wanted.children },
            // children use adult ticket
            {
                val freeAdultSeats = this.adultSeats - wanted.adults
                val freeChildrenSeats = (this.childrenSeats + freeAdultSeats) - wanted.children

                if (freeAdultSeats < 0) {
                    // not enough seats for adults
                    false
                }
                else {
                    freeChildrenSeats >= 0
                }
            }
        ).any {
            it()
        }
}

/**
 * Find the cheapest price given a request and an offer
 */
fun cheapestPrice(wanted: Wanted, offer: List<Ticket>): Proposition {
    if (wanted.noPassenger()) {
        throw IllegalArgumentException("Need at least 1 traveler")
    }
    return browseAllPropositions(
        wanted,
        offer.sortedByDescending { it.adultCapacity }
    )
}

fun browseAllPropositions(
    wanted: Wanted,
    offer: List<Ticket>
): Proposition {
    var bestSoFar = Proposition.EMPTY
    var bestPriceSoFar = Float.MAX_VALUE
    /**
     * The Int, an index, is there to know which element in the offer list
     * was used to create the proposition and avoid repeating propositions
     */
    val queue = LinkedList<Pair<Int, Proposition>>(listOf(0 to bestSoFar))

    /**
     * we may have to look for solutions which don't use all the seats
     * but we must not look for too long in that direction as this is:
     * 1. leading to OutOfMemory because a solution which can accomodate only chlidren isn't suited for adults
     * TODO: tune ratios
     */
    val maxChildrenToAdultRatio = offer.maxCAratio()
    val maxAdultToChildrenRatio = offer.maxACratio()

    val extraAdultsCapacity = offer.maxBy {
        it.adultCapacity
    }!!.adultCapacity + wanted.adults * maxAdultToChildrenRatio

    val extraChildrenCapacity = offer.maxBy {
        it.childrenCapacity
    }!!.childrenCapacity + wanted.children * maxChildrenToAdultRatio

    while (queue.isNotEmpty()) {
        val (index, current) = queue.removeAt(0)
        val price = current.getPrice(wanted.area, wanted.tripsPerPeople)
        if (price < bestPriceSoFar) {
            if (current.canAccommodate(wanted)) {
                bestSoFar = current
                bestPriceSoFar = price
            }

            for (i in index until offer.size) {
                val new = current + offer[i]
                // Don't look too far
                val noExcessAdultsCapacity = new.adultSeats <= wanted.adults + extraAdultsCapacity
                val noExcessChildrenCapacity = new.childrenSeats <= wanted.children + extraChildrenCapacity
                // stop searching when it's more expansive than an existing solution
                val newPrice = new.getPrice(wanted.area, wanted.tripsPerPeople)
                if (noExcessAdultsCapacity && noExcessChildrenCapacity && newPrice < bestPriceSoFar) {
                    queue.add(i to new)
                }
            }
        }
    }

    return bestSoFar
}

private fun <E : Ticket> List<E>.maxCAratio(): Double {
    val found = this.map {
        if (it.adultCapacity > 0) it.childrenCapacity / it.adultCapacity else 0
    }.max() ?: 1

    // don't return 0
    return max(1.0, found.toDouble())
}

private fun <E : Ticket> List<E>.maxACratio(): Double {
    val found = this.map {
        if (it.childrenCapacity > 0) it.adultCapacity / it.childrenCapacity else 0
    }.max() ?: 1

    // don't return 0
    return max(1.0, found.toDouble())
}

Compiled from "ThriftTicket.kt"
public final class strassenbahn.ThriftTicketKt {
  public static final strassenbahn.Proposition cheapestPrice(strassenbahn.Wanted, java.util.List<? extends strassenbahn.Ticket>);
    Code:
       0: aload_0
       1: ldc           #10                 // String wanted
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #18                 // String offer
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokevirtual #24                 // Method strassenbahn/Wanted.noPassenger:()Z
      16: ifeq          29
      19: new           #26                 // class java/lang/IllegalArgumentException
      22: dup
      23: ldc           #28                 // String Need at least 1 traveler
      25: invokespecial #32                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
      28: athrow
      29: aload_0
      30: aload_1
      31: checkcast     #34                 // class java/lang/Iterable
      34: astore_2
      35: iconst_0
      36: istore_3
      37: aload_2
      38: new           #36                 // class strassenbahn/ThriftTicketKt$cheapestPrice$$inlined$sortedByDescending$1
      41: dup
      42: invokespecial #39                 // Method strassenbahn/ThriftTicketKt$cheapestPrice$$inlined$sortedByDescending$1."<init>":()V
      45: checkcast     #41                 // class java/util/Comparator
      48: invokestatic  #47                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      51: invokestatic  #50                 // Method browseAllPropositions:(Lstrassenbahn/Wanted;Ljava/util/List;)Lstrassenbahn/Proposition;
      54: areturn

  public static final strassenbahn.Proposition browseAllPropositions(strassenbahn.Wanted, java.util.List<? extends strassenbahn.Ticket>);
    Code:
       0: aload_0
       1: ldc           #10                 // String wanted
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #18                 // String offer
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: getstatic     #62                 // Field strassenbahn/Proposition.Companion:Lstrassenbahn/Proposition$Companion;
      15: invokevirtual #68                 // Method strassenbahn/Proposition$Companion.getEMPTY:()Lstrassenbahn/Proposition;
      18: astore_2
      19: ldc           #69                 // float 3.4028235E38f
      21: fstore_3
      22: new           #71                 // class java/util/LinkedList
      25: dup
      26: iconst_0
      27: invokestatic  #77                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      30: aload_2
      31: invokestatic  #83                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      34: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      37: checkcast     #89                 // class java/util/Collection
      40: invokespecial #92                 // Method java/util/LinkedList."<init>":(Ljava/util/Collection;)V
      43: astore        4
      45: aload_1
      46: invokestatic  #96                 // Method maxCAratio:(Ljava/util/List;)D
      49: dstore        5
      51: aload_1
      52: invokestatic  #99                 // Method maxACratio:(Ljava/util/List;)D
      55: dstore        7
      57: aload_1
      58: checkcast     #34                 // class java/lang/Iterable
      61: astore        11
      63: iconst_0
      64: istore        12
      66: aload         11
      68: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      73: astore        13
      75: aload         13
      77: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      82: ifne          93
      85: new           #110                // class java/util/NoSuchElementException
      88: dup
      89: invokespecial #111                // Method java/util/NoSuchElementException."<init>":()V
      92: athrow
      93: aload         13
      95: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     100: astore        14
     102: aload         13
     104: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     109: ifne          117
     112: aload         14
     114: goto          191
     117: aload         14
     119: checkcast     #117                // class strassenbahn/Ticket
     122: astore        15
     124: iconst_0
     125: istore        16
     127: aload         15
     129: invokeinterface #121,  1          // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
     134: istore        15
     136: aload         13
     138: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     143: astore        16
     145: aload         16
     147: checkcast     #117                // class strassenbahn/Ticket
     150: astore        17
     152: iconst_0
     153: istore        18
     155: aload         17
     157: invokeinterface #121,  1          // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
     162: istore        17
     164: iload         15
     166: iload         17
     168: if_icmpge     179
     171: aload         16
     173: astore        14
     175: iload         17
     177: istore        15
     179: aload         13
     181: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     186: ifne          136
     189: aload         14
     191: dup
     192: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     195: checkcast     #117                // class strassenbahn/Ticket
     198: invokeinterface #121,  1          // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
     203: i2d
     204: aload_0
     205: invokevirtual #128                // Method strassenbahn/Wanted.getAdults:()I
     208: i2d
     209: dload         7
     211: dmul
     212: dadd
     213: dstore        9
     215: aload_1
     216: checkcast     #34                 // class java/lang/Iterable
     219: astore        13
     221: iconst_0
     222: istore        14
     224: aload         13
     226: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     231: astore        15
     233: aload         15
     235: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     240: ifne          251
     243: new           #110                // class java/util/NoSuchElementException
     246: dup
     247: invokespecial #111                // Method java/util/NoSuchElementException."<init>":()V
     250: athrow
     251: aload         15
     253: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     258: astore        16
     260: aload         15
     262: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     267: ifne          275
     270: aload         16
     272: goto          349
     275: aload         16
     277: checkcast     #117                // class strassenbahn/Ticket
     280: astore        17
     282: iconst_0
     283: istore        18
     285: aload         17
     287: invokeinterface #131,  1          // InterfaceMethod strassenbahn/Ticket.getChildrenCapacity:()I
     292: istore        17
     294: aload         15
     296: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     301: astore        18
     303: aload         18
     305: checkcast     #117                // class strassenbahn/Ticket
     308: astore        19
     310: iconst_0
     311: istore        20
     313: aload         19
     315: invokeinterface #131,  1          // InterfaceMethod strassenbahn/Ticket.getChildrenCapacity:()I
     320: istore        19
     322: iload         17
     324: iload         19
     326: if_icmpge     337
     329: aload         18
     331: astore        16
     333: iload         19
     335: istore        17
     337: aload         15
     339: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     344: ifne          294
     347: aload         16
     349: dup
     350: invokestatic  #125                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     353: checkcast     #117                // class strassenbahn/Ticket
     356: invokeinterface #131,  1          // InterfaceMethod strassenbahn/Ticket.getChildrenCapacity:()I
     361: i2d
     362: aload_0
     363: invokevirtual #134                // Method strassenbahn/Wanted.getChildren:()I
     366: i2d
     367: dload         5
     369: dmul
     370: dadd
     371: dstore        11
     373: aload         4
     375: checkcast     #89                 // class java/util/Collection
     378: invokeinterface #137,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     383: ifne          390
     386: iconst_1
     387: goto          391
     390: iconst_0
     391: ifeq          612
     394: aload         4
     396: iconst_0
     397: invokevirtual #141                // Method java/util/LinkedList.remove:(I)Ljava/lang/Object;
     400: dup
     401: ldc           #143                // String removeAt(...)
     403: invokestatic  #146                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     406: checkcast     #148                // class kotlin/Pair
     409: astore        13
     411: aload         13
     413: invokevirtual #151                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     416: checkcast     #153                // class java/lang/Number
     419: invokevirtual #156                // Method java/lang/Number.intValue:()I
     422: istore        14
     424: aload         13
     426: invokevirtual #159                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     429: checkcast     #58                 // class strassenbahn/Proposition
     432: astore        15
     434: aload         15
     436: aload_0
     437: invokevirtual #162                // Method strassenbahn/Wanted.getArea:()I
     440: aload_0
     441: invokevirtual #165                // Method strassenbahn/Wanted.getTripsPerPeople:()I
     444: invokevirtual #169                // Method strassenbahn/Proposition.getPrice:(II)F
     447: fstore        16
     449: fload         16
     451: fload_3
     452: fcmpg
     453: ifge          373
     456: aload         15
     458: aload_0
     459: invokevirtual #173                // Method strassenbahn/Proposition.canAccommodate:(Lstrassenbahn/Wanted;)Z
     462: ifeq          471
     465: aload         15
     467: astore_2
     468: fload         16
     470: fstore_3
     471: iload         14
     473: istore        17
     475: aload_1
     476: invokeinterface #178,  1          // InterfaceMethod java/util/List.size:()I
     481: istore        18
     483: iload         17
     485: iload         18
     487: if_icmpge     373
     490: aload         15
     492: aload_1
     493: iload         17
     495: invokeinterface #181,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     500: checkcast     #117                // class strassenbahn/Ticket
     503: invokevirtual #185                // Method strassenbahn/Proposition.plus:(Lstrassenbahn/Ticket;)Lstrassenbahn/Proposition;
     506: astore        19
     508: aload         19
     510: invokevirtual #188                // Method strassenbahn/Proposition.getAdultSeats:()I
     513: i2d
     514: aload_0
     515: invokevirtual #128                // Method strassenbahn/Wanted.getAdults:()I
     518: i2d
     519: dload         9
     521: dadd
     522: dcmpg
     523: ifgt          530
     526: iconst_1
     527: goto          531
     530: iconst_0
     531: istore        20
     533: aload         19
     535: invokevirtual #191                // Method strassenbahn/Proposition.getChildrenSeats:()I
     538: i2d
     539: aload_0
     540: invokevirtual #134                // Method strassenbahn/Wanted.getChildren:()I
     543: i2d
     544: dload         11
     546: dadd
     547: dcmpg
     548: ifgt          555
     551: iconst_1
     552: goto          556
     555: iconst_0
     556: istore        21
     558: aload         19
     560: aload_0
     561: invokevirtual #162                // Method strassenbahn/Wanted.getArea:()I
     564: aload_0
     565: invokevirtual #165                // Method strassenbahn/Wanted.getTripsPerPeople:()I
     568: invokevirtual #169                // Method strassenbahn/Proposition.getPrice:(II)F
     571: fstore        22
     573: iload         20
     575: ifeq          606
     578: iload         21
     580: ifeq          606
     583: fload         22
     585: fload_3
     586: fcmpg
     587: ifge          606
     590: aload         4
     592: iload         17
     594: invokestatic  #77                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     597: aload         19
     599: invokestatic  #83                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     602: invokevirtual #195                // Method java/util/LinkedList.add:(Ljava/lang/Object;)Z
     605: pop
     606: iinc          17, 1
     609: goto          483
     612: aload_2
     613: areturn

  private static final <E extends strassenbahn.Ticket> double maxCAratio(java.util.List<? extends E>);
    Code:
       0: aload_0
       1: checkcast     #34                 // class java/lang/Iterable
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: astore        4
      10: new           #231                // class java/util/ArrayList
      13: dup
      14: aload_2
      15: bipush        10
      17: invokestatic  #235                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      20: invokespecial #238                // Method java/util/ArrayList."<init>":(I)V
      23: checkcast     #89                 // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          117
      50: aload         7
      52: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         5
      61: aload         8
      63: checkcast     #117                // class strassenbahn/Ticket
      66: astore        9
      68: astore        11
      70: iconst_0
      71: istore        10
      73: aload         9
      75: invokeinterface #121,  1          // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
      80: ifle          101
      83: aload         9
      85: invokeinterface #131,  1          // InterfaceMethod strassenbahn/Ticket.getChildrenCapacity:()I
      90: aload         9
      92: invokeinterface #121,  1          // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
      97: idiv
      98: goto          102
     101: iconst_0
     102: invokestatic  #77                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     105: aload         11
     107: swap
     108: invokeinterface #239,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     113: pop
     114: goto          40
     117: aload         5
     119: checkcast     #175                // class java/util/List
     122: nop
     123: checkcast     #34                 // class java/lang/Iterable
     126: invokestatic  #243                // Method kotlin/collections/CollectionsKt.maxOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
     129: checkcast     #153                // class java/lang/Number
     132: invokevirtual #156                // Method java/lang/Number.intValue:()I
     135: nop
     136: istore_1
     137: dconst_1
     138: iload_1
     139: i2d
     140: invokestatic  #249                // Method java/lang/Math.max:(DD)D
     143: dreturn

  private static final <E extends strassenbahn.Ticket> double maxACratio(java.util.List<? extends E>);
    Code:
       0: aload_0
       1: checkcast     #34                 // class java/lang/Iterable
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: astore        4
      10: new           #231                // class java/util/ArrayList
      13: dup
      14: aload_2
      15: bipush        10
      17: invokestatic  #235                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      20: invokespecial #238                // Method java/util/ArrayList."<init>":(I)V
      23: checkcast     #89                 // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #103,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #108,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          117
      50: aload         7
      52: invokeinterface #115,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         5
      61: aload         8
      63: checkcast     #117                // class strassenbahn/Ticket
      66: astore        9
      68: astore        11
      70: iconst_0
      71: istore        10
      73: aload         9
      75: invokeinterface #131,  1          // InterfaceMethod strassenbahn/Ticket.getChildrenCapacity:()I
      80: ifle          101
      83: aload         9
      85: invokeinterface #121,  1          // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
      90: aload         9
      92: invokeinterface #131,  1          // InterfaceMethod strassenbahn/Ticket.getChildrenCapacity:()I
      97: idiv
      98: goto          102
     101: iconst_0
     102: invokestatic  #77                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     105: aload         11
     107: swap
     108: invokeinterface #239,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     113: pop
     114: goto          40
     117: aload         5
     119: checkcast     #175                // class java/util/List
     122: nop
     123: checkcast     #34                 // class java/lang/Iterable
     126: invokestatic  #243                // Method kotlin/collections/CollectionsKt.maxOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
     129: checkcast     #153                // class java/lang/Number
     132: invokevirtual #156                // Method java/lang/Number.intValue:()I
     135: nop
     136: istore_1
     137: dconst_1
     138: iload_1
     139: i2d
     140: invokestatic  #249                // Method java/lang/Math.max:(DD)D
     143: dreturn
}

Compiled from "Comparisons.kt"
public final class strassenbahn.ThriftTicketKt$cheapestPrice$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public strassenbahn.ThriftTicketKt$cheapestPrice$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class strassenbahn/Ticket
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokeinterface #27,  1           // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
      14: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      17: checkcast     #35                 // class java/lang/Comparable
      20: aload_1
      21: checkcast     #23                 // class strassenbahn/Ticket
      24: astore_3
      25: astore        5
      27: iconst_0
      28: istore        4
      30: aload_3
      31: invokeinterface #27,  1           // InterfaceMethod strassenbahn/Ticket.getAdultCapacity:()I
      36: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      39: aload         5
      41: swap
      42: checkcast     #35                 // class java/lang/Comparable
      45: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      48: ireturn
}


package quick.start

enum class Op(val i: Int) {
  Sum(0),
  Prod(1),
  Min(2),
  Max(3),
  Lit(4),
  Gt(5),
  Lt(6),
  Eq(7);
  companion object {
    fun fromInt(i: Int) = Op.values().first { it.i == i }
  }
}

class Packet(version: Int, op: Op, lit: Long, children: List<Packet>) {
  val version = version
  val op = op
  val children = children
  val lit = lit

  // literal
  constructor(v: Int, l: Long) : this(v, Op.Lit, l, emptyList()) {}
  // recursive
  constructor(v: Int, op: Op, ch: List<Packet>) : this(v, op, 0, ch) {}

  fun versionTotal(): Int {
    return version + children.map { it.versionTotal() }.sum()
  }
  fun eval(): Long {
    if (this.op == Op.Lit) return this.lit

    val res = children.map { it.eval() }
    if (op == Op.Sum) return res.sum()
    if (op == Op.Prod) return res.reduce(Long::times)
    if (op == Op.Min) return res.minOrNull()!!
    if (op == Op.Max) return res.maxOrNull()!!

    val (lhs, rhs) = res
    var cond = false
    if (op == Op.Gt) cond = lhs > rhs
    if (op == Op.Lt) cond = lhs < rhs
    if (op == Op.Eq) cond = lhs == rhs
    return if (cond) 1 else 0
  }
}

fun parseLit(s: String): Pair<Long, String> {
  var s = s
  var res = 0L
  var done = false
  while (!done) {
    res = res * 16 + s.substring(1, 5).toLong(2)
    done = s[0] == '0'
    s = s.substring(5)
  }
  return Pair(res, s)
}

fun parsePacket(s: String): Pair<Packet, String> {
  val v = s.substring(0, 3).toInt(2)
  val ty = Op.fromInt(s.substring(3, 6).toInt(2))
  val s = s.substring(6)
  if (ty == Op.Lit) {
    val (l, s) = parseLit(s)
    return Pair(Packet(v, l), s)
  }
  if (s[0] == '0') { // length of packets
    val len = s.substring(1, 16).toInt(2)
    val ss = s.substring(16 + len)
    var s = s.substring(16, 16 + len)
    var ps = mutableListOf<Packet>()
    while (!s.isEmpty()) {
      val (p, ss) = parsePacket(s)
      s = ss
      ps.add(p)
    }
    return Pair(Packet(v, ty, ps), ss)
  } else { // num. packets
    val num = s.substring(1, 12).toInt(2)
    var s = s.substring(12)
    var ps = mutableListOf<Packet>()
    for (i in 1..num) {
      val (p, ss) = parsePacket(s)
      s = ss
      ps.add(p)
    }
    return Pair(Packet(v, ty, ps), s)
  }
}

fun parseFull(s: String): Packet {
  val (p, s) = parsePacket(s)
  assert(s.all { it == '0' })
  return p
}

fun main() {
  val inp = readLine()!!
  val data = ('1' + inp).toBigInteger(16).toString(2).drop(1)
  val packet = parseFull(data)
  println(packet.versionTotal())
  println(packet.eval())
}

Compiled from "day16.kt"
public final class quick.start.Day16Kt {
  public static final kotlin.Pair<java.lang.Long, java.lang.String> parseLit(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String s
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: astore_1
       8: lconst_0
       9: lstore_2
      10: iconst_0
      11: istore        4
      13: iload         4
      15: ifne          76
      18: lload_2
      19: bipush        16
      21: i2l
      22: lmul
      23: aload_1
      24: iconst_1
      25: iconst_5
      26: invokevirtual #22                 // Method java/lang/String.substring:(II)Ljava/lang/String;
      29: dup
      30: ldc           #24                 // String substring(...)
      32: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      35: iconst_2
      36: invokestatic  #33                 // Method kotlin/text/CharsKt.checkRadix:(I)I
      39: invokestatic  #39                 // Method java/lang/Long.parseLong:(Ljava/lang/String;I)J
      42: ladd
      43: lstore_2
      44: aload_1
      45: iconst_0
      46: invokevirtual #43                 // Method java/lang/String.charAt:(I)C
      49: bipush        48
      51: if_icmpne     58
      54: iconst_1
      55: goto          59
      58: iconst_0
      59: istore        4
      61: aload_1
      62: iconst_5
      63: invokevirtual #46                 // Method java/lang/String.substring:(I)Ljava/lang/String;
      66: dup
      67: ldc           #24                 // String substring(...)
      69: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      72: astore_1
      73: goto          13
      76: new           #48                 // class kotlin/Pair
      79: dup
      80: lload_2
      81: invokestatic  #52                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      84: aload_1
      85: invokespecial #56                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      88: areturn

  public static final kotlin.Pair<quick.start.Packet, java.lang.String> parsePacket(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String s
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_0
       8: iconst_3
       9: invokevirtual #22                 // Method java/lang/String.substring:(II)Ljava/lang/String;
      12: dup
      13: ldc           #24                 // String substring(...)
      15: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      18: iconst_2
      19: invokestatic  #33                 // Method kotlin/text/CharsKt.checkRadix:(I)I
      22: invokestatic  #69                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;I)I
      25: istore_1
      26: getstatic     #75                 // Field quick/start/Op.Companion:Lquick/start/Op$Companion;
      29: aload_0
      30: iconst_3
      31: bipush        6
      33: invokevirtual #22                 // Method java/lang/String.substring:(II)Ljava/lang/String;
      36: dup
      37: ldc           #24                 // String substring(...)
      39: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      42: iconst_2
      43: invokestatic  #33                 // Method kotlin/text/CharsKt.checkRadix:(I)I
      46: invokestatic  #69                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;I)I
      49: invokevirtual #81                 // Method quick/start/Op$Companion.fromInt:(I)Lquick/start/Op;
      52: astore_2
      53: aload_0
      54: bipush        6
      56: invokevirtual #46                 // Method java/lang/String.substring:(I)Ljava/lang/String;
      59: dup
      60: ldc           #24                 // String substring(...)
      62: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      65: astore_3
      66: aload_2
      67: getstatic     #85                 // Field quick/start/Op.Lit:Lquick/start/Op;
      70: if_acmpne     122
      73: aload_3
      74: invokestatic  #87                 // Method parseLit:(Ljava/lang/String;)Lkotlin/Pair;
      77: astore        4
      79: aload         4
      81: invokevirtual #91                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
      84: checkcast     #93                 // class java/lang/Number
      87: invokevirtual #97                 // Method java/lang/Number.longValue:()J
      90: lstore        5
      92: aload         4
      94: invokevirtual #100                // Method kotlin/Pair.component2:()Ljava/lang/Object;
      97: checkcast     #18                 // class java/lang/String
     100: astore        7
     102: new           #48                 // class kotlin/Pair
     105: dup
     106: new           #102                // class quick/start/Packet
     109: dup
     110: iload_1
     111: lload         5
     113: invokespecial #105                // Method quick/start/Packet."<init>":(IJ)V
     116: aload         7
     118: invokespecial #56                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     121: areturn
     122: aload_3
     123: iconst_0
     124: invokevirtual #43                 // Method java/lang/String.charAt:(I)C
     127: bipush        48
     129: if_icmpne     288
     132: aload_3
     133: iconst_1
     134: bipush        16
     136: invokevirtual #22                 // Method java/lang/String.substring:(II)Ljava/lang/String;
     139: dup
     140: ldc           #24                 // String substring(...)
     142: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     145: iconst_2
     146: invokestatic  #33                 // Method kotlin/text/CharsKt.checkRadix:(I)I
     149: invokestatic  #69                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;I)I
     152: istore        4
     154: aload_3
     155: bipush        16
     157: iload         4
     159: iadd
     160: invokevirtual #46                 // Method java/lang/String.substring:(I)Ljava/lang/String;
     163: dup
     164: ldc           #24                 // String substring(...)
     166: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     169: astore        5
     171: aload_3
     172: bipush        16
     174: bipush        16
     176: iload         4
     178: iadd
     179: invokevirtual #22                 // Method java/lang/String.substring:(II)Ljava/lang/String;
     182: dup
     183: ldc           #24                 // String substring(...)
     185: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     188: astore        6
     190: new           #107                // class java/util/ArrayList
     193: dup
     194: invokespecial #110                // Method java/util/ArrayList."<init>":()V
     197: checkcast     #112                // class java/util/List
     200: astore        7
     202: aload         6
     204: checkcast     #114                // class java/lang/CharSequence
     207: invokeinterface #118,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     212: ifne          219
     215: iconst_1
     216: goto          220
     219: iconst_0
     220: ifne          267
     223: aload         6
     225: invokestatic  #120                // Method parsePacket:(Ljava/lang/String;)Lkotlin/Pair;
     228: astore        8
     230: aload         8
     232: invokevirtual #91                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
     235: checkcast     #102                // class quick/start/Packet
     238: astore        9
     240: aload         8
     242: invokevirtual #100                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     245: checkcast     #18                 // class java/lang/String
     248: astore        10
     250: aload         10
     252: astore        6
     254: aload         7
     256: aload         9
     258: invokeinterface #124,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     263: pop
     264: goto          202
     267: new           #48                 // class kotlin/Pair
     270: dup
     271: new           #102                // class quick/start/Packet
     274: dup
     275: iload_1
     276: aload_2
     277: aload         7
     279: invokespecial #127                // Method quick/start/Packet."<init>":(ILquick/start/Op;Ljava/util/List;)V
     282: aload         5
     284: invokespecial #56                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     287: areturn
     288: aload_3
     289: iconst_1
     290: bipush        12
     292: invokevirtual #22                 // Method java/lang/String.substring:(II)Ljava/lang/String;
     295: dup
     296: ldc           #24                 // String substring(...)
     298: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     301: iconst_2
     302: invokestatic  #33                 // Method kotlin/text/CharsKt.checkRadix:(I)I
     305: invokestatic  #69                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;I)I
     308: istore        4
     310: aload_3
     311: bipush        12
     313: invokevirtual #46                 // Method java/lang/String.substring:(I)Ljava/lang/String;
     316: dup
     317: ldc           #24                 // String substring(...)
     319: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     322: astore        5
     324: new           #107                // class java/util/ArrayList
     327: dup
     328: invokespecial #110                // Method java/util/ArrayList."<init>":()V
     331: checkcast     #112                // class java/util/List
     334: astore        6
     336: iconst_1
     337: istore        7
     339: iload         7
     341: iload         4
     343: if_icmpgt     400
     346: aload         5
     348: invokestatic  #120                // Method parsePacket:(Ljava/lang/String;)Lkotlin/Pair;
     351: astore        8
     353: aload         8
     355: invokevirtual #91                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
     358: checkcast     #102                // class quick/start/Packet
     361: astore        9
     363: aload         8
     365: invokevirtual #100                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     368: checkcast     #18                 // class java/lang/String
     371: astore        10
     373: aload         10
     375: astore        5
     377: aload         6
     379: aload         9
     381: invokeinterface #124,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     386: pop
     387: iload         7
     389: iload         4
     391: if_icmpeq     400
     394: iinc          7, 1
     397: goto          346
     400: new           #48                 // class kotlin/Pair
     403: dup
     404: new           #102                // class quick/start/Packet
     407: dup
     408: iload_1
     409: aload_2
     410: aload         6
     412: invokespecial #127                // Method quick/start/Packet."<init>":(ILquick/start/Op;Ljava/util/List;)V
     415: aload         5
     417: invokespecial #56                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     420: areturn

  public static final quick.start.Packet parseFull(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String s
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #120                // Method parsePacket:(Ljava/lang/String;)Lkotlin/Pair;
      10: astore_1
      11: aload_1
      12: invokevirtual #91                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
      15: checkcast     #102                // class quick/start/Packet
      18: astore_2
      19: aload_1
      20: invokevirtual #100                // Method kotlin/Pair.component2:()Ljava/lang/Object;
      23: checkcast     #18                 // class java/lang/String
      26: astore_3
      27: aload_3
      28: checkcast     #114                // class java/lang/CharSequence
      31: astore        4
      33: iconst_0
      34: istore        5
      36: iconst_0
      37: istore        6
      39: iload         6
      41: aload         4
      43: invokeinterface #118,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      48: if_icmpge     94
      51: aload         4
      53: iload         6
      55: invokeinterface #142,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      60: istore        7
      62: iload         7
      64: istore        8
      66: iconst_0
      67: istore        9
      69: iload         8
      71: bipush        48
      73: if_icmpne     80
      76: iconst_1
      77: goto          81
      80: iconst_0
      81: ifne          88
      84: iconst_0
      85: goto          95
      88: iinc          6, 1
      91: goto          39
      94: iconst_1
      95: istore        4
      97: getstatic     #147                // Field kotlin/_Assertions.ENABLED:Z
     100: ifeq          122
     103: iload         4
     105: ifne          122
     108: ldc           #149                // String Assertion failed
     110: astore        5
     112: new           #151                // class java/lang/AssertionError
     115: dup
     116: aload         5
     118: invokespecial #154                // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
     121: athrow
     122: aload_2
     123: areturn

  public static final void main();
    Code:
       0: invokestatic  #168                // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
       3: dup
       4: invokestatic  #171                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
       7: astore_0
       8: bipush        49
      10: istore_3
      11: new           #173                // class java/lang/StringBuilder
      14: dup
      15: invokespecial #174                // Method java/lang/StringBuilder."<init>":()V
      18: iload_3
      19: invokevirtual #178                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      22: aload_0
      23: invokevirtual #181                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      26: invokevirtual #184                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      29: astore_3
      30: bipush        16
      32: istore        4
      34: new           #186                // class java/math/BigInteger
      37: dup
      38: aload_3
      39: iload         4
      41: invokestatic  #33                 // Method kotlin/text/CharsKt.checkRadix:(I)I
      44: invokespecial #189                // Method java/math/BigInteger."<init>":(Ljava/lang/String;I)V
      47: iconst_2
      48: invokevirtual #191                // Method java/math/BigInteger.toString:(I)Ljava/lang/String;
      51: dup
      52: ldc           #193                // String toString(...)
      54: invokestatic  #27                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      57: iconst_1
      58: invokestatic  #199                // Method kotlin/text/StringsKt.drop:(Ljava/lang/String;I)Ljava/lang/String;
      61: astore_1
      62: aload_1
      63: invokestatic  #201                // Method parseFull:(Ljava/lang/String;)Lquick/start/Packet;
      66: astore_2
      67: aload_2
      68: invokevirtual #204                // Method quick/start/Packet.versionTotal:()I
      71: istore_3
      72: getstatic     #210                // Field java/lang/System.out:Ljava/io/PrintStream;
      75: iload_3
      76: invokevirtual #216                // Method java/io/PrintStream.println:(I)V
      79: aload_2
      80: invokevirtual #219                // Method quick/start/Packet.eval:()J
      83: lstore_3
      84: getstatic     #210                // Field java/lang/System.out:Ljava/io/PrintStream;
      87: lload_3
      88: invokevirtual #222                // Method java/io/PrintStream.println:(J)V
      91: return

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