package advent.of.code.day15

import java.io.File
import java.util.*
import kotlin.collections.LinkedHashSet
import kotlin.math.abs

data class Position(val x: Int, val y: Int) : Comparable<Position> {
    override fun compareTo(other: Position): Int {
        return compareBy<Position>({ it.y }, { it.x }).compare(this, other)
    }

    override fun toString(): String {
        return "(${x.toString().padStart(3, ' ')},${y.toString().padStart(3, ' ')})"
    }

    private fun up() = copy(y = y - 1)
    private fun down() = copy(y = y + 1)
    private fun left() = copy(x = x - 1)
    private fun right() = copy(x = x + 1)

    fun around(near: Position? = null) = listOf(up(), left(), right(), down())
        .filter { it.x >= 0 && it.y >= 0 }
        .sortedWith(compareBy({ it.distance(near ?: it) }, { it.y }, { it.x }))

    fun distance(b: Position) = abs(x - b.x) + abs(y - b.y)
}

fun Piece?.isDead() = (this?.hitPoints ?: 0) <= 0

sealed class Piece(open var position: Position, open val symbol: Char, open var hitPoints: Int = 200) :
    Comparable<Piece> {

    val y: Int
        get() = position.y

    val x: Int
        get() = position.x

    override fun compareTo(other: Piece) = position.compareTo(other.position)
}

abstract class Creature(
    override var position: Position,
    open val attack: Int = 3,
    override val symbol: Char
) : Piece(position, symbol) {

    fun damage(hit: Int) {
        hitPoints -= hit
    }

    abstract fun enemy(crit: Creature?): Boolean
}

const val WALL = '#'
const val ELF = 'E'
const val GOBLIN = 'G'

data class Elf(override var position: Position, override val attack: Int = 3, override var hitPoints: Int = 200) :
    Creature(position, attack, ELF) {
    override fun enemy(crit: Creature?) = crit is Goblin
}

data class Goblin(override var position: Position, override val attack: Int = 3, override var hitPoints: Int = 200) :
    Creature(position, attack, GOBLIN) {
    override fun enemy(crit: Creature?) = crit is Elf
}

data class Wall(override var position: Position) : Piece(position, WALL)

class GameBoard(initFile: File) {
    var pieces: MutableSet<Piece> = TreeSet()

    val elves: Set<Elf>
        get() = pieces.mapNotNullTo(LinkedHashSet()) { (it as? Elf) }

    val goblins: Set<Goblin>
        get() = pieces.mapNotNullTo(LinkedHashSet()) { (it as? Goblin) }

    val creatures: Set<Creature>
        get() = pieces.mapNotNullTo(LinkedHashSet()) { (it as? Creature) }

    init {
        initFile.readLines().forEachIndexed { y, line ->
            line.forEachIndexed { x, symbol ->
                val pos = Position(x, y)
                when (symbol) {
                    WALL -> Wall(pos)
                    ELF -> Elf(pos)
                    GOBLIN -> Goblin(pos)
                    else -> null
                }?.let {
                    pieces.add(it)
                }
            }
        }
    }

    fun inRange(crit: Creature): Pair<Creature, Set<Position>> = crit to pieces.mapNotNull { it as? Creature }
        .filter { crit.enemy(it) }
        .flatMap { it.position.around() }
        .filterTo(TreeSet()) { (piece(it) !is Creature) and (piece(it) !is Wall) }

    private fun distance(
        pos1: Position,
        pos2: Position,
        pastPos: MutableList<Position> = mutableListOf(),
        distance: Int = 0
    ): Int? =
        when {
            piece(pos1) is Wall -> null
            (piece(pos1) is Creature) and !piece(pos1).isDead() -> null
            pos1 in pastPos -> null
            pos1 == pos2 -> distance
            else -> pos1.around(pos2)
                .mapNotNull { distance(it, pos2, pastPos.apply { this += pos1 }, distance + 1) }.min()
        }

    fun nearestReachable(data: Pair<Creature, Set<Position>>) =
        data.second.flatMap {
            data.first.position.around(it)
                .map { a -> a to distance(a, it) }
                .filter { p -> p.second != null }
        }.minWith(compareBy({ it.second ?: Int.MAX_VALUE }, { it.first.y }, { it.first.x }))
            ?.first

    fun buryDead() {
        pieces = pieces.filterTo(TreeSet()) { it.hitPoints > 0 }
    }

    fun piece(pos: Position?) = pieces.firstOrNull { it.position == pos }

    override fun toString(): String {
        var output = ""
        for (y in (0..(pieces.map { it.y }.max() ?: 0))) {
            for (x in (0..(pieces.map { it.x }.max() ?: 0)))
                output += piece(Position(x, y))?.symbol ?: '.'
            output += '\n'
        }
        return output
    }
}

val input = File("day15-test.txt")

fun part1(): Int {
    val board = GameBoard(input)
    var round = 0
    println("init")
    println(board)
    while (board.elves.isNotEmpty() and board.goblins.isNotEmpty()) {
        round++
        for (crit in board.creatures) {
            if (crit.isDead())
                continue

            //move
            if (crit.position.around().none { crit.enemy(board.piece(it) as? Creature) }) {
                val chosenPos = board.nearestReachable(board.inRange(crit))
                if (chosenPos != null)
                    crit.position = chosenPos
            }

            val target = crit.position.around().filter { crit.enemy(board.piece(it) as? Creature) }
                .mapNotNull { board.piece(it) as? Creature }
                .sortedWith(compareBy({ it.hitPoints }, { it.y }, { it.x }))
                .firstOrNull()

            target?.damage(crit.attack)
        }
        board.buryDead()
        println("$round (${board.creatures.size}) -> ${round * board.creatures.map { it.hitPoints }.sum()}")
        println(board)
        println(board.creatures.joinToString("\n"))
        println()
    }

    return 0
}

fun part2() = 2

Compiled from "Solution.kt"
public final class advent.of.code.day15.SolutionKt {
  public static final char WALL;

  public static final char ELF;

  public static final char GOBLIN;

  private static final java.io.File input;

  public static final boolean isDead(advent.of.code.day15.Piece);
    Code:
       0: aload_0
       1: dup
       2: ifnull        11
       5: invokevirtual #13                 // Method advent/of/code/day15/Piece.getHitPoints:()I
       8: goto          13
      11: pop
      12: iconst_0
      13: ifgt          20
      16: iconst_1
      17: goto          21
      20: iconst_0
      21: ireturn

  public static final java.io.File getInput();
    Code:
       0: getstatic     #22                 // Field input:Ljava/io/File;
       3: areturn

