package day15

import Point
import day15.CavePoint.Sensor
import kotlin.math.abs
import readInput
import union

val regex = """.+x=(-?\d+).*y=(-?\d+):.*x=(-?\d+).*y=(-?\d+)""".toRegex()

const val prd_row = 2_000_000
const val test_row = 10

val prd_range = 0..4000000
val test_range = 0..20

typealias Cave = MutableSet<CavePoint>

sealed class CavePoint(open val location: Point) {

    data class BeaconExcluded(override val location: Point) : CavePoint(location)

    data class Sensor(override val location: Point, val beacon: Point) : CavePoint(beacon) {
        val beaconDistance
            get() = location.distanceTo(beacon)
    }

    override fun equals(other: Any?): Boolean {
        return if (other is CavePoint) location == other.location else false
    }

    override fun hashCode(): Int {
        return location.hashCode()
    }
}

fun main() {
    val input = readInput("main/day15/Day15_test")
    println(part1(input))
    println(part2(input))
}

fun part1(input: List<String>): Int {
    val cave = input.parse()

    val row = if (input.size < 20) test_row else prd_row
    cave.markNoBeaconArea(row)
    val beaconLocations = cave.filterIsInstance<Sensor>().map { it.beacon }.toSet()
    return cave.count { it.location.y == row && it.location !in beaconLocations }
}

fun part2(input: List<String>): Long {
    val cave = input.parse()
    val range = if (input.size > 20) prd_range else test_range
    range.forEach { row ->
        cave.lineRangesFor(row).reduce { acc, range -> (acc.union(range)) ?: return (acc.last + 1) * 4_000_000L + row }
    }
    return -1
}

fun Cave.markNoBeaconArea(row: Int) {
    val sensors = filterIsInstance<Sensor>()
    sensors.forEach { sensor ->
        (sensor.location.x - sensor.beaconDistance..sensor.location.x + sensor.beaconDistance).forEach { x ->
            val candidate = Point(x, row)
            if (candidate.distanceTo(sensor.location) <= sensor.beaconDistance) add(CavePoint.BeaconExcluded(candidate))
        }
    }
}

fun Cave.lineRangesFor(row: Int): List<IntRange> {
    return filterIsInstance<Sensor>().map { sensor ->
        val distance = sensor.beaconDistance - abs(row - sensor.location.y)
        sensor.location.x - distance..sensor.location.x + distance
    }.sortedBy { it.first }
}

fun List<String>.parse(): Cave = map {
    regex.matchEntire(it)?.destructured?.let { (sX, sY, bX, bY) ->
        Sensor(location = Point(x = sX.toInt(), y = sY.toInt()), beacon = Point(bX.toInt(), bY.toInt()))
    } ?: error("PARSER PROBLEM")
}.toMutableSet()

Compiled from "day15.kt"
public final class day15.Day15Kt {
  private static final kotlin.text.Regex regex;

  public static final int prd_row;

  public static final int test_row;

  private static final kotlin.ranges.IntRange prd_range;

  private static final kotlin.ranges.IntRange test_range;

  public static final kotlin.text.Regex getRegex();
    Code:
       0: getstatic     #11                 // Field regex:Lkotlin/text/Regex;
       3: areturn

  public static final kotlin.ranges.IntRange getPrd_range();
    Code:
       0: getstatic     #17                 // Field prd_range:Lkotlin/ranges/IntRange;
       3: areturn

  public static final kotlin.ranges.IntRange getTest_range();
    Code:
       0: getstatic     #21                 // Field test_range:Lkotlin/ranges/IntRange;
       3: areturn

  public static final void main();
    Code:
       0: ldc           #25                 // String main/day15/Day15_test
       2: invokestatic  #31                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #35                 // Method part1:(Ljava/util/List;)I
      10: istore_1
      11: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;
      14: iload_1
      15: invokevirtual #47                 // Method java/io/PrintStream.println:(I)V
      18: aload_0
      19: invokestatic  #51                 // Method part2:(Ljava/util/List;)J
      22: lstore_1
      23: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: lload_1
      27: invokevirtual #54                 // Method java/io/PrintStream.println:(J)V
      30: return

  public static final int part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #58                 // String input
       3: invokestatic  #64                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #68                 // Method parse:(Ljava/util/List;)Ljava/util/Set;
      10: astore_1
      11: aload_0
      12: invokeinterface #74,  1           // InterfaceMethod java/util/List.size:()I
      17: bipush        20
      19: if_icmpge     27
      22: bipush        10
      24: goto          29
      27: ldc           #75                 // int 2000000
      29: istore_2
      30: aload_1
      31: iload_2
      32: invokestatic  #79                 // Method markNoBeaconArea:(Ljava/util/Set;I)V
      35: aload_1
      36: checkcast     #81                 // class java/lang/Iterable
      39: astore        4
      41: iconst_0
      42: istore        5
      44: aload         4
      46: astore        6
      48: new           #83                 // class java/util/ArrayList
      51: dup
      52: invokespecial #86                 // Method java/util/ArrayList."<init>":()V
      55: checkcast     #88                 // class java/util/Collection
      58: astore        7
      60: iconst_0
      61: istore        8
      63: aload         6
      65: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      70: astore        9
      72: aload         9
      74: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      79: ifeq          112
      82: aload         9
      84: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      89: astore        10
      91: aload         10
      93: instanceof    #104                // class day15/CavePoint$Sensor
      96: ifeq          72
      99: aload         7
     101: aload         10
     103: invokeinterface #108,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     108: pop
     109: goto          72
     112: aload         7
     114: checkcast     #70                 // class java/util/List
     117: nop
     118: checkcast     #81                 // class java/lang/Iterable
     121: astore        4
     123: nop
     124: iconst_0
     125: istore        5
     127: aload         4
     129: astore        6
     131: new           #83                 // class java/util/ArrayList
     134: dup
     135: aload         4
     137: bipush        10
     139: invokestatic  #114                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     142: invokespecial #116                // Method java/util/ArrayList."<init>":(I)V
     145: checkcast     #88                 // class java/util/Collection
     148: astore        7
     150: iconst_0
     151: istore        8
     153: aload         6
     155: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     160: astore        9
     162: aload         9
     164: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     169: ifeq          212
     172: aload         9
     174: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     179: astore        10
     181: aload         7
     183: aload         10
     185: checkcast     #104                // class day15/CavePoint$Sensor
     188: astore        11
     190: astore        13
     192: iconst_0
     193: istore        12
     195: aload         11
     197: invokevirtual #120                // Method day15/CavePoint$Sensor.getBeacon:()LPoint;
     200: aload         13
     202: swap
     203: invokeinterface #108,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     208: pop
     209: goto          162
     212: aload         7
     214: checkcast     #70                 // class java/util/List
     217: nop
     218: checkcast     #81                 // class java/lang/Iterable
     221: invokestatic  #124                // Method kotlin/collections/CollectionsKt.toSet:(Ljava/lang/Iterable;)Ljava/util/Set;
     224: astore_3
     225: aload_1
     226: checkcast     #81                 // class java/lang/Iterable
     229: astore        4
     231: iconst_0
     232: istore        5
     234: aload         4
     236: instanceof    #88                 // class java/util/Collection
     239: ifeq          259
     242: aload         4
     244: checkcast     #88                 // class java/util/Collection
     247: invokeinterface #127,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     252: ifeq          259
     255: iconst_0
     256: goto          350
     259: iconst_0
     260: istore        6
     262: aload         4
     264: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     269: astore        7
     271: aload         7
     273: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     278: ifeq          348
     281: aload         7
     283: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     288: astore        8
     290: aload         8
     292: checkcast     #129                // class day15/CavePoint
     295: astore        9
     297: iconst_0
     298: istore        10
     300: aload         9
     302: invokevirtual #132                // Method day15/CavePoint.getLocation:()LPoint;
     305: invokevirtual #137                // Method Point.getY:()I
     308: iload_2
     309: if_icmpne     330
     312: aload_3
     313: aload         9
     315: invokevirtual #132                // Method day15/CavePoint.getLocation:()LPoint;
     318: invokeinterface #142,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     323: ifne          330
     326: iconst_1
     327: goto          331
     330: iconst_0
     331: ifeq          271
     334: iinc          6, 1
     337: iload         6
     339: ifge          271
     342: invokestatic  #145                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     345: goto          271
     348: iload         6
     350: ireturn

