package day18

import java.nio.file.Files
import java.nio.file.Paths

fun main() {
  fun part1(input: Input): Int {
    return input.reduce { acc, snailfish ->
      SnailfishPair(acc, snailfish).reduce()
    }.magnitude()
  }

  fun part2(input: Input): Int {
    return input.maxOf { lhs ->
      input.maxOf { rhs ->
        if (lhs != rhs) SnailfishPair(lhs, rhs).reduce().magnitude()
        else Int.MIN_VALUE
      }
    }
  }

  check(part1(readInput("test-input.txt")) == 4140)
  check(part2(readInput("test-input.txt")) == 3993)

  println(part1(readInput("input.txt")))
  println(part2(readInput("input.txt")))
}

private fun Snailfish.reduce(): Snailfish =
  reduceExplode(0)?.first?.reduce()
    ?: reduceSplit()?.reduce()
    ?: this

private fun Snailfish.reduceExplode(depth: Int): Triple<Snailfish, Int, Int>? {
  fun propagateRight(snailfish: Snailfish, add: Int): Snailfish = if (add == 0) snailfish else
    when (snailfish) {
      is SnailfishNumber -> SnailfishNumber(snailfish.value + add)
      is SnailfishPair -> SnailfishPair(snailfish.lhs, propagateRight(snailfish.rhs, add))
    }

  fun propagateLeft(snailfish: Snailfish, add: Int): Snailfish = if (add == 0) snailfish else
    when (snailfish) {
      is SnailfishNumber -> SnailfishNumber(snailfish.value + add)
      is SnailfishPair -> SnailfishPair(propagateLeft(snailfish.lhs, add), snailfish.rhs)
    }

  return when (this) {
    is SnailfishNumber -> null
    is SnailfishPair -> if (depth == 4) {
      check(lhs is SnailfishNumber && rhs is SnailfishNumber)
      Triple(SnailfishNumber(0), lhs.value, rhs.value)
    } else {
      lhs.reduceExplode(depth + 1)
        ?.let { (snailfish, left, right) ->
          Triple(SnailfishPair(snailfish, propagateLeft(rhs, right)), left, 0)
        }
        ?: rhs.reduceExplode(depth + 1)
          ?.let { (snailfish, left, right) ->
            Triple(SnailfishPair(propagateRight(lhs, left), snailfish), 0, right)
          }
    }
  }
}

private fun Snailfish.reduceSplit(): SnailfishPair? = when(this) {
  is SnailfishNumber -> if (value < 10) null else
    SnailfishPair(SnailfishNumber(value / 2), SnailfishNumber((value + 1) / 2))
  is SnailfishPair ->
    lhs.reduceSplit()?.let { SnailfishPair(it, rhs) } ?:
      rhs.reduceSplit()?.let { SnailfishPair(lhs, it) }
}

private fun Snailfish.magnitude(): Int = when(this) {
  is SnailfishNumber -> value
  is SnailfishPair -> 3 * lhs.magnitude() + 2 * rhs.magnitude()
}

private sealed interface Snailfish
private data class SnailfishPair(
  val lhs: Snailfish,
  val rhs: Snailfish,
) : Snailfish
private data class SnailfishNumber(
  val value: Int,
) : Snailfish

private class Parser(private val input: String) : AutoCloseable {
  private var ptr = 0

  fun parseSnailfish(): Snailfish = if (input[ptr] == '[') {
    parsePair()
  } else {
    parseNumber()
  }

  private fun parseNumber(): SnailfishNumber {
    check(input[ptr] in '0'..'9')
    var res = 0
    while (ptr < input.length && input[ptr].isDigit()) {
      res = 10 * res + input[ptr++].code - '0'.code
    }
    return SnailfishNumber(res)
  }

  private fun parsePair(): SnailfishPair {
    check(input[ptr++] == '[')
    val lhs = parseSnailfish()
    check(input[ptr++] == ',')
    val rhs = parseSnailfish()
    check(input[ptr++] == ']')
    return SnailfishPair(lhs, rhs)
  }

  override fun close() {
    check(ptr == input.length)
  }
}

private fun readInput(s: String): Input {
  return Files.newBufferedReader(Paths.get("src/day18/$s")).readLines().map { line ->
    Parser(line).use { it.parseSnailfish() }
  }
}

private typealias Input = List<Snailfish>

Compiled from "Solution.kt"
public final class day18.SolutionKt {
  public static final void main();
    Code:
       0: ldc           #8                  // String test-input.txt
       2: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Ljava/util/List;
       5: invokestatic  #16                 // Method main$part1:(Ljava/util/List;)I
       8: sipush        4140
      11: if_icmpne     18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: ifne          32
      22: new           #18                 // class java/lang/IllegalStateException
      25: dup
      26: ldc           #20                 // String Check failed.
      28: invokespecial #24                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      31: athrow
      32: ldc           #8                  // String test-input.txt
      34: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Ljava/util/List;
      37: invokestatic  #27                 // Method main$part2:(Ljava/util/List;)I
      40: sipush        3993
      43: if_icmpne     50
      46: iconst_1
      47: goto          51
      50: iconst_0
      51: ifne          64
      54: new           #18                 // class java/lang/IllegalStateException
      57: dup
      58: ldc           #20                 // String Check failed.
      60: invokespecial #24                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      63: athrow
      64: ldc           #29                 // String input.txt
      66: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Ljava/util/List;
      69: invokestatic  #16                 // Method main$part1:(Ljava/util/List;)I
      72: istore_0
      73: getstatic     #35                 // Field java/lang/System.out:Ljava/io/PrintStream;
      76: iload_0
      77: invokevirtual #41                 // Method java/io/PrintStream.println:(I)V
      80: ldc           #29                 // String input.txt
      82: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Ljava/util/List;
      85: invokestatic  #27                 // Method main$part2:(Ljava/util/List;)I
      88: istore_0
      89: getstatic     #35                 // Field java/lang/System.out:Ljava/io/PrintStream;
      92: iload_0
      93: invokevirtual #41                 // Method java/io/PrintStream.println:(I)V
      96: return