  public static final int part1();
    Code:
       0: new           #25                 // class advent/of/code/day15/GameBoard
       3: dup
       4: getstatic     #22                 // Field input:Ljava/io/File;
       7: invokespecial #29                 // Method advent/of/code/day15/GameBoard."<init>":(Ljava/io/File;)V
      10: astore_0
      11: iconst_0
      12: istore_1
      13: ldc           #31                 // String init
      15: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: swap
      19: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      22: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
      25: aload_0
      26: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      29: aload_0
      30: invokevirtual #47                 // Method advent/of/code/day15/GameBoard.getElves:()Ljava/util/Set;
      33: checkcast     #49                 // class java/util/Collection
      36: invokeinterface #53,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      41: ifne          48
      44: iconst_1
      45: goto          49
      48: iconst_0
      49: aload_0
      50: invokevirtual #56                 // Method advent/of/code/day15/GameBoard.getGoblins:()Ljava/util/Set;
      53: checkcast     #49                 // class java/util/Collection
      56: invokeinterface #53,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
      61: ifne          68
      64: iconst_1
      65: goto          69
      68: iconst_0
      69: iand
      70: ifeq          816
      73: iinc          1, 1
      76: aload_0
      77: invokevirtual #59                 // Method advent/of/code/day15/GameBoard.getCreatures:()Ljava/util/Set;
      80: invokeinterface #65,  1           // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      85: astore_2
      86: aload_2
      87: invokeinterface #70,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      92: ifeq          598
      95: aload_2
      96: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     101: checkcast     #76                 // class advent/of/code/day15/Creature
     104: astore_3
     105: aload_3
     106: checkcast     #9                  // class advent/of/code/day15/Piece
     109: invokestatic  #78                 // Method isDead:(Ladvent/of/code/day15/Piece;)Z
     112: ifeq          118
     115: goto          86
     118: aload_3
     119: invokevirtual #82                 // Method advent/of/code/day15/Creature.getPosition:()Ladvent/of/code/day15/Position;
     122: aconst_null
     123: iconst_1
     124: aconst_null
     125: invokestatic  #88                 // Method advent/of/code/day15/Position.around$default:(Ladvent/of/code/day15/Position;Ladvent/of/code/day15/Position;ILjava/lang/Object;)Ljava/util/List;
     128: checkcast     #90                 // class java/lang/Iterable
     131: astore        4
     133: iconst_0
     134: istore        5
     136: aload         4
     138: instanceof    #49                 // class java/util/Collection
     141: ifeq          161
     144: aload         4
     146: checkcast     #49                 // class java/util/Collection
     149: invokeinterface #53,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     154: ifeq          161
     157: iconst_1
     158: goto          236
     161: aload         4
     163: invokeinterface #91,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     168: astore        6
     170: aload         6
     172: invokeinterface #70,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     177: ifeq          235
     180: aload         6
     182: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     187: astore        7
     189: aload         7
     191: checkcast     #84                 // class advent/of/code/day15/Position
     194: astore        8
     196: iconst_0
     197: istore        9
     199: aload_3
     200: aload_0
     201: aload         8
     203: invokevirtual #95                 // Method advent/of/code/day15/GameBoard.piece:(Ladvent/of/code/day15/Position;)Ladvent/of/code/day15/Piece;
     206: astore        10
     208: aload         10
     210: instanceof    #76                 // class advent/of/code/day15/Creature
     213: ifeq          224
     216: aload         10
     218: checkcast     #76                 // class advent/of/code/day15/Creature
     221: goto          225
     224: aconst_null
     225: invokevirtual #99                 // Method advent/of/code/day15/Creature.enemy:(Ladvent/of/code/day15/Creature;)Z
     228: ifeq          170
     231: iconst_0
     232: goto          236
     235: iconst_1
     236: ifeq          261
     239: aload_0
     240: aload_0
     241: aload_3
     242: invokevirtual #103                // Method advent/of/code/day15/GameBoard.inRange:(Ladvent/of/code/day15/Creature;)Lkotlin/Pair;
     245: invokevirtual #107                // Method advent/of/code/day15/GameBoard.nearestReachable:(Lkotlin/Pair;)Ladvent/of/code/day15/Position;
     248: astore        4
     250: aload         4
     252: ifnull        261
     255: aload_3
     256: aload         4
     258: invokevirtual #111                // Method advent/of/code/day15/Creature.setPosition:(Ladvent/of/code/day15/Position;)V
     261: aload_3
     262: invokevirtual #82                 // Method advent/of/code/day15/Creature.getPosition:()Ladvent/of/code/day15/Position;
     265: aconst_null
     266: iconst_1
     267: aconst_null
     268: invokestatic  #88                 // Method advent/of/code/day15/Position.around$default:(Ladvent/of/code/day15/Position;Ladvent/of/code/day15/Position;ILjava/lang/Object;)Ljava/util/List;
     271: checkcast     #90                 // class java/lang/Iterable
     274: astore        5
     276: iconst_0
     277: istore        6
     279: aload         5
     281: astore        7
     283: new           #113                // class java/util/ArrayList
     286: dup
     287: invokespecial #116                // Method java/util/ArrayList."<init>":()V
     290: checkcast     #49                 // class java/util/Collection
     293: astore        8
     295: iconst_0
     296: istore        9
     298: aload         7
     300: invokeinterface #91,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     305: astore        10
     307: aload         10
     309: invokeinterface #70,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     314: ifeq          381
     317: aload         10
     319: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     324: astore        11
     326: aload         11
     328: checkcast     #84                 // class advent/of/code/day15/Position
     331: astore        12
     333: iconst_0
     334: istore        13
     336: aload_3
     337: aload_0
     338: aload         12
     340: invokevirtual #95                 // Method advent/of/code/day15/GameBoard.piece:(Ladvent/of/code/day15/Position;)Ladvent/of/code/day15/Piece;
     343: astore        14
     345: aload         14
     347: instanceof    #76                 // class advent/of/code/day15/Creature
     350: ifeq          361
     353: aload         14
     355: checkcast     #76                 // class advent/of/code/day15/Creature
     358: goto          362
     361: aconst_null
     362: invokevirtual #99                 // Method advent/of/code/day15/Creature.enemy:(Ladvent/of/code/day15/Creature;)Z
     365: ifeq          307
     368: aload         8
     370: aload         11
     372: invokeinterface #120,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     377: pop
     378: goto          307
     381: aload         8
     383: checkcast     #122                // class java/util/List
     386: nop
     387: checkcast     #90                 // class java/lang/Iterable
     390: astore        5
     392: nop
     393: iconst_0
     394: istore        6
     396: aload         5
     398: astore        7
     400: new           #113                // class java/util/ArrayList
     403: dup
     404: invokespecial #116                // Method java/util/ArrayList."<init>":()V
     407: checkcast     #49                 // class java/util/Collection
     410: astore        8
     412: iconst_0
     413: istore        9
     415: aload         7
     417: astore        10
     419: iconst_0
     420: istore        11
     422: aload         10
     424: invokeinterface #91,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     429: astore        12
     431: aload         12
     433: invokeinterface #70,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     438: ifeq          519
     441: aload         12
     443: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     448: astore        13
     450: aload         13
     452: astore        14
     454: iconst_0
     455: istore        15
     457: aload         14
     459: checkcast     #84                 // class advent/of/code/day15/Position
     462: astore        16
     464: iconst_0
     465: istore        17
     467: aload_0
     468: aload         16
     470: invokevirtual #95                 // Method advent/of/code/day15/GameBoard.piece:(Ladvent/of/code/day15/Position;)Ladvent/of/code/day15/Piece;
     473: astore        18
     475: aload         18
     477: instanceof    #76                 // class advent/of/code/day15/Creature
     480: ifeq          491
     483: aload         18
     485: checkcast     #76                 // class advent/of/code/day15/Creature
     488: goto          492
     491: aconst_null
     492: dup
     493: ifnull        514
     496: astore        19
     498: iconst_0
     499: istore        20
     501: aload         8
     503: aload         19
     505: invokeinterface #120,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     510: pop
     511: goto          515
     514: pop
     515: nop
     516: goto          431
     519: nop
     520: aload         8
     522: checkcast     #122                // class java/util/List
     525: nop
     526: checkcast     #90                 // class java/lang/Iterable
     529: iconst_3
     530: anewarray     #124                // class kotlin/jvm/functions/Function1
     533: astore        5
     535: aload         5
     537: iconst_0
     538: invokedynamic #143,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     543: aastore
     544: aload         5
     546: iconst_1
     547: invokedynamic #148,  0            // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function1;
     552: aastore
     553: aload         5
     555: iconst_2
     556: invokedynamic #153,  0            // InvokeDynamic #2:invoke:()Lkotlin/jvm/functions/Function1;
     561: aastore
     562: aload         5
     564: invokestatic  #159                // Method kotlin/comparisons/ComparisonsKt.compareBy:([Lkotlin/jvm/functions/Function1;)Ljava/util/Comparator;
     567: invokestatic  #165                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
     570: invokestatic  #169                // Method kotlin/collections/CollectionsKt.firstOrNull:(Ljava/util/List;)Ljava/lang/Object;
     573: checkcast     #76                 // class advent/of/code/day15/Creature
     576: astore        4
     578: aload         4
     580: dup
     581: ifnull        594
     584: aload_3
     585: invokevirtual #172                // Method advent/of/code/day15/Creature.getAttack:()I
     588: invokevirtual #176                // Method advent/of/code/day15/Creature.damage:(I)V
     591: goto          86
     594: pop
     595: goto          86
     598: aload_0
     599: invokevirtual #179                // Method advent/of/code/day15/GameBoard.buryDead:()V
     602: new           #181                // class java/lang/StringBuilder
     605: dup
     606: invokespecial #182                // Method java/lang/StringBuilder."<init>":()V
     609: iload_1
     610: invokevirtual #186                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     613: ldc           #188                // String  (
     615: invokevirtual #191                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     618: aload_0
     619: invokevirtual #59                 // Method advent/of/code/day15/GameBoard.getCreatures:()Ljava/util/Set;
     622: invokeinterface #194,  1          // InterfaceMethod java/util/Set.size:()I
     627: invokevirtual #186                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     630: ldc           #196                // String ) ->
     632: invokevirtual #191                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     635: iload_1
     636: aload_0
     637: invokevirtual #59                 // Method advent/of/code/day15/GameBoard.getCreatures:()Ljava/util/Set;
     640: checkcast     #90                 // class java/lang/Iterable
     643: astore_2
     644: istore        22
     646: astore        21
     648: iconst_0
     649: istore_3
     650: aload_2
     651: astore        4
     653: new           #113                // class java/util/ArrayList
     656: dup
     657: aload_2
     658: bipush        10
     660: invokestatic  #200                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     663: invokespecial #202                // Method java/util/ArrayList."<init>":(I)V
     666: checkcast     #49                 // class java/util/Collection
     669: astore        5
     671: iconst_0
     672: istore        6
     674: aload         4
     676: invokeinterface #91,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     681: astore        7
     683: aload         7
     685: invokeinterface #70,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     690: ifeq          736
     693: aload         7
     695: invokeinterface #74,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     700: astore        8
     702: aload         5
     704: aload         8
     706: checkcast     #76                 // class advent/of/code/day15/Creature
     709: astore        9
     711: astore        23
     713: iconst_0
     714: istore        10
     716: aload         9
     718: invokevirtual #203                // Method advent/of/code/day15/Creature.getHitPoints:()I
     721: invokestatic  #209                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     724: aload         23
     726: swap
     727: invokeinterface #120,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     732: pop
     733: goto          683
     736: aload         5
     738: checkcast     #122                // class java/util/List
     741: nop
     742: astore        23
     744: aload         21
     746: iload         22
     748: aload         23
     750: checkcast     #90                 // class java/lang/Iterable
     753: invokestatic  #213                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     756: imul
     757: invokevirtual #186                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     760: invokevirtual #217                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     763: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     766: swap
     767: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     770: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     773: aload_0
     774: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     777: aload_0
     778: invokevirtual #59                 // Method advent/of/code/day15/GameBoard.getCreatures:()Ljava/util/Set;
     781: checkcast     #90                 // class java/lang/Iterable
     784: ldc           #219                // String \n
     786: checkcast     #221                // class java/lang/CharSequence
     789: aconst_null
     790: aconst_null
     791: iconst_0
     792: aconst_null
     793: aconst_null
     794: bipush        62
     796: aconst_null
     797: invokestatic  #225                // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     800: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     803: swap
     804: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     807: getstatic     #37                 // Field java/lang/System.out:Ljava/io/PrintStream;
     810: invokevirtual #227                // Method java/io/PrintStream.println:()V
     813: goto          29
     816: iconst_0
     817: ireturn

