package day24

import java.io.File
import kotlin.math.max

fun main() {
    val data = parse("src/day24/Day24.txt")

    println("🎄 Day 24 🎄")

    println()

    println("[Part 1]")
    println("Answer: ${part1(data)}")

    // For Part 2, see the Python implementation.
}

private data class Vec3(
    val x: Long,
    val y: Long,
    val z: Long,
)

private data class Hailstone(
    val position: Vec3,
    val velocity: Vec3,
)

private fun String.toHailstone(): Hailstone {
    val (lhs, rhs) = this.split(" @ ")

    val position = lhs.split(", ")
        .map(String::trim)
        .map(String::toLong)
        .let { (x, y, z) -> Vec3(x, y, z) }

    val velocity = rhs.split(", ")
        .map(String::trim)
        .map(String::toLong)
        .let { (x, y, z) -> Vec3(x, y, z) }

    return Hailstone(position, velocity)
}

private fun parse(path: String): List<Hailstone> =
    File(path)
        .readLines()
        .map(String::toHailstone)

private fun intersect(a: Hailstone, b: Hailstone, min: Long, max: Long): Boolean {
    val dx = (b.position.x - a.position.x).toDouble()
    val dy = (b.position.y - a.position.y).toDouble()

    val det = (b.velocity.x * a.velocity.y - b.velocity.y * a.velocity.x).toDouble()

    val u = (dy * b.velocity.x - dx * b.velocity.y) / det
    val v = (dy * a.velocity.x - dx * a.velocity.y) / det

    if (u < 0 || v < 0) {
        return false
    }

    val x = a.position.x + a.velocity.x * u
    val y = a.position.y + a.velocity.y * u

    if (x.toLong() !in min..max) {
        return false
    }
    if (y.toLong() !in min..max) {
        return false
    }

    return true
}

private fun part1(data: List<Hailstone>): Int {
    val min = 200000000000000L
    val max = 400000000000000L

    var counter = 0
    for ((i, a) in data.withIndex()) {
        for ((j, b) in data.withIndex()) {
            if (j > i && intersect(a, b, min, max)) {
                counter += 1
            }
        }
    }

    return counter
}