  public static final long part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #58                 // String input
       3: invokestatic  #64                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #68                 // Method parse:(Ljava/util/List;)Ljava/util/Set;
      10: astore_1
      11: aload_0
      12: invokeinterface #74,  1           // InterfaceMethod java/util/List.size:()I
      17: bipush        20
      19: if_icmple     28
      22: getstatic     #17                 // Field prd_range:Lkotlin/ranges/IntRange;
      25: goto          31
      28: getstatic     #21                 // Field test_range:Lkotlin/ranges/IntRange;
      31: astore_2
      32: aload_2
      33: checkcast     #81                 // class java/lang/Iterable
      36: astore_3
      37: iconst_0
      38: istore        4
      40: aload_3
      41: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      46: astore        5
      48: aload         5
      50: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      55: ifeq          199
      58: aload         5
      60: checkcast     #176                // class kotlin/collections/IntIterator
      63: invokevirtual #179                // Method kotlin/collections/IntIterator.nextInt:()I
      66: istore        6
      68: iload         6
      70: istore        7
      72: iconst_0
      73: istore        8
      75: aload_1
      76: iload         7
      78: invokestatic  #183                // Method lineRangesFor:(Ljava/util/Set;I)Ljava/util/List;
      81: checkcast     #81                 // class java/lang/Iterable
      84: astore        9
      86: iconst_0
      87: istore        10
      89: aload         9
      91: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      96: astore        11
      98: aload         11
     100: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     105: ifne          118
     108: new           #185                // class java/lang/UnsupportedOperationException
     111: dup
     112: ldc           #187                // String Empty collection can\'t be reduced.
     114: invokespecial #190                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     117: athrow
     118: aload         11
     120: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     125: astore        12
     127: aload         11
     129: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     134: ifeq          193
     137: aload         12
     139: aload         11
     141: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     146: checkcast     #192                // class kotlin/ranges/IntRange
     149: astore        13
     151: checkcast     #192                // class kotlin/ranges/IntRange
     154: astore        14
     156: iconst_0
     157: istore        15
     159: aload         14
     161: aload         13
     163: invokestatic  #196                // Method UtilsKt.union:(Lkotlin/ranges/IntRange;Lkotlin/ranges/IntRange;)Lkotlin/ranges/IntRange;
     166: dup
     167: ifnonnull     188
     170: pop
     171: aload         14
     173: invokevirtual #199                // Method kotlin/ranges/IntRange.getLast:()I
     176: iconst_1
     177: iadd
     178: i2l
     179: ldc2_w        #200                // long 4000000l
     182: lmul
     183: iload         7
     185: i2l
     186: ladd
     187: lreturn
     188: astore        12
     190: goto          127
     193: nop
     194: nop
     195: nop
     196: goto          48
     199: nop
     200: ldc2_w        #202                // long -1l
     203: lreturn

  public static final void markNoBeaconArea(java.util.Set<day15.CavePoint>, int);
    Code:
       0: aload_0
       1: ldc           #217                // String <this>
       3: invokestatic  #64                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #81                 // class java/lang/Iterable
      10: astore_3
      11: iconst_0
      12: istore        4
      14: aload_3
      15: astore        5
      17: new           #83                 // class java/util/ArrayList
      20: dup
      21: invokespecial #86                 // Method java/util/ArrayList."<init>":()V
      24: checkcast     #88                 // class java/util/Collection
      27: astore        6
      29: iconst_0
      30: istore        7
      32: aload         5
      34: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      39: astore        8
      41: aload         8
      43: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      48: ifeq          81
      51: aload         8
      53: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      58: astore        9
      60: aload         9
      62: instanceof    #104                // class day15/CavePoint$Sensor
      65: ifeq          41
      68: aload         6
      70: aload         9
      72: invokeinterface #108,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      77: pop
      78: goto          41
      81: aload         6
      83: checkcast     #70                 // class java/util/List
      86: nop
      87: astore_2
      88: aload_2
      89: checkcast     #81                 // class java/lang/Iterable
      92: astore_3
      93: iconst_0
      94: istore        4
      96: aload_3
      97: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     102: astore        5
     104: aload         5
     106: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     111: ifeq          269
     114: aload         5
     116: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     121: astore        6
     123: aload         6
     125: checkcast     #104                // class day15/CavePoint$Sensor
     128: astore        7
     130: iconst_0
     131: istore        8
     133: new           #192                // class kotlin/ranges/IntRange
     136: dup
     137: aload         7
     139: invokevirtual #218                // Method day15/CavePoint$Sensor.getLocation:()LPoint;
     142: invokevirtual #221                // Method Point.getX:()I
     145: aload         7
     147: invokevirtual #224                // Method day15/CavePoint$Sensor.getBeaconDistance:()I
     150: isub
     151: aload         7
     153: invokevirtual #218                // Method day15/CavePoint$Sensor.getLocation:()LPoint;
     156: invokevirtual #221                // Method Point.getX:()I
     159: aload         7
     161: invokevirtual #224                // Method day15/CavePoint$Sensor.getBeaconDistance:()I
     164: iadd
     165: invokespecial #227                // Method kotlin/ranges/IntRange."<init>":(II)V
     168: checkcast     #81                 // class java/lang/Iterable
     171: astore        9
     173: iconst_0
     174: istore        10
     176: aload         9
     178: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     183: astore        11
     185: aload         11
     187: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     192: ifeq          263
     195: aload         11
     197: checkcast     #176                // class kotlin/collections/IntIterator
     200: invokevirtual #179                // Method kotlin/collections/IntIterator.nextInt:()I
     203: istore        12
     205: iload         12
     207: istore        13
     209: iconst_0
     210: istore        14
     212: new           #134                // class Point
     215: dup
     216: iload         13
     218: iload_1
     219: invokespecial #228                // Method Point."<init>":(II)V
     222: astore        15
     224: aload         15
     226: aload         7
     228: invokevirtual #218                // Method day15/CavePoint$Sensor.getLocation:()LPoint;
     231: invokevirtual #232                // Method Point.distanceTo:(LPoint;)I
     234: aload         7
     236: invokevirtual #224                // Method day15/CavePoint$Sensor.getBeaconDistance:()I
     239: if_icmpgt     258
     242: aload_0
     243: new           #234                // class day15/CavePoint$BeaconExcluded
     246: dup
     247: aload         15
     249: invokespecial #237                // Method day15/CavePoint$BeaconExcluded."<init>":(LPoint;)V
     252: invokeinterface #238,  2          // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
     257: pop
     258: nop
     259: nop
     260: goto          185
     263: nop
     264: nop
     265: nop
     266: goto          104
     269: nop
     270: return

  public static final java.util.List<kotlin.ranges.IntRange> lineRangesFor(java.util.Set<day15.CavePoint>, int);
    Code:
       0: aload_0
       1: ldc           #217                // String <this>
       3: invokestatic  #64                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #81                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: astore        4
      16: new           #83                 // class java/util/ArrayList
      19: dup
      20: invokespecial #86                 // Method java/util/ArrayList."<init>":()V
      23: checkcast     #88                 // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          80
      50: aload         7
      52: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         8
      61: instanceof    #104                // class day15/CavePoint$Sensor
      64: ifeq          40
      67: aload         5
      69: aload         8
      71: invokeinterface #108,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      76: pop
      77: goto          40
      80: aload         5
      82: checkcast     #70                 // class java/util/List
      85: nop
      86: checkcast     #81                 // class java/lang/Iterable
      89: astore_2
      90: nop
      91: iconst_0
      92: istore_3
      93: aload_2
      94: astore        4
      96: new           #83                 // class java/util/ArrayList
      99: dup
     100: aload_2
     101: bipush        10
     103: invokestatic  #114                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     106: invokespecial #116                // Method java/util/ArrayList."<init>":(I)V
     109: checkcast     #88                 // class java/util/Collection
     112: astore        5
     114: iconst_0
     115: istore        6
     117: aload         4
     119: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     124: astore        7
     126: aload         7
     128: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     133: ifeq          221
     136: aload         7
     138: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     143: astore        8
     145: aload         5
     147: aload         8
     149: checkcast     #104                // class day15/CavePoint$Sensor
     152: astore        9
     154: astore        12
     156: iconst_0
     157: istore        10
     159: aload         9
     161: invokevirtual #224                // Method day15/CavePoint$Sensor.getBeaconDistance:()I
     164: iload_1
     165: aload         9
     167: invokevirtual #218                // Method day15/CavePoint$Sensor.getLocation:()LPoint;
     170: invokevirtual #137                // Method Point.getY:()I
     173: isub
     174: invokestatic  #253                // Method java/lang/Math.abs:(I)I
     177: isub
     178: istore        11
     180: new           #192                // class kotlin/ranges/IntRange
     183: dup
     184: aload         9
     186: invokevirtual #218                // Method day15/CavePoint$Sensor.getLocation:()LPoint;
     189: invokevirtual #221                // Method Point.getX:()I
     192: iload         11
     194: isub
     195: aload         9
     197: invokevirtual #218                // Method day15/CavePoint$Sensor.getLocation:()LPoint;
     200: invokevirtual #221                // Method Point.getX:()I
     203: iload         11
     205: iadd
     206: invokespecial #227                // Method kotlin/ranges/IntRange."<init>":(II)V
     209: aload         12
     211: swap
     212: invokeinterface #108,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     217: pop
     218: goto          126
     221: aload         5
     223: checkcast     #70                 // class java/util/List
     226: nop
     227: checkcast     #81                 // class java/lang/Iterable
     230: astore_2
     231: nop
     232: iconst_0
     233: istore_3
     234: aload_2
     235: new           #255                // class day15/Day15Kt$lineRangesFor$$inlined$sortedBy$1
     238: dup
     239: invokespecial #256                // Method day15/Day15Kt$lineRangesFor$$inlined$sortedBy$1."<init>":()V
     242: checkcast     #258                // class java/util/Comparator
     245: invokestatic  #262                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
     248: areturn