  public static final int part2();
    Code:
       0: iconst_2
       1: ireturn

  private static final java.lang.Comparable part1$lambda$3(advent.of.code.day15.Creature);
    Code:
       0: aload_0
       1: ldc_w         #272                // String it
       4: invokestatic  #278                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #203                // Method advent/of/code/day15/Creature.getHitPoints:()I
      11: invokestatic  #209                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: checkcast     #280                // class java/lang/Comparable
      17: areturn

  private static final java.lang.Comparable part1$lambda$4(advent.of.code.day15.Creature);
    Code:
       0: aload_0
       1: ldc_w         #272                // String it
       4: invokestatic  #278                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #283                // Method advent/of/code/day15/Creature.getY:()I
      11: invokestatic  #209                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: checkcast     #280                // class java/lang/Comparable
      17: areturn

  private static final java.lang.Comparable part1$lambda$5(advent.of.code.day15.Creature);
    Code:
       0: aload_0
       1: ldc_w         #272                // String it
       4: invokestatic  #278                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokevirtual #286                // Method advent/of/code/day15/Creature.getX:()I
      11: invokestatic  #209                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: checkcast     #280                // class java/lang/Comparable
      17: areturn

  static {};
    Code:
       0: new           #289                // class java/io/File
       3: dup
       4: ldc_w         #291                // String day15-test.txt
       7: invokespecial #294                // Method java/io/File."<init>":(Ljava/lang/String;)V
      10: putstatic     #22                 // Field input:Ljava/io/File;
      13: return
}


package advent.of.code.day14

fun processUntil10(e1: Byte, e2: Byte, created: Int): String {
    val recipes = mutableListOf(e1, e2)
    var elf1 = 0
    var elf2 = 1
    while (recipes.size < created + 10) {
        val combine = recipes[elf1] + recipes[elf2]
        val recipe1 = if (combine > 9) 1.toByte() else null
        val recipe2 = (combine % 10.toByte()).toByte()
        if (recipe1 != null) recipes += recipe1
        recipes += recipe2
        elf1 = (elf1 + recipes[elf1].toInt() + 1) % recipes.size
        elf2 = (elf2 + recipes[elf2].toInt() + 1) % recipes.size
    }
    return recipes.takeLast(10).joinToString("")
}

fun findSize(e1: Byte, e2: Byte, search: List<Byte>): Int {
    val recipes = mutableListOf(e1, e2)
    var elf1 = 0
    var elf2 = 1
    while (true) {
        val combine = recipes[elf1] + recipes[elf2]
        val recipe1 = if (combine > 9) 1.toByte() else null
        val recipe2 = (combine % 10.toByte()).toByte()
        if (recipe1 != null) {
            recipes += recipe1
            if (recipes.takeLast(search.size) == search)
                return recipes.size - search.size
        }
        recipes += recipe2
        if (recipes.takeLast(search.size) == search)
            return recipes.size - search.size
        elf1 = (elf1 + recipes[elf1].toInt() + 1) % recipes.size
        elf2 = (elf2 + recipes[elf2].toInt() + 1) % recipes.size
    }
}

fun part1() = processUntil10(3, 7, 920831)

fun part2() = findSize(3, 7, listOf(9, 2, 0, 8, 3, 1))

Compiled from "Solution.kt"
public final class advent.of.code.day14.SolutionKt {
  public static final java.lang.String processUntil10(byte, byte, int);
    Code:
       0: iconst_2
       1: anewarray     #9                  // class java/lang/Byte
       4: astore        4
       6: aload         4
       8: iconst_0
       9: iload_0
      10: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      13: aastore
      14: aload         4
      16: iconst_1
      17: iload_1
      18: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      21: aastore
      22: aload         4
      24: invokestatic  #19                 // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
      27: astore_3
      28: iconst_0
      29: istore        4
      31: iconst_1
      32: istore        5
      34: aload_3
      35: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
      40: iload_2
      41: bipush        10
      43: iadd
      44: if_icmpge     198
      47: aload_3
      48: iload         4
      50: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      55: checkcast     #31                 // class java/lang/Number
      58: invokevirtual #34                 // Method java/lang/Number.intValue:()I
      61: aload_3
      62: iload         5
      64: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      69: checkcast     #31                 // class java/lang/Number
      72: invokevirtual #34                 // Method java/lang/Number.intValue:()I
      75: iadd
      76: istore        6
      78: iload         6
      80: bipush        9
      82: if_icmple     92
      85: iconst_1
      86: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      89: goto          93
      92: aconst_null
      93: astore        7
      95: iload         6
      97: bipush        10
      99: irem
     100: i2b
     101: istore        8
     103: aload         7
     105: ifnull        120
     108: aload_3
     109: checkcast     #36                 // class java/util/Collection
     112: aload         7
     114: invokeinterface #40,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     119: pop
     120: iload         8
     122: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
     125: astore        9
     127: aload_3
     128: checkcast     #36                 // class java/util/Collection
     131: aload         9
     133: invokeinterface #40,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     138: pop
     139: iload         4
     141: aload_3
     142: iload         4
     144: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     149: checkcast     #31                 // class java/lang/Number
     152: invokevirtual #44                 // Method java/lang/Number.byteValue:()B
     155: iadd
     156: iconst_1
     157: iadd
     158: aload_3
     159: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     164: irem
     165: istore        4
     167: iload         5
     169: aload_3
     170: iload         5
     172: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     177: checkcast     #31                 // class java/lang/Number
     180: invokevirtual #44                 // Method java/lang/Number.byteValue:()B
     183: iadd
     184: iconst_1
     185: iadd
     186: aload_3
     187: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     192: irem
     193: istore        5
     195: goto          34
     198: aload_3
     199: bipush        10
     201: invokestatic  #48                 // Method kotlin/collections/CollectionsKt.takeLast:(Ljava/util/List;I)Ljava/util/List;
     204: checkcast     #50                 // class java/lang/Iterable
     207: ldc           #52                 // String
     209: checkcast     #54                 // class java/lang/CharSequence
     212: aconst_null
     213: aconst_null
     214: iconst_0
     215: aconst_null
     216: aconst_null
     217: bipush        62
     219: aconst_null
     220: invokestatic  #58                 // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     223: areturn