  private static final day18.Snailfish reduce(day18.Snailfish);
    Code:
       0: aload_0
       1: iconst_0
       2: invokestatic  #47                 // Method reduceExplode:(Lday18/Snailfish;I)Lkotlin/Triple;
       5: dup
       6: ifnull        26
       9: invokevirtual #53                 // Method kotlin/Triple.getFirst:()Ljava/lang/Object;
      12: checkcast     #55                 // class day18/Snailfish
      15: dup
      16: ifnull        26
      19: invokestatic  #57                 // Method reduce:(Lday18/Snailfish;)Lday18/Snailfish;
      22: dup
      23: ifnonnull     47
      26: pop
      27: aload_0
      28: invokestatic  #61                 // Method reduceSplit:(Lday18/Snailfish;)Lday18/SnailfishPair;
      31: dup
      32: ifnull        44
      35: checkcast     #55                 // class day18/Snailfish
      38: invokestatic  #57                 // Method reduce:(Lday18/Snailfish;)Lday18/Snailfish;
      41: goto          47
      44: pop
      45: nop
      46: aload_0
      47: areturn

  private static final kotlin.Triple<day18.Snailfish, java.lang.Integer, java.lang.Integer> reduceExplode(day18.Snailfish, int);
    Code:
       0: aload_0
       1: astore_2
       2: aload_2
       3: instanceof    #68                 // class day18/SnailfishNumber
       6: ifeq          13
       9: aconst_null
      10: goto          336
      13: aload_2
      14: instanceof    #65                 // class day18/SnailfishPair
      17: ifeq          328
      20: iload_1
      21: iconst_4
      22: if_icmpne     120
      25: nop
      26: aload_0
      27: checkcast     #65                 // class day18/SnailfishPair
      30: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
      33: instanceof    #68                 // class day18/SnailfishNumber
      36: ifeq          56
      39: aload_0
      40: checkcast     #65                 // class day18/SnailfishPair
      43: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
      46: instanceof    #68                 // class day18/SnailfishNumber
      49: ifeq          56
      52: iconst_1
      53: goto          57
      56: iconst_0
      57: ifne          70
      60: new           #18                 // class java/lang/IllegalStateException
      63: dup
      64: ldc           #20                 // String Check failed.
      66: invokespecial #24                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      69: athrow
      70: new           #49                 // class kotlin/Triple
      73: dup
      74: new           #68                 // class day18/SnailfishNumber
      77: dup
      78: iconst_0
      79: invokespecial #77                 // Method day18/SnailfishNumber."<init>":(I)V
      82: aload_0
      83: checkcast     #65                 // class day18/SnailfishPair
      86: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
      89: checkcast     #68                 // class day18/SnailfishNumber
      92: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
      95: invokestatic  #87                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      98: aload_0
      99: checkcast     #65                 // class day18/SnailfishPair
     102: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
     105: checkcast     #68                 // class day18/SnailfishNumber
     108: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
     111: invokestatic  #87                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     114: invokespecial #90                 // Method kotlin/Triple."<init>":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
     117: goto          336
     120: aload_0
     121: checkcast     #65                 // class day18/SnailfishPair
     124: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
     127: iload_1
     128: iconst_1
     129: iadd
     130: invokestatic  #47                 // Method reduceExplode:(Lday18/Snailfish;I)Lkotlin/Triple;
     133: astore_3
     134: aload_3
     135: ifnull        221
     138: aload_3
     139: astore        5
     141: iconst_0
     142: istore        6
     144: aload         5
     146: invokevirtual #93                 // Method kotlin/Triple.component1:()Ljava/lang/Object;
     149: checkcast     #55                 // class day18/Snailfish
     152: astore        7
     154: aload         5
     156: invokevirtual #96                 // Method kotlin/Triple.component2:()Ljava/lang/Object;
     159: checkcast     #98                 // class java/lang/Number
     162: invokevirtual #101                // Method java/lang/Number.intValue:()I
     165: istore        8
     167: aload         5
     169: invokevirtual #104                // Method kotlin/Triple.component3:()Ljava/lang/Object;
     172: checkcast     #98                 // class java/lang/Number
     175: invokevirtual #101                // Method java/lang/Number.intValue:()I
     178: istore        9
     180: new           #49                 // class kotlin/Triple
     183: dup
     184: new           #65                 // class day18/SnailfishPair
     187: dup
     188: aload         7
     190: aload_0
     191: checkcast     #65                 // class day18/SnailfishPair
     194: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
     197: iload         9
     199: invokestatic  #108                // Method reduceExplode$propagateLeft:(Lday18/Snailfish;I)Lday18/Snailfish;
     202: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     205: iload         8
     207: invokestatic  #87                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     210: iconst_0
     211: invokestatic  #87                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     214: invokespecial #90                 // Method kotlin/Triple."<init>":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
     217: nop
     218: goto          336
     221: aload_0
     222: checkcast     #65                 // class day18/SnailfishPair
     225: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
     228: iload_1
     229: iconst_1
     230: iadd
     231: invokestatic  #47                 // Method reduceExplode:(Lday18/Snailfish;I)Lkotlin/Triple;
     234: astore        4
     236: aload         4
     238: ifnull        324
     241: aload         4
     243: astore        6
     245: iconst_0
     246: istore        7
     248: aload         6
     250: invokevirtual #93                 // Method kotlin/Triple.component1:()Ljava/lang/Object;
     253: checkcast     #55                 // class day18/Snailfish
     256: astore        8
     258: aload         6
     260: invokevirtual #96                 // Method kotlin/Triple.component2:()Ljava/lang/Object;
     263: checkcast     #98                 // class java/lang/Number
     266: invokevirtual #101                // Method java/lang/Number.intValue:()I
     269: istore        9
     271: aload         6
     273: invokevirtual #104                // Method kotlin/Triple.component3:()Ljava/lang/Object;
     276: checkcast     #98                 // class java/lang/Number
     279: invokevirtual #101                // Method java/lang/Number.intValue:()I
     282: istore        10
     284: new           #49                 // class kotlin/Triple
     287: dup
     288: new           #65                 // class day18/SnailfishPair
     291: dup
     292: aload_0
     293: checkcast     #65                 // class day18/SnailfishPair
     296: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
     299: iload         9
     301: invokestatic  #114                // Method reduceExplode$propagateRight:(Lday18/Snailfish;I)Lday18/Snailfish;
     304: aload         8
     306: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     309: iconst_0
     310: invokestatic  #87                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     313: iload         10
     315: invokestatic  #87                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     318: invokespecial #90                 // Method kotlin/Triple."<init>":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
     321: goto          336
     324: aconst_null
     325: goto          336
     328: new           #116                // class kotlin/NoWhenBranchMatchedException
     331: dup
     332: invokespecial #118                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     335: athrow
     336: areturn