  public static final java.util.Set<day15.CavePoint> parse(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #217                // String <this>
       3: invokestatic  #64                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #81                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #83                 // class java/util/ArrayList
      18: dup
      19: aload_1
      20: bipush        10
      22: invokestatic  #114                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      25: invokespecial #116                // Method java/util/ArrayList."<init>":(I)V
      28: checkcast     #88                 // class java/util/Collection
      31: astore        4
      33: iconst_0
      34: istore        5
      36: aload_3
      37: invokeinterface #92,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      42: astore        6
      44: aload         6
      46: invokeinterface #98,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      51: ifeq          262
      54: aload         6
      56: invokeinterface #102,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      61: astore        7
      63: aload         4
      65: aload         7
      67: checkcast     #270                // class java/lang/String
      70: astore        8
      72: astore        16
      74: iconst_0
      75: istore        9
      77: getstatic     #11                 // Field regex:Lkotlin/text/Regex;
      80: aload         8
      82: checkcast     #272                // class java/lang/CharSequence
      85: invokevirtual #278                // Method kotlin/text/Regex.matchEntire:(Ljava/lang/CharSequence;)Lkotlin/text/MatchResult;
      88: dup
      89: ifnull        235
      92: invokeinterface #284,  1          // InterfaceMethod kotlin/text/MatchResult.getDestructured:()Lkotlin/text/MatchResult$Destructured;
      97: dup
      98: ifnull        235
     101: astore        10
     103: iconst_0
     104: istore        11
     106: aload         10
     108: invokevirtual #290                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     111: invokeinterface #294,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     116: iconst_1
     117: invokeinterface #298,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     122: checkcast     #270                // class java/lang/String
     125: astore        12
     127: aload         10
     129: invokevirtual #290                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     132: invokeinterface #294,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     137: iconst_2
     138: invokeinterface #298,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     143: checkcast     #270                // class java/lang/String
     146: astore        13
     148: aload         10
     150: invokevirtual #290                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     153: invokeinterface #294,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     158: iconst_3
     159: invokeinterface #298,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     164: checkcast     #270                // class java/lang/String
     167: astore        14
     169: aload         10
     171: invokevirtual #290                // Method kotlin/text/MatchResult$Destructured.getMatch:()Lkotlin/text/MatchResult;
     174: invokeinterface #294,  1          // InterfaceMethod kotlin/text/MatchResult.getGroupValues:()Ljava/util/List;
     179: iconst_4
     180: invokeinterface #298,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     185: checkcast     #270                // class java/lang/String
     188: astore        15
     190: new           #104                // class day15/CavePoint$Sensor
     193: dup
     194: new           #134                // class Point
     197: dup
     198: aload         12
     200: invokestatic  #304                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     203: aload         13
     205: invokestatic  #304                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     208: invokespecial #228                // Method Point."<init>":(II)V
     211: new           #134                // class Point
     214: dup
     215: aload         14
     217: invokestatic  #304                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     220: aload         15
     222: invokestatic  #304                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     225: invokespecial #228                // Method Point."<init>":(II)V
     228: invokespecial #307                // Method day15/CavePoint$Sensor."<init>":(LPoint;LPoint;)V
     231: nop
     232: goto          250
     235: pop
     236: new           #309                // class java/lang/IllegalStateException
     239: dup
     240: ldc_w         #311                // String PARSER PROBLEM
     243: invokevirtual #315                // Method java/lang/Object.toString:()Ljava/lang/String;
     246: invokespecial #316                // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     249: athrow
     250: aload         16
     252: swap
     253: invokeinterface #108,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     258: pop
     259: goto          44
     262: aload         4
     264: checkcast     #70                 // class java/util/List
     267: nop
     268: checkcast     #81                 // class java/lang/Iterable
     271: invokestatic  #319                // Method kotlin/collections/CollectionsKt.toMutableSet:(Ljava/lang/Iterable;)Ljava/util/Set;
     274: areturn

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

  static {};
    Code:
       0: new           #274                // class kotlin/text/Regex
       3: dup
       4: ldc_w         #335                // String .+x=(-?\\d+).*y=(-?\\d+):.*x=(-?\\d+).*y=(-?\\d+)
       7: invokespecial #336                // Method kotlin/text/Regex."<init>":(Ljava/lang/String;)V
      10: putstatic     #11                 // Field regex:Lkotlin/text/Regex;
      13: new           #192                // class kotlin/ranges/IntRange
      16: dup
      17: iconst_0
      18: ldc_w         #337                // int 4000000
      21: invokespecial #227                // Method kotlin/ranges/IntRange."<init>":(II)V
      24: putstatic     #17                 // Field prd_range:Lkotlin/ranges/IntRange;
      27: new           #192                // class kotlin/ranges/IntRange
      30: dup
      31: iconst_0
      32: bipush        20
      34: invokespecial #227                // Method kotlin/ranges/IntRange."<init>":(II)V
      37: putstatic     #21                 // Field test_range:Lkotlin/ranges/IntRange;
      40: return
}

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

  public final int compare(T, T);
    Code:
       0: aload_1
       1: checkcast     #23                 // class kotlin/ranges/IntRange
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method kotlin/ranges/IntRange.getFirst:()I
      12: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_2
      19: checkcast     #23                 // class kotlin/ranges/IntRange
      22: astore_3
      23: astore        5
      25: iconst_0
      26: istore        4
      28: aload_3
      29: invokevirtual #27                 // Method kotlin/ranges/IntRange.getFirst:()I
      32: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      35: aload         5
      37: swap
      38: checkcast     #35                 // class java/lang/Comparable
      41: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      44: ireturn
}


package day14

import kotlin.math.max
import kotlin.math.min
import readInput

private typealias Cave = MutableSet<Point>
private typealias Rock = Point
private typealias Grain = Point

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

private val source = Point(500, 0)

fun main() {
    val input = readInput("main/day14/Day14_test")
    println(part1(input))
    println(part2(input))
}

fun part1(input: List<String>): Int {

    val cave = input.parseTosSolidRock()
    return cave.pourSand()
}

fun part2(input: List<String>): Int {
    val cave = input.parseTosSolidRock()
    val maxX = cave.maxOf { it.x } //.also { println("max x: $it") }
    val minX = cave.minOf { it.x } //.also { println("min x: $it") }

    val floorY = cave.maxOf { it.y } + 2
    cave.addRock(Point(minX - 1500, floorY), Point(maxX + 1500, floorY))

    return cave.pourSand()
}

private fun Cave.pourSand(): Int {
    val startSize = size
    do {
        val droppedGrain = source.fall(this)
        if (droppedGrain != null) add(droppedGrain)
        if (size % 1000 == 0) println(size)
    } while (droppedGrain != null)
    return size - startSize
}

private fun Grain.fall(cave: Cave): Grain? {
    if (cave.contains(source))
        return null

    if (down().y > cave.maxOf { it.y }) return null

    if (!cave.contains(down())) return down().fall(cave)
    if (!cave.contains(downLeft())) return downLeft().fall(cave)
    if (!cave.contains(downRight())) return downRight().fall(cave)

    return this
}

private fun Cave.addRock(start: Point, end: Point) {
    val startX = min(start.x, end.x)
    val startY = min(start.y, end.y)
    val endX = max(start.x, end.x)
    val endY = max(start.y, end.y)

    (startX..endX).forEach { x ->
        (startY..endY).forEach { y ->
            add(Rock(x, y))
        }
    }
}