  public static final int findSize(byte, byte, java.util.List<java.lang.Byte>);
    Code:
       0: aload_2
       1: ldc           #76                 // String search
       3: invokestatic  #82                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_2
       7: anewarray     #9                  // class java/lang/Byte
      10: astore        4
      12: aload         4
      14: iconst_0
      15: iload_0
      16: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      19: aastore
      20: aload         4
      22: iconst_1
      23: iload_1
      24: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      27: aastore
      28: aload         4
      30: invokestatic  #19                 // Method kotlin/collections/CollectionsKt.mutableListOf:([Ljava/lang/Object;)Ljava/util/List;
      33: astore_3
      34: iconst_0
      35: istore        4
      37: iconst_1
      38: istore        5
      40: nop
      41: aload_3
      42: iload         4
      44: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      49: checkcast     #31                 // class java/lang/Number
      52: invokevirtual #34                 // Method java/lang/Number.intValue:()I
      55: aload_3
      56: iload         5
      58: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      63: checkcast     #31                 // class java/lang/Number
      66: invokevirtual #34                 // Method java/lang/Number.intValue:()I
      69: iadd
      70: istore        6
      72: iload         6
      74: bipush        9
      76: if_icmple     86
      79: iconst_1
      80: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      83: goto          87
      86: aconst_null
      87: astore        7
      89: iload         6
      91: bipush        10
      93: irem
      94: i2b
      95: istore        8
      97: aload         7
      99: ifnull        145
     102: aload_3
     103: checkcast     #36                 // class java/util/Collection
     106: aload         7
     108: invokeinterface #40,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     113: pop
     114: aload_3
     115: aload_2
     116: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     121: invokestatic  #48                 // Method kotlin/collections/CollectionsKt.takeLast:(Ljava/util/List;I)Ljava/util/List;
     124: aload_2
     125: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     128: ifeq          145
     131: aload_3
     132: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     137: aload_2
     138: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     143: isub
     144: ireturn
     145: iload         8
     147: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
     150: astore        9
     152: aload_3
     153: checkcast     #36                 // class java/util/Collection
     156: aload         9
     158: invokeinterface #40,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     163: pop
     164: aload_3
     165: aload_2
     166: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     171: invokestatic  #48                 // Method kotlin/collections/CollectionsKt.takeLast:(Ljava/util/List;I)Ljava/util/List;
     174: aload_2
     175: invokestatic  #86                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     178: ifeq          195
     181: aload_3
     182: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     187: aload_2
     188: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     193: isub
     194: ireturn
     195: iload         4
     197: aload_3
     198: iload         4
     200: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     205: checkcast     #31                 // class java/lang/Number
     208: invokevirtual #44                 // Method java/lang/Number.byteValue:()B
     211: iadd
     212: iconst_1
     213: iadd
     214: aload_3
     215: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     220: irem
     221: istore        4
     223: iload         5
     225: aload_3
     226: iload         5
     228: invokeinterface #29,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     233: checkcast     #31                 // class java/lang/Number
     236: invokevirtual #44                 // Method java/lang/Number.byteValue:()B
     239: iadd
     240: iconst_1
     241: iadd
     242: aload_3
     243: invokeinterface #25,  1           // InterfaceMethod java/util/List.size:()I
     248: irem
     249: istore        5
     251: goto          40

  public static final java.lang.String part1();
    Code:
       0: iconst_3
       1: bipush        7
       3: ldc           #89                 // int 920831
       5: invokestatic  #91                 // Method processUntil10:(BBI)Ljava/lang/String;
       8: areturn

  public static final int part2();
    Code:
       0: iconst_3
       1: bipush        7
       3: bipush        6
       5: anewarray     #9                  // class java/lang/Byte
       8: astore_0
       9: aload_0
      10: iconst_0
      11: bipush        9
      13: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      16: aastore
      17: aload_0
      18: iconst_1
      19: iconst_2
      20: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      23: aastore
      24: aload_0
      25: iconst_2
      26: iconst_0
      27: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      30: aastore
      31: aload_0
      32: iconst_3
      33: bipush        8
      35: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      38: aastore
      39: aload_0
      40: iconst_4
      41: iconst_3
      42: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      45: aastore
      46: aload_0
      47: iconst_5
      48: iconst_1
      49: invokestatic  #13                 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
      52: aastore
      53: aload_0
      54: invokestatic  #95                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      57: invokestatic  #97                 // Method findSize:(BBLjava/util/List;)I
      60: ireturn
}


package advent.of.code.day04

import advent.of.code.day04.State.*
import java.io.File

enum class State(val match: Regex) {
    SHIFT(Regex(".+Guard #([0-9]+) begins shift")),
    SLEEP(Regex(".+:([0-9]{2})\\] falls asleep")),
    AWAKE(Regex(".+:([0-9]{2})\\] wakes up"))
}

fun commonPart(selector: (Map.Entry<Int, Array<Int>>) -> Int): Int {
    val guardSleep = mutableMapOf<Int, Array<Int>>()
    var currentGuard = 0
    var asleep = 0
    val lines = File("day04.txt").readLines().sorted()
    for (line in lines) {
        when {
            SHIFT.match matches line -> {
                currentGuard = SHIFT.match.find(line)?.groups!![1]!!.value.toInt()
                if (guardSleep[currentGuard] == null)
                    guardSleep[currentGuard] = Array(60) { 0 }
            }
            SLEEP.match matches line -> {
                asleep = SLEEP.match.find(line)!!.groups[1]!!.value.toInt()
            }
            AWAKE.match matches line -> {
                val awake = AWAKE.match.find(line)!!.groups[1]!!.value.toInt()
                for (b in (asleep until awake))
                    guardSleep[currentGuard]!![b]++
            }
        }
    }
    val guardMostSleep = guardSleep.maxBy(selector)!!.key
    return guardMostSleep * guardSleep[guardMostSleep]!!
        .mapIndexed { index, i -> Pair(index, i) }
        .maxBy { it.second }!!.first

}

fun part1() = commonPart { it.value.sum() }

fun part2() = commonPart { it.value.max() ?: 0 }

