object Day19 {
    const val EXPECTED_PART1_CHECK_ANSWER = 33
    const val EXPECTED_PART2_CHECK_ANSWER = 3472

    val BLUEPRINT_REGEX =
        Regex("Blueprint (\\d+): Each ore robot costs (\\d+) ore. Each clay robot costs (\\d+) ore. Each obsidian robot costs (\\d+) ore and (\\d+) clay. Each geode robot costs (\\d+) ore and (\\d+) obsidian.")

    const val PART1_MINUTES = 24
}

enum class RobotCurrency {
    ORE, CLAY, OBSIDIAN
}

enum class RobotType {
    ORE_COLLECTOR, CLAY_COLLECTOR, OBSIDIAN_COLLECTOR, GEODE_CRACKING
}

data class RobotBuildCost(val amount: Int, val currency: RobotCurrency)

data class Blueprint(
    val id: Int,
    val buildCosts: Map<RobotType, Set<RobotBuildCost>>,
)

data class CollectingState(
    val minutesDone: Int = 0,
    val orePerMinute: Int = 1,
    val clayPerMinute: Int = 0,
    val obsidianPerMinute: Int = 0,
    val geoCrackedPerMinute: Int = 0,
    val ore: Int = 0,
    val clay: Int = 0,
    val obs: Int = 0,
    val geoCracked: Int = 0,
)

fun main() {
    fun List<String>.parseBlueprints() =
        map {
            val (id, oreRobotOre, clayRobotOre, obsRobotOre, obsRobotClay, geoRobotOre, geoRobotObs) = Day19.BLUEPRINT_REGEX.matchEntire(
                it
            )?.destructured ?: error("Oops")
            Blueprint(
                id.toInt(),
                mapOf(
                    RobotType.ORE_COLLECTOR to setOf(RobotBuildCost(oreRobotOre.toInt(), RobotCurrency.ORE)),
                    RobotType.CLAY_COLLECTOR to setOf(RobotBuildCost(clayRobotOre.toInt(), RobotCurrency.ORE)),
                    RobotType.OBSIDIAN_COLLECTOR to setOf(RobotBuildCost(obsRobotOre.toInt(), RobotCurrency.ORE), RobotBuildCost(obsRobotClay.toInt(), RobotCurrency.CLAY)),
                    RobotType.GEODE_CRACKING to setOf(RobotBuildCost(geoRobotOre.toInt(), RobotCurrency.ORE), RobotBuildCost(geoRobotObs.toInt(), RobotCurrency.OBSIDIAN)),
                )
            )
        }

    fun findBest(
        blueprint: Blueprint,
        minutesToRun: Int,
        state: CollectingState,
    ): Int {
        val minutesLeft = minutesToRun - state.minutesDone
        return blueprint.buildCosts
            .maxOf { (robotType, buildCosts) ->
                if (
                    (robotType == RobotType.ORE_COLLECTOR && state.orePerMinute > 5) ||
                    (robotType == RobotType.CLAY_COLLECTOR && state.clayPerMinute > 5) ||
                    (robotType == RobotType.OBSIDIAN_COLLECTOR && state.obsidianPerMinute > 5)
                ){
                    -1
                } else {
                    val minutesPerCurrency = buildCosts.map {
                        when (it.currency) {
                            RobotCurrency.ORE -> if (state.ore >= it.amount) 0 else if (state.orePerMinute > 0) it.amount - state.ore / state.orePerMinute else -1
                            RobotCurrency.CLAY -> if (state.clay >= it.amount) 0 else if (state.clayPerMinute > 0) it.amount - state.clay / state.clayPerMinute else -1
                            RobotCurrency.OBSIDIAN -> if (state.obs >= it.amount) 0 else if (state.obsidianPerMinute > 0) it.amount - state.obs / state.obsidianPerMinute else -1
                        }
                    }
                    val canNotMake = minutesPerCurrency.any { it == -1 }
                    val minutesUntilWeCanMakeRobot = minutesPerCurrency.max() + 1

                    if (canNotMake || minutesUntilWeCanMakeRobot >= minutesLeft) {
                        state.copy(
                            minutesDone = minutesToRun,
                            ore = state.ore + state.orePerMinute * minutesLeft,
                            clay = state.clay + state.clayPerMinute * minutesLeft,
                            obs = state.obs + state.obsidianPerMinute * minutesLeft,
                            geoCracked = state.geoCracked + state.geoCrackedPerMinute * minutesLeft,
                        ).geoCracked
                    } else {
                        findBest(
                            blueprint,
                            minutesToRun,
                            state.copy(
                                minutesDone = state.minutesDone + minutesUntilWeCanMakeRobot,
                                ore = state.ore + (minutesUntilWeCanMakeRobot * state.orePerMinute) - (buildCosts.firstOrNull { it.currency == RobotCurrency.ORE }?.amount
                                    ?: 0),
                                clay = state.clay + (minutesUntilWeCanMakeRobot * state.clayPerMinute) - (buildCosts.firstOrNull { it.currency == RobotCurrency.CLAY }?.amount
                                    ?: 0),
                                obs = state.obs + (minutesUntilWeCanMakeRobot * state.obsidianPerMinute) - (buildCosts.firstOrNull { it.currency == RobotCurrency.OBSIDIAN }?.amount
                                    ?: 0),
                                geoCracked = state.geoCracked + (minutesUntilWeCanMakeRobot * state.geoCrackedPerMinute),
                                orePerMinute = state.orePerMinute + if (robotType == RobotType.ORE_COLLECTOR) 1 else 0,
                                clayPerMinute = state.clayPerMinute + if (robotType == RobotType.CLAY_COLLECTOR) 1 else 0,
                                obsidianPerMinute = state.obsidianPerMinute + if (robotType == RobotType.OBSIDIAN_COLLECTOR) 1 else 0,
                                geoCrackedPerMinute = state.geoCrackedPerMinute + if (robotType == RobotType.GEODE_CRACKING) 1 else 0,
                            )
                        )
                    }
                }
            }
    }

    fun part1(input: List<String>): Int {
        val bluePrints = input.parseBlueprints()
        println(bluePrints)
        bluePrints.forEach { bluePrint -> println("${bluePrint.id}: ${findBest(bluePrint, 24 /*Day19.PART1_MINUTES*/, CollectingState())}") }
        return 1
    }

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

    // test if implementation meets criteria from the description, like:
    val testInput = readInput("Day19_test")
    check(part1(testInput) == Day19.EXPECTED_PART1_CHECK_ANSWER) { "Part 1 failed" }
    check(part2(testInput) == Day19.EXPECTED_PART2_CHECK_ANSWER) { "Part 2 failed" }

    val input = readInput("Day19")
    println(part1(input))
    println(part2(input))
}

Compiled from "Day19.kt"
public final class Day19Kt$WhenMappings {
  public static final int[] $EnumSwitchMapping$0;

  static {};
    Code:
       0: invokestatic  #14                 // Method RobotCurrency.values:()[LRobotCurrency;
       3: arraylength
       4: newarray       int
       6: astore_0
       7: nop
       8: aload_0
       9: getstatic     #18                 // Field RobotCurrency.ORE:LRobotCurrency;
      12: invokevirtual #22                 // Method RobotCurrency.ordinal:()I
      15: iconst_1
      16: iastore
      17: goto          21
      20: astore_1
      21: nop
      22: aload_0
      23: getstatic     #25                 // Field RobotCurrency.CLAY:LRobotCurrency;
      26: invokevirtual #22                 // Method RobotCurrency.ordinal:()I
      29: iconst_2
      30: iastore
      31: goto          35
      34: astore_1
      35: nop
      36: aload_0
      37: getstatic     #28                 // Field RobotCurrency.OBSIDIAN:LRobotCurrency;
      40: invokevirtual #22                 // Method RobotCurrency.ordinal:()I
      43: iconst_3
      44: iastore
      45: goto          49
      48: astore_1
      49: aload_0
      50: putstatic     #32                 // Field $EnumSwitchMapping$0:[I
      53: return
    Exception table:
       from    to  target type
           7    17    20   Class java/lang/NoSuchFieldError
          21    31    34   Class java/lang/NoSuchFieldError
          35    45    48   Class java/lang/NoSuchFieldError
}

