package day20

import java.io.File

private const val LIGHT_PIXEL = '#'
private const val DARK_PIXEL = '.'

fun parseInput(lines: List<String>): Pair<String, List<String>> = lines.first() to lines.drop(2)

private fun square3x3(center: Pair<Int, Int>): List<Pair<Int, Int>> =
  listOf(
    // sorted according to the particular order in which the square has to be traversed
    -1 to -1, 0 to -1, 1 to -1,
    -1 to 0, 0 to 0, 1 to 0,
    -1 to 1, 0 to 1, 1 to 1,
  ).map { (x, y) -> center.first + x to center.second + y }

fun enhanceImage(imageEnhancement: String, image: List<String>, iterations: Int): List<String> {
  fun computePixel(position: Pair<Int, Int>, image: List<String>, default: Char): Char {
    val index = square3x3(position)
      .map { (x, y) -> image.getOrNull(y)?.getOrNull(x) ?: default }
      .fold(0) { acc, pixel -> acc.shl(1) + if (pixel == LIGHT_PIXEL) 1 else 0 }
    return imageEnhancement[index]
  }

  fun iterate(image: List<String>, default: Char): List<String> {
    // the canvas extends in all directions indefinitely so the 'default' char in
    // the position 'out of the frame' is also subject to image enhancement effects
    // the default is the one that should be used when checking for an adjacent that's
    // out of the frame. This default will change depending on the algorithm
    val canvasWidth = image.firstOrNull()?.length ?: 0
    val blankLine = listOf(default.toString().repeat(canvasWidth))
    val expandedImage = blankLine + image + blankLine
    val outputImage = mutableListOf<String>()
    for ((y, line) in expandedImage.withIndex()) {
      val builder = StringBuilder()
      for (x in -1..(line.length + 1)) {
        builder.append(computePixel(x to y, expandedImage, default))
      }
      outputImage.add(builder.toString())
    }
    return outputImage
  }

  var default = DARK_PIXEL
  var outputImage = image
  repeat(iterations) {
    outputImage = iterate(outputImage, default)
    default = imageEnhancement[if (default == LIGHT_PIXEL) 511 else 0]
  }
  return outputImage
}

fun countLightPixels(image: List<String>): Int = image.sumOf { it.count { pixel -> pixel == LIGHT_PIXEL } }

fun main() {
  File("./input/day20.txt").useLines { lines ->
    val (enhancement, image) = parseInput(lines.toList())
    val output = enhanceImage(enhancement, image, 50)
    println(countLightPixels(output))
  }
}

Compiled from "Day20.kt"
public final class day20.Day20Kt {
  private static final char LIGHT_PIXEL;

  private static final char DARK_PIXEL;