  private static final day18.SnailfishPair reduceSplit(day18.Snailfish);
    Code:
       0: aload_0
       1: astore_1
       2: aload_1
       3: instanceof    #68                 // class day18/SnailfishNumber
       6: ifeq          75
       9: aload_0
      10: checkcast     #68                 // class day18/SnailfishNumber
      13: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
      16: bipush        10
      18: if_icmpge     25
      21: aconst_null
      22: goto          174
      25: new           #65                 // class day18/SnailfishPair
      28: dup
      29: new           #68                 // class day18/SnailfishNumber
      32: dup
      33: aload_0
      34: checkcast     #68                 // class day18/SnailfishNumber
      37: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
      40: iconst_2
      41: idiv
      42: invokespecial #77                 // Method day18/SnailfishNumber."<init>":(I)V
      45: checkcast     #55                 // class day18/Snailfish
      48: new           #68                 // class day18/SnailfishNumber
      51: dup
      52: aload_0
      53: checkcast     #68                 // class day18/SnailfishNumber
      56: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
      59: iconst_1
      60: iadd
      61: iconst_2
      62: idiv
      63: invokespecial #77                 // Method day18/SnailfishNumber."<init>":(I)V
      66: checkcast     #55                 // class day18/Snailfish
      69: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
      72: goto          174
      75: aload_1
      76: instanceof    #65                 // class day18/SnailfishPair
      79: ifeq          166
      82: aload_0
      83: checkcast     #65                 // class day18/SnailfishPair
      86: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
      89: invokestatic  #61                 // Method reduceSplit:(Lday18/Snailfish;)Lday18/SnailfishPair;
      92: dup
      93: ifnull        121
      96: astore_2
      97: iconst_0
      98: istore_3
      99: new           #65                 // class day18/SnailfishPair
     102: dup
     103: aload_2
     104: checkcast     #55                 // class day18/Snailfish
     107: aload_0
     108: checkcast     #65                 // class day18/SnailfishPair
     111: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
     114: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     117: nop
     118: goto          174
     121: pop
     122: aload_0
     123: checkcast     #65                 // class day18/SnailfishPair
     126: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
     129: invokestatic  #61                 // Method reduceSplit:(Lday18/Snailfish;)Lday18/SnailfishPair;
     132: dup
     133: ifnull        161
     136: astore_3
     137: iconst_0
     138: istore        4
     140: new           #65                 // class day18/SnailfishPair
     143: dup
     144: aload_0
     145: checkcast     #65                 // class day18/SnailfishPair
     148: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
     151: aload_3
     152: checkcast     #55                 // class day18/Snailfish
     155: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     158: goto          174
     161: pop
     162: aconst_null
     163: goto          174
     166: new           #116                // class kotlin/NoWhenBranchMatchedException
     169: dup
     170: invokespecial #118                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
     173: athrow
     174: areturn

  private static final int magnitude(day18.Snailfish);
    Code:
       0: aload_0
       1: astore_1
       2: aload_1
       3: instanceof    #68                 // class day18/SnailfishNumber
       6: ifeq          19
       9: aload_0
      10: checkcast     #68                 // class day18/SnailfishNumber
      13: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
      16: goto          62
      19: aload_1
      20: instanceof    #65                 // class day18/SnailfishPair
      23: ifeq          54
      26: iconst_3
      27: aload_0
      28: checkcast     #65                 // class day18/SnailfishPair
      31: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
      34: invokestatic  #135                // Method magnitude:(Lday18/Snailfish;)I
      37: imul
      38: iconst_2
      39: aload_0
      40: checkcast     #65                 // class day18/SnailfishPair
      43: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
      46: invokestatic  #135                // Method magnitude:(Lday18/Snailfish;)I
      49: imul
      50: iadd
      51: goto          62
      54: new           #116                // class kotlin/NoWhenBranchMatchedException
      57: dup
      58: invokespecial #118                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
      61: athrow
      62: ireturn

  private static final java.util.List<day18.Snailfish> readInput(java.lang.String);
    Code:
       0: new           #141                // class java/lang/StringBuilder
       3: dup
       4: invokespecial #142                // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #144                // String src/day18/
       9: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      16: invokevirtual #152                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      19: iconst_0
      20: anewarray     #154                // class java/lang/String
      23: invokestatic  #160                // Method java/nio/file/Paths.get:(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;
      26: invokestatic  #166                // Method java/nio/file/Files.newBufferedReader:(Ljava/nio/file/Path;)Ljava/io/BufferedReader;
      29: dup
      30: ldc           #168                // String newBufferedReader(...)
      32: invokestatic  #174                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      35: checkcast     #176                // class java/io/Reader
      38: invokestatic  #182                // Method kotlin/io/TextStreamsKt.readLines:(Ljava/io/Reader;)Ljava/util/List;
      41: checkcast     #184                // class java/lang/Iterable
      44: astore_1
      45: iconst_0
      46: istore_2
      47: aload_1
      48: astore_3
      49: new           #186                // class java/util/ArrayList
      52: dup
      53: aload_1
      54: bipush        10
      56: invokestatic  #192                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      59: invokespecial #193                // Method java/util/ArrayList."<init>":(I)V
      62: checkcast     #195                // class java/util/Collection
      65: astore        4
      67: iconst_0
      68: istore        5
      70: aload_3
      71: invokeinterface #199,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      76: astore        6
      78: aload         6
      80: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      85: ifeq          192
      88: aload         6
      90: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      95: astore        7
      97: aload         4
      99: aload         7
     101: checkcast     #154                // class java/lang/String
     104: astore        8
     106: astore        14
     108: iconst_0
     109: istore        9
     111: new           #210                // class day18/Parser
     114: dup
     115: aload         8
     117: invokespecial #211                // Method day18/Parser."<init>":(Ljava/lang/String;)V
     120: checkcast     #213                // class java/lang/AutoCloseable
     123: astore        10
     125: aconst_null
     126: astore        11
     128: nop
     129: aload         10
     131: checkcast     #210                // class day18/Parser
     134: astore        12
     136: iconst_0
     137: istore        13
     139: aload         12
     141: invokevirtual #216                // Method day18/Parser.parseSnailfish:()Lday18/Snailfish;
     144: astore        12
     146: aload         10
     148: aload         11
     150: invokestatic  #222                // Method kotlin/jdk7/AutoCloseableKt.closeFinally:(Ljava/lang/AutoCloseable;Ljava/lang/Throwable;)V
     153: aload         12
     155: goto          179
     158: astore        13
     160: aload         13
     162: astore        11
     164: aload         13
     166: athrow
     167: astore        13
     169: aload         10
     171: aload         11
     173: invokestatic  #222                // Method kotlin/jdk7/AutoCloseableKt.closeFinally:(Ljava/lang/AutoCloseable;Ljava/lang/Throwable;)V
     176: aload         13
     178: athrow
     179: nop
     180: aload         14
     182: swap
     183: invokeinterface #226,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     188: pop
     189: goto          78
     192: aload         4
     194: checkcast     #228                // class java/util/List
     197: nop
     198: areturn
    Exception table:
       from    to  target type
         128   146   158   Class java/lang/Throwable
         128   146   167   any
         158   167   167   any
         167   169   167   any

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