Compiled from "Day19.kt"
public final class Day19Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Day19_test
       2: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      10: bipush        33
      12: if_icmpne     19
      15: iconst_1
      16: goto          20
      19: iconst_0
      20: ifne          40
      23: iconst_0
      24: istore_2
      25: ldc           #20                 // String Part 1 failed
      27: astore_2
      28: new           #22                 // class java/lang/IllegalStateException
      31: dup
      32: aload_2
      33: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      36: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      39: athrow
      40: aload_0
      41: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      44: sipush        3472
      47: if_icmpne     54
      50: iconst_1
      51: goto          55
      54: iconst_0
      55: ifne          75
      58: iconst_0
      59: istore_2
      60: ldc           #35                 // String Part 2 failed
      62: astore_2
      63: new           #22                 // class java/lang/IllegalStateException
      66: dup
      67: aload_2
      68: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      71: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      74: athrow
      75: ldc           #37                 // String Day19
      77: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      80: astore_1
      81: aload_1
      82: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      85: istore_2
      86: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      89: iload_2
      90: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
      93: aload_1
      94: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      97: istore_2
      98: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     101: iload_2
     102: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
     105: return

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

  private static final java.util.List<Blueprint> main$parseBlueprints(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #67                 // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: astore_3
       9: new           #69                 // class java/util/ArrayList
      12: dup
      13: aload_1
      14: bipush        10
      16: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      19: invokespecial #77                 // Method java/util/ArrayList."<init>":(I)V
      22: checkcast     #79                 // class java/util/Collection
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          485
      48: aload         6
      50: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         4
      59: aload         7
      61: checkcast     #95                 // class java/lang/String
      64: astore        8
      66: astore        20
      68: iconst_0
      69: istore        9
      71: getstatic     #100                // Field Day19.INSTANCE:LDay19;
      74: invokevirtual #104                // Method Day19.getBLUEPRINT_REGEX:()Lkotlin/text/Regex;
      77: aload         8
      79: checkcast     #106                // class java/lang/CharSequence
      82: invokevirtual #112                // Method kotlin/text/Regex.matchEntire:(Ljava/lang/CharSequence;)Lkotlin/text/MatchResult;
      85: astore        10
      87: aload         10
      89: ifnull        111
      92: aload         10
      94: invokeinterface #118,  1          // InterfaceMethod kotlin/text/MatchResult.getDestructured:()Lkotlin/text/MatchResult$Destructured;
      99: astore        11
     101: aload         11
     103: ifnull        111
     106: aload         11
     108: goto          124
     111: new           #22                 // class java/lang/IllegalStateException
     114: dup
     115: ldc           #120                // String Oops
     117: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
     120: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     123: athrow
     124: astore        12
     126: aload         12
     128: invokevirtual #126                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     131: invokeinterface #130,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     136: iconst_1
     137: invokeinterface #134,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     142: checkcast     #95                 // class java/lang/String
     145: astore        10
     147: aload         12
     149: invokevirtual #126                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     152: invokeinterface #130,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     157: iconst_2
     158: invokeinterface #134,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     163: checkcast     #95                 // class java/lang/String
     166: astore        11
     168: aload         12
     170: invokevirtual #126                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     173: invokeinterface #130,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     178: iconst_3
     179: invokeinterface #134,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     184: checkcast     #95                 // class java/lang/String
     187: astore        13
     189: aload         12
     191: invokevirtual #126                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     194: invokeinterface #130,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     199: iconst_4
     200: invokeinterface #134,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     205: checkcast     #95                 // class java/lang/String
     208: astore        14
     210: aload         12
     212: invokevirtual #126                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     215: invokeinterface #130,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     220: iconst_5
     221: invokeinterface #134,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     226: checkcast     #95                 // class java/lang/String
     229: astore        15
     231: aload         12
     233: invokevirtual #126                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     236: invokeinterface #130,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     241: bipush        6
     243: invokeinterface #134,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     248: checkcast     #95                 // class java/lang/String
     251: astore        16
     253: aload         12
     255: invokevirtual #126                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     258: invokeinterface #130,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     263: bipush        7
     265: invokeinterface #134,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     270: checkcast     #95                 // class java/lang/String
     273: astore        17
     275: new           #136                // class Blueprint
     278: dup
     279: aload         10
     281: invokestatic  #142                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     284: iconst_4
     285: anewarray     #144                // class kotlin/Pair
     288: astore        18
     290: aload         18
     292: iconst_0
     293: getstatic     #150                // Field RobotType.ORE_COLLECTOR:LRobotType;
     296: new           #152                // class RobotBuildCost
     299: dup
     300: aload         11
     302: invokestatic  #142                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     305: getstatic     #158                // Field RobotCurrency.ORE:LRobotCurrency;
     308: invokespecial #161                // Method RobotBuildCost."<init>":(ILRobotCurrency;)V
     311: invokestatic  #167                // Method kotlin/collections/SetsKt.setOf:(Ljava/lang/Object;)Ljava/util/Set;
     314: invokestatic  #173                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     317: aastore
     318: aload         18
     320: iconst_1
     321: getstatic     #176                // Field RobotType.CLAY_COLLECTOR:LRobotType;
     324: new           #152                // class RobotBuildCost
     327: dup
     328: aload         13
     330: invokestatic  #142                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     333: getstatic     #158                // Field RobotCurrency.ORE:LRobotCurrency;
     336: invokespecial #161                // Method RobotBuildCost."<init>":(ILRobotCurrency;)V
     339: invokestatic  #167                // Method kotlin/collections/SetsKt.setOf:(Ljava/lang/Object;)Ljava/util/Set;
     342: invokestatic  #173                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     345: aastore
     346: aload         18
     348: iconst_2
     349: getstatic     #179                // Field RobotType.OBSIDIAN_COLLECTOR:LRobotType;
     352: iconst_2
     353: anewarray     #152                // class RobotBuildCost
     356: astore        19
     358: aload         19
     360: iconst_0
     361: new           #152                // class RobotBuildCost
     364: dup
     365: aload         14
     367: invokestatic  #142                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     370: getstatic     #158                // Field RobotCurrency.ORE:LRobotCurrency;
     373: invokespecial #161                // Method RobotBuildCost."<init>":(ILRobotCurrency;)V
     376: aastore
     377: aload         19
     379: iconst_1
     380: new           #152                // class RobotBuildCost
     383: dup
     384: aload         15
     386: invokestatic  #142                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     389: getstatic     #182                // Field RobotCurrency.CLAY:LRobotCurrency;
     392: invokespecial #161                // Method RobotBuildCost."<init>":(ILRobotCurrency;)V
     395: aastore
     396: aload         19
     398: invokestatic  #185                // Method kotlin/collections/SetsKt.setOf:([Ljava/lang/Object;)Ljava/util/Set;
     401: invokestatic  #173                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     404: aastore
     405: aload         18
     407: iconst_3
     408: getstatic     #188                // Field RobotType.GEODE_CRACKING:LRobotType;
     411: iconst_2
     412: anewarray     #152                // class RobotBuildCost
     415: astore        19
     417: aload         19
     419: iconst_0
     420: new           #152                // class RobotBuildCost
     423: dup
     424: aload         16
     426: invokestatic  #142                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     429: getstatic     #158                // Field RobotCurrency.ORE:LRobotCurrency;
     432: invokespecial #161                // Method RobotBuildCost."<init>":(ILRobotCurrency;)V
     435: aastore
     436: aload         19
     438: iconst_1
     439: new           #152                // class RobotBuildCost
     442: dup
     443: aload         17
     445: invokestatic  #142                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     448: getstatic     #191                // Field RobotCurrency.OBSIDIAN:LRobotCurrency;
     451: invokespecial #161                // Method RobotBuildCost."<init>":(ILRobotCurrency;)V
     454: aastore
     455: aload         19
     457: invokestatic  #185                // Method kotlin/collections/SetsKt.setOf:([Ljava/lang/Object;)Ljava/util/Set;
     460: invokestatic  #173                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     463: aastore
     464: aload         18
     466: invokestatic  #197                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     469: invokespecial #200                // Method Blueprint."<init>":(ILjava/util/Map;)V
     472: nop
     473: aload         20
     475: swap
     476: invokeinterface #204,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     481: pop
     482: goto          38
     485: aload         4
     487: checkcast     #57                 // class java/util/List
     490: nop
     491: areturn

  private static final int main$findBest(Blueprint, int, CollectingState);
    Code:
       0: iload_1
       1: aload_2
       2: invokevirtual #232                // Method CollectingState.getMinutesDone:()I
       5: isub
       6: istore_3
       7: aload_0
       8: invokevirtual #236                // Method Blueprint.getBuildCosts:()Ljava/util/Map;
      11: invokeinterface #242,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      16: checkcast     #67                 // class java/lang/Iterable
      19: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      24: astore        4
      26: aload         4
      28: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      33: ifne          44
      36: new           #244                // class java/util/NoSuchElementException
      39: dup
      40: invokespecial #246                // Method java/util/NoSuchElementException."<init>":()V
      43: athrow
      44: aload         4
      46: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      51: checkcast     #248                // class java/util/Map$Entry
      54: astore        5
      56: iconst_0
      57: istore        6
      59: aload         5
      61: invokeinterface #251,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
      66: checkcast     #146                // class RobotType
      69: astore        7
      71: aload         5
      73: invokeinterface #254,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      78: checkcast     #256                // class java/util/Set
      81: astore        8
      83: aload         7
      85: getstatic     #150                // Field RobotType.ORE_COLLECTOR:LRobotType;
      88: if_acmpne     99
      91: aload_2
      92: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
      95: iconst_5
      96: if_icmpgt     131
      99: aload         7
     101: getstatic     #176                // Field RobotType.CLAY_COLLECTOR:LRobotType;
     104: if_acmpne     115
     107: aload_2
     108: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
     111: iconst_5
     112: if_icmpgt     131
     115: aload         7
     117: getstatic     #179                // Field RobotType.OBSIDIAN_COLLECTOR:LRobotType;
     120: if_acmpne     135
     123: aload_2
     124: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
     127: iconst_5
     128: if_icmple     135
     131: iconst_m1
     132: goto          1094
     135: aload         8
     137: checkcast     #67                 // class java/lang/Iterable
     140: astore        9
     142: iconst_0
     143: istore        10
     145: aload         9
     147: astore        11
     149: new           #69                 // class java/util/ArrayList
     152: dup
     153: aload         9
     155: bipush        10
     157: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     160: invokespecial #77                 // Method java/util/ArrayList."<init>":(I)V
     163: checkcast     #79                 // class java/util/Collection
     166: astore        12
     168: iconst_0
     169: istore        13
     171: aload         11
     173: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     178: astore        14
     180: aload         14
     182: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     187: ifeq          411
     190: aload         14
     192: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     197: astore        15
     199: aload         12
     201: aload         15
     203: checkcast     #152                // class RobotBuildCost
     206: astore        16
     208: astore        17
     210: iconst_0
     211: istore        18
     213: aload         16
     215: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
     218: getstatic     #275                // Field Day19Kt$WhenMappings.$EnumSwitchMapping$0:[I
     221: swap
     222: invokevirtual #278                // Method RobotCurrency.ordinal:()I
     225: iaload
     226: tableswitch   { // 1 to 3
                     1: 252
                     2: 297
                     3: 342
               default: 387
          }
     252: aload_2
     253: invokevirtual #281                // Method CollectingState.getOre:()I
     256: aload         16
     258: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     261: if_icmplt     268
     264: iconst_0
     265: goto          395
     268: aload_2
     269: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
     272: ifle          293
     275: aload         16
     277: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     280: aload_2
     281: invokevirtual #281                // Method CollectingState.getOre:()I
     284: aload_2
     285: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
     288: idiv
     289: isub
     290: goto          395
     293: iconst_m1
     294: goto          395
     297: aload_2
     298: invokevirtual #287                // Method CollectingState.getClay:()I
     301: aload         16
     303: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     306: if_icmplt     313
     309: iconst_0
     310: goto          395
     313: aload_2
     314: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
     317: ifle          338
     320: aload         16
     322: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     325: aload_2
     326: invokevirtual #287                // Method CollectingState.getClay:()I
     329: aload_2
     330: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
     333: idiv
     334: isub
     335: goto          395
     338: iconst_m1
     339: goto          395
     342: aload_2
     343: invokevirtual #290                // Method CollectingState.getObs:()I
     346: aload         16
     348: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     351: if_icmplt     358
     354: iconst_0
     355: goto          395
     358: aload_2
     359: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
     362: ifle          383
     365: aload         16
     367: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     370: aload_2
     371: invokevirtual #290                // Method CollectingState.getObs:()I
     374: aload_2
     375: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
     378: idiv
     379: isub
     380: goto          395
     383: iconst_m1
     384: goto          395
     387: new           #292                // class kotlin/NoWhenBranchMatchedException
     390: dup
     391: invokespecial #293                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     394: athrow
     395: nop
     396: invokestatic  #297                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     399: aload         17
     401: swap
     402: invokeinterface #204,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     407: pop
     408: goto          180
     411: aload         12
     413: checkcast     #57                 // class java/util/List
     416: nop
     417: astore        19
     419: aload         19
     421: checkcast     #67                 // class java/lang/Iterable
     424: astore        10
     426: iconst_0
     427: istore        11
     429: aload         10
     431: instanceof    #79                 // class java/util/Collection
     434: ifeq          454
     437: aload         10
     439: checkcast     #79                 // class java/util/Collection
     442: invokeinterface #300,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     447: ifeq          454
     450: iconst_0
     451: goto          514
     454: aload         10
     456: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     461: astore        12
     463: aload         12
     465: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     470: ifeq          513
     473: aload         12
     475: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     480: astore        13
     482: aload         13
     484: checkcast     #302                // class java/lang/Number
     487: invokevirtual #305                // Method java/lang/Number.intValue:()I
     490: istore        14
     492: iconst_0
     493: istore        15
     495: iload         14
     497: iconst_m1
     498: if_icmpne     505
     501: iconst_1
     502: goto          506
     505: iconst_0
     506: ifeq          463
     509: iconst_1
     510: goto          514
     513: iconst_0
     514: istore        9
     516: aload         19
     518: checkcast     #67                 // class java/lang/Iterable
     521: invokestatic  #309                // Method kotlin/collections/CollectionsKt.maxOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
     524: checkcast     #302                // class java/lang/Number
     527: invokevirtual #305                // Method java/lang/Number.intValue:()I
     530: iconst_1
     531: iadd
     532: istore        10
     534: iload         9
     536: ifne          545
     539: iload         10
     541: iload_3
     542: if_icmplt     607
     545: aload_2
     546: iload_1
     547: iconst_0
     548: iconst_0
     549: iconst_0
     550: iconst_0
     551: aload_2
     552: invokevirtual #281                // Method CollectingState.getOre:()I
     555: aload_2
     556: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
     559: iload_3
     560: imul
     561: iadd
     562: aload_2
     563: invokevirtual #287                // Method CollectingState.getClay:()I
     566: aload_2
     567: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
     570: iload_3
     571: imul
     572: iadd
     573: aload_2
     574: invokevirtual #290                // Method CollectingState.getObs:()I
     577: aload_2
     578: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
     581: iload_3
     582: imul
     583: iadd
     584: aload_2
     585: invokevirtual #312                // Method CollectingState.getGeoCracked:()I
     588: aload_2
     589: invokevirtual #315                // Method CollectingState.getGeoCrackedPerMinute:()I
     592: iload_3
     593: imul
     594: iadd
     595: bipush        30
     597: aconst_null
     598: invokestatic  #319                // Method CollectingState.copy$default:(LCollectingState;IIIIIIIIIILjava/lang/Object;)LCollectingState;
     601: invokevirtual #312                // Method CollectingState.getGeoCracked:()I
     604: goto          1094
     607: aload_0
     608: iload_1
     609: aload_2
     610: invokevirtual #232                // Method CollectingState.getMinutesDone:()I
     613: iload         10
     615: iadd
     616: istore        11
     618: aload_2
     619: invokevirtual #281                // Method CollectingState.getOre:()I
     622: iload         10
     624: aload_2
     625: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
     628: imul
     629: iadd
     630: aload         8
     632: checkcast     #67                 // class java/lang/Iterable
     635: astore        14
     637: istore        20
     639: istore        21
     641: astore        17
     643: iconst_0
     644: istore        15
     646: aload         14
     648: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     653: astore        16
     655: aload         16
     657: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     662: ifeq          708
     665: aload         16
     667: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     672: astore        18
     674: aload         18
     676: checkcast     #152                // class RobotBuildCost
     679: astore        22
     681: iconst_0
     682: istore        23
     684: aload         22
     686: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
     689: getstatic     #158                // Field RobotCurrency.ORE:LRobotCurrency;
     692: if_acmpne     699
     695: iconst_1
     696: goto          700
     699: iconst_0
     700: ifeq          655
     703: aload         18
     705: goto          709
     708: aconst_null
     709: astore        24
     711: aload         17
     713: iload         21
     715: iload         20
     717: aload         24
     719: checkcast     #152                // class RobotBuildCost
     722: dup
     723: ifnull        732
     726: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     729: goto          734
     732: pop
     733: iconst_0
     734: isub
     735: istore        12
     737: aload_2
     738: invokevirtual #287                // Method CollectingState.getClay:()I
     741: iload         10
     743: aload_2
     744: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
     747: imul
     748: iadd
     749: aload         8
     751: checkcast     #67                 // class java/lang/Iterable
     754: astore        15
     756: istore        20
     758: istore        21
     760: astore        17
     762: iconst_0
     763: istore        16
     765: aload         15
     767: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     772: astore        18
     774: aload         18
     776: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     781: ifeq          827
     784: aload         18
     786: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     791: astore        22
     793: aload         22
     795: checkcast     #152                // class RobotBuildCost
     798: astore        23
     800: iconst_0
     801: istore        25
     803: aload         23
     805: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
     808: getstatic     #182                // Field RobotCurrency.CLAY:LRobotCurrency;
     811: if_acmpne     818
     814: iconst_1
     815: goto          819
     818: iconst_0
     819: ifeq          774
     822: aload         22
     824: goto          828
     827: aconst_null
     828: astore        24
     830: aload         17
     832: iload         21
     834: iload         20
     836: aload         24
     838: checkcast     #152                // class RobotBuildCost
     841: dup
     842: ifnull        851
     845: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     848: goto          853
     851: pop
     852: iconst_0
     853: isub
     854: istore        13
     856: aload_2
     857: invokevirtual #290                // Method CollectingState.getObs:()I
     860: iload         10
     862: aload_2
     863: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
     866: imul
     867: iadd
     868: aload         8
     870: checkcast     #67                 // class java/lang/Iterable
     873: astore        16
     875: istore        20
     877: istore        21
     879: astore        17
     881: iconst_0
     882: istore        18
     884: aload         16
     886: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     891: astore        22
     893: aload         22
     895: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     900: ifeq          946
     903: aload         22
     905: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     910: astore        23
     912: aload         23
     914: checkcast     #152                // class RobotBuildCost
     917: astore        25
     919: iconst_0
     920: istore        26
     922: aload         25
     924: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
     927: getstatic     #191                // Field RobotCurrency.OBSIDIAN:LRobotCurrency;
     930: if_acmpne     937
     933: iconst_1
     934: goto          938
     937: iconst_0
     938: ifeq          893
     941: aload         23
     943: goto          947
     946: aconst_null
     947: astore        24
     949: aload         17
     951: iload         21
     953: iload         20
     955: aload         24
     957: checkcast     #152                // class RobotBuildCost
     960: dup
     961: ifnull        970
     964: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
     967: goto          972
     970: pop
     971: iconst_0
     972: isub
     973: istore        14
     975: aload_2
     976: invokevirtual #312                // Method CollectingState.getGeoCracked:()I
     979: iload         10
     981: aload_2
     982: invokevirtual #315                // Method CollectingState.getGeoCrackedPerMinute:()I
     985: imul
     986: iadd
     987: istore        15
     989: aload_2
     990: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
     993: aload         7
     995: getstatic     #150                // Field RobotType.ORE_COLLECTOR:LRobotType;
     998: if_acmpne     1005
    1001: iconst_1
    1002: goto          1006
    1005: iconst_0
    1006: iadd
    1007: istore        16
    1009: aload_2
    1010: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
    1013: aload         7
    1015: getstatic     #176                // Field RobotType.CLAY_COLLECTOR:LRobotType;
    1018: if_acmpne     1025
    1021: iconst_1
    1022: goto          1026
    1025: iconst_0
    1026: iadd
    1027: istore        18
    1029: aload_2
    1030: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
    1033: aload         7
    1035: getstatic     #179                // Field RobotType.OBSIDIAN_COLLECTOR:LRobotType;
    1038: if_acmpne     1045
    1041: iconst_1
    1042: goto          1046
    1045: iconst_0
    1046: iadd
    1047: istore        22
    1049: aload_2
    1050: invokevirtual #315                // Method CollectingState.getGeoCrackedPerMinute:()I
    1053: aload         7
    1055: getstatic     #188                // Field RobotType.GEODE_CRACKING:LRobotType;
    1058: if_acmpne     1065
    1061: iconst_1
    1062: goto          1066
    1065: iconst_0
    1066: iadd
    1067: istore        23
    1069: aload_2
    1070: iload         11
    1072: iload         16
    1074: iload         18
    1076: iload         22
    1078: iload         23
    1080: iload         12
    1082: iload         13
    1084: iload         14
    1086: iload         15
    1088: invokevirtual #323                // Method CollectingState.copy:(IIIIIIIII)LCollectingState;
    1091: invokestatic  #325                // Method main$findBest:(LBlueprint;ILCollectingState;)I
    1094: nop
    1095: istore        5
    1097: aload         4
    1099: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1104: ifeq          2175
    1107: aload         4
    1109: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1114: checkcast     #248                // class java/util/Map$Entry
    1117: astore        6
    1119: iconst_0
    1120: istore        7
    1122: aload         6
    1124: invokeinterface #251,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
    1129: checkcast     #146                // class RobotType
    1132: astore        8
    1134: aload         6
    1136: invokeinterface #254,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
    1141: checkcast     #256                // class java/util/Set
    1144: astore        9
    1146: aload         8
    1148: getstatic     #150                // Field RobotType.ORE_COLLECTOR:LRobotType;
    1151: if_acmpne     1162
    1154: aload_2
    1155: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
    1158: iconst_5
    1159: if_icmpgt     1194
    1162: aload         8
    1164: getstatic     #176                // Field RobotType.CLAY_COLLECTOR:LRobotType;
    1167: if_acmpne     1178
    1170: aload_2
    1171: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
    1174: iconst_5
    1175: if_icmpgt     1194
    1178: aload         8
    1180: getstatic     #179                // Field RobotType.OBSIDIAN_COLLECTOR:LRobotType;
    1183: if_acmpne     1198
    1186: aload_2
    1187: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
    1190: iconst_5
    1191: if_icmple     1198
    1194: iconst_m1
    1195: goto          2158
    1198: aload         9
    1200: checkcast     #67                 // class java/lang/Iterable
    1203: astore        10
    1205: iconst_0
    1206: istore        11
    1208: aload         10
    1210: astore        12
    1212: new           #69                 // class java/util/ArrayList
    1215: dup
    1216: aload         10
    1218: bipush        10
    1220: invokestatic  #75                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
    1223: invokespecial #77                 // Method java/util/ArrayList."<init>":(I)V
    1226: checkcast     #79                 // class java/util/Collection
    1229: astore        13
    1231: iconst_0
    1232: istore        14
    1234: aload         12
    1236: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    1241: astore        15
    1243: aload         15
    1245: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1250: ifeq          1475
    1253: aload         15
    1255: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1260: astore        16
    1262: aload         13
    1264: aload         16
    1266: checkcast     #152                // class RobotBuildCost
    1269: astore        17
    1271: astore        18
    1273: iconst_0
    1274: istore        19
    1276: aload         17
    1278: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
    1281: getstatic     #275                // Field Day19Kt$WhenMappings.$EnumSwitchMapping$0:[I
    1284: swap
    1285: invokevirtual #278                // Method RobotCurrency.ordinal:()I
    1288: iaload
    1289: tableswitch   { // 1 to 3
                     1: 1316
                     2: 1361
                     3: 1406
               default: 1451
          }
    1316: aload_2
    1317: invokevirtual #281                // Method CollectingState.getOre:()I
    1320: aload         17
    1322: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1325: if_icmplt     1332
    1328: iconst_0
    1329: goto          1459
    1332: aload_2
    1333: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
    1336: ifle          1357
    1339: aload         17
    1341: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1344: aload_2
    1345: invokevirtual #281                // Method CollectingState.getOre:()I
    1348: aload_2
    1349: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
    1352: idiv
    1353: isub
    1354: goto          1459
    1357: iconst_m1
    1358: goto          1459
    1361: aload_2
    1362: invokevirtual #287                // Method CollectingState.getClay:()I
    1365: aload         17
    1367: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1370: if_icmplt     1377
    1373: iconst_0
    1374: goto          1459
    1377: aload_2
    1378: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
    1381: ifle          1402
    1384: aload         17
    1386: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1389: aload_2
    1390: invokevirtual #287                // Method CollectingState.getClay:()I
    1393: aload_2
    1394: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
    1397: idiv
    1398: isub
    1399: goto          1459
    1402: iconst_m1
    1403: goto          1459
    1406: aload_2
    1407: invokevirtual #290                // Method CollectingState.getObs:()I
    1410: aload         17
    1412: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1415: if_icmplt     1422
    1418: iconst_0
    1419: goto          1459
    1422: aload_2
    1423: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
    1426: ifle          1447
    1429: aload         17
    1431: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1434: aload_2
    1435: invokevirtual #290                // Method CollectingState.getObs:()I
    1438: aload_2
    1439: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
    1442: idiv
    1443: isub
    1444: goto          1459
    1447: iconst_m1
    1448: goto          1459
    1451: new           #292                // class kotlin/NoWhenBranchMatchedException
    1454: dup
    1455: invokespecial #293                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
    1458: athrow
    1459: nop
    1460: invokestatic  #297                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    1463: aload         18
    1465: swap
    1466: invokeinterface #204,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
    1471: pop
    1472: goto          1243
    1475: aload         13
    1477: checkcast     #57                 // class java/util/List
    1480: nop
    1481: astore        20
    1483: aload         20
    1485: checkcast     #67                 // class java/lang/Iterable
    1488: astore        11
    1490: iconst_0
    1491: istore        12
    1493: aload         11
    1495: instanceof    #79                 // class java/util/Collection
    1498: ifeq          1518
    1501: aload         11
    1503: checkcast     #79                 // class java/util/Collection
    1506: invokeinterface #300,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
    1511: ifeq          1518
    1514: iconst_0
    1515: goto          1578
    1518: aload         11
    1520: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    1525: astore        13
    1527: aload         13
    1529: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1534: ifeq          1577
    1537: aload         13
    1539: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1544: astore        14
    1546: aload         14
    1548: checkcast     #302                // class java/lang/Number
    1551: invokevirtual #305                // Method java/lang/Number.intValue:()I
    1554: istore        15
    1556: iconst_0
    1557: istore        16
    1559: iload         15
    1561: iconst_m1
    1562: if_icmpne     1569
    1565: iconst_1
    1566: goto          1570
    1569: iconst_0
    1570: ifeq          1527
    1573: iconst_1
    1574: goto          1578
    1577: iconst_0
    1578: istore        10
    1580: aload         20
    1582: checkcast     #67                 // class java/lang/Iterable
    1585: invokestatic  #309                // Method kotlin/collections/CollectionsKt.maxOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
    1588: checkcast     #302                // class java/lang/Number
    1591: invokevirtual #305                // Method java/lang/Number.intValue:()I
    1594: iconst_1
    1595: iadd
    1596: istore        11
    1598: iload         10
    1600: ifne          1609
    1603: iload         11
    1605: iload_3
    1606: if_icmplt     1671
    1609: aload_2
    1610: iload_1
    1611: iconst_0
    1612: iconst_0
    1613: iconst_0
    1614: iconst_0
    1615: aload_2
    1616: invokevirtual #281                // Method CollectingState.getOre:()I
    1619: aload_2
    1620: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
    1623: iload_3
    1624: imul
    1625: iadd
    1626: aload_2
    1627: invokevirtual #287                // Method CollectingState.getClay:()I
    1630: aload_2
    1631: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
    1634: iload_3
    1635: imul
    1636: iadd
    1637: aload_2
    1638: invokevirtual #290                // Method CollectingState.getObs:()I
    1641: aload_2
    1642: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
    1645: iload_3
    1646: imul
    1647: iadd
    1648: aload_2
    1649: invokevirtual #312                // Method CollectingState.getGeoCracked:()I
    1652: aload_2
    1653: invokevirtual #315                // Method CollectingState.getGeoCrackedPerMinute:()I
    1656: iload_3
    1657: imul
    1658: iadd
    1659: bipush        30
    1661: aconst_null
    1662: invokestatic  #319                // Method CollectingState.copy$default:(LCollectingState;IIIIIIIIIILjava/lang/Object;)LCollectingState;
    1665: invokevirtual #312                // Method CollectingState.getGeoCracked:()I
    1668: goto          2158
    1671: aload_0
    1672: iload_1
    1673: aload_2
    1674: invokevirtual #232                // Method CollectingState.getMinutesDone:()I
    1677: iload         11
    1679: iadd
    1680: istore        12
    1682: aload_2
    1683: invokevirtual #281                // Method CollectingState.getOre:()I
    1686: iload         11
    1688: aload_2
    1689: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
    1692: imul
    1693: iadd
    1694: aload         9
    1696: checkcast     #67                 // class java/lang/Iterable
    1699: astore        15
    1701: istore        21
    1703: istore        22
    1705: astore        18
    1707: iconst_0
    1708: istore        16
    1710: aload         15
    1712: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    1717: astore        17
    1719: aload         17
    1721: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1726: ifeq          1772
    1729: aload         17
    1731: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1736: astore        19
    1738: aload         19
    1740: checkcast     #152                // class RobotBuildCost
    1743: astore        23
    1745: iconst_0
    1746: istore        24
    1748: aload         23
    1750: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
    1753: getstatic     #158                // Field RobotCurrency.ORE:LRobotCurrency;
    1756: if_acmpne     1763
    1759: iconst_1
    1760: goto          1764
    1763: iconst_0
    1764: ifeq          1719
    1767: aload         19
    1769: goto          1773
    1772: aconst_null
    1773: astore        25
    1775: aload         18
    1777: iload         22
    1779: iload         21
    1781: aload         25
    1783: checkcast     #152                // class RobotBuildCost
    1786: dup
    1787: ifnull        1796
    1790: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1793: goto          1798
    1796: pop
    1797: iconst_0
    1798: isub
    1799: istore        13
    1801: aload_2
    1802: invokevirtual #287                // Method CollectingState.getClay:()I
    1805: iload         11
    1807: aload_2
    1808: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
    1811: imul
    1812: iadd
    1813: aload         9
    1815: checkcast     #67                 // class java/lang/Iterable
    1818: astore        16
    1820: istore        21
    1822: istore        22
    1824: astore        18
    1826: iconst_0
    1827: istore        17
    1829: aload         16
    1831: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    1836: astore        19
    1838: aload         19
    1840: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1845: ifeq          1891
    1848: aload         19
    1850: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1855: astore        23
    1857: aload         23
    1859: checkcast     #152                // class RobotBuildCost
    1862: astore        24
    1864: iconst_0
    1865: istore        26
    1867: aload         24
    1869: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
    1872: getstatic     #182                // Field RobotCurrency.CLAY:LRobotCurrency;
    1875: if_acmpne     1882
    1878: iconst_1
    1879: goto          1883
    1882: iconst_0
    1883: ifeq          1838
    1886: aload         23
    1888: goto          1892
    1891: aconst_null
    1892: astore        25
    1894: aload         18
    1896: iload         22
    1898: iload         21
    1900: aload         25
    1902: checkcast     #152                // class RobotBuildCost
    1905: dup
    1906: ifnull        1915
    1909: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    1912: goto          1917
    1915: pop
    1916: iconst_0
    1917: isub
    1918: istore        14
    1920: aload_2
    1921: invokevirtual #290                // Method CollectingState.getObs:()I
    1924: iload         11
    1926: aload_2
    1927: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
    1930: imul
    1931: iadd
    1932: aload         9
    1934: checkcast     #67                 // class java/lang/Iterable
    1937: astore        17
    1939: istore        21
    1941: istore        22
    1943: astore        18
    1945: iconst_0
    1946: istore        19
    1948: aload         17
    1950: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    1955: astore        23
    1957: aload         23
    1959: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1964: ifeq          2010
    1967: aload         23
    1969: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1974: astore        24
    1976: aload         24
    1978: checkcast     #152                // class RobotBuildCost
    1981: astore        26
    1983: iconst_0
    1984: istore        27
    1986: aload         26
    1988: invokevirtual #269                // Method RobotBuildCost.getCurrency:()LRobotCurrency;
    1991: getstatic     #191                // Field RobotCurrency.OBSIDIAN:LRobotCurrency;
    1994: if_acmpne     2001
    1997: iconst_1
    1998: goto          2002
    2001: iconst_0
    2002: ifeq          1957
    2005: aload         24
    2007: goto          2011
    2010: aconst_null
    2011: astore        25
    2013: aload         18
    2015: iload         22
    2017: iload         21
    2019: aload         25
    2021: checkcast     #152                // class RobotBuildCost
    2024: dup
    2025: ifnull        2034
    2028: invokevirtual #284                // Method RobotBuildCost.getAmount:()I
    2031: goto          2036
    2034: pop
    2035: iconst_0
    2036: isub
    2037: istore        15
    2039: aload_2
    2040: invokevirtual #312                // Method CollectingState.getGeoCracked:()I
    2043: iload         11
    2045: aload_2
    2046: invokevirtual #315                // Method CollectingState.getGeoCrackedPerMinute:()I
    2049: imul
    2050: iadd
    2051: istore        16
    2053: aload_2
    2054: invokevirtual #259                // Method CollectingState.getOrePerMinute:()I
    2057: aload         8
    2059: getstatic     #150                // Field RobotType.ORE_COLLECTOR:LRobotType;
    2062: if_acmpne     2069
    2065: iconst_1
    2066: goto          2070
    2069: iconst_0
    2070: iadd
    2071: istore        17
    2073: aload_2
    2074: invokevirtual #262                // Method CollectingState.getClayPerMinute:()I
    2077: aload         8
    2079: getstatic     #176                // Field RobotType.CLAY_COLLECTOR:LRobotType;
    2082: if_acmpne     2089
    2085: iconst_1
    2086: goto          2090
    2089: iconst_0
    2090: iadd
    2091: istore        19
    2093: aload_2
    2094: invokevirtual #265                // Method CollectingState.getObsidianPerMinute:()I
    2097: aload         8
    2099: getstatic     #179                // Field RobotType.OBSIDIAN_COLLECTOR:LRobotType;
    2102: if_acmpne     2109
    2105: iconst_1
    2106: goto          2110
    2109: iconst_0
    2110: iadd
    2111: istore        23
    2113: aload_2
    2114: invokevirtual #315                // Method CollectingState.getGeoCrackedPerMinute:()I
    2117: aload         8
    2119: getstatic     #188                // Field RobotType.GEODE_CRACKING:LRobotType;
    2122: if_acmpne     2129
    2125: iconst_1
    2126: goto          2130
    2129: iconst_0
    2130: iadd
    2131: istore        24
    2133: aload_2
    2134: iload         12
    2136: iload         17
    2138: iload         19
    2140: iload         23
    2142: iload         24
    2144: iload         13
    2146: iload         14
    2148: iload         15
    2150: iload         16
    2152: invokevirtual #323                // Method CollectingState.copy:(IIIIIIIII)LCollectingState;
    2155: invokestatic  #325                // Method main$findBest:(LBlueprint;ILCollectingState;)I
    2158: nop
    2159: istore        6
    2161: iload         5
    2163: iload         6
    2165: if_icmpge     1097
    2168: iload         6
    2170: istore        5
    2172: goto          1097
    2175: iload         5
    2177: ireturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: invokestatic  #353                // Method main$parseBlueprints:(Ljava/util/List;)Ljava/util/List;
       4: astore_1
       5: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
       8: aload_1
       9: invokevirtual #356                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      12: aload_1
      13: checkcast     #67                 // class java/lang/Iterable
      16: astore_2
      17: iconst_0
      18: istore_3
      19: aload_2
      20: invokeinterface #83,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      25: astore        4
      27: aload         4
      29: invokeinterface #89,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      34: ifeq          122
      37: aload         4
      39: invokeinterface #93,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      44: astore        5
      46: aload         5
      48: checkcast     #136                // class Blueprint
      51: astore        6
      53: iconst_0
      54: istore        7
      56: new           #358                // class java/lang/StringBuilder
      59: dup
      60: invokespecial #359                // Method java/lang/StringBuilder."<init>":()V
      63: aload         6
      65: invokevirtual #362                // Method Blueprint.getId:()I
      68: invokevirtual #366                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      71: ldc_w         #368                // String :
      74: invokevirtual #371                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      77: aload         6
      79: bipush        24
      81: new           #228                // class CollectingState
      84: dup
      85: iconst_0
      86: iconst_0
      87: iconst_0
      88: iconst_0
      89: iconst_0
      90: iconst_0
      91: iconst_0
      92: iconst_0
      93: iconst_0
      94: sipush        511
      97: aconst_null
      98: invokespecial #374                // Method CollectingState."<init>":(IIIIIIIIIILkotlin/jvm/internal/DefaultConstructorMarker;)V
     101: invokestatic  #325                // Method main$findBest:(LBlueprint;ILCollectingState;)I
     104: invokevirtual #366                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     107: invokevirtual #375                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     110: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     113: swap
     114: invokevirtual #356                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     117: nop
     118: nop
     119: goto          27
     122: nop
     123: iconst_1
     124: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: iconst_1
       1: ireturn
}