private fun List<String>.parseTosSolidRock(): Cave {
    val cave = mutableSetOf<Point>()

    map { line ->
        line.split(" -> ")
            .map { it.split(", ") }
            .windowed(2) { (start, end) ->
                cave.addRock(
                    rock(start.first()),
                    rock(end.first())
                )
            }
    }
    return cave
}

private fun rock(point: String): Rock {
    return point.split(",").map { it.toInt() }.let { (x, y) ->
        Point(x, y)
    }
}

private fun Grain.down() = copy(y = y + 1)
private fun Grain.downLeft() = copy(x = x - 1, y = y + 1)
private fun Grain.downRight() = copy(x = x + 1, y = y + 1)

Compiled from "day14.kt"
public final class day14.Day14Kt {
  private static final day14.Point source;

  public static final void main();
    Code:
       0: ldc           #8                  // String main/day14/Day14_test
       2: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #18                 // Method part1:(Ljava/util/List;)I
      10: istore_1
      11: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
      14: iload_1
      15: invokevirtual #30                 // Method java/io/PrintStream.println:(I)V
      18: aload_0
      19: invokestatic  #33                 // Method part2:(Ljava/util/List;)I
      22: istore_1
      23: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: iload_1
      27: invokevirtual #30                 // Method java/io/PrintStream.println:(I)V
      30: return

  public static final int part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #38                 // String input
       3: invokestatic  #44                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #48                 // Method parseTosSolidRock:(Ljava/util/List;)Ljava/util/Set;
      10: astore_1
      11: aload_1
      12: invokestatic  #52                 // Method pourSand:(Ljava/util/Set;)I
      15: ireturn

  public static final int part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #38                 // String input
       3: invokestatic  #44                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #48                 // Method parseTosSolidRock:(Ljava/util/List;)Ljava/util/Set;
      10: astore_1
      11: aload_1
      12: checkcast     #56                 // class java/lang/Iterable
      15: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      20: astore        4
      22: aload         4
      24: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      29: ifne          40
      32: new           #68                 // class java/util/NoSuchElementException
      35: dup
      36: invokespecial #71                 // Method java/util/NoSuchElementException."<init>":()V
      39: athrow
      40: aload         4
      42: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      47: checkcast     #77                 // class day14/Point
      50: astore        5
      52: iconst_0
      53: istore        6
      55: aload         5
      57: invokevirtual #81                 // Method day14/Point.getX:()I
      60: istore        5
      62: aload         4
      64: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      69: ifeq          108
      72: aload         4
      74: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      79: checkcast     #77                 // class day14/Point
      82: astore        6
      84: iconst_0
      85: istore        7
      87: aload         6
      89: invokevirtual #81                 // Method day14/Point.getX:()I
      92: istore        6
      94: iload         5
      96: iload         6
      98: if_icmpge     62
     101: iload         6
     103: istore        5
     105: goto          62
     108: iload         5
     110: istore_2
     111: aload_1
     112: checkcast     #56                 // class java/lang/Iterable
     115: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     120: astore        5
     122: aload         5
     124: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     129: ifne          140
     132: new           #68                 // class java/util/NoSuchElementException
     135: dup
     136: invokespecial #71                 // Method java/util/NoSuchElementException."<init>":()V
     139: athrow
     140: aload         5
     142: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     147: checkcast     #77                 // class day14/Point
     150: astore        6
     152: iconst_0
     153: istore        7
     155: aload         6
     157: invokevirtual #81                 // Method day14/Point.getX:()I
     160: istore        6
     162: aload         5
     164: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     169: ifeq          208
     172: aload         5
     174: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     179: checkcast     #77                 // class day14/Point
     182: astore        7
     184: iconst_0
     185: istore        8
     187: aload         7
     189: invokevirtual #81                 // Method day14/Point.getX:()I
     192: istore        7
     194: iload         6
     196: iload         7
     198: if_icmple     162
     201: iload         7
     203: istore        6
     205: goto          162
     208: iload         6
     210: istore_3
     211: aload_1
     212: checkcast     #56                 // class java/lang/Iterable
     215: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     220: astore        6
     222: aload         6
     224: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     229: ifne          240
     232: new           #68                 // class java/util/NoSuchElementException
     235: dup
     236: invokespecial #71                 // Method java/util/NoSuchElementException."<init>":()V
     239: athrow
     240: aload         6
     242: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     247: checkcast     #77                 // class day14/Point
     250: astore        7
     252: iconst_0
     253: istore        8
     255: aload         7
     257: invokevirtual #84                 // Method day14/Point.getY:()I
     260: istore        7
     262: aload         6
     264: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     269: ifeq          308
     272: aload         6
     274: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     279: checkcast     #77                 // class day14/Point
     282: astore        8
     284: iconst_0
     285: istore        9
     287: aload         8
     289: invokevirtual #84                 // Method day14/Point.getY:()I
     292: istore        8
     294: iload         7
     296: iload         8
     298: if_icmpge     262
     301: iload         8
     303: istore        7
     305: goto          262
     308: iload         7
     310: iconst_2
     311: iadd
     312: istore        4
     314: aload_1
     315: new           #77                 // class day14/Point
     318: dup
     319: iload_3
     320: sipush        1500
     323: isub
     324: iload         4
     326: invokespecial #87                 // Method day14/Point."<init>":(II)V
     329: new           #77                 // class day14/Point
     332: dup
     333: iload_2
     334: sipush        1500
     337: iadd
     338: iload         4
     340: invokespecial #87                 // Method day14/Point."<init>":(II)V
     343: invokestatic  #91                 // Method addRock:(Ljava/util/Set;Lday14/Point;Lday14/Point;)V
     346: aload_1
     347: invokestatic  #52                 // Method pourSand:(Ljava/util/Set;)I
     350: ireturn

  private static final int pourSand(java.util.Set<day14.Point>);
    Code:
       0: aload_0
       1: invokeinterface #108,  1          // InterfaceMethod java/util/Set.size:()I
       6: istore_1
       7: getstatic     #111                // Field source:Lday14/Point;
      10: aload_0
      11: invokestatic  #115                // Method fall:(Lday14/Point;Ljava/util/Set;)Lday14/Point;
      14: astore_2
      15: aload_2
      16: ifnull        27
      19: aload_0
      20: aload_2
      21: invokeinterface #119,  2          // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
      26: pop
      27: aload_0
      28: invokeinterface #108,  1          // InterfaceMethod java/util/Set.size:()I
      33: sipush        1000
      36: irem
      37: ifne          54
      40: aload_0
      41: invokeinterface #108,  1          // InterfaceMethod java/util/Set.size:()I
      46: istore_3
      47: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
      50: iload_3
      51: invokevirtual #30                 // Method java/io/PrintStream.println:(I)V
      54: aload_2
      55: ifnonnull     7
      58: aload_0
      59: invokeinterface #108,  1          // InterfaceMethod java/util/Set.size:()I
      64: iload_1
      65: isub
      66: ireturn

  private static final day14.Point fall(day14.Point, java.util.Set<day14.Point>);
    Code:
       0: aload_1
       1: getstatic     #111                // Field source:Lday14/Point;
       4: invokeinterface #126,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
       9: ifeq          14
      12: aconst_null
      13: areturn
      14: aload_0
      15: invokestatic  #130                // Method down:(Lday14/Point;)Lday14/Point;
      18: invokevirtual #84                 // Method day14/Point.getY:()I
      21: aload_1
      22: checkcast     #56                 // class java/lang/Iterable
      25: astore_2
      26: istore        7
      28: aload_2
      29: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      34: astore_3
      35: aload_3
      36: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      41: ifne          52
      44: new           #68                 // class java/util/NoSuchElementException
      47: dup
      48: invokespecial #71                 // Method java/util/NoSuchElementException."<init>":()V
      51: athrow
      52: aload_3
      53: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      58: checkcast     #77                 // class day14/Point
      61: astore        4
      63: iconst_0
      64: istore        5
      66: aload         4
      68: invokevirtual #84                 // Method day14/Point.getY:()I
      71: istore        4
      73: aload_3
      74: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      79: ifeq          117
      82: aload_3
      83: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      88: checkcast     #77                 // class day14/Point
      91: astore        5
      93: iconst_0
      94: istore        6
      96: aload         5
      98: invokevirtual #84                 // Method day14/Point.getY:()I
     101: istore        5
     103: iload         4
     105: iload         5
     107: if_icmpge     73
     110: iload         5
     112: istore        4
     114: goto          73
     117: iload         4
     119: istore        8
     121: iload         7
     123: iload         8
     125: if_icmple     130
     128: aconst_null
     129: areturn
     130: aload_1
     131: aload_0
     132: invokestatic  #130                // Method down:(Lday14/Point;)Lday14/Point;
     135: invokeinterface #126,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     140: ifne          152
     143: aload_0
     144: invokestatic  #130                // Method down:(Lday14/Point;)Lday14/Point;
     147: aload_1
     148: invokestatic  #115                // Method fall:(Lday14/Point;Ljava/util/Set;)Lday14/Point;
     151: areturn
     152: aload_1
     153: aload_0
     154: invokestatic  #133                // Method downLeft:(Lday14/Point;)Lday14/Point;
     157: invokeinterface #126,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     162: ifne          174
     165: aload_0
     166: invokestatic  #133                // Method downLeft:(Lday14/Point;)Lday14/Point;
     169: aload_1
     170: invokestatic  #115                // Method fall:(Lday14/Point;Ljava/util/Set;)Lday14/Point;
     173: areturn
     174: aload_1
     175: aload_0
     176: invokestatic  #136                // Method downRight:(Lday14/Point;)Lday14/Point;
     179: invokeinterface #126,  2          // InterfaceMethod java/util/Set.contains:(Ljava/lang/Object;)Z
     184: ifne          196
     187: aload_0
     188: invokestatic  #136                // Method downRight:(Lday14/Point;)Lday14/Point;
     191: aload_1
     192: invokestatic  #115                // Method fall:(Lday14/Point;Ljava/util/Set;)Lday14/Point;
     195: areturn
     196: aload_0
     197: areturn