Compiled from "Solution.kt"
public final class advent.of.code.day04.SolutionKt {
  public static final int commonPart(kotlin.jvm.functions.Function1<? super java.util.Map$Entry<java.lang.Integer, java.lang.Integer[]>, java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #10                 // String selector
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #18                 // class java/util/LinkedHashMap
       9: dup
      10: invokespecial #22                 // Method java/util/LinkedHashMap."<init>":()V
      13: checkcast     #24                 // class java/util/Map
      16: astore_1
      17: iconst_0
      18: istore_2
      19: iconst_0
      20: istore_3
      21: new           #26                 // class java/io/File
      24: dup
      25: ldc           #28                 // String day04.txt
      27: invokespecial #31                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      30: aconst_null
      31: iconst_1
      32: aconst_null
      33: invokestatic  #37                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      36: checkcast     #39                 // class java/lang/Iterable
      39: invokestatic  #45                 // Method kotlin/collections/CollectionsKt.sorted:(Ljava/lang/Iterable;)Ljava/util/List;
      42: astore        4
      44: aload         4
      46: invokeinterface #51,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      51: astore        5
      53: aload         5
      55: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      60: ifeq          407
      63: aload         5
      65: invokeinterface #61,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      70: checkcast     #63                 // class java/lang/String
      73: astore        6
      75: nop
      76: getstatic     #69                 // Field advent/of/code/day04/State.SHIFT:Ladvent/of/code/day04/State;
      79: invokevirtual #73                 // Method advent/of/code/day04/State.getMatch:()Lkotlin/text/Regex;
      82: aload         6
      84: checkcast     #75                 // class java/lang/CharSequence
      87: invokevirtual #81                 // Method kotlin/text/Regex.matches:(Ljava/lang/CharSequence;)Z
      90: ifeq          222
      93: getstatic     #69                 // Field advent/of/code/day04/State.SHIFT:Ladvent/of/code/day04/State;
      96: invokevirtual #73                 // Method advent/of/code/day04/State.getMatch:()Lkotlin/text/Regex;
      99: aload         6
     101: checkcast     #75                 // class java/lang/CharSequence
     104: iconst_0
     105: iconst_2
     106: aconst_null
     107: invokestatic  #85                 // Method kotlin/text/Regex.find$default:(Lkotlin/text/Regex;Ljava/lang/CharSequence;IILjava/lang/Object;)Lkotlin/text/MatchResult;
     110: dup
     111: ifnull        122
     114: invokeinterface #91,  1           // InterfaceMethod kotlin/text/MatchResult.getGroups:()Lkotlin/text/MatchGroupCollection;
     119: goto          124
     122: pop
     123: aconst_null
     124: dup
     125: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     128: iconst_1
     129: invokeinterface #101,  2          // InterfaceMethod kotlin/text/MatchGroupCollection.get:(I)Lkotlin/text/MatchGroup;
     134: dup
     135: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     138: invokevirtual #107                // Method kotlin/text/MatchGroup.getValue:()Ljava/lang/String;
     141: invokestatic  #113                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     144: istore_2
     145: aload_1
     146: iload_2
     147: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     150: invokeinterface #120,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     155: ifnonnull     53
     158: aload_1
     159: astore        7
     161: iload_2
     162: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     165: astore        8
     167: iconst_0
     168: istore        9
     170: bipush        60
     172: anewarray     #109                // class java/lang/Integer
     175: astore        10
     177: iload         9
     179: bipush        60
     181: if_icmpge     203
     184: iload         9
     186: istore        11
     188: aload         10
     190: iload         11
     192: iconst_0
     193: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     196: aastore
     197: iinc          9, 1
     200: goto          177
     203: aload         10
     205: astore        9
     207: aload         7
     209: aload         8
     211: aload         9
     213: invokeinterface #124,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     218: pop
     219: goto          53
     222: getstatic     #127                // Field advent/of/code/day04/State.SLEEP:Ladvent/of/code/day04/State;
     225: invokevirtual #73                 // Method advent/of/code/day04/State.getMatch:()Lkotlin/text/Regex;
     228: aload         6
     230: checkcast     #75                 // class java/lang/CharSequence
     233: invokevirtual #81                 // Method kotlin/text/Regex.matches:(Ljava/lang/CharSequence;)Z
     236: ifeq          285
     239: getstatic     #127                // Field advent/of/code/day04/State.SLEEP:Ladvent/of/code/day04/State;
     242: invokevirtual #73                 // Method advent/of/code/day04/State.getMatch:()Lkotlin/text/Regex;
     245: aload         6
     247: checkcast     #75                 // class java/lang/CharSequence
     250: iconst_0
     251: iconst_2
     252: aconst_null
     253: invokestatic  #85                 // Method kotlin/text/Regex.find$default:(Lkotlin/text/Regex;Ljava/lang/CharSequence;IILjava/lang/Object;)Lkotlin/text/MatchResult;
     256: dup
     257: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     260: invokeinterface #91,  1           // InterfaceMethod kotlin/text/MatchResult.getGroups:()Lkotlin/text/MatchGroupCollection;
     265: iconst_1
     266: invokeinterface #101,  2          // InterfaceMethod kotlin/text/MatchGroupCollection.get:(I)Lkotlin/text/MatchGroup;
     271: dup
     272: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     275: invokevirtual #107                // Method kotlin/text/MatchGroup.getValue:()Ljava/lang/String;
     278: invokestatic  #113                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     281: istore_3
     282: goto          53
     285: getstatic     #130                // Field advent/of/code/day04/State.AWAKE:Ladvent/of/code/day04/State;
     288: invokevirtual #73                 // Method advent/of/code/day04/State.getMatch:()Lkotlin/text/Regex;
     291: aload         6
     293: checkcast     #75                 // class java/lang/CharSequence
     296: invokevirtual #81                 // Method kotlin/text/Regex.matches:(Ljava/lang/CharSequence;)Z
     299: ifeq          53
     302: getstatic     #130                // Field advent/of/code/day04/State.AWAKE:Ladvent/of/code/day04/State;
     305: invokevirtual #73                 // Method advent/of/code/day04/State.getMatch:()Lkotlin/text/Regex;
     308: aload         6
     310: checkcast     #75                 // class java/lang/CharSequence
     313: iconst_0
     314: iconst_2
     315: aconst_null
     316: invokestatic  #85                 // Method kotlin/text/Regex.find$default:(Lkotlin/text/Regex;Ljava/lang/CharSequence;IILjava/lang/Object;)Lkotlin/text/MatchResult;
     319: dup
     320: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     323: invokeinterface #91,  1           // InterfaceMethod kotlin/text/MatchResult.getGroups:()Lkotlin/text/MatchGroupCollection;
     328: iconst_1
     329: invokeinterface #101,  2          // InterfaceMethod kotlin/text/MatchGroupCollection.get:(I)Lkotlin/text/MatchGroup;
     334: dup
     335: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     338: invokevirtual #107                // Method kotlin/text/MatchGroup.getValue:()Ljava/lang/String;
     341: invokestatic  #113                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     344: istore        7
     346: iload_3
     347: istore        8
     349: iload         8
     351: iload         7
     353: if_icmpge     53
     356: aload_1
     357: iload_2
     358: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     361: invokeinterface #120,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     366: dup
     367: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     370: checkcast     #132                // class "[Ljava/lang/Integer;"
     373: astore        9
     375: iload         8
     377: istore        10
     379: aload         9
     381: iload         10
     383: aaload
     384: invokevirtual #136                // Method java/lang/Integer.intValue:()I
     387: istore        11
     389: aload         9
     391: iload         10
     393: iload         11
     395: iconst_1
     396: iadd
     397: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     400: aastore
     401: iinc          8, 1
     404: goto          349
     407: aload_1
     408: invokeinterface #140,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     413: checkcast     #39                 // class java/lang/Iterable
     416: astore        7
     418: aload         7
     420: invokeinterface #141,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     425: astore        8
     427: aload         8
     429: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     434: ifne          445
     437: new           #143                // class java/util/NoSuchElementException
     440: dup
     441: invokespecial #144                // Method java/util/NoSuchElementException."<init>":()V
     444: athrow
     445: aload         8
     447: invokeinterface #61,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     452: astore        9
     454: aload         8
     456: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     461: ifne          469
     464: aload         9
     466: goto          536
     469: aload_0
     470: aload         9
     472: invokeinterface #149,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     477: checkcast     #151                // class java/lang/Comparable
     480: astore        10
     482: aload         8
     484: invokeinterface #61,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     489: astore        11
     491: aload_0
     492: aload         11
     494: invokeinterface #149,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     499: checkcast     #151                // class java/lang/Comparable
     502: astore        12
     504: aload         10
     506: aload         12
     508: invokeinterface #155,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     513: ifge          524
     516: aload         11
     518: astore        9
     520: aload         12
     522: astore        10
     524: aload         8
     526: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     531: ifne          482
     534: aload         9
     536: checkcast     #157                // class java/util/Map$Entry
     539: dup
     540: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     543: invokeinterface #160,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     548: checkcast     #162                // class java/lang/Number
     551: invokevirtual #163                // Method java/lang/Number.intValue:()I
     554: istore        5
     556: iload         5
     558: aload_1
     559: iload         5
     561: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     564: invokeinterface #120,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     569: dup
     570: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     573: checkcast     #165                // class "[Ljava/lang/Object;"
     576: astore        6
     578: istore        18
     580: iconst_0
     581: istore        7
     583: aload         6
     585: astore        8
     587: new           #167                // class java/util/ArrayList
     590: dup
     591: aload         6
     593: arraylength
     594: invokespecial #170                // Method java/util/ArrayList."<init>":(I)V
     597: checkcast     #172                // class java/util/Collection
     600: astore        9
     602: iconst_0
     603: istore        10
     605: iconst_0
     606: istore        11
     608: iconst_0
     609: istore        12
     611: aload         8
     613: arraylength
     614: istore        13
     616: iload         12
     618: iload         13
     620: if_icmpge     686
     623: aload         8
     625: iload         12
     627: aaload
     628: astore        14
     630: aload         9
     632: iload         11
     634: iinc          11, 1
     637: aload         14
     639: checkcast     #162                // class java/lang/Number
     642: invokevirtual #163                // Method java/lang/Number.intValue:()I
     645: istore        15
     647: istore        16
     649: astore        19
     651: iconst_0
     652: istore        17
     654: new           #174                // class kotlin/Pair
     657: dup
     658: iload         16
     660: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     663: iload         15
     665: invokestatic  #117                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     668: invokespecial #177                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     671: aload         19
     673: swap
     674: invokeinterface #181,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     679: pop
     680: iinc          12, 1
     683: goto          616
     686: aload         9
     688: checkcast     #47                 // class java/util/List
     691: nop
     692: astore        19
     694: iload         18
     696: aload         19
     698: checkcast     #39                 // class java/lang/Iterable
     701: astore        6
     703: istore        18
     705: iconst_0
     706: istore        7
     708: aload         6
     710: invokeinterface #141,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     715: astore        8
     717: aload         8
     719: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     724: ifne          735
     727: new           #143                // class java/util/NoSuchElementException
     730: dup
     731: invokespecial #144                // Method java/util/NoSuchElementException."<init>":()V
     734: athrow
     735: aload         8
     737: invokeinterface #61,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     742: astore        9
     744: aload         8
     746: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     751: ifne          759
     754: aload         9
     756: goto          841
     759: aload         9
     761: checkcast     #174                // class kotlin/Pair
     764: astore        10
     766: iconst_0
     767: istore        11
     769: aload         10
     771: invokevirtual #184                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     774: checkcast     #162                // class java/lang/Number
     777: invokevirtual #163                // Method java/lang/Number.intValue:()I
     780: istore        10
     782: aload         8
     784: invokeinterface #61,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     789: astore        11
     791: aload         11
     793: checkcast     #174                // class kotlin/Pair
     796: astore        12
     798: iconst_0
     799: istore        13
     801: aload         12
     803: invokevirtual #184                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     806: checkcast     #162                // class java/lang/Number
     809: invokevirtual #163                // Method java/lang/Number.intValue:()I
     812: istore        12
     814: iload         10
     816: iload         12
     818: if_icmpge     829
     821: aload         11
     823: astore        9
     825: iload         12
     827: istore        10
     829: aload         8
     831: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     836: ifne          782
     839: aload         9
     841: astore        19
     843: iload         18
     845: aload         19
     847: dup
     848: invokestatic  #95                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     851: checkcast     #174                // class kotlin/Pair
     854: invokevirtual #187                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     857: checkcast     #162                // class java/lang/Number
     860: invokevirtual #163                // Method java/lang/Number.intValue:()I
     863: imul
     864: ireturn

  public static final int part1();
    Code:
       0: invokedynamic #243,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
       5: invokestatic  #245                // Method commonPart:(Lkotlin/jvm/functions/Function1;)I
       8: ireturn

  public static final int part2();
    Code:
       0: invokedynamic #251,  0            // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function1;
       5: invokestatic  #245                // Method commonPart:(Lkotlin/jvm/functions/Function1;)I
       8: ireturn

  private static final int part1$lambda$2(java.util.Map$Entry);
    Code:
       0: aload_0
       1: ldc           #252                // String it
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #254,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      12: checkcast     #132                // class "[Ljava/lang/Integer;"
      15: invokestatic  #260                // Method kotlin/collections/ArraysKt.sumOfInt:([Ljava/lang/Integer;)I
      18: ireturn

  private static final int part2$lambda$3(java.util.Map$Entry);
    Code:
       0: aload_0
       1: ldc           #252                // String it
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #254,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      12: checkcast     #263                // class "[Ljava/lang/Comparable;"
      15: invokestatic  #267                // Method kotlin/collections/ArraysKt.maxOrThrow:([Ljava/lang/Comparable;)Ljava/lang/Comparable;
      18: checkcast     #162                // class java/lang/Number
      21: invokevirtual #163                // Method java/lang/Number.intValue:()I
      24: ireturn
}


package advent.of.code.day18

import advent.of.code.day18.Acre.*
import java.io.File

data class Position(val x: Int, val y: Int) : Comparable<Position> {
    override fun compareTo(other: Position): Int {
        return compareBy<Position>({ it.y }, { it.x }).compare(this, other)
    }