Compiled from "Day19.kt"
public final class Day19 {
  public static final Day19 INSTANCE;

  public static final int EXPECTED_PART1_CHECK_ANSWER;

  public static final int EXPECTED_PART2_CHECK_ANSWER;

  private static final kotlin.text.Regex BLUEPRINT_REGEX;

  public static final int PART1_MINUTES;

  private Day19();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final kotlin.text.Regex getBLUEPRINT_REGEX();
    Code:
       0: getstatic     #17                 // Field BLUEPRINT_REGEX:Lkotlin/text/Regex;
       3: areturn

  static {};
    Code:
       0: new           #2                  // class Day19
       3: dup
       4: invokespecial #19                 // Method "<init>":()V
       7: putstatic     #22                 // Field INSTANCE:LDay19;
      10: new           #24                 // class kotlin/text/Regex
      13: dup
      14: ldc           #26                 // String Blueprint (\\d+): Each ore robot costs (\\d+) ore. Each clay robot costs (\\d+) ore. Each obsidian robot costs (\\d+) ore and (\\d+) clay. Each geode robot costs (\\d+) ore and (\\d+) obsidian.
      16: invokespecial #29                 // Method kotlin/text/Regex."<init>":(Ljava/lang/String;)V
      19: putstatic     #17                 // Field BLUEPRINT_REGEX:Lkotlin/text/Regex;
      22: return
}