  private static final void addRock(java.util.Set<day14.Point>, day14.Point, day14.Point);
    Code:
       0: aload_1
       1: invokevirtual #81                 // Method day14/Point.getX:()I
       4: aload_2
       5: invokevirtual #81                 // Method day14/Point.getX:()I
       8: invokestatic  #145                // Method java/lang/Math.min:(II)I
      11: istore_3
      12: aload_1
      13: invokevirtual #84                 // Method day14/Point.getY:()I
      16: aload_2
      17: invokevirtual #84                 // Method day14/Point.getY:()I
      20: invokestatic  #145                // Method java/lang/Math.min:(II)I
      23: istore        4
      25: aload_1
      26: invokevirtual #81                 // Method day14/Point.getX:()I
      29: aload_2
      30: invokevirtual #81                 // Method day14/Point.getX:()I
      33: invokestatic  #148                // Method java/lang/Math.max:(II)I
      36: istore        5
      38: aload_1
      39: invokevirtual #84                 // Method day14/Point.getY:()I
      42: aload_2
      43: invokevirtual #84                 // Method day14/Point.getY:()I
      46: invokestatic  #148                // Method java/lang/Math.max:(II)I
      49: istore        6
      51: new           #150                // class kotlin/ranges/IntRange
      54: dup
      55: iload_3
      56: iload         5
      58: invokespecial #151                // Method kotlin/ranges/IntRange."<init>":(II)V
      61: checkcast     #56                 // class java/lang/Iterable
      64: astore        7
      66: iconst_0
      67: istore        8
      69: aload         7
      71: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      76: astore        9
      78: aload         9
      80: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      85: ifeq          189
      88: aload         9
      90: checkcast     #153                // class kotlin/collections/IntIterator
      93: invokevirtual #156                // Method kotlin/collections/IntIterator.nextInt:()I
      96: istore        10
      98: iload         10
     100: istore        11
     102: iconst_0
     103: istore        12
     105: new           #150                // class kotlin/ranges/IntRange
     108: dup
     109: iload         4
     111: iload         6
     113: invokespecial #151                // Method kotlin/ranges/IntRange."<init>":(II)V
     116: checkcast     #56                 // class java/lang/Iterable
     119: astore        13
     121: iconst_0
     122: istore        14
     124: aload         13
     126: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     131: astore        15
     133: aload         15
     135: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     140: ifeq          183
     143: aload         15
     145: checkcast     #153                // class kotlin/collections/IntIterator
     148: invokevirtual #156                // Method kotlin/collections/IntIterator.nextInt:()I
     151: istore        16
     153: iload         16
     155: istore        17
     157: iconst_0
     158: istore        18
     160: aload_0
     161: new           #77                 // class day14/Point
     164: dup
     165: iload         11
     167: iload         17
     169: invokespecial #87                 // Method day14/Point."<init>":(II)V
     172: invokeinterface #119,  2          // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
     177: pop
     178: nop
     179: nop
     180: goto          133
     183: nop
     184: nop
     185: nop
     186: goto          78
     189: nop
     190: return

  private static final java.util.Set<day14.Point> parseTosSolidRock(java.util.List<java.lang.String>);
    Code:
       0: new           #174                // class java/util/LinkedHashSet
       3: dup
       4: invokespecial #175                // Method java/util/LinkedHashSet."<init>":()V
       7: checkcast     #104                // class java/util/Set
      10: astore_1
      11: aload_0
      12: checkcast     #56                 // class java/lang/Iterable
      15: astore_2
      16: iconst_0
      17: istore_3
      18: aload_2
      19: astore        4
      21: new           #177                // class java/util/ArrayList
      24: dup
      25: aload_2
      26: bipush        10
      28: invokestatic  #183                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      31: invokespecial #185                // Method java/util/ArrayList."<init>":(I)V
      34: checkcast     #187                // class java/util/Collection
      37: astore        5
      39: iconst_0
      40: istore        6
      42: aload         4
      44: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      49: astore        7
      51: aload         7
      53: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      58: ifeq          264
      61: aload         7
      63: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      68: astore        8
      70: aload         5
      72: aload         8
      74: checkcast     #189                // class java/lang/String
      77: astore        9
      79: astore        22
      81: iconst_0
      82: istore        10
      84: aload         9
      86: checkcast     #191                // class java/lang/CharSequence
      89: iconst_1
      90: anewarray     #189                // class java/lang/String
      93: astore        11
      95: aload         11
      97: iconst_0
      98: ldc           #193                // String  ->
     100: aastore
     101: aload         11
     103: iconst_0
     104: iconst_0
     105: bipush        6
     107: aconst_null
     108: invokestatic  #199                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     111: checkcast     #56                 // class java/lang/Iterable
     114: astore        11
     116: nop
     117: iconst_0
     118: istore        12
     120: aload         11
     122: astore        13
     124: new           #177                // class java/util/ArrayList
     127: dup
     128: aload         11
     130: bipush        10
     132: invokestatic  #183                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     135: invokespecial #185                // Method java/util/ArrayList."<init>":(I)V
     138: checkcast     #187                // class java/util/Collection
     141: astore        14
     143: iconst_0
     144: istore        15
     146: aload         13
     148: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     153: astore        16
     155: aload         16
     157: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     162: ifeq          227
     165: aload         16
     167: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     172: astore        17
     174: aload         14
     176: aload         17
     178: checkcast     #189                // class java/lang/String
     181: astore        18
     183: astore        19
     185: iconst_0
     186: istore        20
     188: aload         18
     190: checkcast     #191                // class java/lang/CharSequence
     193: iconst_1
     194: anewarray     #189                // class java/lang/String
     197: astore        21
     199: aload         21
     201: iconst_0
     202: ldc           #201                // String ,
     204: aastore
     205: aload         21
     207: iconst_0
     208: iconst_0
     209: bipush        6
     211: aconst_null
     212: invokestatic  #199                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     215: aload         19
     217: swap
     218: invokeinterface #202,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     223: pop
     224: goto          155
     227: aload         14
     229: checkcast     #102                // class java/util/List
     232: nop
     233: checkcast     #56                 // class java/lang/Iterable
     236: iconst_2
     237: iconst_0
     238: iconst_0
     239: aload_1
     240: invokedynamic #222,  0            // InvokeDynamic #0:invoke:(Ljava/util/Set;)Lkotlin/jvm/functions/Function1;
     245: bipush        6
     247: aconst_null
     248: invokestatic  #226                // Method kotlin/collections/CollectionsKt.windowed$default:(Ljava/lang/Iterable;IIZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/util/List;
     251: nop
     252: aload         22
     254: swap
     255: invokeinterface #202,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     260: pop
     261: goto          51
     264: aload         5
     266: checkcast     #102                // class java/util/List
     269: nop
     270: pop
     271: aload_1
     272: areturn