  public static final kotlin.Pair<java.lang.String, java.util.List<java.lang.String>> parseInput(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #10                 // String lines
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #22                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      10: aload_0
      11: checkcast     #24                 // class java/lang/Iterable
      14: iconst_2
      15: invokestatic  #28                 // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      18: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      21: areturn

  private static final java.util.List<kotlin.Pair<java.lang.Integer, java.lang.Integer>> square3x3(kotlin.Pair<java.lang.Integer, java.lang.Integer>);
    Code:
       0: bipush        9
       2: anewarray     #40                 // class kotlin/Pair
       5: astore_1
       6: aload_1
       7: iconst_0
       8: iconst_m1
       9: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      12: iconst_m1
      13: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      16: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      19: aastore
      20: aload_1
      21: iconst_1
      22: iconst_0
      23: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      26: iconst_m1
      27: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      30: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      33: aastore
      34: aload_1
      35: iconst_2
      36: iconst_1
      37: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      40: iconst_m1
      41: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      44: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      47: aastore
      48: aload_1
      49: iconst_3
      50: iconst_m1
      51: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      54: iconst_0
      55: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      58: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      61: aastore
      62: aload_1
      63: iconst_4
      64: iconst_0
      65: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      68: iconst_0
      69: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      72: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      75: aastore
      76: aload_1
      77: iconst_5
      78: iconst_1
      79: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      82: iconst_0
      83: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      86: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      89: aastore
      90: aload_1
      91: bipush        6
      93: iconst_m1
      94: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      97: iconst_1
      98: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     101: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     104: aastore
     105: aload_1
     106: bipush        7
     108: iconst_0
     109: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     112: iconst_1
     113: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     116: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     119: aastore
     120: aload_1
     121: bipush        8
     123: iconst_1
     124: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     127: iconst_1
     128: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     131: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     134: aastore
     135: aload_1
     136: invokestatic  #50                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     139: checkcast     #24                 // class java/lang/Iterable
     142: astore_1
     143: nop
     144: iconst_0
     145: istore_2
     146: aload_1
     147: astore_3
     148: new           #52                 // class java/util/ArrayList
     151: dup
     152: aload_1
     153: bipush        10
     155: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     158: invokespecial #60                 // Method java/util/ArrayList."<init>":(I)V
     161: checkcast     #62                 // class java/util/Collection
     164: astore        4
     166: iconst_0
     167: istore        5
     169: aload_3
     170: invokeinterface #66,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     175: astore        6
     177: aload         6
     179: invokeinterface #72,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     184: ifeq          283
     187: aload         6
     189: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     194: astore        7
     196: aload         4
     198: aload         7
     200: checkcast     #40                 // class kotlin/Pair
     203: astore        8
     205: astore        12
     207: iconst_0
     208: istore        9
     210: aload         8
     212: invokevirtual #79                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
     215: checkcast     #81                 // class java/lang/Number
     218: invokevirtual #85                 // Method java/lang/Number.intValue:()I
     221: istore        10
     223: aload         8
     225: invokevirtual #88                 // Method kotlin/Pair.component2:()Ljava/lang/Object;
     228: checkcast     #81                 // class java/lang/Number
     231: invokevirtual #85                 // Method java/lang/Number.intValue:()I
     234: istore        11
     236: aload_0
     237: invokevirtual #91                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     240: checkcast     #81                 // class java/lang/Number
     243: invokevirtual #85                 // Method java/lang/Number.intValue:()I
     246: iload         10
     248: iadd
     249: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     252: aload_0
     253: invokevirtual #94                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     256: checkcast     #81                 // class java/lang/Number
     259: invokevirtual #85                 // Method java/lang/Number.intValue:()I
     262: iload         11
     264: iadd
     265: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     268: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     271: aload         12
     273: swap
     274: invokeinterface #98,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     279: pop
     280: goto          177
     283: aload         4
     285: checkcast     #100                // class java/util/List
     288: nop
     289: areturn

  public static final java.util.List<java.lang.String> enhanceImage(java.lang.String, java.util.List<java.lang.String>, int);
    Code:
       0: aload_0
       1: ldc           #120                // String imageEnhancement
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #122                // String image
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: iconst_0
      13: istore_3
      14: bipush        46
      16: istore_3
      17: aconst_null
      18: astore        4
      20: aload_1
      21: astore        4
      23: iconst_0
      24: istore        5
      26: iload         5
      28: iload_2
      29: if_icmpge     73
      32: iload         5
      34: istore        6
      36: iconst_0
      37: istore        7
      39: aload_0
      40: aload         4
      42: iload_3
      43: invokestatic  #126                // Method enhanceImage$iterate:(Ljava/lang/String;Ljava/util/List;C)Ljava/util/List;
      46: astore        4
      48: aload_0
      49: iload_3
      50: bipush        35
      52: if_icmpne     61
      55: sipush        511
      58: goto          62
      61: iconst_0
      62: invokevirtual #132                // Method java/lang/String.charAt:(I)C
      65: istore_3
      66: nop
      67: iinc          5, 1
      70: goto          26
      73: aload         4
      75: areturn

  public static final int countLightPixels(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #122                // String image
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #24                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: invokeinterface #66,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      19: astore_3
      20: aload_3
      21: invokeinterface #72,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      26: ifeq          134
      29: aload_3
      30: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      35: astore        4
      37: iload_2
      38: aload         4
      40: checkcast     #128                // class java/lang/String
      43: astore        5
      45: istore        14
      47: iconst_0
      48: istore        6
      50: aload         5
      52: checkcast     #144                // class java/lang/CharSequence
      55: astore        7
      57: iconst_0
      58: istore        8
      60: iconst_0
      61: istore        9
      63: iconst_0
      64: istore        10
      66: iload         10
      68: aload         7
      70: invokeinterface #147,  1          // InterfaceMethod java/lang/CharSequence.length:()I
      75: if_icmpge     120
      78: aload         7
      80: iload         10
      82: invokeinterface #148,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      87: istore        11
      89: iload         11
      91: istore        12
      93: iconst_0
      94: istore        13
      96: iload         12
      98: bipush        35
     100: if_icmpne     107
     103: iconst_1
     104: goto          108
     107: iconst_0
     108: ifeq          114
     111: iinc          9, 1
     114: iinc          10, 1
     117: goto          66
     120: iload         9
     122: nop
     123: istore        15
     125: iload         14
     127: iload         15
     129: iadd
     130: istore_2
     131: goto          20
     134: iload_2
     135: ireturn

  public static final void main();
    Code:
       0: new           #162                // class java/io/File
       3: dup
       4: ldc           #164                // String ./input/day20.txt
       6: invokespecial #167                // Method java/io/File."<init>":(Ljava/lang/String;)V
       9: astore_0
      10: getstatic     #173                // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      13: astore_1
      14: iconst_0
      15: istore_2
      16: aload_0
      17: astore_3
      18: sipush        8192
      21: istore        4
      23: aload_3
      24: astore        5
      26: new           #175                // class java/io/InputStreamReader
      29: dup
      30: new           #177                // class java/io/FileInputStream
      33: dup
      34: aload         5
      36: invokespecial #180                // Method java/io/FileInputStream."<init>":(Ljava/io/File;)V
      39: checkcast     #182                // class java/io/InputStream
      42: aload_1
      43: invokespecial #185                // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/nio/charset/Charset;)V
      46: checkcast     #187                // class java/io/Reader
      49: astore        5
      51: aload         5
      53: instanceof    #189                // class java/io/BufferedReader
      56: ifeq          67
      59: aload         5
      61: checkcast     #189                // class java/io/BufferedReader
      64: goto          78
      67: new           #189                // class java/io/BufferedReader
      70: dup
      71: aload         5
      73: iload         4
      75: invokespecial #192                // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;I)V
      78: checkcast     #194                // class java/io/Closeable
      81: astore_3
      82: aconst_null
      83: astore        4
      85: nop
      86: aload_3
      87: checkcast     #189                // class java/io/BufferedReader
      90: astore        5
      92: iconst_0
      93: istore        6
      95: aload         5
      97: invokestatic  #200                // Method kotlin/io/TextStreamsKt.lineSequence:(Ljava/io/BufferedReader;)Lkotlin/sequences/Sequence;
     100: astore        7
     102: iconst_0
     103: istore        8
     105: aload         7
     107: invokestatic  #206                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
     110: invokestatic  #208                // Method parseInput:(Ljava/util/List;)Lkotlin/Pair;
     113: astore        9
     115: aload         9
     117: invokevirtual #79                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
     120: checkcast     #128                // class java/lang/String
     123: astore        10
     125: aload         9
     127: invokevirtual #88                 // Method kotlin/Pair.component2:()Ljava/lang/Object;
     130: checkcast     #100                // class java/util/List
     133: astore        11
     135: aload         10
     137: aload         11
     139: bipush        50
     141: invokestatic  #210                // Method enhanceImage:(Ljava/lang/String;Ljava/util/List;I)Ljava/util/List;
     144: astore        12
     146: aload         12
     148: invokestatic  #212                // Method countLightPixels:(Ljava/util/List;)I
     151: istore        13
     153: getstatic     #218                // Field java/lang/System.out:Ljava/io/PrintStream;
     156: iload         13
     158: invokevirtual #223                // Method java/io/PrintStream.println:(I)V
     161: nop
     162: getstatic     #229                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     165: astore        5
     167: aload_3
     168: aload         4
     170: invokestatic  #235                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     173: goto          196
     176: astore        6
     178: aload         6
     180: astore        4
     182: aload         6
     184: athrow
     185: astore        6
     187: aload_3
     188: aload         4
     190: invokestatic  #235                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     193: aload         6
     195: athrow
     196: nop
     197: return
    Exception table:
       from    to  target type
          85   167   176   Class java/lang/Throwable
          85   167   185   any
         176   185   185   any
         185   187   185   any

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

  private static final char enhanceImage$computePixel(java.lang.String, kotlin.Pair<java.lang.Integer, java.lang.Integer>, java.util.List<java.lang.String>, char);
    Code:
       0: aload_1
       1: invokestatic  #260                // Method square3x3:(Lkotlin/Pair;)Ljava/util/List;
       4: checkcast     #24                 // class java/lang/Iterable
       7: astore        5
       9: nop
      10: iconst_0
      11: istore        6
      13: aload         5
      15: astore        7
      17: new           #52                 // class java/util/ArrayList
      20: dup
      21: aload         5
      23: bipush        10
      25: invokestatic  #56                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      28: invokespecial #60                 // Method java/util/ArrayList."<init>":(I)V
      31: checkcast     #62                 // class java/util/Collection
      34: astore        8
      36: iconst_0
      37: istore        9
      39: aload         7
      41: invokeinterface #66,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      46: astore        10
      48: aload         10
      50: invokeinterface #72,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      55: ifeq          155
      58: aload         10
      60: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      65: astore        11
      67: aload         8
      69: aload         11
      71: checkcast     #40                 // class kotlin/Pair
      74: astore        12
      76: astore        16
      78: iconst_0
      79: istore        13
      81: aload         12
      83: invokevirtual #79                 // Method kotlin/Pair.component1:()Ljava/lang/Object;
      86: checkcast     #81                 // class java/lang/Number
      89: invokevirtual #85                 // Method java/lang/Number.intValue:()I
      92: istore        14
      94: aload         12
      96: invokevirtual #88                 // Method kotlin/Pair.component2:()Ljava/lang/Object;
      99: checkcast     #81                 // class java/lang/Number
     102: invokevirtual #85                 // Method java/lang/Number.intValue:()I
     105: istore        15
     107: aload_2
     108: iload         15
     110: invokestatic  #264                // Method kotlin/collections/CollectionsKt.getOrNull:(Ljava/util/List;I)Ljava/lang/Object;
     113: checkcast     #128                // class java/lang/String
     116: dup
     117: ifnull        138
     120: checkcast     #144                // class java/lang/CharSequence
     123: iload         14
     125: invokestatic  #269                // Method kotlin/text/StringsKt.getOrNull:(Ljava/lang/CharSequence;I)Ljava/lang/Character;
     128: dup
     129: ifnull        138
     132: invokevirtual #275                // Method java/lang/Character.charValue:()C
     135: goto          140
     138: pop
     139: iload_3
     140: invokestatic  #278                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     143: aload         16
     145: swap
     146: invokeinterface #98,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     151: pop
     152: goto          48
     155: aload         8
     157: checkcast     #100                // class java/util/List
     160: nop
     161: checkcast     #24                 // class java/lang/Iterable
     164: astore        5
     166: iconst_0
     167: istore        6
     169: iconst_0
     170: istore        7
     172: iload         6
     174: istore        8
     176: aload         5
     178: invokeinterface #66,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     183: astore        9
     185: aload         9
     187: invokeinterface #72,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     192: ifeq          243
     195: aload         9
     197: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     202: astore        10
     204: iload         8
     206: aload         10
     208: checkcast     #271                // class java/lang/Character
     211: invokevirtual #275                // Method java/lang/Character.charValue:()C
     214: istore        11
     216: istore        12
     218: iconst_0
     219: istore        13
     221: iload         12
     223: iconst_1
     224: ishl
     225: iload         11
     227: bipush        35
     229: if_icmpne     236
     232: iconst_1
     233: goto          237
     236: iconst_0
     237: iadd
     238: istore        8
     240: goto          185
     243: iload         8
     245: istore        4
     247: aload_0
     248: iload         4
     250: invokevirtual #132                // Method java/lang/String.charAt:(I)C
     253: ireturn

  private static final java.util.List<java.lang.String> enhanceImage$iterate(java.lang.String, java.util.List<java.lang.String>, char);
    Code:
       0: aload_1
       1: invokestatic  #292                // Method kotlin/collections/CollectionsKt.firstOrNull:(Ljava/util/List;)Ljava/lang/Object;
       4: checkcast     #128                // class java/lang/String
       7: dup
       8: ifnull        17
      11: invokevirtual #293                // Method java/lang/String.length:()I
      14: goto          19
      17: pop
      18: iconst_0
      19: istore_3
      20: iload_2
      21: invokestatic  #296                // Method java/lang/String.valueOf:(C)Ljava/lang/String;
      24: checkcast     #144                // class java/lang/CharSequence
      27: iload_3
      28: invokestatic  #300                // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      31: invokestatic  #303                // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
      34: astore        4
      36: aload         4
      38: checkcast     #62                 // class java/util/Collection
      41: aload_1
      42: checkcast     #24                 // class java/lang/Iterable
      45: invokestatic  #307                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
      48: checkcast     #62                 // class java/util/Collection
      51: aload         4
      53: checkcast     #24                 // class java/lang/Iterable
      56: invokestatic  #307                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
      59: astore        5
      61: new           #52                 // class java/util/ArrayList
      64: dup
      65: invokespecial #309                // Method java/util/ArrayList."<init>":()V
      68: checkcast     #100                // class java/util/List
      71: astore        6
      73: aload         5
      75: checkcast     #24                 // class java/lang/Iterable
      78: invokeinterface #66,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      83: astore        7
      85: iconst_0
      86: istore        8
      88: aload         7
      90: invokeinterface #72,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      95: ifeq          210
      98: iload         8
     100: istore        9
     102: iload         8
     104: iconst_1
     105: iadd
     106: istore        8
     108: aload         7
     110: invokeinterface #76,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     115: checkcast     #128                // class java/lang/String
     118: astore        10
     120: new           #311                // class java/lang/StringBuilder
     123: dup
     124: invokespecial #312                // Method java/lang/StringBuilder."<init>":()V
     127: astore        11
     129: iconst_m1
     130: istore        12
     132: aload         10
     134: invokevirtual #293                // Method java/lang/String.length:()I
     137: iconst_1
     138: iadd
     139: istore        13
     141: iload         12
     143: iload         13
     145: if_icmpgt     187
     148: aload         11
     150: aload_0
     151: iload         12
     153: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     156: iload         9
     158: invokestatic  #46                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     161: invokestatic  #34                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     164: aload         5
     166: iload_2
     167: invokestatic  #314                // Method enhanceImage$computePixel:(Ljava/lang/String;Lkotlin/Pair;Ljava/util/List;C)C
     170: invokevirtual #318                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     173: pop
     174: iload         12
     176: iload         13
     178: if_icmpeq     187
     181: iinc          12, 1
     184: goto          148
     187: aload         6
     189: aload         11
     191: invokevirtual #322                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     194: dup
     195: ldc_w         #324                // String toString(...)
     198: invokestatic  #327                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     201: invokeinterface #328,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     206: pop
     207: goto          88
     210: aload         6
     212: areturn
}


package day16

import java.io.File
import java.util.Optional

sealed interface Packet {
  val version: Int
  val value: Long
}

data class Literal(override val version: Int, override val value: Long) : Packet
data class Op(override val version: Int, private val type: Int, val packets: List<Packet>) : Packet {
  override val value: Long
    get() = when (type) {
      0 -> packets.sumOf { it.value }
      1 -> packets.fold(1L) { acc, packet -> acc * packet.value }
      2 -> packets.minOf { it.value }
      3 -> packets.maxOf { it.value }
      5 -> if (packets[0].value > packets[1].value) 1 else 0
      6 -> if (packets[0].value < packets[1].value) 1 else 0
      7 -> if (packets[0].value == packets[1].value) 1 else 0
      else -> TODO("Operation $type is not supported")
    }
}

private val hexBinMap2 = (0..0xF).associate { n -> n.toString(16).first().uppercaseChar() to n.toString(2).padStart(4, '0') }
fun hexToBits(input: String): Iterator<Char> = input.flatMap { hexBinMap2[it]!!.asIterable() }.iterator()

// Syntax sugar methods that will carelessly throw exception if there aren't enough bits
private fun Iterator<Char>.take(bits: Int): String = (1..bits).map { next() }.joinToString("")
private fun Iterator<Char>.takeInt(bits: Int): Int = take(bits).toInt(2)

fun decodePackets(input: Iterator<Char>): List<Packet> = sequence {
  while (input.hasNext()) {
    val next = decodeNextPacket(input)
    if (next.isPresent) yield(next.get())
  }
}.toList()

fun decodeNPackets(input: Iterator<Char>, number: Int) = (1..number).map { decodeNextPacket(input).get() }

fun decodeNextPacket(input: Iterator<Char>): Optional<Packet> = runCatching {
  val version = input.takeInt(3)
  val typeId = input.takeInt(3)
  return Optional.ofNullable(
    when (typeId) {
      4 -> Literal(version, decodeLiteralPayload(input))
      else -> Op(version, typeId, decodeOperatorPayload(input))
    }
  )
}.getOrElse { Optional.empty() }

private fun decodeLiteralPayload(input: Iterator<Char>): Long {
  tailrec fun rec(input: Iterator<Char>, number: Long): Long {
    val controlBit = input.next()
    val n = number.shl(4) + input.takeInt(4)
    return if (controlBit == '0') n else rec(input, n)
  }
  return rec(input, 0)
}

private fun decodeOperatorPayload(input: Iterator<Char>): List<Packet> = runCatching {
  when (input.next()) {
    '0' -> { // takes 15 bits to parse the size of the payload in bits
      decodePackets(boundedIteratorWrap(input, input.takeInt(15)))
    }
    '1' -> { // takes 11 bits to parse the number of packets in its payload
      decodeNPackets(input, input.takeInt(11))
    }
    else -> TODO("Should never happen")
  }
}.getOrElse { emptyList() }

private fun boundedIteratorWrap(iterator: Iterator<Char>, limit: Int) = object : Iterator<Char> {
  private var counter = 0
  override fun hasNext(): Boolean = iterator.hasNext() && counter < limit

  override fun next(): Char =
    if (hasNext()) {
      counter += 1
      iterator.next()
    } else throw NoSuchElementException("End of bounded iterator")
}

fun sumAllVersionsOfTheTransmission(input: Iterator<Char>): Long {
  fun sumVersions(p: Packet): Long = when (p) {
    is Literal -> p.version.toLong()
    is Op -> p.packets.fold(p.version.toLong()) { acc, packet -> acc + sumVersions(packet) }
  }

  return decodePackets(input).fold(0L) { acc, packet -> acc + sumVersions(packet) }
}

fun evaluateTransmission(input: Iterator<Char>): Long = decodeNextPacket(input).get().value

fun main() {
  File("./input/day16.txt").useLines { lines ->
    val transmission = lines.first()
    println(sumAllVersionsOfTheTransmission(hexToBits(transmission)))
    println(evaluateTransmission(hexToBits(transmission)))
  }
}

Compiled from "Day16.kt"
final class day16.Day16Kt$decodePackets$1 extends kotlin.coroutines.jvm.internal.RestrictedSuspendLambda implements kotlin.jvm.functions.Function2<kotlin.sequences.SequenceScope<? super day16.Packet>, kotlin.coroutines.Continuation<? super kotlin.Unit>, java.lang.Object> {
  int label;

  private java.lang.Object L$0;

  final java.util.Iterator<java.lang.Character> $input;

  day16.Day16Kt$decodePackets$1(java.util.Iterator<java.lang.Character>, kotlin.coroutines.Continuation<? super day16.Day16Kt$decodePackets$1>);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #14                 // Field $input:Ljava/util/Iterator;
       5: aload_0
       6: iconst_2
       7: aload_2
       8: invokespecial #17                 // Method kotlin/coroutines/jvm/internal/RestrictedSuspendLambda."<init>":(ILkotlin/coroutines/Continuation;)V
      11: return

  public final java.lang.Object invokeSuspend(java.lang.Object);
    Code:
       0: invokestatic  #43                 // Method kotlin/coroutines/intrinsics/IntrinsicsKt.getCOROUTINE_SUSPENDED:()Ljava/lang/Object;
       3: astore        4
       5: aload_0
       6: getfield      #47                 // Field label:I
       9: tableswitch   { // 0 to 1
                     0: 32
                     1: 102
               default: 123
          }
      32: aload_1
      33: invokestatic  #53                 // Method kotlin/ResultKt.throwOnFailure:(Ljava/lang/Object;)V
      36: aload_0
      37: getfield      #56                 // Field L$0:Ljava/lang/Object;
      40: checkcast     #58                 // class kotlin/sequences/SequenceScope
      43: astore_2
      44: aload_0
      45: getfield      #14                 // Field $input:Ljava/util/Iterator;
      48: invokeinterface #64,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          119
      56: aload_0
      57: getfield      #14                 // Field $input:Ljava/util/Iterator;
      60: invokestatic  #70                 // Method day16/Day16Kt.decodeNextPacket:(Ljava/util/Iterator;)Ljava/util/Optional;
      63: astore_3
      64: aload_3
      65: invokevirtual #75                 // Method java/util/Optional.isPresent:()Z
      68: ifeq          44
      71: aload_2
      72: aload_3
      73: invokevirtual #78                 // Method java/util/Optional.get:()Ljava/lang/Object;
      76: aload_0
      77: checkcast     #80                 // class kotlin/coroutines/Continuation
      80: aload_0
      81: aload_2
      82: putfield      #56                 // Field L$0:Ljava/lang/Object;
      85: aload_0
      86: iconst_1
      87: putfield      #47                 // Field label:I
      90: invokevirtual #84                 // Method kotlin/sequences/SequenceScope.yield:(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
      93: dup
      94: aload         4
      96: if_acmpne     115
      99: aload         4
     101: areturn
     102: aload_0
     103: getfield      #56                 // Field L$0:Ljava/lang/Object;
     106: checkcast     #58                 // class kotlin/sequences/SequenceScope
     109: astore_2
     110: aload_1
     111: invokestatic  #53                 // Method kotlin/ResultKt.throwOnFailure:(Ljava/lang/Object;)V
     114: aload_1
     115: pop
     116: goto          44
     119: getstatic     #90                 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     122: areturn
     123: new           #92                 // class java/lang/IllegalStateException
     126: dup
     127: ldc           #94                 // String call to \'resume\' before \'invoke\' with coroutine
     129: invokespecial #97                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
     132: athrow

  public final kotlin.coroutines.Continuation<kotlin.Unit> create(java.lang.Object, kotlin.coroutines.Continuation<?>);
    Code:
       0: new           #2                  // class day16/Day16Kt$decodePackets$1
       3: dup
       4: aload_0
       5: getfield      #14                 // Field $input:Ljava/util/Iterator;
       8: aload_2
       9: invokespecial #108                // Method "<init>":(Ljava/util/Iterator;Lkotlin/coroutines/Continuation;)V
      12: astore_3
      13: aload_3
      14: aload_1
      15: putfield      #56                 // Field L$0:Ljava/lang/Object;
      18: aload_3
      19: checkcast     #80                 // class kotlin/coroutines/Continuation
      22: areturn

  public final java.lang.Object invoke(kotlin.sequences.SequenceScope<? super day16.Packet>, kotlin.coroutines.Continuation<? super kotlin.Unit>);
    Code:
       0: aload_0
       1: aload_1
       2: aload_2
       3: invokevirtual #114                // Method create:(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
       6: checkcast     #2                  // class day16/Day16Kt$decodePackets$1
       9: getstatic     #90                 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      12: invokevirtual #116                // Method invokeSuspend:(Ljava/lang/Object;)Ljava/lang/Object;
      15: areturn

  public java.lang.Object invoke(java.lang.Object, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #58                 // class kotlin/sequences/SequenceScope
       5: aload_2
       6: checkcast     #80                 // class kotlin/coroutines/Continuation
       9: invokevirtual #121                // Method invoke:(Lkotlin/sequences/SequenceScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
      12: areturn
}

Compiled from "Day16.kt"
public final class day16.Day16Kt {
  private static final java.util.Map<java.lang.Character, java.lang.String> hexBinMap2;

  public static final java.util.Iterator<java.lang.Character> hexToBits(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #18                 // class java/lang/CharSequence
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #20                 // class java/util/ArrayList
      18: dup
      19: invokespecial #24                 // Method java/util/ArrayList."<init>":()V
      22: checkcast     #26                 // class java/util/Collection
      25: astore        4
      27: iconst_0
      28: istore        5
      30: iconst_0
      31: istore        6
      33: iload         6
      35: aload_3
      36: invokeinterface #30,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      41: if_icmpge     100
      44: aload_3
      45: iload         6
      47: invokeinterface #34,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      52: istore        7
      54: iload         7
      56: istore        8
      58: iconst_0
      59: istore        9
      61: getstatic     #38                 // Field hexBinMap2:Ljava/util/Map;
      64: iload         8
      66: invokestatic  #44                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      69: invokeinterface #50,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      74: dup
      75: invokestatic  #54                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      78: checkcast     #18                 // class java/lang/CharSequence
      81: invokestatic  #60                 // Method kotlin/text/StringsKt.asIterable:(Ljava/lang/CharSequence;)Ljava/lang/Iterable;
      84: astore        8
      86: aload         4
      88: aload         8
      90: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
      93: pop
      94: iinc          6, 1
      97: goto          33
     100: aload         4
     102: checkcast     #68                 // class java/util/List
     105: nop
     106: invokeinterface #72,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     111: areturn

  private static final java.lang.String take(java.util.Iterator<java.lang.Character>, int);
    Code:
       0: new           #94                 // class kotlin/ranges/IntRange
       3: dup
       4: iconst_1
       5: iload_1
       6: invokespecial #97                 // Method kotlin/ranges/IntRange."<init>":(II)V
       9: checkcast     #99                 // class java/lang/Iterable
      12: astore_2
      13: iconst_0
      14: istore_3
      15: aload_2
      16: astore        4
      18: new           #20                 // class java/util/ArrayList
      21: dup
      22: aload_2
      23: bipush        10
      25: invokestatic  #103                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      28: invokespecial #106                // Method java/util/ArrayList."<init>":(I)V
      31: checkcast     #26                 // class java/util/Collection
      34: astore        5
      36: iconst_0
      37: istore        6
      39: aload         4
      41: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      46: astore        7
      48: aload         7
      50: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      55: ifeq          106
      58: aload         7
      60: checkcast     #115                // class kotlin/collections/IntIterator
      63: invokevirtual #118                // Method kotlin/collections/IntIterator.nextInt:()I
      66: istore        8
      68: aload         5
      70: iload         8
      72: istore        9
      74: astore        11
      76: iconst_0
      77: istore        10
      79: aload_0
      80: invokeinterface #122,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      85: checkcast     #40                 // class java/lang/Character
      88: invokevirtual #126                // Method java/lang/Character.charValue:()C
      91: invokestatic  #44                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      94: aload         11
      96: swap
      97: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     102: pop
     103: goto          48
     106: aload         5
     108: checkcast     #68                 // class java/util/List
     111: nop
     112: checkcast     #99                 // class java/lang/Iterable
     115: ldc           #132                // String
     117: checkcast     #18                 // class java/lang/CharSequence
     120: aconst_null
     121: aconst_null
     122: iconst_0
     123: aconst_null
     124: aconst_null
     125: bipush        62
     127: aconst_null
     128: invokestatic  #136                // 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;
     131: areturn

  private static final int takeInt(java.util.Iterator<java.lang.Character>, int);
    Code:
       0: aload_0
       1: iload_1
       2: invokestatic  #150                // Method take:(Ljava/util/Iterator;I)Ljava/lang/String;
       5: iconst_2
       6: invokestatic  #156                // Method kotlin/text/CharsKt.checkRadix:(I)I
       9: invokestatic  #162                // Method java/lang/Integer.parseInt:(Ljava/lang/String;I)I
      12: ireturn

  public static final java.util.List<day16.Packet> decodePackets(java.util.Iterator<java.lang.Character>);
    Code:
       0: aload_0
       1: ldc           #10                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #168                // class day16/Day16Kt$decodePackets$1
       9: dup
      10: aload_0
      11: aconst_null
      12: invokespecial #171                // Method day16/Day16Kt$decodePackets$1."<init>":(Ljava/util/Iterator;Lkotlin/coroutines/Continuation;)V
      15: checkcast     #173                // class kotlin/jvm/functions/Function2
      18: invokestatic  #179                // Method kotlin/sequences/SequencesKt.sequence:(Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence;
      21: invokestatic  #183                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
      24: areturn

  public static final java.util.List<day16.Packet> decodeNPackets(java.util.Iterator<java.lang.Character>, int);
    Code:
       0: aload_0
       1: ldc           #10                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #94                 // class kotlin/ranges/IntRange
       9: dup
      10: iconst_1
      11: iload_1
      12: invokespecial #97                 // Method kotlin/ranges/IntRange."<init>":(II)V
      15: checkcast     #99                 // class java/lang/Iterable
      18: astore_2
      19: iconst_0
      20: istore_3
      21: aload_2
      22: astore        4
      24: new           #20                 // class java/util/ArrayList
      27: dup
      28: aload_2
      29: bipush        10
      31: invokestatic  #103                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      34: invokespecial #106                // Method java/util/ArrayList."<init>":(I)V
      37: checkcast     #26                 // class java/util/Collection
      40: astore        5
      42: iconst_0
      43: istore        6
      45: aload         4
      47: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      52: astore        7
      54: aload         7
      56: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      61: ifeq          107
      64: aload         7
      66: checkcast     #115                // class kotlin/collections/IntIterator
      69: invokevirtual #118                // Method kotlin/collections/IntIterator.nextInt:()I
      72: istore        8
      74: aload         5
      76: iload         8
      78: istore        9
      80: astore        11
      82: iconst_0
      83: istore        10
      85: aload_0
      86: invokestatic  #190                // Method decodeNextPacket:(Ljava/util/Iterator;)Ljava/util/Optional;
      89: invokevirtual #194                // Method java/util/Optional.get:()Ljava/lang/Object;
      92: checkcast     #196                // class day16/Packet
      95: aload         11
      97: swap
      98: invokeinterface #130,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     103: pop
     104: goto          54
     107: aload         5
     109: checkcast     #68                 // class java/util/List
     112: nop
     113: areturn

  public static final java.util.Optional<day16.Packet> decodeNextPacket(java.util.Iterator<java.lang.Character>);
    Code:
       0: aload_0
       1: ldc           #10                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: nop
       7: getstatic     #207                // Field kotlin/Result.Companion:Lkotlin/Result$Companion;
      10: pop
      11: iconst_0
      12: istore_1
      13: aload_0
      14: iconst_3
      15: invokestatic  #209                // Method takeInt:(Ljava/util/Iterator;I)I
      18: istore_2
      19: aload_0
      20: iconst_3
      21: invokestatic  #209                // Method takeInt:(Ljava/util/Iterator;I)I
      24: istore_3
      25: iload_3
      26: iconst_4
      27: if_icmpne     48
      30: new           #211                // class day16/Literal
      33: dup
      34: iload_2
      35: aload_0
      36: invokestatic  #215                // Method decodeLiteralPayload:(Ljava/util/Iterator;)J
      39: invokespecial #218                // Method day16/Literal."<init>":(IJ)V
      42: checkcast     #196                // class day16/Packet
      45: goto          64
      48: new           #220                // class day16/Op
      51: dup
      52: iload_2
      53: iload_3
      54: aload_0
      55: invokestatic  #223                // Method decodeOperatorPayload:(Ljava/util/Iterator;)Ljava/util/List;
      58: invokespecial #226                // Method day16/Op."<init>":(IILjava/util/List;)V
      61: checkcast     #196                // class day16/Packet
      64: invokestatic  #230                // Method java/util/Optional.ofNullable:(Ljava/lang/Object;)Ljava/util/Optional;
      67: dup
      68: ldc           #232                // String ofNullable(...)
      70: invokestatic  #235                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      73: areturn
      74: astore_2
      75: getstatic     #207                // Field kotlin/Result.Companion:Lkotlin/Result$Companion;
      78: pop
      79: aload_2
      80: invokestatic  #241                // Method kotlin/ResultKt.createFailure:(Ljava/lang/Throwable;)Ljava/lang/Object;
      83: invokestatic  #244                // Method kotlin/Result."constructor-impl":(Ljava/lang/Object;)Ljava/lang/Object;
      86: astore_1
      87: aload_1
      88: invokestatic  #248                // Method kotlin/Result."exceptionOrNull-impl":(Ljava/lang/Object;)Ljava/lang/Throwable;
      91: dup
      92: ifnonnull     100
      95: pop
      96: aload_1
      97: goto          107
     100: astore_2
     101: iconst_0
     102: istore_3
     103: invokestatic  #252                // Method java/util/Optional.empty:()Ljava/util/Optional;
     106: nop
     107: dup
     108: ldc           #254                // String getOrElse(...)
     110: invokestatic  #235                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     113: checkcast     #192                // class java/util/Optional
     116: areturn
    Exception table:
       from    to  target type
           6    74    74   Class java/lang/Throwable

  private static final long decodeLiteralPayload(java.util.Iterator<java.lang.Character>);
    Code:
       0: aload_0
       1: lconst_0
       2: invokestatic  #264                // Method decodeLiteralPayload$rec:(Ljava/util/Iterator;J)J
       5: lreturn

  private static final java.util.List<day16.Packet> decodeOperatorPayload(java.util.Iterator<java.lang.Character>);
    Code:
       0: nop
       1: getstatic     #207                // Field kotlin/Result.Companion:Lkotlin/Result$Companion;
       4: pop
       5: iconst_0
       6: istore_1
       7: aload_0
       8: invokeinterface #122,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      13: checkcast     #40                 // class java/lang/Character
      16: invokevirtual #126                // Method java/lang/Character.charValue:()C
      19: tableswitch   { // 48 to 49
                    48: 40
                    49: 59
               default: 72
          }
      40: aload_0
      41: aload_0
      42: bipush        15
      44: invokestatic  #209                // Method takeInt:(Ljava/util/Iterator;I)I
      47: invokestatic  #268                // Method boundedIteratorWrap:(Ljava/util/Iterator;I)Lday16/Day16Kt$boundedIteratorWrap$1;
      50: checkcast     #109                // class java/util/Iterator
      53: invokestatic  #270                // Method decodePackets:(Ljava/util/Iterator;)Ljava/util/List;
      56: goto          104
      59: aload_0
      60: aload_0
      61: bipush        11
      63: invokestatic  #209                // Method takeInt:(Ljava/util/Iterator;I)I
      66: invokestatic  #272                // Method decodeNPackets:(Ljava/util/Iterator;I)Ljava/util/List;
      69: goto          104
      72: ldc_w         #274                // String Should never happen
      75: astore_2
      76: new           #276                // class kotlin/NotImplementedError
      79: dup
      80: new           #278                // class java/lang/StringBuilder
      83: dup
      84: invokespecial #279                // Method java/lang/StringBuilder."<init>":()V
      87: ldc_w         #281                // String An operation is not implemented:
      90: invokevirtual #285                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      93: aload_2
      94: invokevirtual #285                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      97: invokevirtual #289                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     100: invokespecial #292                // Method kotlin/NotImplementedError."<init>":(Ljava/lang/String;)V
     103: athrow
     104: nop
     105: invokestatic  #244                // Method kotlin/Result."constructor-impl":(Ljava/lang/Object;)Ljava/lang/Object;
     108: astore_1
     109: goto          125
     112: astore_2
     113: getstatic     #207                // Field kotlin/Result.Companion:Lkotlin/Result$Companion;
     116: pop
     117: aload_2
     118: invokestatic  #241                // Method kotlin/ResultKt.createFailure:(Ljava/lang/Throwable;)Ljava/lang/Object;
     121: invokestatic  #244                // Method kotlin/Result."constructor-impl":(Ljava/lang/Object;)Ljava/lang/Object;
     124: astore_1
     125: aload_1
     126: astore_1
     127: aload_1
     128: invokestatic  #248                // Method kotlin/Result."exceptionOrNull-impl":(Ljava/lang/Object;)Ljava/lang/Throwable;
     131: dup
     132: ifnonnull     140
     135: pop
     136: aload_1
     137: goto          146
     140: astore_2
     141: iconst_0
     142: istore_3
     143: invokestatic  #296                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     146: checkcast     #68                 // class java/util/List
     149: areturn
    Exception table:
       from    to  target type
           0   109   112   Class java/lang/Throwable

  private static final day16.Day16Kt$boundedIteratorWrap$1 boundedIteratorWrap(java.util.Iterator<java.lang.Character>, int);
    Code:
       0: new           #301                // class day16/Day16Kt$boundedIteratorWrap$1
       3: dup
       4: aload_0
       5: iload_1
       6: invokespecial #304                // Method day16/Day16Kt$boundedIteratorWrap$1."<init>":(Ljava/util/Iterator;I)V
       9: areturn

  public static final long sumAllVersionsOfTheTransmission(java.util.Iterator<java.lang.Character>);
    Code:
       0: aload_0
       1: ldc           #10                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #270                // Method decodePackets:(Ljava/util/Iterator;)Ljava/util/List;
      10: checkcast     #99                 // class java/lang/Iterable
      13: astore_1
      14: lconst_0
      15: lstore_2
      16: iconst_0
      17: istore        4
      19: lload_2
      20: lstore        5
      22: aload_1
      23: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      28: astore        7
      30: aload         7
      32: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      37: ifeq          76
      40: aload         7
      42: invokeinterface #122,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      47: astore        8
      49: lload         5
      51: aload         8
      53: checkcast     #196                // class day16/Packet
      56: astore        9
      58: lstore        10
      60: iconst_0
      61: istore        12
      63: lload         10
      65: aload         9
      67: invokestatic  #310                // Method sumAllVersionsOfTheTransmission$sumVersions:(Lday16/Packet;)J
      70: ladd
      71: lstore        5
      73: goto          30
      76: lload         5
      78: lreturn

  public static final long evaluateTransmission(java.util.Iterator<java.lang.Character>);
    Code:
       0: aload_0
       1: ldc           #10                 // String input
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #190                // Method decodeNextPacket:(Ljava/util/Iterator;)Ljava/util/Optional;
      10: invokevirtual #194                // Method java/util/Optional.get:()Ljava/lang/Object;
      13: checkcast     #196                // class day16/Packet
      16: invokeinterface #326,  1          // InterfaceMethod day16/Packet.getValue:()J
      21: lreturn

  public static final void main();
    Code:
       0: new           #329                // class java/io/File
       3: dup
       4: ldc_w         #331                // String ./input/day16.txt
       7: invokespecial #332                // Method java/io/File."<init>":(Ljava/lang/String;)V
      10: astore_0
      11: getstatic     #338                // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      14: astore_1
      15: iconst_0
      16: istore_2
      17: aload_0
      18: astore_3
      19: sipush        8192
      22: istore        4
      24: aload_3
      25: astore        5
      27: new           #340                // class java/io/InputStreamReader
      30: dup
      31: new           #342                // class java/io/FileInputStream
      34: dup
      35: aload         5
      37: invokespecial #345                // Method java/io/FileInputStream."<init>":(Ljava/io/File;)V
      40: checkcast     #347                // class java/io/InputStream
      43: aload_1
      44: invokespecial #350                // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/nio/charset/Charset;)V
      47: checkcast     #352                // class java/io/Reader
      50: astore        5
      52: aload         5
      54: instanceof    #354                // class java/io/BufferedReader
      57: ifeq          68
      60: aload         5
      62: checkcast     #354                // class java/io/BufferedReader
      65: goto          79
      68: new           #354                // class java/io/BufferedReader
      71: dup
      72: aload         5
      74: iload         4
      76: invokespecial #357                // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;I)V
      79: checkcast     #359                // class java/io/Closeable
      82: astore_3
      83: aconst_null
      84: astore        4
      86: nop
      87: aload_3
      88: checkcast     #354                // class java/io/BufferedReader
      91: astore        5
      93: iconst_0
      94: istore        6
      96: aload         5
      98: invokestatic  #365                // Method kotlin/io/TextStreamsKt.lineSequence:(Ljava/io/BufferedReader;)Lkotlin/sequences/Sequence;
     101: astore        7
     103: iconst_0
     104: istore        8
     106: aload         7
     108: invokestatic  #369                // Method kotlin/sequences/SequencesKt.first:(Lkotlin/sequences/Sequence;)Ljava/lang/Object;
     111: checkcast     #89                 // class java/lang/String
     114: astore        9
     116: aload         9
     118: invokestatic  #371                // Method hexToBits:(Ljava/lang/String;)Ljava/util/Iterator;
     121: invokestatic  #373                // Method sumAllVersionsOfTheTransmission:(Ljava/util/Iterator;)J
     124: lstore        10
     126: getstatic     #379                // Field java/lang/System.out:Ljava/io/PrintStream;
     129: lload         10
     131: invokevirtual #385                // Method java/io/PrintStream.println:(J)V
     134: aload         9
     136: invokestatic  #371                // Method hexToBits:(Ljava/lang/String;)Ljava/util/Iterator;
     139: invokestatic  #387                // Method evaluateTransmission:(Ljava/util/Iterator;)J
     142: lstore        10
     144: getstatic     #379                // Field java/lang/System.out:Ljava/io/PrintStream;
     147: lload         10
     149: invokevirtual #385                // Method java/io/PrintStream.println:(J)V
     152: nop
     153: getstatic     #393                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     156: astore        5
     158: aload_3
     159: aload         4
     161: invokestatic  #399                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     164: goto          187
     167: astore        6
     169: aload         6
     171: astore        4
     173: aload         6
     175: athrow
     176: astore        6
     178: aload_3
     179: aload         4
     181: invokestatic  #399                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     184: aload         6
     186: athrow
     187: nop
     188: return
    Exception table:
       from    to  target type
          86   158   167   Class java/lang/Throwable
          86   158   176   any
         167   176   176   any
         176   178   176   any

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

  private static final long decodeLiteralPayload$rec(java.util.Iterator<java.lang.Character>, long);
    Code:
       0: aload_0
       1: invokeinterface #122,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
       6: checkcast     #40                 // class java/lang/Character
       9: invokevirtual #126                // Method java/lang/Character.charValue:()C
      12: istore_3
      13: lload_1
      14: iconst_4
      15: lshl
      16: aload_0
      17: iconst_4
      18: invokestatic  #209                // Method takeInt:(Ljava/util/Iterator;I)I
      21: i2l
      22: ladd
      23: lstore        4
      25: iload_3
      26: bipush        48
      28: if_icmpne     36
      31: lload         4
      33: goto          44
      36: aload_0
      37: astore_0
      38: lload         4
      40: lstore_1
      41: goto          0
      44: lreturn

  private static final long sumAllVersionsOfTheTransmission$sumVersions(day16.Packet);
    Code:
       0: aload_0
       1: astore_1
       2: aload_1
       3: instanceof    #211                // class day16/Literal
       6: ifeq          20
       9: aload_0
      10: checkcast     #211                // class day16/Literal
      13: invokevirtual #425                // Method day16/Literal.getVersion:()I
      16: i2l
      17: goto          120
      20: aload_1
      21: instanceof    #220                // class day16/Op
      24: ifeq          112
      27: aload_0
      28: checkcast     #220                // class day16/Op
      31: invokevirtual #428                // Method day16/Op.getPackets:()Ljava/util/List;
      34: checkcast     #99                 // class java/lang/Iterable
      37: astore_2
      38: aload_0
      39: checkcast     #220                // class day16/Op
      42: invokevirtual #429                // Method day16/Op.getVersion:()I
      45: i2l
      46: lstore_3
      47: iconst_0
      48: istore        5
      50: lload_3
      51: lstore        6
      53: aload_2
      54: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      59: astore        8
      61: aload         8
      63: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      68: ifeq          107
      71: aload         8
      73: invokeinterface #122,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      78: astore        9
      80: lload         6
      82: aload         9
      84: checkcast     #196                // class day16/Packet
      87: astore        10
      89: lstore        11
      91: iconst_0
      92: istore        13
      94: lload         11
      96: aload         10
      98: invokestatic  #310                // Method sumAllVersionsOfTheTransmission$sumVersions:(Lday16/Packet;)J
     101: ladd
     102: lstore        6
     104: goto          61
     107: lload         6
     109: goto          120
     112: new           #431                // class kotlin/NoWhenBranchMatchedException
     115: dup
     116: invokespecial #432                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     119: athrow
     120: lreturn

  static {};
    Code:
       0: new           #94                 // class kotlin/ranges/IntRange
       3: dup
       4: iconst_0
       5: bipush        15
       7: invokespecial #97                 // Method kotlin/ranges/IntRange."<init>":(II)V
      10: checkcast     #99                 // class java/lang/Iterable
      13: astore_0
      14: iconst_0
      15: istore_1
      16: aload_0
      17: bipush        10
      19: invokestatic  #103                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      22: invokestatic  #440                // Method kotlin/collections/MapsKt.mapCapacity:(I)I
      25: bipush        16
      27: invokestatic  #446                // Method kotlin/ranges/RangesKt.coerceAtLeast:(II)I
      30: istore_2
      31: aload_0
      32: astore_3
      33: new           #448                // class java/util/LinkedHashMap
      36: dup
      37: iload_2
      38: invokespecial #449                // Method java/util/LinkedHashMap."<init>":(I)V
      41: checkcast     #46                 // class java/util/Map
      44: astore        4
      46: iconst_0
      47: istore        5
      49: aload_3
      50: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      55: astore        6
      57: aload         6
      59: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      64: ifeq          165
      67: aload         6
      69: checkcast     #115                // class kotlin/collections/IntIterator
      72: invokevirtual #118                // Method kotlin/collections/IntIterator.nextInt:()I
      75: istore        7
      77: aload         4
      79: astore        8
      81: iload         7
      83: istore        9
      85: iconst_0
      86: istore        10
      88: iload         9
      90: bipush        16
      92: invokestatic  #156                // Method kotlin/text/CharsKt.checkRadix:(I)I
      95: invokestatic  #452                // Method java/lang/Integer.toString:(II)Ljava/lang/String;
      98: dup
      99: ldc_w         #454                // String toString(...)
     102: invokestatic  #235                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     105: checkcast     #18                 // class java/lang/CharSequence
     108: invokestatic  #457                // Method kotlin/text/StringsKt.first:(Ljava/lang/CharSequence;)C
     111: invokestatic  #461                // Method java/lang/Character.toUpperCase:(C)C
     114: invokestatic  #44                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     117: iload         9
     119: iconst_2
     120: invokestatic  #156                // Method kotlin/text/CharsKt.checkRadix:(I)I
     123: invokestatic  #452                // Method java/lang/Integer.toString:(II)Ljava/lang/String;
     126: dup
     127: ldc_w         #454                // String toString(...)
     130: invokestatic  #235                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     133: iconst_4
     134: bipush        48
     136: invokestatic  #465                // Method kotlin/text/StringsKt.padStart:(Ljava/lang/String;IC)Ljava/lang/String;
     139: invokestatic  #471                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     142: astore        9
     144: aload         8
     146: aload         9
     148: invokevirtual #476                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     151: aload         9
     153: invokevirtual #479                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     156: invokeinterface #483,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     161: pop
     162: goto          57
     165: aload         4
     167: nop
     168: putstatic     #38                 // Field hexBinMap2:Ljava/util/Map;
     171: return
}

Compiled from "Day16.kt"
public final class day16.Day16Kt$boundedIteratorWrap$1 implements java.util.Iterator<java.lang.Character>, kotlin.jvm.internal.markers.KMappedMarker {
  private int counter;

  final java.util.Iterator<java.lang.Character> $iterator;

  final int $limit;

  day16.Day16Kt$boundedIteratorWrap$1(java.util.Iterator<java.lang.Character>, int);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #16                 // Field $iterator:Ljava/util/Iterator;
       5: aload_0
       6: iload_2
       7: putfield      #20                 // Field $limit:I
      10: aload_0
      11: invokespecial #23                 // Method java/lang/Object."<init>":()V
      14: return

  public boolean hasNext();
    Code:
       0: aload_0
       1: getfield      #16                 // Field $iterator:Ljava/util/Iterator;
       4: invokeinterface #29,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
       9: ifeq          27
      12: aload_0
      13: getfield      #32                 // Field counter:I
      16: aload_0
      17: getfield      #20                 // Field $limit:I
      20: if_icmpge     27
      23: iconst_1
      24: goto          28
      27: iconst_0
      28: ireturn

  public java.lang.Character next();
    Code:
       0: aload_0
       1: invokevirtual #35                 // Method hasNext:()Z
       4: ifeq          35
       7: aload_0
       8: aload_0
       9: getfield      #32                 // Field counter:I
      12: iconst_1
      13: iadd
      14: putfield      #32                 // Field counter:I
      17: aload_0
      18: getfield      #16                 // Field $iterator:Ljava/util/Iterator;
      21: invokeinterface #38,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      26: checkcast     #40                 // class java/lang/Character
      29: invokevirtual #44                 // Method java/lang/Character.charValue:()C
      32: goto          45
      35: new           #46                 // class java/util/NoSuchElementException
      38: dup
      39: ldc           #48                 // String End of bounded iterator
      41: invokespecial #51                 // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
      44: athrow
      45: invokestatic  #55                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      48: areturn

  public void remove();
    Code:
       0: new           #58                 // class java/lang/UnsupportedOperationException
       3: dup
       4: ldc           #60                 // String Operation is not supported for read-only collection
       6: invokespecial #61                 // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
       9: athrow

  public java.lang.Object next();
    Code:
       0: aload_0
       1: invokevirtual #63                 // Method next:()Ljava/lang/Character;
       4: areturn
}