import java.io.File
import java.math.BigInteger
import java.security.MessageDigest

/**
 * Reads lines from the given input txt file.
 */
fun readInput(name: String) = File("src", "$name.txt")
    .readLines()

/**
 * Converts string to md5 hash.
 */
fun String.md5() = BigInteger(1, MessageDigest.getInstance("MD5").digest(toByteArray()))
    .toString(16)
    .padStart(32, '0')

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

enum class Direction(val move: Coordinates) {
    WEST(Coordinates(-1, 0)),
    NORTH(Coordinates(0, -1)),
    EAST(Coordinates(1, 0)),
    SOUTH(Coordinates(0, 1));

    fun next() = when (this) {
        WEST -> EAST
        NORTH -> SOUTH
        EAST -> NORTH
        SOUTH -> WEST
    }
}

data class Coordinates(val x: Int, val y: Int) {
    operator fun plus(distance: Coordinates): Coordinates = Coordinates(this.x + distance.x, this.y + distance.y)

    fun move(direction: Direction) = when (direction) {
        Direction.NORTH -> Coordinates(x, y - 1)
        Direction.SOUTH -> Coordinates(x, y + 1)
        Direction.EAST -> Coordinates(x + 1, y)
        Direction.WEST -> Coordinates(x - 1, y)
    }