  private static final day14.Point rock(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #191                // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #189                // class java/lang/String
       8: astore_1
       9: aload_1
      10: iconst_0
      11: ldc           #243                // String ,
      13: aastore
      14: aload_1
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #199                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: checkcast     #56                 // class java/lang/Iterable
      26: astore_1
      27: iconst_0
      28: istore_2
      29: aload_1
      30: astore_3
      31: new           #177                // class java/util/ArrayList
      34: dup
      35: aload_1
      36: bipush        10
      38: invokestatic  #183                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      41: invokespecial #185                // Method java/util/ArrayList."<init>":(I)V
      44: checkcast     #187                // class java/util/Collection
      47: astore        4
      49: iconst_0
      50: istore        5
      52: aload_3
      53: invokeinterface #60,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      58: astore        6
      60: aload         6
      62: invokeinterface #66,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      67: ifeq          114
      70: aload         6
      72: invokeinterface #75,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      77: astore        7
      79: aload         4
      81: aload         7
      83: checkcast     #189                // class java/lang/String
      86: astore        8
      88: astore        10
      90: iconst_0
      91: istore        9
      93: aload         8
      95: invokestatic  #249                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      98: nop
      99: invokestatic  #253                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     102: aload         10
     104: swap
     105: invokeinterface #202,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     110: pop
     111: goto          60
     114: aload         4
     116: checkcast     #102                // class java/util/List
     119: nop
     120: astore_2
     121: iconst_0
     122: istore_3
     123: aload_2
     124: iconst_0
     125: invokeinterface #257,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     130: checkcast     #259                // class java/lang/Number
     133: invokevirtual #262                // Method java/lang/Number.intValue:()I
     136: istore        4
     138: aload_2
     139: iconst_1
     140: invokeinterface #257,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     145: checkcast     #259                // class java/lang/Number
     148: invokevirtual #262                // Method java/lang/Number.intValue:()I
     151: istore        5
     153: new           #77                 // class day14/Point
     156: dup
     157: iload         4
     159: iload         5
     161: invokespecial #87                 // Method day14/Point."<init>":(II)V
     164: nop
     165: areturn

  private static final day14.Point down(day14.Point);
    Code:
       0: aload_0
       1: iconst_0
       2: aload_0
       3: invokevirtual #84                 // Method day14/Point.getY:()I
       6: iconst_1
       7: iadd
       8: iconst_1
       9: aconst_null
      10: invokestatic  #269                // Method day14/Point.copy$default:(Lday14/Point;IIILjava/lang/Object;)Lday14/Point;
      13: areturn

  private static final day14.Point downLeft(day14.Point);
    Code:
       0: aload_0
       1: aload_0
       2: invokevirtual #81                 // Method day14/Point.getX:()I
       5: iconst_1
       6: isub
       7: aload_0
       8: invokevirtual #84                 // Method day14/Point.getY:()I
      11: iconst_1
      12: iadd
      13: invokevirtual #274                // Method day14/Point.copy:(II)Lday14/Point;
      16: areturn

  private static final day14.Point downRight(day14.Point);
    Code:
       0: aload_0
       1: aload_0
       2: invokevirtual #81                 // Method day14/Point.getX:()I
       5: iconst_1
       6: iadd
       7: aload_0
       8: invokevirtual #84                 // Method day14/Point.getY:()I
      11: iconst_1
      12: iadd
      13: invokevirtual #274                // Method day14/Point.copy:(II)Lday14/Point;
      16: areturn

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

  private static final kotlin.Unit parseTosSolidRock$lambda$8$lambda$7(java.util.Set, java.util.List);
    Code:
       0: aload_1
       1: ldc_w         #283                // String <destruct>
       4: invokestatic  #44                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_1
       8: iconst_0
       9: invokeinterface #257,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      14: checkcast     #102                // class java/util/List
      17: astore_2
      18: aload_1
      19: iconst_1
      20: invokeinterface #257,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      25: checkcast     #102                // class java/util/List
      28: astore_3
      29: aload_0
      30: aload_2
      31: invokestatic  #287                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      34: checkcast     #189                // class java/lang/String
      37: invokestatic  #289                // Method rock:(Ljava/lang/String;)Lday14/Point;
      40: aload_3
      41: invokestatic  #287                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      44: checkcast     #189                // class java/lang/String
      47: invokestatic  #289                // Method rock:(Ljava/lang/String;)Lday14/Point;
      50: invokestatic  #91                 // Method addRock:(Ljava/util/Set;Lday14/Point;Lday14/Point;)V
      53: getstatic     #295                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      56: areturn

  static {};
    Code:
       0: new           #77                 // class day14/Point
       3: dup
       4: sipush        500
       7: iconst_0
       8: invokespecial #87                 // Method day14/Point."<init>":(II)V
      11: putstatic     #111                // Field source:Lday14/Point;
      14: return
}


package day13

import java.util.*
import readInput
import second

sealed interface Packet : Comparable<Packet> {
    data class ListPacket(val packets: MutableList<Packet> = mutableListOf()) : Packet {

        override fun compareTo(other: Packet): Int {
            return when (other) {
                is IntPacket -> this.compareTo(other.toListPacket())
                is ListPacket -> packets.compareTo(other.packets)
            }
        }

        private fun Iterable<Packet>.compareTo(other: Iterable<Packet>): Int {
            val left = Stack<Packet>()
            this.reversed().forEach { left.push(it) }
            val right = Stack<Packet>()
            other.reversed().forEach { right.push(it) }

            while (left.isNotEmpty()) {
                val l = left.pop()
                val r = if (right.isNotEmpty()) right.pop() else return 1
                val comp = l.compareTo(r)
                if (comp != 0) return comp
            }
            // left is empty is right also empty?
            return if (right.isEmpty()) 0 else -1
        }
    }

    data class IntPacket(val value: Int) : Packet {
        override fun compareTo(other: Packet): Int {
            return when (other) {
                is ListPacket -> toListPacket().compareTo(other)
                is IntPacket -> value.compareTo(other.value)
            }
        }
    }

    fun toListPacket(): Packet = ListPacket(mutableListOf(this))

    companion object {
        fun parse(input: String): Packet =
            toPacket(
                input.split("""((?<=[\[\],])|(?=[\[\],]))""".toRegex())
                    .filter { it.isNotBlank() }
                    .filterNot { it == "," }
                    .iterator()
            )

        private fun toPacket(input: Iterator<String>): Packet {
            val packets = mutableListOf<Packet>()
            while (input.hasNext()) {
                when (val symbol = input.next()) {
                    "]" -> return ListPacket(packets)
                    "[" -> packets.add(toPacket(input))
                    else -> packets.add(IntPacket(symbol.toInt()))
                }
            }
            return ListPacket(packets)
        }
    }
}

fun main() {
    val input = readInput("main/day13/Day13")
    println(part1(input))
    println(part2(input))
}

fun part1(input: List<String>): Int {
    val list = input.filter(String::isNotBlank).map {
        Packet.parse(it)
    }.chunked(2)

    return list.mapIndexed { index, signals ->
        if (signals.first() < signals.second())
            index + 1
        else
            0
    }.sum()
}

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

    val firstDivider = Packet.parse("[[2]]")
    val secondDivider = Packet.parse("[[6]]")

    val list = (input.filter(String::isNotBlank).map {
        Packet.parse(it)
    } + listOf(firstDivider, secondDivider)).sorted()

    return (list.indexOf(firstDivider) + 1) * (list.indexOf(secondDivider) + 1)
}