    override fun toString(): String {
        return "(${x.toString().padStart(3, ' ')},${y.toString().padStart(3, ' ')})"
    }

    fun up() = copy(y = y - 1)
    fun down() = copy(y = y + 1)
    fun left() = copy(x = x - 1)
    fun right() = copy(x = x + 1)
    fun upLeft() = copy(x = x - 1, y = y - 1)
    fun upRight() = copy(x = x + 1, y = y - 1)
    fun downLeft() = copy(y = y + 1, x = x - 1)
    fun downRight() = copy(y = y + 1, x = x + 1)

    fun around() = listOf(up(), down(), left(), right(), upLeft(), upRight(), downLeft(), downRight())
}

val input = File("day18.txt")

enum class Acre(val symbol: Char) {
    TREES('|'), LUMBERYARD('#'), OPEN('.')
}

class ForestField(input: File) {
    var acres = mapOf<Position, Acre>()

    init {
        var y = 0
        acres = input.readLines().flatMap { line ->
            var x = 0
            line.mapNotNull { symbol ->
                val pos = Position(x++, y)
                when (symbol) {
                    TREES.symbol -> Pair(pos, TREES)
                    LUMBERYARD.symbol -> Pair(pos, LUMBERYARD)
                    else -> null
                }
            }.apply { y++ }
        }.toMap()
    }

    fun around(position: Position) = position.around().mapNotNull { acres[it] }

    fun plots() = (0..(acres.map { it.key.y }.max() ?: 0)).flatMap { y ->
        (0..(acres.map { it.key.x }.max() ?: 0)).map { x ->
            val pos = Position(x, y)
            Pair(pos, acres[pos] ?: OPEN)
        }
    }

    override fun toString(): String {
        var output = ""
        for (y in (0..(acres.map { it.key.y }.max() ?: 0))) {
            for (x in (0..(acres.map { it.key.x }.max() ?: 0)))
                output += (acres[Position(x, y)] ?: OPEN).symbol
            output += '\n'
        }
        return output
    }
}

// 1000000000

fun part1(): Int {
    val forest = ForestField(input)
    println((1..1000000000).map { idx ->
        forest.acres = forest.plots().mapNotNull {
            when (it.second) {
                TREES -> {
                    if (forest.around(it.first).count { near -> near == LUMBERYARD } >= 3)
                        Pair(it.first, LUMBERYARD)
                    else
                        it
                }
                LUMBERYARD -> {
                    if (forest.around(it.first).count { near -> near == LUMBERYARD } >= 1 &&
                        forest.around(it.first).count { near -> near == TREES } >= 1)
                        Pair(it.first, LUMBERYARD)
                    else
                        null
                }
                else -> {
                    if (forest.around(it.first).count { near -> near == TREES } >= 3)
                        Pair(it.first, TREES)
                    else
                        it
                }
            }
        }.toMap()
        val wood = forest.plots().count { it.second == TREES }
        val yards = forest.plots().count { it.second == LUMBERYARD }
        if (((idx - 1000) % 7000 in listOf(6999, 0, 1))) println("$idx -> $wood -> $yards -> ${wood * yards}")
        idx to wood * yards
    }.last())
    return forest.plots().count { it.second == LUMBERYARD } * forest.plots().count { it.second == TREES }
}

Compiled from "Solution.kt"
public final class advent.of.code.day18.SolutionKt$WhenMappings {
  public static final int[] $EnumSwitchMapping$0;

  static {};
    Code:
       0: invokestatic  #14                 // Method advent/of/code/day18/Acre.values:()[Ladvent/of/code/day18/Acre;
       3: arraylength
       4: newarray       int
       6: astore_0
       7: nop
       8: aload_0
       9: getstatic     #18                 // Field advent/of/code/day18/Acre.TREES:Ladvent/of/code/day18/Acre;
      12: invokevirtual #22                 // Method advent/of/code/day18/Acre.ordinal:()I
      15: iconst_1
      16: iastore
      17: goto          21
      20: astore_1
      21: nop
      22: aload_0
      23: getstatic     #25                 // Field advent/of/code/day18/Acre.LUMBERYARD:Ladvent/of/code/day18/Acre;
      26: invokevirtual #22                 // Method advent/of/code/day18/Acre.ordinal:()I
      29: iconst_2
      30: iastore
      31: goto          35
      34: astore_1
      35: aload_0
      36: putstatic     #29                 // Field $EnumSwitchMapping$0:[I
      39: return
    Exception table:
       from    to  target type
           7    17    20   Class java/lang/NoSuchFieldError
          21    31    34   Class java/lang/NoSuchFieldError
}

Compiled from "Solution.kt"
public final class advent.of.code.day18.SolutionKt {
  private static final java.io.File input;

  public static final java.io.File getInput();
    Code:
       0: getstatic     #11                 // Field input:Ljava/io/File;
       3: areturn