    fun adjacentPositions(includeDiagonal: Boolean = true): Set<Coordinates> =
        adjacentPositions(Direction.NORTH, includeDiagonal) +
                adjacentPositions(Direction.EAST, includeDiagonal) +
                adjacentPositions(Direction.SOUTH, includeDiagonal) +
                adjacentPositions(Direction.WEST, includeDiagonal)

    fun adjacentPositions(direction: Direction, includeDiagonal: Boolean = true): Set<Coordinates> =
        when (direction) {
            Direction.NORTH -> setOf(
                this + Coordinates(0, -1),
            ) + if (includeDiagonal) setOf(
                this + Coordinates(-1, -1),
                this + Coordinates(1, -1),
            ) else emptySet()
            Direction.EAST -> setOf(
                this + Coordinates(1, 0),
            ) + if (includeDiagonal) setOf(
                this + Coordinates(1, -1),
                this + Coordinates(1, 1),
            ) else emptySet()
            Direction.SOUTH -> setOf(
                this + Coordinates(0, 1),
            ) + if (includeDiagonal) setOf(
                this + Coordinates(1, 1),
                this + Coordinates(-1, 1),
            ) else emptySet()
            Direction.WEST -> setOf(
                this + Coordinates(-1, 0),
            ) + if (includeDiagonal) setOf(
                this + Coordinates(-1, -1),
                this + Coordinates(-1, 1),
            ) else emptySet()
        }
}