Compiled from "day13.kt"
public final class day13.Day13Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String main/day13/Day13
       2: invokestatic  #14                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #18                 // Method part1:(Ljava/util/List;)I
      10: istore_1
      11: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
      14: iload_1
      15: invokevirtual #30                 // Method java/io/PrintStream.println:(I)V
      18: aload_0
      19: invokestatic  #33                 // Method part2:(Ljava/util/List;)I
      22: istore_1
      23: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: iload_1
      27: invokevirtual #30                 // Method java/io/PrintStream.println:(I)V
      30: return

  public static final int part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #38                 // String input
       3: invokestatic  #44                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #46                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: astore        4
      16: new           #48                 // class java/util/ArrayList
      19: dup
      20: invokespecial #51                 // Method java/util/ArrayList."<init>":()V
      23: checkcast     #53                 // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          102
      50: aload         7
      52: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         8
      61: checkcast     #69                 // class java/lang/String
      64: astore        9
      66: iconst_0
      67: istore        10
      69: aload         9
      71: checkcast     #71                 // class java/lang/CharSequence
      74: invokestatic  #77                 // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
      77: ifne          84
      80: iconst_1
      81: goto          85
      84: iconst_0
      85: nop
      86: ifeq          40
      89: aload         5
      91: aload         8
      93: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      98: pop
      99: goto          40
     102: aload         5
     104: checkcast     #83                 // class java/util/List
     107: nop
     108: checkcast     #46                 // class java/lang/Iterable
     111: astore_2
     112: nop
     113: iconst_0
     114: istore_3
     115: aload_2
     116: astore        4
     118: new           #48                 // class java/util/ArrayList
     121: dup
     122: aload_2
     123: bipush        10
     125: invokestatic  #89                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     128: invokespecial #91                 // Method java/util/ArrayList."<init>":(I)V
     131: checkcast     #53                 // class java/util/Collection
     134: astore        5
     136: iconst_0
     137: istore        6
     139: aload         4
     141: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     146: astore        7
     148: aload         7
     150: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     155: ifeq          201
     158: aload         7
     160: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     165: astore        8
     167: aload         5
     169: aload         8
     171: checkcast     #69                 // class java/lang/String
     174: astore        9
     176: astore        14
     178: iconst_0
     179: istore        10
     181: getstatic     #97                 // Field day13/Packet.Companion:Lday13/Packet$Companion;
     184: aload         9
     186: invokevirtual #103                // Method day13/Packet$Companion.parse:(Ljava/lang/String;)Lday13/Packet;
     189: aload         14
     191: swap
     192: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     197: pop
     198: goto          148
     201: aload         5
     203: checkcast     #83                 // class java/util/List
     206: nop
     207: checkcast     #46                 // class java/lang/Iterable
     210: iconst_2
     211: invokestatic  #107                // Method kotlin/collections/CollectionsKt.chunked:(Ljava/lang/Iterable;I)Ljava/util/List;
     214: astore_1
     215: aload_1
     216: checkcast     #46                 // class java/lang/Iterable
     219: astore_2
     220: iconst_0
     221: istore_3
     222: aload_2
     223: astore        4
     225: new           #48                 // class java/util/ArrayList
     228: dup
     229: aload_2
     230: bipush        10
     232: invokestatic  #89                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     235: invokespecial #91                 // Method java/util/ArrayList."<init>":(I)V
     238: checkcast     #53                 // class java/util/Collection
     241: astore        5
     243: iconst_0
     244: istore        6
     246: iconst_0
     247: istore        7
     249: aload         4
     251: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     256: astore        8
     258: aload         8
     260: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     265: ifeq          354
     268: aload         8
     270: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     275: astore        9
     277: aload         5
     279: iload         7
     281: iinc          7, 1
     284: istore        10
     286: iload         10
     288: ifge          294
     291: invokestatic  #110                // Method kotlin/collections/CollectionsKt.throwIndexOverflow:()V
     294: iload         10
     296: aload         9
     298: checkcast     #83                 // class java/util/List
     301: astore        11
     303: istore        12
     305: astore        14
     307: iconst_0
     308: istore        13
     310: aload         11
     312: invokestatic  #114                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     315: checkcast     #93                 // class day13/Packet
     318: aload         11
     320: invokestatic  #117                // Method UtilsKt.second:(Ljava/util/List;)Ljava/lang/Object;
     323: invokeinterface #121,  2          // InterfaceMethod day13/Packet.compareTo:(Ljava/lang/Object;)I
     328: ifge          338
     331: iload         12
     333: iconst_1
     334: iadd
     335: goto          339
     338: iconst_0
     339: invokestatic  #127                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     342: aload         14
     344: swap
     345: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     350: pop
     351: goto          258
     354: aload         5
     356: checkcast     #83                 // class java/util/List
     359: nop
     360: checkcast     #46                 // class java/lang/Iterable
     363: invokestatic  #131                // Method kotlin/collections/CollectionsKt.sumOfInt:(Ljava/lang/Iterable;)I
     366: ireturn

  public static final int part2(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #38                 // String input
       3: invokestatic  #44                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #97                 // Field day13/Packet.Companion:Lday13/Packet$Companion;
       9: ldc           #162                // String [[2]]
      11: invokevirtual #103                // Method day13/Packet$Companion.parse:(Ljava/lang/String;)Lday13/Packet;
      14: astore_1
      15: getstatic     #97                 // Field day13/Packet.Companion:Lday13/Packet$Companion;
      18: ldc           #164                // String [[6]]
      20: invokevirtual #103                // Method day13/Packet$Companion.parse:(Ljava/lang/String;)Lday13/Packet;
      23: astore_2
      24: aload_0
      25: checkcast     #46                 // class java/lang/Iterable
      28: astore        4
      30: iconst_0
      31: istore        5
      33: aload         4
      35: astore        6
      37: new           #48                 // class java/util/ArrayList
      40: dup
      41: invokespecial #51                 // Method java/util/ArrayList."<init>":()V
      44: checkcast     #53                 // class java/util/Collection
      47: astore        7
      49: iconst_0
      50: istore        8
      52: aload         6
      54: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      59: astore        9
      61: aload         9
      63: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      68: ifeq          123
      71: aload         9
      73: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      78: astore        10
      80: aload         10
      82: checkcast     #69                 // class java/lang/String
      85: astore        11
      87: iconst_0
      88: istore        12
      90: aload         11
      92: checkcast     #71                 // class java/lang/CharSequence
      95: invokestatic  #77                 // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
      98: ifne          105
     101: iconst_1
     102: goto          106
     105: iconst_0
     106: nop
     107: ifeq          61
     110: aload         7
     112: aload         10
     114: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     119: pop
     120: goto          61
     123: aload         7
     125: checkcast     #83                 // class java/util/List
     128: nop
     129: checkcast     #46                 // class java/lang/Iterable
     132: astore        4
     134: nop
     135: iconst_0
     136: istore        5
     138: aload         4
     140: astore        6
     142: new           #48                 // class java/util/ArrayList
     145: dup
     146: aload         4
     148: bipush        10
     150: invokestatic  #89                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     153: invokespecial #91                 // Method java/util/ArrayList."<init>":(I)V
     156: checkcast     #53                 // class java/util/Collection
     159: astore        7
     161: iconst_0
     162: istore        8
     164: aload         6
     166: invokeinterface #57,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     171: astore        9
     173: aload         9
     175: invokeinterface #63,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     180: ifeq          226
     183: aload         9
     185: invokeinterface #67,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     190: astore        10
     192: aload         7
     194: aload         10
     196: checkcast     #69                 // class java/lang/String
     199: astore        11
     201: astore        13
     203: iconst_0
     204: istore        12
     206: getstatic     #97                 // Field day13/Packet.Companion:Lday13/Packet$Companion;
     209: aload         11
     211: invokevirtual #103                // Method day13/Packet$Companion.parse:(Ljava/lang/String;)Lday13/Packet;
     214: aload         13
     216: swap
     217: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     222: pop
     223: goto          173
     226: aload         7
     228: checkcast     #83                 // class java/util/List
     231: nop
     232: checkcast     #53                 // class java/util/Collection
     235: iconst_2
     236: anewarray     #93                 // class day13/Packet
     239: astore        4
     241: aload         4
     243: iconst_0
     244: aload_1
     245: aastore
     246: aload         4
     248: iconst_1
     249: aload_2
     250: aastore
     251: aload         4
     253: invokestatic  #168                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     256: checkcast     #46                 // class java/lang/Iterable
     259: invokestatic  #172                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     262: checkcast     #46                 // class java/lang/Iterable
     265: invokestatic  #176                // Method kotlin/collections/CollectionsKt.sorted:(Ljava/lang/Iterable;)Ljava/util/List;
     268: astore_3
     269: aload_3
     270: aload_1
     271: invokeinterface #179,  2          // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
     276: iconst_1
     277: iadd
     278: aload_3
     279: aload_2
     280: invokeinterface #179,  2          // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
     285: iconst_1
     286: iadd
     287: imul
     288: ireturn

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


package day25

import kotlin.math.pow
import kotlin.math.roundToLong
import readInput

val UNSNAFU = mapOf(
    "=" to -2.0,
    "-" to -1.0,
    "0" to 0.0,
    "1" to 1.0,
    "2" to 2.0,
)

fun main() {
    val input = readInput("main/day25/Day25")

    println(part1(input))
}

fun part1(input: List<String>): String {

    val numbers = input.associateBy { it.unsnafucate() }

    return numbers.keys.sum().snafucate()
}

fun Long.snafucate(): String {
    return generateSequence(this) { (it + 2) / 5 }
        .takeWhile { it != 0L }.toList()
        .map { "012=-"[(it % 5).toInt()] }
        .joinToString("").reversed()
}

fun String.unsnafucate(): Long {
    return indices.sumOf {
        (5.0.pow(it) * UNSNAFU[this[length - it - 1].toString()]!!.toLong()).roundToLong()
    }
}

Compiled from "day25.kt"
public final class day25.Day25Kt {
  private static final java.util.Map<java.lang.String, java.lang.Double> UNSNAFU;

  public static final java.util.Map<java.lang.String, java.lang.Double> getUNSNAFU();
    Code:
       0: getstatic     #12                 // Field UNSNAFU:Ljava/util/Map;
       3: areturn

  public static final void main();
    Code:
       0: ldc           #16                 // String main/day25/Day25
       2: invokestatic  #22                 // Method UtilsKt.readInput:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: aload_0
       7: invokestatic  #26                 // Method part1:(Ljava/util/List;)Ljava/lang/String;
      10: getstatic     #32                 // Field java/lang/System.out:Ljava/io/PrintStream;
      13: swap
      14: invokevirtual #38                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      17: return

  public static final java.lang.String part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #42                 // String input
       3: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #50                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: bipush        10
      16: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      19: invokestatic  #62                 // Method kotlin/collections/MapsKt.mapCapacity:(I)I
      22: bipush        16
      24: invokestatic  #68                 // Method kotlin/ranges/RangesKt.coerceAtLeast:(II)I
      27: istore        4
      29: aload_2
      30: astore        5
      32: new           #70                 // class java/util/LinkedHashMap
      35: dup
      36: iload         4
      38: invokespecial #74                 // Method java/util/LinkedHashMap."<init>":(I)V
      41: checkcast     #76                 // class java/util/Map
      44: astore        6
      46: iconst_0
      47: istore        7
      49: aload         5
      51: invokeinterface #80,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      56: astore        8
      58: aload         8
      60: invokeinterface #86,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      65: ifeq          113
      68: aload         8
      70: invokeinterface #90,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      75: astore        9
      77: aload         6
      79: aload         9
      81: checkcast     #92                 // class java/lang/String
      84: astore        10
      86: astore        12
      88: iconst_0
      89: istore        11
      91: aload         10
      93: invokestatic  #96                 // Method unsnafucate:(Ljava/lang/String;)J
      96: invokestatic  #102                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      99: aload         12
     101: swap
     102: aload         9
     104: invokeinterface #106,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     109: pop
     110: goto          58
     113: aload         6
     115: nop
     116: astore_1
     117: aload_1
     118: invokeinterface #110,  1          // InterfaceMethod java/util/Map.keySet:()Ljava/util/Set;
     123: checkcast     #50                 // class java/lang/Iterable
     126: invokestatic  #114                // Method kotlin/collections/CollectionsKt.sumOfLong:(Ljava/lang/Iterable;)J
     129: invokestatic  #118                // Method snafucate:(J)Ljava/lang/String;
     132: areturn

  public static final java.lang.String snafucate(long);
    Code:
       0: lload_0
       1: invokestatic  #102                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
       4: invokedynamic #153,  0            // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
       9: invokestatic  #159                // Method kotlin/sequences/SequencesKt.generateSequence:(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      12: invokedynamic #167,  0            // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function1;
      17: invokestatic  #171                // Method kotlin/sequences/SequencesKt.takeWhile:(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
      20: invokestatic  #175                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
      23: checkcast     #50                 // class java/lang/Iterable
      26: astore_2
      27: nop
      28: iconst_0
      29: istore_3
      30: aload_2
      31: astore        4
      33: new           #177                // class java/util/ArrayList
      36: dup
      37: aload_2
      38: bipush        10
      40: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      43: invokespecial #178                // Method java/util/ArrayList."<init>":(I)V
      46: checkcast     #180                // class java/util/Collection
      49: astore        5
      51: iconst_0
      52: istore        6
      54: aload         4
      56: invokeinterface #80,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      61: astore        7
      63: aload         7
      65: invokeinterface #86,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      70: ifeq          125
      73: aload         7
      75: invokeinterface #90,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      80: astore        8
      82: aload         5
      84: aload         8
      86: checkcast     #182                // class java/lang/Number
      89: invokevirtual #186                // Method java/lang/Number.longValue:()J
      92: lstore        9
      94: astore        12
      96: iconst_0
      97: istore        11
      99: ldc           #188                // String 012=-
     101: lload         9
     103: iconst_5
     104: i2l
     105: lrem
     106: l2i
     107: invokevirtual #192                // Method java/lang/String.charAt:(I)C
     110: invokestatic  #197                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     113: aload         12
     115: swap
     116: invokeinterface #201,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     121: pop
     122: goto          63
     125: aload         5
     127: checkcast     #134                // class java/util/List
     130: nop
     131: checkcast     #50                 // class java/lang/Iterable
     134: ldc           #203                // String
     136: checkcast     #205                // class java/lang/CharSequence
     139: aconst_null
     140: aconst_null
     141: iconst_0
     142: aconst_null
     143: aconst_null
     144: bipush        62
     146: aconst_null
     147: invokestatic  #209                // 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;
     150: checkcast     #205                // class java/lang/CharSequence
     153: invokestatic  #215                // Method kotlin/text/StringsKt.reversed:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     156: invokevirtual #219                // Method java/lang/Object.toString:()Ljava/lang/String;
     159: areturn

  public static final long unsnafucate(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #230                // String <this>
       3: invokestatic  #48                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #205                // class java/lang/CharSequence
      10: invokestatic  #234                // Method kotlin/text/StringsKt.getIndices:(Ljava/lang/CharSequence;)Lkotlin/ranges/IntRange;
      13: checkcast     #50                 // class java/lang/Iterable
      16: astore_1
      17: lconst_0
      18: lstore_2
      19: aload_1
      20: invokeinterface #80,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      25: astore        4
      27: aload         4
      29: invokeinterface #86,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      34: ifeq          117
      37: aload         4
      39: checkcast     #236                // class kotlin/collections/IntIterator
      42: invokevirtual #240                // Method kotlin/collections/IntIterator.nextInt:()I
      45: istore        5
      47: lload_2
      48: iload         5
      50: istore        6
      52: lstore        8
      54: iconst_0
      55: istore        7
      57: ldc2_w        #241                // double 5.0d
      60: iload         6
      62: i2d
      63: invokestatic  #248                // Method java/lang/Math.pow:(DD)D
      66: getstatic     #12                 // Field UNSNAFU:Ljava/util/Map;
      69: aload_0
      70: aload_0
      71: invokevirtual #251                // Method java/lang/String.length:()I
      74: iload         6
      76: isub
      77: iconst_1
      78: isub
      79: invokevirtual #192                // Method java/lang/String.charAt:(I)C
      82: invokestatic  #254                // Method java/lang/String.valueOf:(C)Ljava/lang/String;
      85: invokeinterface #257,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      90: dup
      91: invokestatic  #260                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      94: checkcast     #182                // class java/lang/Number
      97: invokevirtual #264                // Method java/lang/Number.doubleValue:()D
     100: d2l
     101: l2d
     102: dmul
     103: invokestatic  #270                // Method kotlin/math/MathKt.roundToLong:(D)J
     106: lstore        10
     108: lload         8
     110: lload         10
     112: ladd
     113: lstore_2
     114: goto          27
     117: lload_2
     118: lreturn

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

  private static final java.lang.Long snafucate$lambda$1(long);
    Code:
       0: lload_0
       1: iconst_2
       2: i2l
       3: ladd
       4: iconst_5
       5: i2l
       6: ldiv
       7: invokestatic  #102                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      10: areturn

  private static final boolean snafucate$lambda$2(long);
    Code:
       0: lload_0
       1: lconst_0
       2: lcmp
       3: ifeq          10
       6: iconst_1
       7: goto          11
      10: iconst_0
      11: ireturn

  static {};
    Code:
       0: iconst_5
       1: anewarray     #280                // class kotlin/Pair
       4: astore_0
       5: aload_0
       6: iconst_0
       7: ldc_w         #282                // String =
      10: ldc2_w        #283                // double -2.0d
      13: invokestatic  #289                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      16: invokestatic  #295                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      19: aastore
      20: aload_0
      21: iconst_1
      22: ldc_w         #297                // String -
      25: ldc2_w        #298                // double -1.0d
      28: invokestatic  #289                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      31: invokestatic  #295                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      34: aastore
      35: aload_0
      36: iconst_2
      37: ldc_w         #301                // String 0
      40: dconst_0
      41: invokestatic  #289                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      44: invokestatic  #295                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      47: aastore
      48: aload_0
      49: iconst_3
      50: ldc_w         #303                // String 1
      53: dconst_1
      54: invokestatic  #289                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      57: invokestatic  #295                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      60: aastore
      61: aload_0
      62: iconst_4
      63: ldc_w         #305                // String 2
      66: ldc2_w        #306                // double 2.0d
      69: invokestatic  #289                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      72: invokestatic  #295                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      75: aastore
      76: aload_0
      77: invokestatic  #311                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
      80: putstatic     #12                 // Field UNSNAFU:Ljava/util/Map;
      83: return
}