  private static final int main$part1(java.util.List<? extends day18.Snailfish>);
    Code:
       0: aload_0
       1: checkcast     #184                // class java/lang/Iterable
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: invokeinterface #199,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      13: astore_3
      14: aload_3
      15: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      20: ifne          33
      23: new           #251                // class java/lang/UnsupportedOperationException
      26: dup
      27: ldc           #253                // String Empty collection can\'t be reduced.
      29: invokespecial #254                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
      32: athrow
      33: aload_3
      34: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      39: astore        4
      41: aload_3
      42: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          93
      50: aload         4
      52: aload_3
      53: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      58: checkcast     #55                 // class day18/Snailfish
      61: astore        5
      63: checkcast     #55                 // class day18/Snailfish
      66: astore        6
      68: iconst_0
      69: istore        7
      71: new           #65                 // class day18/SnailfishPair
      74: dup
      75: aload         6
      77: aload         5
      79: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
      82: checkcast     #55                 // class day18/Snailfish
      85: invokestatic  #57                 // Method reduce:(Lday18/Snailfish;)Lday18/Snailfish;
      88: astore        4
      90: goto          41
      93: aload         4
      95: checkcast     #55                 // class day18/Snailfish
      98: invokestatic  #135                // Method magnitude:(Lday18/Snailfish;)I
     101: ireturn

  private static final int main$part2(java.util.List<? extends day18.Snailfish>);
    Code:
       0: aload_0
       1: checkcast     #184                // class java/lang/Iterable
       4: invokeinterface #199,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
       9: astore_1
      10: aload_1
      11: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      16: ifne          27
      19: new           #265                // class java/util/NoSuchElementException
      22: dup
      23: invokespecial #266                // Method java/util/NoSuchElementException."<init>":()V
      26: athrow
      27: aload_1
      28: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      33: checkcast     #55                 // class day18/Snailfish
      36: astore_2
      37: iconst_0
      38: istore_3
      39: aload_0
      40: checkcast     #184                // class java/lang/Iterable
      43: invokeinterface #199,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      48: astore        4
      50: aload         4
      52: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      57: ifne          68
      60: new           #265                // class java/util/NoSuchElementException
      63: dup
      64: invokespecial #266                // Method java/util/NoSuchElementException."<init>":()V
      67: athrow
      68: aload         4
      70: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      75: checkcast     #55                 // class day18/Snailfish
      78: astore        5
      80: iconst_0
      81: istore        6
      83: aload_2
      84: aload         5
      86: invokestatic  #270                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      89: ifne          114
      92: new           #65                 // class day18/SnailfishPair
      95: dup
      96: aload_2
      97: aload         5
      99: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     102: checkcast     #55                 // class day18/Snailfish
     105: invokestatic  #57                 // Method reduce:(Lday18/Snailfish;)Lday18/Snailfish;
     108: invokestatic  #135                // Method magnitude:(Lday18/Snailfish;)I
     111: goto          117
     114: ldc_w         #271                // int -2147483648
     117: istore        5
     119: aload         4
     121: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     126: ifeq          194
     129: aload         4
     131: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     136: checkcast     #55                 // class day18/Snailfish
     139: astore        6
     141: iconst_0
     142: istore        7
     144: aload_2
     145: aload         6
     147: invokestatic  #270                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     150: ifne          175
     153: new           #65                 // class day18/SnailfishPair
     156: dup
     157: aload_2
     158: aload         6
     160: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     163: checkcast     #55                 // class day18/Snailfish
     166: invokestatic  #57                 // Method reduce:(Lday18/Snailfish;)Lday18/Snailfish;
     169: invokestatic  #135                // Method magnitude:(Lday18/Snailfish;)I
     172: goto          178
     175: ldc_w         #271                // int -2147483648
     178: istore        6
     180: iload         5
     182: iload         6
     184: if_icmpge     119
     187: iload         6
     189: istore        5
     191: goto          119
     194: iload         5
     196: nop
     197: istore_2
     198: aload_1
     199: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     204: ifeq          389
     207: aload_1
     208: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     213: checkcast     #55                 // class day18/Snailfish
     216: astore_3
     217: iconst_0
     218: istore        4
     220: aload_0
     221: checkcast     #184                // class java/lang/Iterable
     224: invokeinterface #199,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     229: astore        5
     231: aload         5
     233: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     238: ifne          249
     241: new           #265                // class java/util/NoSuchElementException
     244: dup
     245: invokespecial #266                // Method java/util/NoSuchElementException."<init>":()V
     248: athrow
     249: aload         5
     251: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     256: checkcast     #55                 // class day18/Snailfish
     259: astore        6
     261: iconst_0
     262: istore        7
     264: aload_3
     265: aload         6
     267: invokestatic  #270                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     270: ifne          295
     273: new           #65                 // class day18/SnailfishPair
     276: dup
     277: aload_3
     278: aload         6
     280: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     283: checkcast     #55                 // class day18/Snailfish
     286: invokestatic  #57                 // Method reduce:(Lday18/Snailfish;)Lday18/Snailfish;
     289: invokestatic  #135                // Method magnitude:(Lday18/Snailfish;)I
     292: goto          298
     295: ldc_w         #271                // int -2147483648
     298: istore        6
     300: aload         5
     302: invokeinterface #205,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     307: ifeq          375
     310: aload         5
     312: invokeinterface #208,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     317: checkcast     #55                 // class day18/Snailfish
     320: astore        7
     322: iconst_0
     323: istore        8
     325: aload_3
     326: aload         7
     328: invokestatic  #270                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     331: ifne          356
     334: new           #65                 // class day18/SnailfishPair
     337: dup
     338: aload_3
     339: aload         7
     341: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
     344: checkcast     #55                 // class day18/Snailfish
     347: invokestatic  #57                 // Method reduce:(Lday18/Snailfish;)Lday18/Snailfish;
     350: invokestatic  #135                // Method magnitude:(Lday18/Snailfish;)I
     353: goto          359
     356: ldc_w         #271                // int -2147483648
     359: istore        7
     361: iload         6
     363: iload         7
     365: if_icmpge     300
     368: iload         7
     370: istore        6
     372: goto          300
     375: iload         6
     377: nop
     378: istore_3
     379: iload_2
     380: iload_3
     381: if_icmpge     198
     384: iload_3
     385: istore_2
     386: goto          198
     389: iload_2
     390: ireturn