Compiled from "Day24.kt"
public final class day24.Day24Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String src/day24/Day24.txt
       2: invokestatic  #12                 // Method parse:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: ldc           #14                 // String 🎄 Day 24 🎄
       8: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: swap
      12: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      15: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: invokevirtual #28                 // Method java/io/PrintStream.println:()V
      21: ldc           #30                 // String [Part 1]
      23: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: swap
      27: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      30: new           #32                 // class java/lang/StringBuilder
      33: dup
      34: invokespecial #35                 // Method java/lang/StringBuilder."<init>":()V
      37: ldc           #37                 // String Answer:
      39: invokevirtual #41                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      42: aload_0
      43: invokestatic  #45                 // Method part1:(Ljava/util/List;)I
      46: invokevirtual #48                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      49: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      52: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      55: swap
      56: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      59: return

  private static final day24.Hailstone toHailstone(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #58                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #60                 // class java/lang/String
       8: astore_2
       9: aload_2
      10: iconst_0
      11: ldc           #62                 // String  @
      13: aastore
      14: aload_2
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #68                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: astore_1
      24: aload_1
      25: iconst_0
      26: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      31: checkcast     #60                 // class java/lang/String
      34: astore_2
      35: aload_1
      36: iconst_1
      37: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      42: checkcast     #60                 // class java/lang/String
      45: astore_3
      46: aload_2
      47: checkcast     #58                 // class java/lang/CharSequence
      50: iconst_1
      51: anewarray     #60                 // class java/lang/String
      54: astore        5
      56: aload         5
      58: iconst_0
      59: ldc           #76                 // String ,
      61: aastore
      62: aload         5
      64: iconst_0
      65: iconst_0
      66: bipush        6
      68: aconst_null
      69: invokestatic  #68                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      72: checkcast     #78                 // class java/lang/Iterable
      75: astore        5
      77: nop
      78: iconst_0
      79: istore        6
      81: aload         5
      83: astore        7
      85: new           #80                 // class java/util/ArrayList
      88: dup
      89: aload         5
      91: bipush        10
      93: invokestatic  #86                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      96: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
      99: checkcast     #91                 // class java/util/Collection
     102: astore        8
     104: iconst_0
     105: istore        9
     107: aload         7
     109: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     114: astore        10
     116: aload         10
     118: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     123: ifeq          173
     126: aload         10
     128: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     133: astore        11
     135: aload         8
     137: aload         11
     139: checkcast     #60                 // class java/lang/String
     142: astore        12
     144: astore        15
     146: iconst_0
     147: istore        13
     149: aload         12
     151: checkcast     #58                 // class java/lang/CharSequence
     154: invokestatic  #109                // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     157: invokevirtual #110                // Method java/lang/Object.toString:()Ljava/lang/String;
     160: nop
     161: aload         15
     163: swap
     164: invokeinterface #114,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     169: pop
     170: goto          116
     173: aload         8
     175: checkcast     #70                 // class java/util/List
     178: nop
     179: checkcast     #78                 // class java/lang/Iterable
     182: astore        5
     184: nop
     185: iconst_0
     186: istore        6
     188: aload         5
     190: astore        7
     192: new           #80                 // class java/util/ArrayList
     195: dup
     196: aload         5
     198: bipush        10
     200: invokestatic  #86                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     203: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
     206: checkcast     #91                 // class java/util/Collection
     209: astore        8
     211: iconst_0
     212: istore        9
     214: aload         7
     216: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     221: astore        10
     223: aload         10
     225: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     230: ifeq          277
     233: aload         10
     235: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     240: astore        11
     242: aload         8
     244: aload         11
     246: checkcast     #60                 // class java/lang/String
     249: astore        12
     251: astore        15
     253: iconst_0
     254: istore        13
     256: aload         12
     258: invokestatic  #120                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     261: nop
     262: invokestatic  #124                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     265: aload         15
     267: swap
     268: invokeinterface #114,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     273: pop
     274: goto          223
     277: aload         8
     279: checkcast     #70                 // class java/util/List
     282: nop
     283: astore        6
     285: iconst_0
     286: istore        7
     288: aload         6
     290: iconst_0
     291: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     296: checkcast     #126                // class java/lang/Number
     299: invokevirtual #130                // Method java/lang/Number.longValue:()J
     302: lstore        8
     304: aload         6
     306: iconst_1
     307: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     312: checkcast     #126                // class java/lang/Number
     315: invokevirtual #130                // Method java/lang/Number.longValue:()J
     318: lstore        10
     320: aload         6
     322: iconst_2
     323: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     328: checkcast     #126                // class java/lang/Number
     331: invokevirtual #130                // Method java/lang/Number.longValue:()J
     334: lstore        12
     336: new           #132                // class day24/Vec3
     339: dup
     340: lload         8
     342: lload         10
     344: lload         12
     346: invokespecial #135                // Method day24/Vec3."<init>":(JJJ)V
     349: nop
     350: astore        4
     352: aload_3
     353: checkcast     #58                 // class java/lang/CharSequence
     356: iconst_1
     357: anewarray     #60                 // class java/lang/String
     360: astore        6
     362: aload         6
     364: iconst_0
     365: ldc           #76                 // String ,
     367: aastore
     368: aload         6
     370: iconst_0
     371: iconst_0
     372: bipush        6
     374: aconst_null
     375: invokestatic  #68                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     378: checkcast     #78                 // class java/lang/Iterable
     381: astore        6
     383: nop
     384: iconst_0
     385: istore        7
     387: aload         6
     389: astore        8
     391: new           #80                 // class java/util/ArrayList
     394: dup
     395: aload         6
     397: bipush        10
     399: invokestatic  #86                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     402: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
     405: checkcast     #91                 // class java/util/Collection
     408: astore        9
     410: iconst_0
     411: istore        10
     413: aload         8
     415: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     420: astore        11
     422: aload         11
     424: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     429: ifeq          479
     432: aload         11
     434: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     439: astore        12
     441: aload         9
     443: aload         12
     445: checkcast     #60                 // class java/lang/String
     448: astore        13
     450: astore        15
     452: iconst_0
     453: istore        14
     455: aload         13
     457: checkcast     #58                 // class java/lang/CharSequence
     460: invokestatic  #109                // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     463: invokevirtual #110                // Method java/lang/Object.toString:()Ljava/lang/String;
     466: nop
     467: aload         15
     469: swap
     470: invokeinterface #114,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     475: pop
     476: goto          422
     479: aload         9
     481: checkcast     #70                 // class java/util/List
     484: nop
     485: checkcast     #78                 // class java/lang/Iterable
     488: astore        6
     490: nop
     491: iconst_0
     492: istore        7
     494: aload         6
     496: astore        8
     498: new           #80                 // class java/util/ArrayList
     501: dup
     502: aload         6
     504: bipush        10
     506: invokestatic  #86                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     509: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
     512: checkcast     #91                 // class java/util/Collection
     515: astore        9
     517: iconst_0
     518: istore        10
     520: aload         8
     522: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     527: astore        11
     529: aload         11
     531: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     536: ifeq          583
     539: aload         11
     541: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     546: astore        12
     548: aload         9
     550: aload         12
     552: checkcast     #60                 // class java/lang/String
     555: astore        13
     557: astore        15
     559: iconst_0
     560: istore        14
     562: aload         13
     564: invokestatic  #120                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     567: nop
     568: invokestatic  #124                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     571: aload         15
     573: swap
     574: invokeinterface #114,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     579: pop
     580: goto          529
     583: aload         9
     585: checkcast     #70                 // class java/util/List
     588: nop
     589: astore        7
     591: iconst_0
     592: istore        8
     594: aload         7
     596: iconst_0
     597: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     602: checkcast     #126                // class java/lang/Number
     605: invokevirtual #130                // Method java/lang/Number.longValue:()J
     608: lstore        9
     610: aload         7
     612: iconst_1
     613: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     618: checkcast     #126                // class java/lang/Number
     621: invokevirtual #130                // Method java/lang/Number.longValue:()J
     624: lstore        11
     626: aload         7
     628: iconst_2
     629: invokeinterface #74,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     634: checkcast     #126                // class java/lang/Number
     637: invokevirtual #130                // Method java/lang/Number.longValue:()J
     640: lstore        13
     642: new           #132                // class day24/Vec3
     645: dup
     646: lload         9
     648: lload         11
     650: lload         13
     652: invokespecial #135                // Method day24/Vec3."<init>":(JJJ)V
     655: nop
     656: astore        5
     658: new           #137                // class day24/Hailstone
     661: dup
     662: aload         4
     664: aload         5
     666: invokespecial #140                // Method day24/Hailstone."<init>":(Lday24/Vec3;Lday24/Vec3;)V
     669: areturn

  private static final java.util.List<day24.Hailstone> parse(java.lang.String);
    Code:
       0: new           #171                // class java/io/File
       3: dup
       4: aload_0
       5: invokespecial #174                // Method java/io/File."<init>":(Ljava/lang/String;)V
       8: aconst_null
       9: iconst_1
      10: aconst_null
      11: invokestatic  #180                // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      14: checkcast     #78                 // class java/lang/Iterable
      17: astore_1
      18: nop
      19: iconst_0
      20: istore_2
      21: aload_1
      22: astore_3
      23: new           #80                 // class java/util/ArrayList
      26: dup
      27: aload_1
      28: bipush        10
      30: invokestatic  #86                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      33: invokespecial #89                 // Method java/util/ArrayList."<init>":(I)V
      36: checkcast     #91                 // class java/util/Collection
      39: astore        4
      41: iconst_0
      42: istore        5
      44: aload_3
      45: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      50: astore        6
      52: aload         6
      54: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      59: ifeq          102
      62: aload         6
      64: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      69: astore        7
      71: aload         4
      73: aload         7
      75: checkcast     #60                 // class java/lang/String
      78: astore        8
      80: astore        10
      82: iconst_0
      83: istore        9
      85: aload         8
      87: invokestatic  #182                // Method toHailstone:(Ljava/lang/String;)Lday24/Hailstone;
      90: aload         10
      92: swap
      93: invokeinterface #114,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      98: pop
      99: goto          52
     102: aload         4
     104: checkcast     #70                 // class java/util/List
     107: nop
     108: areturn

  private static final boolean intersect(day24.Hailstone, day24.Hailstone, long, long);
    Code:
       0: aload_1
       1: invokevirtual #190                // Method day24/Hailstone.getPosition:()Lday24/Vec3;
       4: invokevirtual #193                // Method day24/Vec3.getX:()J
       7: aload_0
       8: invokevirtual #190                // Method day24/Hailstone.getPosition:()Lday24/Vec3;
      11: invokevirtual #193                // Method day24/Vec3.getX:()J
      14: lsub
      15: l2d
      16: dstore        6
      18: aload_1
      19: invokevirtual #190                // Method day24/Hailstone.getPosition:()Lday24/Vec3;
      22: invokevirtual #196                // Method day24/Vec3.getY:()J
      25: aload_0
      26: invokevirtual #190                // Method day24/Hailstone.getPosition:()Lday24/Vec3;
      29: invokevirtual #196                // Method day24/Vec3.getY:()J
      32: lsub
      33: l2d
      34: dstore        8
      36: aload_1
      37: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
      40: invokevirtual #193                // Method day24/Vec3.getX:()J
      43: aload_0
      44: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
      47: invokevirtual #196                // Method day24/Vec3.getY:()J
      50: lmul
      51: aload_1
      52: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
      55: invokevirtual #196                // Method day24/Vec3.getY:()J
      58: aload_0
      59: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
      62: invokevirtual #193                // Method day24/Vec3.getX:()J
      65: lmul
      66: lsub
      67: l2d
      68: dstore        10
      70: dload         8
      72: aload_1
      73: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
      76: invokevirtual #193                // Method day24/Vec3.getX:()J
      79: l2d
      80: dmul
      81: dload         6
      83: aload_1
      84: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
      87: invokevirtual #196                // Method day24/Vec3.getY:()J
      90: l2d
      91: dmul
      92: dsub
      93: dload         10
      95: ddiv
      96: dstore        12
      98: dload         8
     100: aload_0
     101: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
     104: invokevirtual #193                // Method day24/Vec3.getX:()J
     107: l2d
     108: dmul
     109: dload         6
     111: aload_0
     112: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
     115: invokevirtual #196                // Method day24/Vec3.getY:()J
     118: l2d
     119: dmul
     120: dsub
     121: dload         10
     123: ddiv
     124: dstore        14
     126: dload         12
     128: dconst_0
     129: dcmpg
     130: iflt          140
     133: dload         14
     135: dconst_0
     136: dcmpg
     137: ifge          142
     140: iconst_0
     141: ireturn
     142: aload_0
     143: invokevirtual #190                // Method day24/Hailstone.getPosition:()Lday24/Vec3;
     146: invokevirtual #193                // Method day24/Vec3.getX:()J
     149: l2d
     150: aload_0
     151: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
     154: invokevirtual #193                // Method day24/Vec3.getX:()J
     157: l2d
     158: dload         12
     160: dmul
     161: dadd
     162: dstore        16
     164: aload_0
     165: invokevirtual #190                // Method day24/Hailstone.getPosition:()Lday24/Vec3;
     168: invokevirtual #196                // Method day24/Vec3.getY:()J
     171: l2d
     172: aload_0
     173: invokevirtual #199                // Method day24/Hailstone.getVelocity:()Lday24/Vec3;
     176: invokevirtual #196                // Method day24/Vec3.getY:()J
     179: l2d
     180: dload         12
     182: dmul
     183: dadd
     184: dstore        18
     186: dload         16
     188: d2l
     189: lstore        20
     191: lload_2
     192: lload         20
     194: lcmp
     195: ifgt          214
     198: lload         20
     200: lload         4
     202: lcmp
     203: ifgt          210
     206: iconst_1
     207: goto          215
     210: iconst_0
     211: goto          215
     214: iconst_0
     215: ifne          220
     218: iconst_0
     219: ireturn
     220: dload         18
     222: d2l
     223: lstore        20
     225: lload_2
     226: lload         20
     228: lcmp
     229: ifgt          248
     232: lload         20
     234: lload         4
     236: lcmp
     237: ifgt          244
     240: iconst_1
     241: goto          249
     244: iconst_0
     245: goto          249
     248: iconst_0
     249: ifne          254
     252: iconst_0
     253: ireturn
     254: iconst_1
     255: ireturn

  private static final int part1(java.util.List<day24.Hailstone>);
    Code:
       0: ldc2_w        #212                // long 200000000000000l
       3: lstore_1
       4: ldc2_w        #214                // long 400000000000000l
       7: lstore_3
       8: iconst_0
       9: istore        5
      11: aload_0
      12: checkcast     #78                 // class java/lang/Iterable
      15: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      20: astore        6
      22: iconst_0
      23: istore        7
      25: aload         6
      27: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      32: ifeq          128
      35: iload         7
      37: istore        8
      39: iload         7
      41: iconst_1
      42: iadd
      43: istore        7
      45: aload         6
      47: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      52: checkcast     #137                // class day24/Hailstone
      55: astore        9
      57: aload_0
      58: checkcast     #78                 // class java/lang/Iterable
      61: invokeinterface #95,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      66: astore        10
      68: iconst_0
      69: istore        11
      71: aload         10
      73: invokeinterface #101,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      78: ifeq          25
      81: iload         11
      83: istore        12
      85: iload         11
      87: iconst_1
      88: iadd
      89: istore        11
      91: aload         10
      93: invokeinterface #105,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      98: checkcast     #137                // class day24/Hailstone
     101: astore        13
     103: iload         12
     105: iload         8
     107: if_icmple     71
     110: aload         9
     112: aload         13
     114: lload_1
     115: lload_3
     116: invokestatic  #217                // Method intersect:(Lday24/Hailstone;Lday24/Hailstone;JJ)Z
     119: ifeq          71
     122: iinc          5, 1
     125: goto          71
     128: iload         5
     130: ireturn

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


package day12

import java.io.File

fun main() {
    val data = parse("src/day12/Day12.txt")

    println("🎄 Day 12 🎄")

    println()

    println("[Part 1]")
    println("Answer: ${part1(data)}")

    println()

    println("[Part 2]")
    println("Answer: ${part2(data)}")
}

private data class Row(
    val springs: String,
    val numbers: List<Int>,
)

private fun String.toRow(): Row {
    val (springs, numbers) = this.split(" ")
    return Row(springs, numbers.split(",").map(String::toInt))
}

private fun parse(path: String): List<Row> =
    File(path)
        .readLines()
        .map(String::toRow)

private typealias Cache = MutableMap<Pair<String, List<Int>>, Long>

private fun solve(springs: String, numbers: List<Int>, cache: Cache = mutableMapOf()): Long {
    if (cache.containsKey(springs to numbers)) {
        return cache.getValue(springs to numbers)
    }

    if (springs.isEmpty()) {
        return if (numbers.isEmpty()) 1L else 0L
    }
    if (numbers.isEmpty()) {
        return if (springs.contains('#')) 0L else 1L
    }

    var count = 0L
    if (springs.first() in ".?") {
        count += solve(springs.substring(1), numbers, cache)
    }
    if (springs.first() in "#?") {
        val n = numbers.first()
        if (springs.length > n) {
            val group = springs.substring(0, n)
            if (!group.contains('.') && springs[n] != '#') {
                count += solve(springs.substring(n + 1), numbers.drop(1), cache)
            }
        }

        if (springs.length == n) {
            if (!springs.contains('.')) {
                count += solve("", numbers.drop(1), cache)
            }
        }
    }

    cache[springs to numbers] = count
    return count
}

private fun part1(data: List<Row>): Long =
    data.sumOf { (springs, numbers) -> solve(springs, numbers) }

private fun part2(data: List<Row>): Long =
    data.sumOf { (springs, numbers) -> solve(
        generateSequence { springs }.take(5).toList().joinToString("?"),
        generateSequence { numbers }.take(5).toList().flatten())
    }

Compiled from "Day12.kt"
public final class day12.Day12Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String src/day12/Day12.txt
       2: invokestatic  #12                 // Method parse:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: ldc           #14                 // String 🎄 Day 12 🎄
       8: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: swap
      12: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      15: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: invokevirtual #28                 // Method java/io/PrintStream.println:()V
      21: ldc           #30                 // String [Part 1]
      23: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: swap
      27: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      30: new           #32                 // class java/lang/StringBuilder
      33: dup
      34: invokespecial #35                 // Method java/lang/StringBuilder."<init>":()V
      37: ldc           #37                 // String Answer:
      39: invokevirtual #41                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      42: aload_0
      43: invokestatic  #45                 // Method part1:(Ljava/util/List;)J
      46: invokevirtual #48                 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      49: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      52: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      55: swap
      56: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      59: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      62: invokevirtual #28                 // Method java/io/PrintStream.println:()V
      65: ldc           #54                 // String [Part 2]
      67: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      70: swap
      71: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      74: new           #32                 // class java/lang/StringBuilder
      77: dup
      78: invokespecial #35                 // Method java/lang/StringBuilder."<init>":()V
      81: ldc           #37                 // String Answer:
      83: invokevirtual #41                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      86: aload_0
      87: invokestatic  #57                 // Method part2:(Ljava/util/List;)J
      90: invokevirtual #48                 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
      93: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      96: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      99: swap
     100: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     103: return

  private static final day12.Row toRow(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #63                 // class java/lang/CharSequence
       4: iconst_1
       5: anewarray     #65                 // class java/lang/String
       8: astore_2
       9: aload_2
      10: iconst_0
      11: ldc           #67                 // String
      13: aastore
      14: aload_2
      15: iconst_0
      16: iconst_0
      17: bipush        6
      19: aconst_null
      20: invokestatic  #73                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      23: astore_1
      24: aload_1
      25: iconst_0
      26: invokeinterface #79,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      31: checkcast     #65                 // class java/lang/String
      34: astore_2
      35: aload_1
      36: iconst_1
      37: invokeinterface #79,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      42: checkcast     #65                 // class java/lang/String
      45: astore_3
      46: aload_2
      47: aload_3
      48: checkcast     #63                 // class java/lang/CharSequence
      51: iconst_1
      52: anewarray     #65                 // class java/lang/String
      55: astore        4
      57: aload         4
      59: iconst_0
      60: ldc           #81                 // String ,
      62: aastore
      63: aload         4
      65: iconst_0
      66: iconst_0
      67: bipush        6
      69: aconst_null
      70: invokestatic  #73                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      73: checkcast     #83                 // class java/lang/Iterable
      76: astore        4
      78: astore        13
      80: iconst_0
      81: istore        5
      83: aload         4
      85: astore        6
      87: new           #85                 // class java/util/ArrayList
      90: dup
      91: aload         4
      93: bipush        10
      95: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      98: invokespecial #94                 // Method java/util/ArrayList."<init>":(I)V
     101: checkcast     #96                 // class java/util/Collection
     104: astore        7
     106: iconst_0
     107: istore        8
     109: aload         6
     111: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     116: astore        9
     118: aload         9
     120: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     125: ifeq          172
     128: aload         9
     130: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     135: astore        10
     137: aload         7
     139: aload         10
     141: checkcast     #65                 // class java/lang/String
     144: astore        11
     146: astore        14
     148: iconst_0
     149: istore        12
     151: aload         11
     153: invokestatic  #116                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     156: nop
     157: invokestatic  #120                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     160: aload         14
     162: swap
     163: invokeinterface #124,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     168: pop
     169: goto          118
     172: aload         7
     174: checkcast     #75                 // class java/util/List
     177: nop
     178: aload         13
     180: swap
     181: astore        15
     183: astore        16
     185: new           #126                // class day12/Row
     188: dup
     189: aload         16
     191: aload         15
     193: invokespecial #129                // Method day12/Row."<init>":(Ljava/lang/String;Ljava/util/List;)V
     196: areturn

  private static final java.util.List<day12.Row> parse(java.lang.String);
    Code:
       0: new           #148                // class java/io/File
       3: dup
       4: aload_0
       5: invokespecial #151                // Method java/io/File."<init>":(Ljava/lang/String;)V
       8: aconst_null
       9: iconst_1
      10: aconst_null
      11: invokestatic  #157                // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      14: checkcast     #83                 // class java/lang/Iterable
      17: astore_1
      18: nop
      19: iconst_0
      20: istore_2
      21: aload_1
      22: astore_3
      23: new           #85                 // class java/util/ArrayList
      26: dup
      27: aload_1
      28: bipush        10
      30: invokestatic  #91                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      33: invokespecial #94                 // Method java/util/ArrayList."<init>":(I)V
      36: checkcast     #96                 // class java/util/Collection
      39: astore        4
      41: iconst_0
      42: istore        5
      44: aload_3
      45: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      50: astore        6
      52: aload         6
      54: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      59: ifeq          102
      62: aload         6
      64: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      69: astore        7
      71: aload         4
      73: aload         7
      75: checkcast     #65                 // class java/lang/String
      78: astore        8
      80: astore        10
      82: iconst_0
      83: istore        9
      85: aload         8
      87: invokestatic  #159                // Method toRow:(Ljava/lang/String;)Lday12/Row;
      90: aload         10
      92: swap
      93: invokeinterface #124,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      98: pop
      99: goto          52
     102: aload         4
     104: checkcast     #75                 // class java/util/List
     107: nop
     108: areturn

  private static final long solve(java.lang.String, java.util.List<java.lang.Integer>, java.util.Map<kotlin.Pair<java.lang.String, java.util.List<java.lang.Integer>>, java.lang.Long>);
    Code:
       0: aload_2
       1: aload_0
       2: aload_1
       3: invokestatic  #170                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
       6: invokeinterface #175,  2          // InterfaceMethod java/util/Map.containsKey:(Ljava/lang/Object;)Z
      11: ifeq          30
      14: aload_2
      15: aload_0
      16: aload_1
      17: invokestatic  #170                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      20: invokestatic  #181                // Method kotlin/collections/MapsKt.getValue:(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
      23: checkcast     #183                // class java/lang/Number
      26: invokevirtual #187                // Method java/lang/Number.longValue:()J
      29: lreturn
      30: aload_0
      31: checkcast     #63                 // class java/lang/CharSequence
      34: invokeinterface #191,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      39: ifne          46
      42: iconst_1
      43: goto          47
      46: iconst_0
      47: ifeq          65
      50: aload_1
      51: invokeinterface #194,  1          // InterfaceMethod java/util/List.isEmpty:()Z
      56: ifeq          63
      59: lconst_1
      60: goto          64
      63: lconst_0
      64: lreturn
      65: aload_1
      66: invokeinterface #194,  1          // InterfaceMethod java/util/List.isEmpty:()Z
      71: ifeq          95
      74: aload_0
      75: checkcast     #63                 // class java/lang/CharSequence
      78: bipush        35
      80: iconst_0
      81: iconst_2
      82: aconst_null
      83: invokestatic  #198                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
      86: ifeq          93
      89: lconst_0
      90: goto          94
      93: lconst_1
      94: lreturn
      95: lconst_0
      96: lstore_3
      97: ldc           #200                // String .?
      99: checkcast     #63                 // class java/lang/CharSequence
     102: aload_0
     103: checkcast     #63                 // class java/lang/CharSequence
     106: invokestatic  #204                // Method kotlin/text/StringsKt.first:(Ljava/lang/CharSequence;)C
     109: iconst_0
     110: iconst_2
     111: aconst_null
     112: invokestatic  #198                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
     115: ifeq          137
     118: lload_3
     119: aload_0
     120: iconst_1
     121: invokevirtual #208                // Method java/lang/String.substring:(I)Ljava/lang/String;
     124: dup
     125: ldc           #210                // String substring(...)
     127: invokestatic  #216                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     130: aload_1
     131: aload_2
     132: invokestatic  #218                // Method solve:(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)J
     135: ladd
     136: lstore_3
     137: ldc           #220                // String #?
     139: checkcast     #63                 // class java/lang/CharSequence
     142: aload_0
     143: checkcast     #63                 // class java/lang/CharSequence
     146: invokestatic  #204                // Method kotlin/text/StringsKt.first:(Ljava/lang/CharSequence;)C
     149: iconst_0
     150: iconst_2
     151: aconst_null
     152: invokestatic  #198                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
     155: ifeq          291
     158: aload_1
     159: invokestatic  #223                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     162: checkcast     #183                // class java/lang/Number
     165: invokevirtual #226                // Method java/lang/Number.intValue:()I
     168: istore        5
     170: aload_0
     171: invokevirtual #227                // Method java/lang/String.length:()I
     174: iload         5
     176: if_icmple     250
     179: aload_0
     180: iconst_0
     181: iload         5
     183: invokevirtual #230                // Method java/lang/String.substring:(II)Ljava/lang/String;
     186: dup
     187: ldc           #210                // String substring(...)
     189: invokestatic  #216                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     192: astore        6
     194: aload         6
     196: checkcast     #63                 // class java/lang/CharSequence
     199: bipush        46
     201: iconst_0
     202: iconst_2
     203: aconst_null
     204: invokestatic  #198                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
     207: ifne          250
     210: aload_0
     211: iload         5
     213: invokevirtual #234                // Method java/lang/String.charAt:(I)C
     216: bipush        35
     218: if_icmpeq     250
     221: lload_3
     222: aload_0
     223: iload         5
     225: iconst_1
     226: iadd
     227: invokevirtual #208                // Method java/lang/String.substring:(I)Ljava/lang/String;
     230: dup
     231: ldc           #210                // String substring(...)
     233: invokestatic  #216                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     236: aload_1
     237: checkcast     #83                 // class java/lang/Iterable
     240: iconst_1
     241: invokestatic  #238                // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
     244: aload_2
     245: invokestatic  #218                // Method solve:(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)J
     248: ladd
     249: lstore_3
     250: aload_0
     251: invokevirtual #227                // Method java/lang/String.length:()I
     254: iload         5
     256: if_icmpne     291
     259: aload_0
     260: checkcast     #63                 // class java/lang/CharSequence
     263: bipush        46
     265: iconst_0
     266: iconst_2
     267: aconst_null
     268: invokestatic  #198                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
     271: ifne          291
     274: lload_3
     275: ldc           #240                // String
     277: aload_1
     278: checkcast     #83                 // class java/lang/Iterable
     281: iconst_1
     282: invokestatic  #238                // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
     285: aload_2
     286: invokestatic  #218                // Method solve:(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)J
     289: ladd
     290: lstore_3
     291: lload_3
     292: invokestatic  #245                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     295: astore        7
     297: aload_2
     298: aload_0
     299: aload_1
     300: invokestatic  #170                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     303: aload         7
     305: invokeinterface #249,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     310: pop
     311: lload_3
     312: lreturn

  static long solve$default(java.lang.String, java.util.List, java.util.Map, int, java.lang.Object);
    Code:
       0: iload_3
       1: iconst_4
       2: iand
       3: ifeq          17
       6: new           #259                // class java/util/LinkedHashMap
       9: dup
      10: invokespecial #260                // Method java/util/LinkedHashMap."<init>":()V
      13: checkcast     #172                // class java/util/Map
      16: astore_2
      17: aload_0
      18: aload_1
      19: aload_2
      20: invokestatic  #218                // Method solve:(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)J
      23: lreturn

  private static final long part1(java.util.List<day12.Row>);
    Code:
       0: aload_0
       1: checkcast     #83                 // class java/lang/Iterable
       4: astore_1
       5: lconst_0
       6: lstore_2
       7: aload_1
       8: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore        4
      15: aload         4
      17: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      22: ifeq          82
      25: aload         4
      27: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      32: astore        5
      34: lload_2
      35: aload         5
      37: checkcast     #126                // class day12/Row
      40: astore        6
      42: lstore        10
      44: iconst_0
      45: istore        7
      47: aload         6
      49: invokevirtual #264                // Method day12/Row.component1:()Ljava/lang/String;
      52: astore        8
      54: aload         6
      56: invokevirtual #268                // Method day12/Row.component2:()Ljava/util/List;
      59: astore        9
      61: aload         8
      63: aload         9
      65: aconst_null
      66: iconst_4
      67: aconst_null
      68: invokestatic  #270                // Method solve$default:(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;ILjava/lang/Object;)J
      71: lstore        12
      73: lload         10
      75: lload         12
      77: ladd
      78: lstore_2
      79: goto          15
      82: lload_2
      83: lreturn

  private static final long part2(java.util.List<day12.Row>);
    Code:
       0: aload_0
       1: checkcast     #83                 // class java/lang/Iterable
       4: astore_1
       5: lconst_0
       6: lstore_2
       7: aload_1
       8: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore        4
      15: aload         4
      17: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      22: ifeq          139
      25: aload         4
      27: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      32: astore        5
      34: lload_2
      35: aload         5
      37: checkcast     #126                // class day12/Row
      40: astore        6
      42: lstore        10
      44: iconst_0
      45: istore        7
      47: aload         6
      49: invokevirtual #264                // Method day12/Row.component1:()Ljava/lang/String;
      52: astore        8
      54: aload         6
      56: invokevirtual #268                // Method day12/Row.component2:()Ljava/util/List;
      59: astore        9
      61: aload         8
      63: invokedynamic #289,  0            // InvokeDynamic #0:invoke:(Ljava/lang/String;)Lkotlin/jvm/functions/Function0;
      68: invokestatic  #295                // Method kotlin/sequences/SequencesKt.generateSequence:(Lkotlin/jvm/functions/Function0;)Lkotlin/sequences/Sequence;
      71: iconst_5
      72: invokestatic  #299                // Method kotlin/sequences/SequencesKt.take:(Lkotlin/sequences/Sequence;I)Lkotlin/sequences/Sequence;
      75: invokestatic  #303                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
      78: checkcast     #83                 // class java/lang/Iterable
      81: ldc_w         #305                // String ?
      84: checkcast     #63                 // class java/lang/CharSequence
      87: aconst_null
      88: aconst_null
      89: iconst_0
      90: aconst_null
      91: aconst_null
      92: bipush        62
      94: aconst_null
      95: invokestatic  #309                // 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;
      98: aload         9
     100: invokedynamic #318,  0            // InvokeDynamic #1:invoke:(Ljava/util/List;)Lkotlin/jvm/functions/Function0;
     105: invokestatic  #295                // Method kotlin/sequences/SequencesKt.generateSequence:(Lkotlin/jvm/functions/Function0;)Lkotlin/sequences/Sequence;
     108: iconst_5
     109: invokestatic  #299                // Method kotlin/sequences/SequencesKt.take:(Lkotlin/sequences/Sequence;I)Lkotlin/sequences/Sequence;
     112: invokestatic  #303                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
     115: checkcast     #83                 // class java/lang/Iterable
     118: invokestatic  #322                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
     121: aconst_null
     122: iconst_4
     123: aconst_null
     124: invokestatic  #270                // Method solve$default:(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;ILjava/lang/Object;)J
     127: nop
     128: lstore        12
     130: lload         10
     132: lload         12
     134: ladd
     135: lstore_2
     136: goto          15
     139: lload_2
     140: lreturn

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

  private static final java.lang.String part2$lambda$4$lambda$2(java.lang.String);
    Code:
       0: aload_0
       1: areturn

  private static final java.util.List part2$lambda$4$lambda$3(java.util.List);
    Code:
       0: aload_0
       1: areturn
}


package day15

import java.io.File

fun main() {
    val data = parse("src/day15/Day15.txt")

    println("🎄 Day 15 🎄")

    println()

    println("[Part 1]")
    println("Answer: ${part1(data)}")

    println()

    println("[Part 2]")
    println("Answer: ${part2(data)}")
}

private fun parse(path: String): List<String> =
    File(path)
        .readText()
        .split(",")

private fun String.hash(): Int =
    fold(0) { acc, it -> (acc + it.code) * 17 and 0xFF }

private fun part1(data: List<String>): Int =
    data.sumOf(String::hash)

private data class Lens(
    val label: String,
    val focalLength: Int,
)

private fun part2(data: List<String>): Int {
    val boxes = Array(256) { mutableListOf<Lens>() }
    for (step in data) {
        val (label) = step.split('=', '-')
        val location = label.hash()

        if (step.contains('=')) {
            val focalLength = step.last().digitToInt()

            val index = boxes[location].indexOfFirst { it.label == label }
            if (index >= 0) {
                boxes[location][index] = Lens(label, focalLength)
            } else {
                boxes[location] += Lens(label, focalLength)
            }
        } else {
            boxes[location].removeIf { it.label == label  }
        }
    }

    return boxes.withIndex().sumOf { (boxNumber, box) ->
        box.withIndex().sumOf { (lensNumber, lens) ->
            (boxNumber + 1) * (lensNumber + 1) * lens.focalLength
        }
    }
}

Compiled from "Day15.kt"
public final class day15.Day15Kt {
  public static final void main();
    Code:
       0: ldc           #8                  // String src/day15/Day15.txt
       2: invokestatic  #12                 // Method parse:(Ljava/lang/String;)Ljava/util/List;
       5: astore_0
       6: ldc           #14                 // String 🎄 Day 15 🎄
       8: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: swap
      12: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      15: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: invokevirtual #28                 // Method java/io/PrintStream.println:()V
      21: ldc           #30                 // String [Part 1]
      23: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: swap
      27: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      30: new           #32                 // class java/lang/StringBuilder
      33: dup
      34: invokespecial #35                 // Method java/lang/StringBuilder."<init>":()V
      37: ldc           #37                 // String Answer:
      39: invokevirtual #41                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      42: aload_0
      43: invokestatic  #45                 // Method part1:(Ljava/util/List;)I
      46: invokevirtual #48                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      49: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      52: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      55: swap
      56: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      59: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      62: invokevirtual #28                 // Method java/io/PrintStream.println:()V
      65: ldc           #54                 // String [Part 2]
      67: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      70: swap
      71: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      74: new           #32                 // class java/lang/StringBuilder
      77: dup
      78: invokespecial #35                 // Method java/lang/StringBuilder."<init>":()V
      81: ldc           #37                 // String Answer:
      83: invokevirtual #41                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      86: aload_0
      87: invokestatic  #57                 // Method part2:(Ljava/util/List;)I
      90: invokevirtual #48                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      93: invokevirtual #52                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      96: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
      99: swap
     100: invokevirtual #26                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     103: return

  private static final java.util.List<java.lang.String> parse(java.lang.String);
    Code:
       0: new           #62                 // class java/io/File
       3: dup
       4: aload_0
       5: invokespecial #65                 // Method java/io/File."<init>":(Ljava/lang/String;)V
       8: aconst_null
       9: iconst_1
      10: aconst_null
      11: invokestatic  #71                 // Method kotlin/io/FilesKt.readText$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String;
      14: checkcast     #73                 // class java/lang/CharSequence
      17: iconst_1
      18: anewarray     #75                 // class java/lang/String
      21: astore_1
      22: aload_1
      23: iconst_0
      24: ldc           #77                 // String ,
      26: aastore
      27: aload_1
      28: iconst_0
      29: iconst_0
      30: bipush        6
      32: aconst_null
      33: invokestatic  #83                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      36: areturn

  private static final int hash(java.lang.String);
    Code:
       0: aload_0
       1: checkcast     #73                 // class java/lang/CharSequence
       4: astore_1
       5: iconst_0
       6: istore_2
       7: iconst_0
       8: istore_3
       9: iload_2
      10: istore        4
      12: iconst_0
      13: istore        5
      15: iload         5
      17: aload_1
      18: invokeinterface #91,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      23: if_icmpge     67
      26: aload_1
      27: iload         5
      29: invokeinterface #95,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      34: istore        6
      36: iload         4
      38: iload         6
      40: istore        7
      42: istore        8
      44: iconst_0
      45: istore        9
      47: iload         8
      49: iload         7
      51: iadd
      52: bipush        17
      54: imul
      55: sipush        255
      58: iand
      59: istore        4
      61: iinc          5, 1
      64: goto          15
      67: iload         4
      69: ireturn

  private static final int part1(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: checkcast     #110                // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: invokeinterface #114,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore_3
      14: aload_3
      15: invokeinterface #120,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      20: ifeq          60
      23: aload_3
      24: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      29: astore        4
      31: iload_2
      32: aload         4
      34: checkcast     #75                 // class java/lang/String
      37: astore        5
      39: istore        7
      41: iconst_0
      42: istore        6
      44: aload         5
      46: invokestatic  #126                // Method hash:(Ljava/lang/String;)I
      49: istore        8
      51: iload         7
      53: iload         8
      55: iadd
      56: istore_2
      57: goto          14
      60: iload_2
      61: ireturn

  private static final int part2(java.util.List<java.lang.String>);
    Code:
       0: iconst_0
       1: istore_2
       2: sipush        256
       5: anewarray     #130                // class java/util/List
       8: astore_3
       9: iload_2
      10: sipush        256
      13: if_icmpge     39
      16: iload_2
      17: istore        4
      19: aload_3
      20: iload         4
      22: new           #132                // class java/util/ArrayList
      25: dup
      26: invokespecial #133                // Method java/util/ArrayList."<init>":()V
      29: checkcast     #130                // class java/util/List
      32: aastore
      33: iinc          2, 1
      36: goto          9
      39: aload_3
      40: astore_1
      41: aload_0
      42: invokeinterface #134,  1          // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      47: astore_2
      48: aload_2
      49: invokeinterface #120,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      54: ifeq          303
      57: aload_2
      58: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: checkcast     #75                 // class java/lang/String
      66: astore_3
      67: aload_3
      68: checkcast     #73                 // class java/lang/CharSequence
      71: iconst_2
      72: newarray       char
      74: astore        5
      76: aload         5
      78: iconst_0
      79: bipush        61
      81: castore
      82: aload         5
      84: iconst_1
      85: bipush        45
      87: castore
      88: aload         5
      90: iconst_0
      91: iconst_0
      92: bipush        6
      94: aconst_null
      95: invokestatic  #137                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[CZIILjava/lang/Object;)Ljava/util/List;
      98: iconst_0
      99: invokeinterface #141,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     104: checkcast     #75                 // class java/lang/String
     107: astore        5
     109: aload         5
     111: invokestatic  #126                // Method hash:(Ljava/lang/String;)I
     114: istore        6
     116: aload_3
     117: checkcast     #73                 // class java/lang/CharSequence
     120: bipush        61
     122: iconst_0
     123: iconst_2
     124: aconst_null
     125: invokestatic  #145                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
     128: ifeq          278
     131: aload_3
     132: checkcast     #73                 // class java/lang/CharSequence
     135: invokestatic  #149                // Method kotlin/text/StringsKt.last:(Ljava/lang/CharSequence;)C
     138: invokestatic  #155                // Method kotlin/text/CharsKt.digitToInt:(C)I
     141: istore        7
     143: aload_1
     144: iload         6
     146: aaload
     147: astore        9
     149: iconst_0
     150: istore        10
     152: iconst_0
     153: istore        11
     155: aload         9
     157: invokeinterface #134,  1          // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     162: astore        12
     164: aload         12
     166: invokeinterface #120,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     171: ifeq          217
     174: aload         12
     176: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     181: astore        13
     183: aload         13
     185: checkcast     #157                // class day15/Lens
     188: astore        14
     190: iconst_0
     191: istore        15
     193: aload         14
     195: invokevirtual #160                // Method day15/Lens.getLabel:()Ljava/lang/String;
     198: aload         5
     200: invokestatic  #166                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     203: ifeq          211
     206: iload         11
     208: goto          218
     211: iinc          11, 1
     214: goto          164
     217: iconst_m1
     218: istore        8
     220: iload         8
     222: iflt          251
     225: aload_1
     226: iload         6
     228: aaload
     229: iload         8
     231: new           #157                // class day15/Lens
     234: dup
     235: aload         5
     237: iload         7
     239: invokespecial #169                // Method day15/Lens."<init>":(Ljava/lang/String;I)V
     242: invokeinterface #173,  3          // InterfaceMethod java/util/List.set:(ILjava/lang/Object;)Ljava/lang/Object;
     247: pop
     248: goto          48
     251: aload_1
     252: iload         6
     254: aaload
     255: checkcast     #175                // class java/util/Collection
     258: new           #157                // class day15/Lens
     261: dup
     262: aload         5
     264: iload         7
     266: invokespecial #169                // Method day15/Lens."<init>":(Ljava/lang/String;I)V
     269: invokeinterface #179,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     274: pop
     275: goto          48
     278: aload_1
     279: iload         6
     281: aaload
     282: aload         5
     284: invokedynamic #199,  0            // InvokeDynamic #0:invoke:(Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
     289: invokedynamic #209,  0            // InvokeDynamic #1:test:(Lkotlin/jvm/functions/Function1;)Ljava/util/function/Predicate;
     294: invokeinterface #213,  2          // InterfaceMethod java/util/List.removeIf:(Ljava/util/function/Predicate;)Z
     299: pop
     300: goto          48
     303: aload_1
     304: invokestatic  #219                // Method kotlin/collections/ArraysKt.withIndex:([Ljava/lang/Object;)Ljava/lang/Iterable;
     307: astore_2
     308: iconst_0
     309: istore_3
     310: aload_2
     311: invokeinterface #114,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     316: astore        4
     318: aload         4
     320: invokeinterface #120,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     325: ifeq          480
     328: aload         4
     330: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     335: astore        5
     337: iload_3
     338: aload         5
     340: checkcast     #221                // class kotlin/collections/IndexedValue
     343: astore        6
     345: istore        20
     347: iconst_0
     348: istore        7
     350: aload         6
     352: invokevirtual #224                // Method kotlin/collections/IndexedValue.component1:()I
     355: istore        8
     357: aload         6
     359: invokevirtual #227                // Method kotlin/collections/IndexedValue.component2:()Ljava/lang/Object;
     362: checkcast     #130                // class java/util/List
     365: astore        9
     367: aload         9
     369: checkcast     #110                // class java/lang/Iterable
     372: invokestatic  #232                // Method kotlin/collections/CollectionsKt.withIndex:(Ljava/lang/Iterable;)Ljava/lang/Iterable;
     375: astore        10
     377: iconst_0
     378: istore        11
     380: aload         10
     382: invokeinterface #114,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     387: astore        12
     389: aload         12
     391: invokeinterface #120,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     396: ifeq          466
     399: aload         12
     401: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     406: astore        13
     408: iload         11
     410: aload         13
     412: checkcast     #221                // class kotlin/collections/IndexedValue
     415: astore        14
     417: istore        15
     419: iconst_0
     420: istore        16
     422: aload         14
     424: invokevirtual #224                // Method kotlin/collections/IndexedValue.component1:()I
     427: istore        17
     429: aload         14
     431: invokevirtual #227                // Method kotlin/collections/IndexedValue.component2:()Ljava/lang/Object;
     434: checkcast     #157                // class day15/Lens
     437: astore        18
     439: iload         8
     441: iconst_1
     442: iadd
     443: iload         17
     445: iconst_1
     446: iadd
     447: imul
     448: aload         18
     450: invokevirtual #235                // Method day15/Lens.getFocalLength:()I
     453: imul
     454: istore        19
     456: iload         15
     458: iload         19
     460: iadd
     461: istore        11
     463: goto          389
     466: iload         11
     468: nop
     469: istore        21
     471: iload         20
     473: iload         21
     475: iadd
     476: istore_3
     477: goto          318
     480: iload_3
     481: ireturn

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

  private static final boolean part2$lambda$2(java.lang.String, day15.Lens);
    Code:
       0: aload_1
       1: ldc_w         #262                // String it
       4: invokestatic  #266                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_1
       8: invokevirtual #160                // Method day15/Lens.getLabel:()Ljava/lang/String;
      11: aload_0
      12: invokestatic  #166                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      15: ireturn

  private static final boolean part2$lambda$3(kotlin.jvm.functions.Function1, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: invokeinterface #271,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
       7: checkcast     #273                // class java/lang/Boolean
      10: invokevirtual #276                // Method java/lang/Boolean.booleanValue:()Z
      13: ireturn
}