data class BigCoordinates(val x: Long, val y: Long)

data class Point3D(val x: Int, val y: Int, val z: Int)

fun List<Coordinates>.findMinAndMax(): Pair<Coordinates, Coordinates> =
    fold(Coordinates(Int.MAX_VALUE, Int.MAX_VALUE) to Coordinates(0, 0)) { (min, max), (x, y) ->
        Coordinates(
            minOf(min.x, x),
            minOf(min.y, y)
        ) to Coordinates(
            maxOf(max.x, x),
            maxOf(max.y, y)
        )
    }

Compiled from "Utils.kt"
public final class UtilsKt {
  public static final java.util.List<java.lang.String> readInput(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String name
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #18                 // class java/io/File
       9: dup
      10: ldc           #20                 // String src
      12: new           #22                 // class java/lang/StringBuilder
      15: dup
      16: invokespecial #26                 // Method java/lang/StringBuilder."<init>":()V
      19: aload_0
      20: invokevirtual #30                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      23: ldc           #32                 // String .txt
      25: invokevirtual #30                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      31: invokespecial #39                 // Method java/io/File."<init>":(Ljava/lang/String;Ljava/lang/String;)V
      34: aconst_null
      35: iconst_1
      36: aconst_null
      37: invokestatic  #45                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      40: areturn

  public static final java.lang.String md5(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #50                 // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #52                 // class java/math/BigInteger
       9: dup
      10: iconst_1
      11: ldc           #54                 // String MD5
      13: invokestatic  #60                 // Method java/security/MessageDigest.getInstance:(Ljava/lang/String;)Ljava/security/MessageDigest;
      16: aload_0
      17: astore_1
      18: getstatic     #66                 // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      21: aload_1
      22: swap
      23: invokevirtual #72                 // Method java/lang/String.getBytes:(Ljava/nio/charset/Charset;)[B
      26: dup
      27: ldc           #74                 // String getBytes(...)
      29: invokestatic  #77                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      32: invokevirtual #81                 // Method java/security/MessageDigest.digest:([B)[B
      35: invokespecial #84                 // Method java/math/BigInteger."<init>":(I[B)V
      38: bipush        16
      40: invokevirtual #87                 // Method java/math/BigInteger.toString:(I)Ljava/lang/String;
      43: dup
      44: ldc           #89                 // String toString(...)
      46: invokestatic  #77                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      49: bipush        32
      51: bipush        48
      53: invokestatic  #95                 // Method kotlin/text/StringsKt.padStart:(Ljava/lang/String;IC)Ljava/lang/String;
      56: areturn

  public static final kotlin.Pair<Coordinates, Coordinates> findMinAndMax(java.util.List<Coordinates>);
    Code:
       0: aload_0
       1: ldc           #50                 // String <this>
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #101                // class java/lang/Iterable
      10: astore_1
      11: new           #103                // class Coordinates
      14: dup
      15: ldc           #104                // int 2147483647
      17: ldc           #104                // int 2147483647
      19: invokespecial #107                // Method Coordinates."<init>":(II)V
      22: new           #103                // class Coordinates
      25: dup
      26: iconst_0
      27: iconst_0
      28: invokespecial #107                // Method Coordinates."<init>":(II)V
      31: invokestatic  #113                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      34: astore_2
      35: iconst_0
      36: istore_3
      37: aload_2
      38: astore        4
      40: aload_1
      41: invokeinterface #117,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      46: astore        5
      48: aload         5
      50: invokeinterface #123,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      55: ifeq          178
      58: aload         5
      60: invokeinterface #127,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      65: astore        6
      67: aload         4
      69: aload         6
      71: checkcast     #103                // class Coordinates
      74: astore        7
      76: astore        8
      78: iconst_0
      79: istore        9
      81: aload         8
      83: invokevirtual #132                // Method kotlin/Pair.component1:()Ljava/lang/Object;
      86: checkcast     #103                // class Coordinates
      89: astore        10
      91: aload         8
      93: invokevirtual #135                // Method kotlin/Pair.component2:()Ljava/lang/Object;
      96: checkcast     #103                // class Coordinates
      99: astore        11
     101: aload         7
     103: invokevirtual #138                // Method Coordinates.component1:()I
     106: istore        12
     108: aload         7
     110: invokevirtual #140                // Method Coordinates.component2:()I
     113: istore        13
     115: new           #103                // class Coordinates
     118: dup
     119: aload         10
     121: invokevirtual #143                // Method Coordinates.getX:()I
     124: iload         12
     126: invokestatic  #149                // Method java/lang/Math.min:(II)I
     129: aload         10
     131: invokevirtual #152                // Method Coordinates.getY:()I
     134: iload         13
     136: invokestatic  #149                // Method java/lang/Math.min:(II)I
     139: invokespecial #107                // Method Coordinates."<init>":(II)V
     142: new           #103                // class Coordinates
     145: dup
     146: aload         11
     148: invokevirtual #143                // Method Coordinates.getX:()I
     151: iload         12
     153: invokestatic  #155                // Method java/lang/Math.max:(II)I
     156: aload         11
     158: invokevirtual #152                // Method Coordinates.getY:()I
     161: iload         13
     163: invokestatic  #155                // Method java/lang/Math.max:(II)I
     166: invokespecial #107                // Method Coordinates."<init>":(II)V
     169: invokestatic  #113                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     172: nop
     173: astore        4
     175: goto          48
     178: aload         4
     180: areturn
}


object Day04 {
    const val EXPECTED_PART1_CHECK_ANSWER = 2
    const val EXPECTED_PART2_CHECK_ANSWER = 4
}

fun main() {

    fun String.parseToIntRangePerElf(): Pair<IntRange, IntRange> =
        this
            .split(",")
            .map { it.split("-") }
            .map { (it[0].toInt())..(it[1].toInt()) }
            .let { it[0] to it[1] }

    fun part1(input: List<String>): Int =
        input
            .map { it.parseToIntRangePerElf() }
            .count { it.first.minus(it.second).isEmpty() || it.second.minus(it.first).isEmpty() }

    fun part2(input: List<String>): Int =
        input
            .map { it.parseToIntRangePerElf() }
            .count { (firstElfSections, secondElfSections) ->
                firstElfSections.any { secondElfSections.contains(it) } || firstElfSections.any {
                    secondElfSections.contains(
                        it
                    )
                }
            }

    // test if implementation meets criteria from the description, like:
    val testInput = readInput("Day04_test")
    check(part1(testInput) == Day04.EXPECTED_PART1_CHECK_ANSWER) { "Part 1 failed" }
    check(part2(testInput) == Day04.EXPECTED_PART2_CHECK_ANSWER) { "Part 2 failed" }

    val input = readInput("Day04")
    println(part1(input))
    println(part2(input))
}

Compiled from "Day04.kt"
public final class Day04Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String Day04_test
       2: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      10: iconst_2
      11: if_icmpne     18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: ifne          39
      22: iconst_0
      23: istore_2
      24: ldc           #20                 // String Part 1 failed
      26: astore_2
      27: new           #22                 // class java/lang/IllegalStateException
      30: dup
      31: aload_2
      32: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      35: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      38: athrow
      39: aload_0
      40: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      43: iconst_4
      44: if_icmpne     51
      47: iconst_1
      48: goto          52
      51: iconst_0
      52: ifne          72
      55: iconst_0
      56: istore_2
      57: ldc           #35                 // String Part 2 failed
      59: astore_2
      60: new           #22                 // class java/lang/IllegalStateException
      63: dup
      64: aload_2
      65: invokevirtual #26                 // Method java/lang/Object.toString:()Ljava/lang/String;
      68: invokespecial #30                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      71: athrow
      72: ldc           #37                 // String Day04
      74: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
      77: astore_1
      78: aload_1
      79: invokestatic  #18                 // Method main$part1:(Ljava/util/List;)I
      82: istore_2
      83: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      86: iload_2
      87: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
      90: aload_1
      91: invokestatic  #33                 // Method main$part2:(Ljava/util/List;)I
      94: istore_2
      95: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      98: iload_2
      99: invokevirtual #49                 // Method java/io/PrintStream.println:(I)V
     102: return

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

  private static final kotlin.Pair<kotlin.ranges.IntRange, kotlin.ranges.IntRange> main$parseToIntRangePerElf(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #67                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #69                 // class java/lang/String
       8: astore_1
       9: aload_1
      10: iconst_0
      11: ldc           #71                 // String ,
      13: aastore
      14: aload_1
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #77                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: checkcast     #79                 // class java/lang/Iterable
      26: astore_1
      27: nop
      28: iconst_0
      29: istore_2
      30: aload_1
      31: astore_3
      32: new           #81                 // class java/util/ArrayList
      35: dup
      36: aload_1
      37: bipush        10
      39: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      42: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
      45: checkcast     #91                 // class java/util/Collection
      48: astore        4
      50: iconst_0
      51: istore        5
      53: aload_3
      54: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      59: astore        6
      61: aload         6
      63: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      68: ifeq          133
      71: aload         6
      73: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      78: astore        7
      80: aload         4
      82: aload         7
      84: checkcast     #69                 // class java/lang/String
      87: astore        8
      89: astore        11
      91: iconst_0
      92: istore        9
      94: aload         8
      96: checkcast     #67                 // class java/lang/CharSequence
      99: iconst_1
     100: anewarray     #69                 // class java/lang/String
     103: astore        10
     105: aload         10
     107: iconst_0
     108: ldc           #107                // String -
     110: aastore
     111: aload         10
     113: iconst_0
     114: iconst_0
     115: bipush        6
     117: aconst_null
     118: invokestatic  #77                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     121: aload         11
     123: swap
     124: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     129: pop
     130: goto          61
     133: aload         4
     135: checkcast     #57                 // class java/util/List
     138: nop
     139: checkcast     #79                 // class java/lang/Iterable
     142: astore_1
     143: nop
     144: iconst_0
     145: istore_2
     146: aload_1
     147: astore_3
     148: new           #81                 // class java/util/ArrayList
     151: dup
     152: aload_1
     153: bipush        10
     155: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     158: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
     161: checkcast     #91                 // class java/util/Collection
     164: astore        4
     166: iconst_0
     167: istore        5
     169: aload_3
     170: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     175: astore        6
     177: aload         6
     179: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     184: ifeq          257
     187: aload         6
     189: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     194: astore        7
     196: aload         4
     198: aload         7
     200: checkcast     #57                 // class java/util/List
     203: astore        8
     205: astore        11
     207: iconst_0
     208: istore        9
     210: new           #113                // class kotlin/ranges/IntRange
     213: dup
     214: aload         8
     216: iconst_0
     217: invokeinterface #117,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     222: checkcast     #69                 // class java/lang/String
     225: invokestatic  #123                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     228: aload         8
     230: iconst_1
     231: invokeinterface #117,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     236: checkcast     #69                 // class java/lang/String
     239: invokestatic  #123                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     242: invokespecial #126                // Method kotlin/ranges/IntRange."<init>":(II)V
     245: aload         11
     247: swap
     248: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     253: pop
     254: goto          177
     257: aload         4
     259: checkcast     #57                 // class java/util/List
     262: nop
     263: astore_2
     264: iconst_0
     265: istore_3
     266: aload_2
     267: iconst_0
     268: invokeinterface #117,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     273: aload_2
     274: iconst_1
     275: invokeinterface #117,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     280: invokestatic  #132                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     283: nop
     284: areturn

  private static final int main$part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #79                 // class java/lang/Iterable
       4: astore_1
       5: nop
       6: iconst_0
       7: istore_2
       8: aload_1
       9: astore_3
      10: new           #81                 // class java/util/ArrayList
      13: dup
      14: aload_1
      15: bipush        10
      17: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      20: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
      23: checkcast     #91                 // class java/util/Collection
      26: astore        4
      28: iconst_0
      29: istore        5
      31: aload_3
      32: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      37: astore        6
      39: aload         6
      41: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      46: ifeq          89
      49: aload         6
      51: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      56: astore        7
      58: aload         4
      60: aload         7
      62: checkcast     #69                 // class java/lang/String
      65: astore        8
      67: astore        10
      69: iconst_0
      70: istore        9
      72: aload         8
      74: invokestatic  #150                // Method main$parseToIntRangePerElf:(Ljava/lang/String;)Lkotlin/Pair;
      77: aload         10
      79: swap
      80: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      85: pop
      86: goto          39
      89: aload         4
      91: checkcast     #57                 // class java/util/List
      94: nop
      95: checkcast     #79                 // class java/lang/Iterable
      98: astore_1
      99: nop
     100: iconst_0
     101: istore_2
     102: aload_1
     103: instanceof    #91                 // class java/util/Collection
     106: ifeq          125
     109: aload_1
     110: checkcast     #91                 // class java/util/Collection
     113: invokeinterface #153,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     118: ifeq          125
     121: iconst_0
     122: goto          240
     125: iconst_0
     126: istore_3
     127: aload_1
     128: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     133: astore        4
     135: aload         4
     137: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     142: ifeq          239
     145: aload         4
     147: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     152: astore        5
     154: aload         5
     156: checkcast     #155                // class kotlin/Pair
     159: astore        6
     161: iconst_0
     162: istore        7
     164: aload         6
     166: invokevirtual #158                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     169: checkcast     #79                 // class java/lang/Iterable
     172: aload         6
     174: invokevirtual #161                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     177: checkcast     #79                 // class java/lang/Iterable
     180: invokestatic  #165                // Method kotlin/collections/CollectionsKt.minus:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/List;
     183: invokeinterface #166,  1          // InterfaceMethod java/util/List.isEmpty:()Z
     188: ifne          218
     191: aload         6
     193: invokevirtual #161                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     196: checkcast     #79                 // class java/lang/Iterable
     199: aload         6
     201: invokevirtual #158                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     204: checkcast     #79                 // class java/lang/Iterable
     207: invokestatic  #165                // Method kotlin/collections/CollectionsKt.minus:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/List;
     210: invokeinterface #166,  1          // InterfaceMethod java/util/List.isEmpty:()Z
     215: ifeq          222
     218: iconst_1
     219: goto          223
     222: iconst_0
     223: ifeq          135
     226: iinc          3, 1
     229: iload_3
     230: ifge          135
     233: invokestatic  #169                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     236: goto          135
     239: iload_3
     240: ireturn

  private static final int main$part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #79                 // class java/lang/Iterable
       4: astore_1
       5: nop
       6: iconst_0
       7: istore_2
       8: aload_1
       9: astore_3
      10: new           #81                 // class java/util/ArrayList
      13: dup
      14: aload_1
      15: bipush        10
      17: invokestatic  #87                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      20: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
      23: checkcast     #91                 // class java/util/Collection
      26: astore        4
      28: iconst_0
      29: istore        5
      31: aload_3
      32: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      37: astore        6
      39: aload         6
      41: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      46: ifeq          89
      49: aload         6
      51: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      56: astore        7
      58: aload         4
      60: aload         7
      62: checkcast     #69                 // class java/lang/String
      65: astore        8
      67: astore        16
      69: iconst_0
      70: istore        9
      72: aload         8
      74: invokestatic  #150                // Method main$parseToIntRangePerElf:(Ljava/lang/String;)Lkotlin/Pair;
      77: aload         16
      79: swap
      80: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      85: pop
      86: goto          39
      89: aload         4
      91: checkcast     #57                 // class java/util/List
      94: nop
      95: checkcast     #79                 // class java/lang/Iterable
      98: astore_1
      99: nop
     100: iconst_0
     101: istore_2
     102: aload_1
     103: instanceof    #91                 // class java/util/Collection
     106: ifeq          125
     109: aload_1
     110: checkcast     #91                 // class java/util/Collection
     113: invokeinterface #153,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     118: ifeq          125
     121: iconst_0
     122: goto          386
     125: iconst_0
     126: istore_3
     127: aload_1
     128: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     133: astore        4
     135: aload         4
     137: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     142: ifeq          385
     145: aload         4
     147: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     152: astore        5
     154: aload         5
     156: checkcast     #155                // class kotlin/Pair
     159: astore        6
     161: iconst_0
     162: istore        7
     164: aload         6
     166: invokevirtual #179                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     169: checkcast     #113                // class kotlin/ranges/IntRange
     172: astore        8
     174: aload         6
     176: invokevirtual #182                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     179: checkcast     #113                // class kotlin/ranges/IntRange
     182: astore        9
     184: aload         8
     186: checkcast     #79                 // class java/lang/Iterable
     189: astore        10
     191: iconst_0
     192: istore        11
     194: aload         10
     196: instanceof    #91                 // class java/util/Collection
     199: ifeq          219
     202: aload         10
     204: checkcast     #91                 // class java/util/Collection
     207: invokeinterface #153,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     212: ifeq          219
     215: iconst_0
     216: goto          270
     219: aload         10
     221: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     226: astore        12
     228: aload         12
     230: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     235: ifeq          269
     238: aload         12
     240: checkcast     #184                // class kotlin/collections/IntIterator
     243: invokevirtual #188                // Method kotlin/collections/IntIterator.nextInt:()I
     246: istore        13
     248: iload         13
     250: istore        14
     252: iconst_0
     253: istore        15
     255: aload         9
     257: iload         14
     259: invokevirtual #192                // Method kotlin/ranges/IntRange.contains:(I)Z
     262: ifeq          228
     265: iconst_1
     266: goto          270
     269: iconst_0
     270: ifne          363
     273: aload         8
     275: checkcast     #79                 // class java/lang/Iterable
     278: astore        10
     280: iconst_0
     281: istore        11
     283: aload         10
     285: instanceof    #91                 // class java/util/Collection
     288: ifeq          308
     291: aload         10
     293: checkcast     #91                 // class java/util/Collection
     296: invokeinterface #153,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     301: ifeq          308
     304: iconst_0
     305: goto          360
     308: aload         10
     310: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     315: astore        12
     317: aload         12
     319: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     324: ifeq          359
     327: aload         12
     329: checkcast     #184                // class kotlin/collections/IntIterator
     332: invokevirtual #188                // Method kotlin/collections/IntIterator.nextInt:()I
     335: istore        13
     337: iload         13
     339: istore        14
     341: iconst_0
     342: istore        15
     344: aload         9
     346: iload         14
     348: invokevirtual #192                // Method kotlin/ranges/IntRange.contains:(I)Z
     351: nop
     352: ifeq          317
     355: iconst_1
     356: goto          360
     359: iconst_0
     360: ifeq          367
     363: iconst_1
     364: goto          368
     367: iconst_0
     368: nop
     369: ifeq          135
     372: iinc          3, 1
     375: iload_3
     376: ifge          135
     379: invokestatic  #169                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     382: goto          135
     385: iload_3
     386: ireturn
}

Compiled from "Day04.kt"
public final class Day04 {
  public static final Day04 INSTANCE;

  public static final int EXPECTED_PART1_CHECK_ANSWER;

  public static final int EXPECTED_PART2_CHECK_ANSWER;

  private Day04();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #2                  // class Day04
       3: dup
       4: invokespecial #12                 // Method "<init>":()V
       7: putstatic     #15                 // Field INSTANCE:LDay04;
      10: return
}