  private static final day18.Snailfish reduceExplode$propagateRight(day18.Snailfish, int);
    Code:
       0: iload_1
       1: ifne          8
       4: aload_0
       5: goto          85
       8: aload_0
       9: astore_2
      10: aload_2
      11: instanceof    #68                 // class day18/SnailfishNumber
      14: ifeq          39
      17: new           #68                 // class day18/SnailfishNumber
      20: dup
      21: aload_0
      22: checkcast     #68                 // class day18/SnailfishNumber
      25: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
      28: iload_1
      29: iadd
      30: invokespecial #77                 // Method day18/SnailfishNumber."<init>":(I)V
      33: checkcast     #55                 // class day18/Snailfish
      36: goto          85
      39: aload_2
      40: instanceof    #65                 // class day18/SnailfishPair
      43: ifeq          77
      46: new           #65                 // class day18/SnailfishPair
      49: dup
      50: aload_0
      51: checkcast     #65                 // class day18/SnailfishPair
      54: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
      57: aload_0
      58: checkcast     #65                 // class day18/SnailfishPair
      61: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
      64: iload_1
      65: invokestatic  #114                // Method reduceExplode$propagateRight:(Lday18/Snailfish;I)Lday18/Snailfish;
      68: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
      71: checkcast     #55                 // class day18/Snailfish
      74: goto          85
      77: new           #116                // class kotlin/NoWhenBranchMatchedException
      80: dup
      81: invokespecial #118                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
      84: athrow
      85: areturn

  private static final day18.Snailfish reduceExplode$propagateLeft(day18.Snailfish, int);
    Code:
       0: iload_1
       1: ifne          8
       4: aload_0
       5: goto          85
       8: aload_0
       9: astore_2
      10: aload_2
      11: instanceof    #68                 // class day18/SnailfishNumber
      14: ifeq          39
      17: new           #68                 // class day18/SnailfishNumber
      20: dup
      21: aload_0
      22: checkcast     #68                 // class day18/SnailfishNumber
      25: invokevirtual #81                 // Method day18/SnailfishNumber.getValue:()I
      28: iload_1
      29: iadd
      30: invokespecial #77                 // Method day18/SnailfishNumber."<init>":(I)V
      33: checkcast     #55                 // class day18/Snailfish
      36: goto          85
      39: aload_2
      40: instanceof    #65                 // class day18/SnailfishPair
      43: ifeq          77
      46: new           #65                 // class day18/SnailfishPair
      49: dup
      50: aload_0
      51: checkcast     #65                 // class day18/SnailfishPair
      54: invokevirtual #72                 // Method day18/SnailfishPair.getLhs:()Lday18/Snailfish;
      57: iload_1
      58: invokestatic  #108                // Method reduceExplode$propagateLeft:(Lday18/Snailfish;I)Lday18/Snailfish;
      61: aload_0
      62: checkcast     #65                 // class day18/SnailfishPair
      65: invokevirtual #75                 // Method day18/SnailfishPair.getRhs:()Lday18/Snailfish;
      68: invokespecial #111                // Method day18/SnailfishPair."<init>":(Lday18/Snailfish;Lday18/Snailfish;)V
      71: checkcast     #55                 // class day18/Snailfish
      74: goto          85
      77: new           #116                // class kotlin/NoWhenBranchMatchedException
      80: dup
      81: invokespecial #118                // Method kotlin/NoWhenBranchMatchedException."<init>":()V
      84: athrow
      85: areturn
}


package day20

import java.nio.file.Files
import java.nio.file.Paths

fun main() {
  fun wrap(field: List<String>, surrounding: Char = '.'): List<String> {
    val length = field.first().length
    val darkRow = buildString(length) { repeat(length) { append(surrounding) } }
    val fix = List(3) { darkRow }
    return (fix + field + fix).map { "$surrounding$surrounding$surrounding$it$surrounding$surrounding$surrounding" }
  }

  fun iterate(wrapped: List<String>, decoder: String): List<String> {
    return buildList(wrapped.size - 2) {
      for (i in 1 until wrapped.lastIndex) {
        add(
          buildString(wrapped[i].length - 2) {
            for (j in 1 until wrapped[i].lastIndex) {
              var index = 0
              for (di in -1..1) {
                for (dj in -1..1) {
                  index = 2 * index + if (wrapped[i + di][j + dj] == '#') 1 else 0
                }
              }
              append(decoder[index])
            }
          }
        )
      }
    }
  }

  fun part1(input: Input): Int {
    return iterate(
      iterate(wrap(input.second), input.first).let { wrap(it, it.first().first()) },
      input.first
    ).sumOf {
      it.count { it == '#' }
    }
  }

  fun part2(input: Input): Int {
    var image = wrap(input.second)
    repeat(50) {
      val next = iterate(image, input.first)
      image = wrap(next, next.first().first())
    }
    return image.sumOf { it.count { it == '#' } }
  }

  check(part1(readInput("test-input.txt")) == 35)
  check(part2(readInput("test-input.txt")) == 3351)

  println(part1(readInput("input.txt")))
  println(part2(readInput("input.txt")))
}