  public static final int part1();
    Code:
       0: new           #15                 // class advent/of/code/day18/ForestField
       3: dup
       4: getstatic     #11                 // Field input:Ljava/io/File;
       7: invokespecial #19                 // Method advent/of/code/day18/ForestField."<init>":(Ljava/io/File;)V
      10: astore_0
      11: new           #21                 // class kotlin/ranges/IntRange
      14: dup
      15: iconst_1
      16: ldc           #22                 // int 1000000000
      18: invokespecial #25                 // Method kotlin/ranges/IntRange."<init>":(II)V
      21: checkcast     #27                 // class java/lang/Iterable
      24: astore_1
      25: iconst_0
      26: istore_2
      27: aload_1
      28: astore_3
      29: new           #29                 // class java/util/ArrayList
      32: dup
      33: aload_1
      34: bipush        10
      36: invokestatic  #35                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      39: invokespecial #38                 // Method java/util/ArrayList."<init>":(I)V
      42: checkcast     #40                 // class java/util/Collection
      45: astore        4
      47: iconst_0
      48: istore        5
      50: aload_3
      51: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      56: astore        6
      58: aload         6
      60: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      65: ifeq          1183
      68: aload         6
      70: checkcast     #52                 // class kotlin/collections/IntIterator
      73: invokevirtual #55                 // Method kotlin/collections/IntIterator.nextInt:()I
      76: istore        7
      78: aload         4
      80: iload         7
      82: istore        8
      84: astore        33
      86: iconst_0
      87: istore        9
      89: aload_0
      90: aload_0
      91: invokevirtual #59                 // Method advent/of/code/day18/ForestField.plots:()Ljava/util/List;
      94: checkcast     #27                 // class java/lang/Iterable
      97: astore        10
      99: astore        11
     101: iconst_0
     102: istore        12
     104: aload         10
     106: astore        13
     108: new           #29                 // class java/util/ArrayList
     111: dup
     112: invokespecial #62                 // Method java/util/ArrayList."<init>":()V
     115: checkcast     #40                 // class java/util/Collection
     118: astore        14
     120: iconst_0
     121: istore        15
     123: aload         13
     125: astore        16
     127: iconst_0
     128: istore        17
     130: aload         16
     132: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     137: astore        18
     139: aload         18
     141: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     146: ifeq          793
     149: aload         18
     151: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     156: astore        19
     158: aload         19
     160: astore        20
     162: iconst_0
     163: istore        21
     165: aload         20
     167: checkcast     #68                 // class kotlin/Pair
     170: astore        22
     172: iconst_0
     173: istore        23
     175: aload         22
     177: invokevirtual #71                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     180: checkcast     #73                 // class advent/of/code/day18/Acre
     183: getstatic     #79                 // Field advent/of/code/day18/SolutionKt$WhenMappings.$EnumSwitchMapping$0:[I
     186: swap
     187: invokevirtual #82                 // Method advent/of/code/day18/Acre.ordinal:()I
     190: iaload
     191: tableswitch   { // 1 to 2
                     1: 212
                     2: 357
               default: 623
          }
     212: aload_0
     213: aload         22
     215: invokevirtual #85                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     218: checkcast     #87                 // class advent/of/code/day18/Position
     221: invokevirtual #91                 // Method advent/of/code/day18/ForestField.around:(Ladvent/of/code/day18/Position;)Ljava/util/List;
     224: checkcast     #27                 // class java/lang/Iterable
     227: astore        24
     229: iconst_0
     230: istore        25
     232: aload         24
     234: instanceof    #40                 // class java/util/Collection
     237: ifeq          257
     240: aload         24
     242: checkcast     #40                 // class java/util/Collection
     245: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     250: ifeq          257
     253: iconst_0
     254: goto          330
     257: iconst_0
     258: istore        26
     260: aload         24
     262: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     267: astore        27
     269: aload         27
     271: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     276: ifeq          328
     279: aload         27
     281: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     286: astore        28
     288: aload         28
     290: checkcast     #73                 // class advent/of/code/day18/Acre
     293: astore        29
     295: iconst_0
     296: istore        30
     298: aload         29
     300: getstatic     #98                 // Field advent/of/code/day18/Acre.LUMBERYARD:Ladvent/of/code/day18/Acre;
     303: if_acmpne     310
     306: iconst_1
     307: goto          311
     310: iconst_0
     311: ifeq          269
     314: iinc          26, 1
     317: iload         26
     319: ifge          269
     322: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     325: goto          269
     328: iload         26
     330: iconst_3
     331: if_icmplt     352
     334: new           #68                 // class kotlin/Pair
     337: dup
     338: aload         22
     340: invokevirtual #85                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     343: getstatic     #98                 // Field advent/of/code/day18/Acre.LUMBERYARD:Ladvent/of/code/day18/Acre;
     346: invokespecial #104                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     349: goto          765
     352: aload         22
     354: goto          765
     357: aload_0
     358: aload         22
     360: invokevirtual #85                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     363: checkcast     #87                 // class advent/of/code/day18/Position
     366: invokevirtual #91                 // Method advent/of/code/day18/ForestField.around:(Ladvent/of/code/day18/Position;)Ljava/util/List;
     369: checkcast     #27                 // class java/lang/Iterable
     372: astore        24
     374: iconst_0
     375: istore        25
     377: aload         24
     379: instanceof    #40                 // class java/util/Collection
     382: ifeq          402
     385: aload         24
     387: checkcast     #40                 // class java/util/Collection
     390: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     395: ifeq          402
     398: iconst_0
     399: goto          475
     402: iconst_0
     403: istore        26
     405: aload         24
     407: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     412: astore        27
     414: aload         27
     416: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     421: ifeq          473
     424: aload         27
     426: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     431: astore        28
     433: aload         28
     435: checkcast     #73                 // class advent/of/code/day18/Acre
     438: astore        29
     440: iconst_0
     441: istore        30
     443: aload         29
     445: getstatic     #98                 // Field advent/of/code/day18/Acre.LUMBERYARD:Ladvent/of/code/day18/Acre;
     448: if_acmpne     455
     451: iconst_1
     452: goto          456
     455: iconst_0
     456: ifeq          414
     459: iinc          26, 1
     462: iload         26
     464: ifge          414
     467: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     470: goto          414
     473: iload         26
     475: iconst_1
     476: if_icmplt     619
     479: aload_0
     480: aload         22
     482: invokevirtual #85                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     485: checkcast     #87                 // class advent/of/code/day18/Position
     488: invokevirtual #91                 // Method advent/of/code/day18/ForestField.around:(Ladvent/of/code/day18/Position;)Ljava/util/List;
     491: checkcast     #27                 // class java/lang/Iterable
     494: astore        24
     496: iconst_0
     497: istore        25
     499: aload         24
     501: instanceof    #40                 // class java/util/Collection
     504: ifeq          524
     507: aload         24
     509: checkcast     #40                 // class java/util/Collection
     512: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     517: ifeq          524
     520: iconst_0
     521: goto          597
     524: iconst_0
     525: istore        26
     527: aload         24
     529: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     534: astore        27
     536: aload         27
     538: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     543: ifeq          595
     546: aload         27
     548: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     553: astore        28
     555: aload         28
     557: checkcast     #73                 // class advent/of/code/day18/Acre
     560: astore        29
     562: iconst_0
     563: istore        30
     565: aload         29
     567: getstatic     #107                // Field advent/of/code/day18/Acre.TREES:Ladvent/of/code/day18/Acre;
     570: if_acmpne     577
     573: iconst_1
     574: goto          578
     577: iconst_0
     578: ifeq          536
     581: iinc          26, 1
     584: iload         26
     586: ifge          536
     589: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     592: goto          536
     595: iload         26
     597: iconst_1
     598: if_icmplt     619
     601: new           #68                 // class kotlin/Pair
     604: dup
     605: aload         22
     607: invokevirtual #85                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     610: getstatic     #98                 // Field advent/of/code/day18/Acre.LUMBERYARD:Ladvent/of/code/day18/Acre;
     613: invokespecial #104                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     616: goto          765
     619: aconst_null
     620: goto          765
     623: aload_0
     624: aload         22
     626: invokevirtual #85                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     629: checkcast     #87                 // class advent/of/code/day18/Position
     632: invokevirtual #91                 // Method advent/of/code/day18/ForestField.around:(Ladvent/of/code/day18/Position;)Ljava/util/List;
     635: checkcast     #27                 // class java/lang/Iterable
     638: astore        24
     640: iconst_0
     641: istore        25
     643: aload         24
     645: instanceof    #40                 // class java/util/Collection
     648: ifeq          668
     651: aload         24
     653: checkcast     #40                 // class java/util/Collection
     656: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     661: ifeq          668
     664: iconst_0
     665: goto          741
     668: iconst_0
     669: istore        26
     671: aload         24
     673: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     678: astore        27
     680: aload         27
     682: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     687: ifeq          739
     690: aload         27
     692: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     697: astore        28
     699: aload         28
     701: checkcast     #73                 // class advent/of/code/day18/Acre
     704: astore        29
     706: iconst_0
     707: istore        30
     709: aload         29
     711: getstatic     #107                // Field advent/of/code/day18/Acre.TREES:Ladvent/of/code/day18/Acre;
     714: if_acmpne     721
     717: iconst_1
     718: goto          722
     721: iconst_0
     722: ifeq          680
     725: iinc          26, 1
     728: iload         26
     730: ifge          680
     733: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     736: goto          680
     739: iload         26
     741: iconst_3
     742: if_icmplt     763
     745: new           #68                 // class kotlin/Pair
     748: dup
     749: aload         22
     751: invokevirtual #85                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     754: getstatic     #107                // Field advent/of/code/day18/Acre.TREES:Ladvent/of/code/day18/Acre;
     757: invokespecial #104                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     760: goto          765
     763: aload         22
     765: nop
     766: dup
     767: ifnull        788
     770: astore        31
     772: iconst_0
     773: istore        32
     775: aload         14
     777: aload         31
     779: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     784: pop
     785: goto          789
     788: pop
     789: nop
     790: goto          139
     793: nop
     794: aload         14
     796: checkcast     #113                // class java/util/List
     799: nop
     800: aload         11
     802: swap
     803: checkcast     #27                 // class java/lang/Iterable
     806: invokestatic  #119                // Method kotlin/collections/MapsKt.toMap:(Ljava/lang/Iterable;)Ljava/util/Map;
     809: invokevirtual #123                // Method advent/of/code/day18/ForestField.setAcres:(Ljava/util/Map;)V
     812: aload_0
     813: invokevirtual #59                 // Method advent/of/code/day18/ForestField.plots:()Ljava/util/List;
     816: checkcast     #27                 // class java/lang/Iterable
     819: astore        12
     821: iconst_0
     822: istore        13
     824: aload         12
     826: instanceof    #40                 // class java/util/Collection
     829: ifeq          849
     832: aload         12
     834: checkcast     #40                 // class java/util/Collection
     837: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     842: ifeq          849
     845: iconst_0
     846: goto          925
     849: iconst_0
     850: istore        14
     852: aload         12
     854: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     859: astore        15
     861: aload         15
     863: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     868: ifeq          923
     871: aload         15
     873: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     878: astore        16
     880: aload         16
     882: checkcast     #68                 // class kotlin/Pair
     885: astore        17
     887: iconst_0
     888: istore        18
     890: aload         17
     892: invokevirtual #71                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     895: getstatic     #107                // Field advent/of/code/day18/Acre.TREES:Ladvent/of/code/day18/Acre;
     898: if_acmpne     905
     901: iconst_1
     902: goto          906
     905: iconst_0
     906: ifeq          861
     909: iinc          14, 1
     912: iload         14
     914: ifge          861
     917: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     920: goto          861
     923: iload         14
     925: istore        10
     927: aload_0
     928: invokevirtual #59                 // Method advent/of/code/day18/ForestField.plots:()Ljava/util/List;
     931: checkcast     #27                 // class java/lang/Iterable
     934: astore        13
     936: iconst_0
     937: istore        14
     939: aload         13
     941: instanceof    #40                 // class java/util/Collection
     944: ifeq          964
     947: aload         13
     949: checkcast     #40                 // class java/util/Collection
     952: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
     957: ifeq          964
     960: iconst_0
     961: goto          1040
     964: iconst_0
     965: istore        15
     967: aload         13
     969: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     974: astore        16
     976: aload         16
     978: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     983: ifeq          1038
     986: aload         16
     988: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     993: astore        17
     995: aload         17
     997: checkcast     #68                 // class kotlin/Pair
    1000: astore        18
    1002: iconst_0
    1003: istore        19
    1005: aload         18
    1007: invokevirtual #71                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
    1010: getstatic     #98                 // Field advent/of/code/day18/Acre.LUMBERYARD:Ladvent/of/code/day18/Acre;
    1013: if_acmpne     1020
    1016: iconst_1
    1017: goto          1021
    1020: iconst_0
    1021: ifeq          976
    1024: iinc          15, 1
    1027: iload         15
    1029: ifge          976
    1032: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
    1035: goto          976
    1038: iload         15
    1040: istore        12
    1042: iconst_3
    1043: anewarray     #125                // class java/lang/Integer
    1046: astore        13
    1048: aload         13
    1050: iconst_0
    1051: sipush        6999
    1054: invokestatic  #129                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    1057: aastore
    1058: aload         13
    1060: iconst_1
    1061: iconst_0
    1062: invokestatic  #129                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    1065: aastore
    1066: aload         13
    1068: iconst_2
    1069: iconst_1
    1070: invokestatic  #129                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    1073: aastore
    1074: aload         13
    1076: invokestatic  #133                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
    1079: iload         8
    1081: sipush        1000
    1084: isub
    1085: sipush        7000
    1088: irem
    1089: invokestatic  #129                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    1092: invokeinterface #136,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
    1097: ifeq          1155
    1100: new           #138                // class java/lang/StringBuilder
    1103: dup
    1104: invokespecial #139                // Method java/lang/StringBuilder."<init>":()V
    1107: iload         8
    1109: invokevirtual #143                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    1112: ldc           #145                // String  ->
    1114: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    1117: iload         10
    1119: invokevirtual #143                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    1122: ldc           #145                // String  ->
    1124: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    1127: iload         12
    1129: invokevirtual #143                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    1132: ldc           #145                // String  ->
    1134: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    1137: iload         10
    1139: iload         12
    1141: imul
    1142: invokevirtual #143                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    1145: invokevirtual #152                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    1148: getstatic     #158                // Field java/lang/System.out:Ljava/io/PrintStream;
    1151: swap
    1152: invokevirtual #164                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
    1155: iload         8
    1157: invokestatic  #129                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    1160: iload         10
    1162: iload         12
    1164: imul
    1165: invokestatic  #129                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    1168: invokestatic  #170                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
    1171: aload         33
    1173: swap
    1174: invokeinterface #111,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
    1179: pop
    1180: goto          58
    1183: aload         4
    1185: checkcast     #113                // class java/util/List
    1188: nop
    1189: invokestatic  #174                // Method kotlin/collections/CollectionsKt.last:(Ljava/util/List;)Ljava/lang/Object;
    1192: astore_1
    1193: getstatic     #158                // Field java/lang/System.out:Ljava/io/PrintStream;
    1196: aload_1
    1197: invokevirtual #164                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
    1200: aload_0
    1201: invokevirtual #59                 // Method advent/of/code/day18/ForestField.plots:()Ljava/util/List;
    1204: checkcast     #27                 // class java/lang/Iterable
    1207: astore_1
    1208: iconst_0
    1209: istore_2
    1210: aload_1
    1211: instanceof    #40                 // class java/util/Collection
    1214: ifeq          1233
    1217: aload_1
    1218: checkcast     #40                 // class java/util/Collection
    1221: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
    1226: ifeq          1233
    1229: iconst_0
    1230: goto          1305
    1233: iconst_0
    1234: istore_3
    1235: aload_1
    1236: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    1241: astore        4
    1243: aload         4
    1245: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1250: ifeq          1304
    1253: aload         4
    1255: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1260: astore        5
    1262: aload         5
    1264: checkcast     #68                 // class kotlin/Pair
    1267: astore        6
    1269: iconst_0
    1270: istore        7
    1272: aload         6
    1274: invokevirtual #71                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
    1277: getstatic     #98                 // Field advent/of/code/day18/Acre.LUMBERYARD:Ladvent/of/code/day18/Acre;
    1280: if_acmpne     1287
    1283: iconst_1
    1284: goto          1288
    1287: iconst_0
    1288: ifeq          1243
    1291: iinc          3, 1
    1294: iload_3
    1295: ifge          1243
    1298: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
    1301: goto          1243
    1304: iload_3
    1305: aload_0
    1306: invokevirtual #59                 // Method advent/of/code/day18/ForestField.plots:()Ljava/util/List;
    1309: checkcast     #27                 // class java/lang/Iterable
    1312: astore_1
    1313: istore        33
    1315: iconst_0
    1316: istore_2
    1317: aload_1
    1318: instanceof    #40                 // class java/util/Collection
    1321: ifeq          1340
    1324: aload_1
    1325: checkcast     #40                 // class java/util/Collection
    1328: invokeinterface #94,  1           // InterfaceMethod java/util/Collection.isEmpty:()Z
    1333: ifeq          1340
    1336: iconst_0
    1337: goto          1412
    1340: iconst_0
    1341: istore_3
    1342: aload_1
    1343: invokeinterface #44,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    1348: astore        4
    1350: aload         4
    1352: invokeinterface #50,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
    1357: ifeq          1411
    1360: aload         4
    1362: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    1367: astore        5
    1369: aload         5
    1371: checkcast     #68                 // class kotlin/Pair
    1374: astore        6
    1376: iconst_0
    1377: istore        7
    1379: aload         6
    1381: invokevirtual #71                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
    1384: getstatic     #107                // Field advent/of/code/day18/Acre.TREES:Ladvent/of/code/day18/Acre;
    1387: if_acmpne     1394
    1390: iconst_1
    1391: goto          1395
    1394: iconst_0
    1395: ifeq          1350
    1398: iinc          3, 1
    1401: iload_3
    1402: ifge          1350
    1405: invokestatic  #101                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
    1408: goto          1350
    1411: iload_3
    1412: istore        34
    1414: iload         33
    1416: iload         34
    1418: imul
    1419: ireturn

  static {};
    Code:
       0: new           #222                // class java/io/File
       3: dup
       4: ldc           #224                // String day18.txt
       6: invokespecial #227                // Method java/io/File."<init>":(Ljava/lang/String;)V
       9: putstatic     #11                 // Field input:Ljava/io/File;
      12: return
}