private fun readInput(s: String): Input {
  return Files.newBufferedReader(Paths.get("src/day20/$s")).readLines().let { lines ->
    Pair(
      lines.first(),
      lines.drop(2).filter { it.isNotBlank() }
    )
  }
}

private typealias Input = Pair<String, List<String>>

Compiled from "Solution.kt"
public final class day20.SolutionKt {
  public static final void main();
    Code:
       0: ldc           #8                  // String test-input.txt
       2: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Lkotlin/Pair;
       5: invokestatic  #16                 // Method main$part1:(Lkotlin/Pair;)I
       8: bipush        35
      10: if_icmpne     17
      13: iconst_1
      14: goto          18
      17: iconst_0
      18: ifne          31
      21: new           #18                 // class java/lang/IllegalStateException
      24: dup
      25: ldc           #20                 // String Check failed.
      27: invokespecial #24                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      30: athrow
      31: ldc           #8                  // String test-input.txt
      33: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Lkotlin/Pair;
      36: invokestatic  #27                 // Method main$part2:(Lkotlin/Pair;)I
      39: sipush        3351
      42: if_icmpne     49
      45: iconst_1
      46: goto          50
      49: iconst_0
      50: ifne          63
      53: new           #18                 // class java/lang/IllegalStateException
      56: dup
      57: ldc           #20                 // String Check failed.
      59: invokespecial #24                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
      62: athrow
      63: ldc           #29                 // String input.txt
      65: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Lkotlin/Pair;
      68: invokestatic  #16                 // Method main$part1:(Lkotlin/Pair;)I
      71: istore_0
      72: getstatic     #35                 // Field java/lang/System.out:Ljava/io/PrintStream;
      75: iload_0
      76: invokevirtual #41                 // Method java/io/PrintStream.println:(I)V
      79: ldc           #29                 // String input.txt
      81: invokestatic  #12                 // Method readInput:(Ljava/lang/String;)Lkotlin/Pair;
      84: invokestatic  #27                 // Method main$part2:(Lkotlin/Pair;)I
      87: istore_0
      88: getstatic     #35                 // Field java/lang/System.out:Ljava/io/PrintStream;
      91: iload_0
      92: invokevirtual #41                 // Method java/io/PrintStream.println:(I)V
      95: return

  private static final kotlin.Pair<java.lang.String, java.util.List<java.lang.String>> readInput(java.lang.String);
    Code:
       0: new           #44                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #46                 // Method java/lang/StringBuilder."<init>":()V
       7: ldc           #48                 // String src/day20/
       9: invokevirtual #52                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      12: aload_0
      13: invokevirtual #52                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      16: invokevirtual #56                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      19: iconst_0
      20: anewarray     #58                 // class java/lang/String
      23: invokestatic  #64                 // Method java/nio/file/Paths.get:(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;
      26: invokestatic  #70                 // Method java/nio/file/Files.newBufferedReader:(Ljava/nio/file/Path;)Ljava/io/BufferedReader;
      29: dup
      30: ldc           #72                 // String newBufferedReader(...)
      32: invokestatic  #78                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      35: checkcast     #80                 // class java/io/Reader
      38: invokestatic  #86                 // Method kotlin/io/TextStreamsKt.readLines:(Ljava/io/Reader;)Ljava/util/List;
      41: astore_1
      42: iconst_0
      43: istore_2
      44: aload_1
      45: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      48: aload_1
      49: checkcast     #94                 // class java/lang/Iterable
      52: iconst_2
      53: invokestatic  #98                 // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      56: checkcast     #94                 // class java/lang/Iterable
      59: astore_3
      60: astore        4
      62: iconst_0
      63: istore        5
      65: aload_3
      66: astore        6
      68: new           #100                // class java/util/ArrayList
      71: dup
      72: invokespecial #101                // Method java/util/ArrayList."<init>":()V
      75: checkcast     #103                // class java/util/Collection
      78: astore        7
      80: iconst_0
      81: istore        8
      83: aload         6
      85: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      90: astore        9
      92: aload         9
      94: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      99: ifeq          154
     102: aload         9
     104: invokeinterface #117,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     109: astore        10
     111: aload         10
     113: checkcast     #58                 // class java/lang/String
     116: astore        11
     118: iconst_0
     119: istore        12
     121: aload         11
     123: checkcast     #119                // class java/lang/CharSequence
     126: invokestatic  #125                // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
     129: ifne          136
     132: iconst_1
     133: goto          137
     136: iconst_0
     137: nop
     138: ifeq          92
     141: aload         7
     143: aload         10
     145: invokeinterface #129,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     150: pop
     151: goto          92
     154: aload         7
     156: checkcast     #131                // class java/util/List
     159: nop
     160: aload         4
     162: swap
     163: astore        13
     165: astore        14
     167: new           #133                // class kotlin/Pair
     170: dup
     171: aload         14
     173: aload         13
     175: invokespecial #136                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     178: nop
     179: nop
     180: areturn

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

  private static final java.util.List<java.lang.String> main$wrap(java.util.List<java.lang.String>, char);
    Code:
       0: aload_0
       1: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
       4: checkcast     #58                 // class java/lang/String
       7: invokevirtual #165                // Method java/lang/String.length:()I
      10: istore_2
      11: new           #44                 // class java/lang/StringBuilder
      14: dup
      15: iload_2
      16: invokespecial #167                // Method java/lang/StringBuilder."<init>":(I)V
      19: astore        4
      21: aload         4
      23: astore        5
      25: iconst_0
      26: istore        6
      28: iconst_0
      29: istore        7
      31: iload         7
      33: iload_2
      34: if_icmpge     57
      37: iload         7
      39: istore        8
      41: iconst_0
      42: istore        9
      44: aload         5
      46: iload_1
      47: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      50: pop
      51: iinc          7, 1
      54: goto          31
      57: nop
      58: aload         4
      60: invokevirtual #56                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      63: astore_3
      64: iconst_3
      65: istore        5
      67: new           #100                // class java/util/ArrayList
      70: dup
      71: iload         5
      73: invokespecial #171                // Method java/util/ArrayList."<init>":(I)V
      76: astore        6
      78: iconst_0
      79: istore        7
      81: iload         7
      83: iload         5
      85: if_icmpge     117
      88: iload         7
      90: istore        8
      92: aload         6
      94: iload         8
      96: istore        9
      98: astore        14
     100: iconst_0
     101: istore        10
     103: aload_3
     104: aload         14
     106: swap
     107: invokevirtual #172                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
     110: pop
     111: iinc          7, 1
     114: goto          81
     117: aload         6
     119: checkcast     #131                // class java/util/List
     122: astore        4
     124: aload         4
     126: checkcast     #103                // class java/util/Collection
     129: aload_0
     130: checkcast     #94                 // class java/lang/Iterable
     133: invokestatic  #176                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     136: checkcast     #103                // class java/util/Collection
     139: aload         4
     141: checkcast     #94                 // class java/lang/Iterable
     144: invokestatic  #176                // Method kotlin/collections/CollectionsKt.plus:(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
     147: checkcast     #94                 // class java/lang/Iterable
     150: astore        5
     152: iconst_0
     153: istore        6
     155: aload         5
     157: astore        7
     159: new           #100                // class java/util/ArrayList
     162: dup
     163: aload         5
     165: bipush        10
     167: invokestatic  #180                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     170: invokespecial #171                // Method java/util/ArrayList."<init>":(I)V
     173: checkcast     #103                // class java/util/Collection
     176: astore        8
     178: iconst_0
     179: istore        9
     181: aload         7
     183: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     188: astore        10
     190: aload         10
     192: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     197: ifeq          274
     200: aload         10
     202: invokeinterface #117,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     207: astore        11
     209: aload         8
     211: aload         11
     213: checkcast     #58                 // class java/lang/String
     216: astore        12
     218: astore        14
     220: iconst_0
     221: istore        13
     223: new           #44                 // class java/lang/StringBuilder
     226: dup
     227: invokespecial #46                 // Method java/lang/StringBuilder."<init>":()V
     230: iload_1
     231: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     234: iload_1
     235: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     238: iload_1
     239: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     242: aload         12
     244: invokevirtual #52                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     247: iload_1
     248: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     251: iload_1
     252: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     255: iload_1
     256: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     259: invokevirtual #56                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     262: aload         14
     264: swap
     265: invokeinterface #129,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     270: pop
     271: goto          190
     274: aload         8
     276: checkcast     #131                // class java/util/List
     279: nop
     280: areturn

  static java.util.List main$wrap$default(java.util.List, char, int, java.lang.Object);
    Code:
       0: iload_2
       1: iconst_2
       2: iand
       3: ifeq          9
       6: bipush        46
       8: istore_1
       9: aload_0
      10: iload_1
      11: invokestatic  #200                // Method main$wrap:(Ljava/util/List;C)Ljava/util/List;
      14: areturn

  private static final java.util.List<java.lang.String> main$iterate(java.util.List<java.lang.String>, java.lang.String);
    Code:
       0: aload_0
       1: invokeinterface #206,  1          // InterfaceMethod java/util/List.size:()I
       6: iconst_2
       7: isub
       8: invokestatic  #210                // Method kotlin/collections/CollectionsKt.createListBuilder:(I)Ljava/util/List;
      11: astore_2
      12: aload_2
      13: astore_3
      14: iconst_0
      15: istore        4
      17: iconst_1
      18: istore        5
      20: aload_0
      21: invokestatic  #214                // Method kotlin/collections/CollectionsKt.getLastIndex:(Ljava/util/List;)I
      24: istore        6
      26: iload         5
      28: iload         6
      30: if_icmpge     208
      33: aload_3
      34: aload_0
      35: iload         5
      37: invokeinterface #217,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      42: checkcast     #58                 // class java/lang/String
      45: invokevirtual #165                // Method java/lang/String.length:()I
      48: iconst_2
      49: isub
      50: istore        7
      52: new           #44                 // class java/lang/StringBuilder
      55: dup
      56: iload         7
      58: invokespecial #167                // Method java/lang/StringBuilder."<init>":(I)V
      61: astore        8
      63: aload         8
      65: astore        9
      67: astore        10
      69: iconst_0
      70: istore        11
      72: iconst_1
      73: istore        12
      75: aload_0
      76: iload         5
      78: invokeinterface #217,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      83: checkcast     #119                // class java/lang/CharSequence
      86: invokestatic  #220                // Method kotlin/text/StringsKt.getLastIndex:(Ljava/lang/CharSequence;)I
      89: istore        13
      91: iload         12
      93: iload         13
      95: if_icmpge     188
      98: iconst_0
      99: istore        14
     101: iconst_m1
     102: istore        15
     104: iload         15
     106: iconst_2
     107: if_icmpge     170
     110: iconst_m1
     111: istore        16
     113: iload         16
     115: iconst_2
     116: if_icmpge     164
     119: iconst_2
     120: iload         14
     122: imul
     123: aload_0
     124: iload         5
     126: iload         15
     128: iadd
     129: invokeinterface #217,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     134: checkcast     #58                 // class java/lang/String
     137: iload         12
     139: iload         16
     141: iadd
     142: invokevirtual #224                // Method java/lang/String.charAt:(I)C
     145: bipush        35
     147: if_icmpne     154
     150: iconst_1
     151: goto          155
     154: iconst_0
     155: iadd
     156: istore        14
     158: iinc          16, 1
     161: goto          113
     164: iinc          15, 1
     167: goto          104
     170: aload         9
     172: aload_1
     173: iload         14
     175: invokevirtual #224                // Method java/lang/String.charAt:(I)C
     178: invokevirtual #170                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     181: pop
     182: iinc          12, 1
     185: goto          91
     188: nop
     189: aload         10
     191: aload         8
     193: invokevirtual #56                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     196: invokeinterface #225,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     201: pop
     202: iinc          5, 1
     205: goto          26
     208: nop
     209: aload_2
     210: invokestatic  #229                // Method kotlin/collections/CollectionsKt.build:(Ljava/util/List;)Ljava/util/List;
     213: areturn

  private static final int main$part1(kotlin.Pair<java.lang.String, ? extends java.util.List<java.lang.String>>);
    Code:
       0: aload_0
       1: invokevirtual #244                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
       4: checkcast     #131                // class java/util/List
       7: iconst_0
       8: iconst_2
       9: aconst_null
      10: invokestatic  #246                // Method main$wrap$default:(Ljava/util/List;CILjava/lang/Object;)Ljava/util/List;
      13: aload_0
      14: invokevirtual #249                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      17: checkcast     #58                 // class java/lang/String
      20: invokestatic  #251                // Method main$iterate:(Ljava/util/List;Ljava/lang/String;)Ljava/util/List;
      23: astore_2
      24: iconst_0
      25: istore_3
      26: aload_2
      27: aload_2
      28: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      31: checkcast     #119                // class java/lang/CharSequence
      34: invokestatic  #254                // Method kotlin/text/StringsKt.first:(Ljava/lang/CharSequence;)C
      37: invokestatic  #200                // Method main$wrap:(Ljava/util/List;C)Ljava/util/List;
      40: nop
      41: aload_0
      42: invokevirtual #249                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      45: checkcast     #58                 // class java/lang/String
      48: invokestatic  #251                // Method main$iterate:(Ljava/util/List;Ljava/lang/String;)Ljava/util/List;
      51: checkcast     #94                 // class java/lang/Iterable
      54: astore_1
      55: iconst_0
      56: istore_2
      57: aload_1
      58: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      63: astore_3
      64: aload_3
      65: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      70: ifeq          178
      73: aload_3
      74: invokeinterface #117,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      79: astore        4
      81: iload_2
      82: aload         4
      84: checkcast     #58                 // class java/lang/String
      87: astore        5
      89: istore        14
      91: iconst_0
      92: istore        6
      94: aload         5
      96: checkcast     #119                // class java/lang/CharSequence
      99: astore        7
     101: iconst_0
     102: istore        8
     104: iconst_0
     105: istore        9
     107: iconst_0
     108: istore        10
     110: iload         10
     112: aload         7
     114: invokeinterface #255,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     119: if_icmpge     164
     122: aload         7
     124: iload         10
     126: invokeinterface #256,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     131: istore        11
     133: iload         11
     135: istore        12
     137: iconst_0
     138: istore        13
     140: iload         12
     142: bipush        35
     144: if_icmpne     151
     147: iconst_1
     148: goto          152
     151: iconst_0
     152: ifeq          158
     155: iinc          9, 1
     158: iinc          10, 1
     161: goto          110
     164: iload         9
     166: nop
     167: istore        15
     169: iload         14
     171: iload         15
     173: iadd
     174: istore_2
     175: goto          64
     178: iload_2
     179: ireturn

  private static final int main$part2(kotlin.Pair<java.lang.String, ? extends java.util.List<java.lang.String>>);
    Code:
       0: aconst_null
       1: astore_1
       2: aload_0
       3: invokevirtual #244                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
       6: checkcast     #131                // class java/util/List
       9: iconst_0
      10: iconst_2
      11: aconst_null
      12: invokestatic  #246                // Method main$wrap$default:(Ljava/util/List;CILjava/lang/Object;)Ljava/util/List;
      15: astore_1
      16: bipush        50
      18: istore_2
      19: iconst_0
      20: istore_3
      21: iload_3
      22: iload_2
      23: if_icmpge     69
      26: iload_3
      27: istore        4
      29: iconst_0
      30: istore        5
      32: aload_1
      33: aload_0
      34: invokevirtual #249                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      37: checkcast     #58                 // class java/lang/String
      40: invokestatic  #251                // Method main$iterate:(Ljava/util/List;Ljava/lang/String;)Ljava/util/List;
      43: astore        6
      45: aload         6
      47: aload         6
      49: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
      52: checkcast     #119                // class java/lang/CharSequence
      55: invokestatic  #254                // Method kotlin/text/StringsKt.first:(Ljava/lang/CharSequence;)C
      58: invokestatic  #200                // Method main$wrap:(Ljava/util/List;C)Ljava/util/List;
      61: astore_1
      62: nop
      63: iinc          3, 1
      66: goto          21
      69: aload_1
      70: checkcast     #94                 // class java/lang/Iterable
      73: astore_2
      74: iconst_0
      75: istore_3
      76: aload_2
      77: invokeinterface #107,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      82: astore        4
      84: aload         4
      86: invokeinterface #113,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      91: ifeq          200
      94: aload         4
      96: invokeinterface #117,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     101: astore        5
     103: iload_3
     104: aload         5
     106: checkcast     #58                 // class java/lang/String
     109: astore        6
     111: istore        15
     113: iconst_0
     114: istore        7
     116: aload         6
     118: checkcast     #119                // class java/lang/CharSequence
     121: astore        8
     123: iconst_0
     124: istore        9
     126: iconst_0
     127: istore        10
     129: iconst_0
     130: istore        11
     132: iload         11
     134: aload         8
     136: invokeinterface #255,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     141: if_icmpge     186
     144: aload         8
     146: iload         11
     148: invokeinterface #256,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     153: istore        12
     155: iload         12
     157: istore        13
     159: iconst_0
     160: istore        14
     162: iload         13
     164: bipush        35
     166: if_icmpne     173
     169: iconst_1
     170: goto          174
     173: iconst_0
     174: ifeq          180
     177: iinc          10, 1
     180: iinc          11, 1
     183: goto          132
     186: iload         10
     188: nop
     189: istore        16
     191: iload         15
     193: iload         16
     195: iadd
     196: istore_3
     197: goto          84
     200: iload_3
     201: ireturn
}