import java.io.*
fun print_day_3() {

    val yellow = "\u001B[33m"
    val reset = "\u001b[0m"
    val green = "\u001B[32m"
    println(yellow + "-".repeat(25) + "Advent of Code - Day 3" + "-".repeat(25) + reset)
    println(green)
    val process = Runtime.getRuntime().exec("figlet Binary Diagnostic -c -f small")
    val reader = BufferedReader(InputStreamReader(process.inputStream))
    reader.forEachLine { println(it) }
    println(reset)

    println(yellow + "-".repeat(33) + "Output" + "-".repeat(33) + reset + "\n")
}
fun main() {
    print_day_3()
    Day3().part_1()
    Day3().part_2()
    println("\u001B[33m" + "=".repeat(72) + "\u001b[0m" + "\n")
}

class Day3 {

    val lines = File("../Input/day3.txt").readLines()

    fun part_1() {
        val matrix = lines.map { s -> s.toCharArray().map { c -> c.digitToInt() } }
        var gamma = ""
        var epsilon = ""

        for(idx in matrix[0].indices) {
            val res = matrix.partition { it[idx] == 1 }
            gamma += if (res.first.count() > res.second.count())  "1" else "0"
            epsilon +=  if (res.first.count() > res.second.count())  "0" else "1"
        }

        val answer = gamma.toInt(2) * epsilon.toInt(2)
        println("Puzzle 1: " + answer)
    }

    fun part_2() {
        fun splitAndRecurse(list: List<List<Int>>, index: Int, max: Boolean) : List<Int> {
            if (list.size == 1) return list[0]

            val res = list.partition { it[index] == 1 }
            val keep =
                if (res.first.count() >= res.second.count())
                    if (max) res.first else res.second
                else
                    if (max) res.second else res.first
            return splitAndRecurse(keep, index+1,  max)
        }

        val matrix = lines.map { s -> s.toCharArray().map { c -> c.digitToInt() } }
        val oxygen = splitAndRecurse(matrix, 0, true)
        val co2 = splitAndRecurse(matrix, 0, false)

        val oxygenDecimal = oxygen.joinToString("").toInt(2)
        val co2Decimal = co2.joinToString("").toInt(2)

        println("Puzzle 2: " + oxygenDecimal * co2Decimal +"\n")
    }
}

Compiled from "day03.kt"
public final class Day03Kt {
  public static final void print_day_3();
    Code:
       0: ldc           #8                  // String \u001b[33m
       2: astore_0
       3: ldc           #10                 // String \u001b[0m
       5: astore_1
       6: ldc           #12                 // String \u001b[32m
       8: astore_2
       9: new           #14                 // class java/lang/StringBuilder
      12: dup
      13: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      16: aload_0
      17: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      20: ldc           #23                 // String -
      22: checkcast     #25                 // class java/lang/CharSequence
      25: bipush        25
      27: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      30: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      33: ldc           #33                 // String Advent of Code - Day 3
      35: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      38: ldc           #23                 // String -
      40: checkcast     #25                 // class java/lang/CharSequence
      43: bipush        25
      45: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      48: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      51: aload_1
      52: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      55: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      58: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      61: swap
      62: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      65: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      68: aload_2
      69: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      72: invokestatic  #55                 // Method java/lang/Runtime.getRuntime:()Ljava/lang/Runtime;
      75: ldc           #57                 // String figlet Binary Diagnostic -c -f small
      77: invokevirtual #61                 // Method java/lang/Runtime.exec:(Ljava/lang/String;)Ljava/lang/Process;
      80: astore_3
      81: new           #63                 // class java/io/BufferedReader
      84: dup
      85: new           #65                 // class java/io/InputStreamReader
      88: dup
      89: aload_3
      90: invokevirtual #71                 // Method java/lang/Process.getInputStream:()Ljava/io/InputStream;
      93: invokespecial #74                 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V
      96: checkcast     #76                 // class java/io/Reader
      99: invokespecial #79                 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V
     102: astore        4
     104: aload         4
     106: checkcast     #76                 // class java/io/Reader
     109: invokedynamic #98,  0             // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     114: invokestatic  #104                // Method kotlin/io/TextStreamsKt.forEachLine:(Ljava/io/Reader;Lkotlin/jvm/functions/Function1;)V
     117: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     120: aload_1
     121: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     124: new           #14                 // class java/lang/StringBuilder
     127: dup
     128: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
     131: aload_0
     132: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     135: ldc           #23                 // String -
     137: checkcast     #25                 // class java/lang/CharSequence
     140: bipush        33
     142: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     145: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     148: ldc           #106                // String Output
     150: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     153: ldc           #23                 // String -
     155: checkcast     #25                 // class java/lang/CharSequence
     158: bipush        33
     160: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     163: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     166: aload_1
     167: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     170: bipush        10
     172: invokevirtual #109                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     175: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     178: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     181: swap
     182: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     185: return

  public static final void main();
    Code:
       0: invokestatic  #120                // Method print_day_3:()V
       3: new           #122                // class Day3
       6: dup
       7: invokespecial #123                // Method Day3."<init>":()V
      10: invokevirtual #126                // Method Day3.part_1:()V
      13: new           #122                // class Day3
      16: dup
      17: invokespecial #123                // Method Day3."<init>":()V
      20: invokevirtual #129                // Method Day3.part_2:()V
      23: new           #14                 // class java/lang/StringBuilder
      26: dup
      27: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      30: ldc           #8                  // String \u001b[33m
      32: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      35: ldc           #131                // String =
      37: checkcast     #25                 // class java/lang/CharSequence
      40: bipush        72
      42: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      45: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      48: ldc           #133                // String \u001b[0m\n
      50: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      53: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      56: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      59: swap
      60: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      63: return

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

  private static final kotlin.Unit print_day_3$lambda$0(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #140                // String it
       3: invokestatic  #146                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: aload_0
      10: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      13: getstatic     #152                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      16: areturn
}


import java.io.*
fun print_day_18() {
    val yellow = "\u001B[33m"
    val reset = "\u001b[0m"
    val green = "\u001B[32m"
    println(yellow + "-".repeat(25) + "Advent of Code - Day 18" + "-".repeat(25) + reset)
    println(green)
    val process = Runtime.getRuntime().exec("figlet Snailfish -c -f small")
    val reader = BufferedReader(InputStreamReader(process.inputStream))
    reader.forEachLine { println(it) }
    println(reset)
    println(yellow + "-".repeat(33) + "Output" + "-".repeat(33) + reset + "\n")
}

fun main() {
    print_day_18()
    println("Puzzle 1: " + Day18().part_1())
    println("Puzzle 2: " + Day18().part_2())
    println("\n" + "\u001B[33m" + "=".repeat(72) + "\u001b[0m" + "\n")
}

class Day18 {
    private val input = File("../Input/day18.txt").readLines()
    fun part_1() = input.map { parse(it) }.reduce { a, b -> a + b }.magnitude()
    fun part_2() = input.indices.flatMap { i -> input.indices.map { j -> i to j}}.filter {(i,j) -> i != j }.maxOf { (i,j) -> (parse(input[i]) + parse(input[j])).magnitude() }

    private fun parse(input: String): Num {
        var cur = 0

        fun _parse(): Num =
            if (input[cur] == '[') {
                cur++
                val left = _parse()
                cur++
                val right = _parse()
                cur++
                Num.NumPair(left, right)
            }
            else Num.NumValue(input[cur].digitToInt()).also { cur++ }

        return _parse()
    }

    sealed class Num {
        var parent: NumPair? = null

        class NumValue(var value: Int) : Num() {
            override fun toString(): String = value.toString()

            fun canSplit(): Boolean = value >= 10
            fun split() {
                val num = NumPair(NumValue(value / 2), NumValue((value + 1) / 2))
                parent?.replaceWith(this, num)
            }
        }
        class NumPair(var left: Num, var right: Num) : Num() {
            init {
                left.parent = this
                right.parent = this
            }
            override fun toString(): String = "[$left,$right]"

            fun explode() {
                val x = if (left is NumValue) (left as NumValue).value else null
                val y = if (right is NumValue) (right as NumValue).value else null
                findValueToLeft()?.let { it.value += x!! }
                findValueToRight()?.let { it.value += y!! }
                parent?.replaceWith(this, NumValue(0))
            }

            fun replaceWith(child: Num, newValue: Num) {
                if (left == child)      { left = newValue  }
                else if (right == child){ right = newValue }

                newValue.parent = this
            }
        }

        fun magnitude(): Int = when(this) {
            is NumValue -> value
            is NumPair -> left.magnitude() * 3 + right.magnitude() * 2
        }

        operator fun plus(other: Num): Num =
            NumPair(this, other).apply {
                left.parent = this
                right.parent = this
                reduce()
            }

        fun reduce() {
            do  {
                var exploded = false
                var split = false

                findNextExplode()?.apply {
                    explode()
                    exploded = true
                }
                if (!exploded) findNextToSplit()?.apply {
                    split()
                    split = true
                }
            } while (exploded || split)
        }

        fun findValueToRight(): NumValue? {
            if (this is NumValue) return this
            if (this == parent?.left) return parent!!.right.findValueFurthestLeft()
            if (this == parent?.right) return parent!!.findValueToRight()

            return null
        }
        fun findValueToLeft(): NumValue? {
            if (this is NumValue) return this
            if (this == parent?.left) return parent!!.findValueToLeft()
            if (this == parent?.right) return parent!!.left.findValueFurthestRight()

            return null
        }
        private fun findValueFurthestLeft(): NumValue? = when(this) {
            is NumValue -> this
            is NumPair -> this.left.findValueFurthestLeft()
        }
        private fun findValueFurthestRight(): NumValue? = when(this) {
            is NumValue -> this
            is NumPair -> this.right.findValueFurthestRight()
        }

        private fun findNextToSplit(): NumValue? =
            if (this is NumValue && canSplit()) this
            else if (this is NumPair) left.findNextToSplit() ?: right.findNextToSplit()
            else null

        private fun findNextExplode(depth: Int = 0): NumPair? =
            if (this is NumPair) {
                if (depth >= 4) this
                else left.findNextExplode(depth + 1) ?: right.findNextExplode(depth + 1)
            }
            else null
    }
}

Compiled from "day18.kt"
public abstract class Day18$Num {
  private Day18$Num$NumPair parent;

  private Day18$Num();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final Day18$Num$NumPair getParent();
    Code:
       0: aload_0
       1: getfield      #17                 // Field parent:LDay18$Num$NumPair;
       4: areturn

  public final void setParent(Day18$Num$NumPair);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #17                 // Field parent:LDay18$Num$NumPair;
       5: return

  public final int magnitude();
    Code:
       0: aload_0
       1: astore_1
       2: aload_1
       3: instanceof    #24                 // class Day18$Num$NumValue
       6: ifeq          19
       9: aload_0
      10: checkcast     #24                 // class Day18$Num$NumValue
      13: invokevirtual #27                 // Method Day18$Num$NumValue.getValue:()I
      16: goto          62
      19: aload_1
      20: instanceof    #29                 // class Day18$Num$NumPair
      23: ifeq          54
      26: aload_0
      27: checkcast     #29                 // class Day18$Num$NumPair
      30: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      33: invokevirtual #35                 // Method magnitude:()I
      36: iconst_3
      37: imul
      38: aload_0
      39: checkcast     #29                 // class Day18$Num$NumPair
      42: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      45: invokevirtual #35                 // Method magnitude:()I
      48: iconst_2
      49: imul
      50: iadd
      51: goto          62
      54: new           #40                 // class kotlin/NoWhenBranchMatchedException
      57: dup
      58: invokespecial #41                 // Method kotlin/NoWhenBranchMatchedException."<init>":()V
      61: athrow
      62: ireturn

  public final Day18$Num plus(Day18$Num);
    Code:
       0: aload_1
       1: ldc           #46                 // String other
       3: invokestatic  #52                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #29                 // class Day18$Num$NumPair
       9: dup
      10: aload_0
      11: aload_1
      12: invokespecial #55                 // Method Day18$Num$NumPair."<init>":(LDay18$Num;LDay18$Num;)V
      15: astore_2
      16: aload_2
      17: astore_3
      18: iconst_0
      19: istore        4
      21: aload_3
      22: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      25: aload_3
      26: putfield      #17                 // Field parent:LDay18$Num$NumPair;
      29: aload_3
      30: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      33: aload_3
      34: putfield      #17                 // Field parent:LDay18$Num$NumPair;
      37: aload_3
      38: invokevirtual #58                 // Method Day18$Num$NumPair.reduce:()V
      41: nop
      42: aload_2
      43: checkcast     #2                  // class Day18$Num
      46: areturn

  public final void reduce();
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_0
       3: istore_2
       4: aload_0
       5: iconst_0
       6: iconst_1
       7: aconst_null
       8: invokestatic  #65                 // Method findNextExplode$default:(LDay18$Num;IILjava/lang/Object;)LDay18$Num$NumPair;
      11: dup
      12: ifnull        33
      15: astore_3
      16: aload_3
      17: astore        4
      19: iconst_0
      20: istore        5
      22: aload         4
      24: invokevirtual #68                 // Method Day18$Num$NumPair.explode:()V
      27: iconst_1
      28: istore_1
      29: nop
      30: goto          35
      33: pop
      34: nop
      35: iload_1
      36: ifne          67
      39: aload_0
      40: invokespecial #72                 // Method findNextToSplit:()LDay18$Num$NumValue;
      43: dup
      44: ifnull        65
      47: astore_3
      48: aload_3
      49: astore        4
      51: iconst_0
      52: istore        5
      54: aload         4
      56: invokevirtual #75                 // Method Day18$Num$NumValue.split:()V
      59: iconst_1
      60: istore_2
      61: nop
      62: goto          67
      65: pop
      66: nop
      67: iload_1
      68: ifne          0
      71: iload_2
      72: ifne          0
      75: return

  public final Day18$Num$NumValue findValueToRight();
    Code:
       0: aload_0
       1: instanceof    #24                 // class Day18$Num$NumValue
       4: ifeq          12
       7: aload_0
       8: checkcast     #24                 // class Day18$Num$NumValue
      11: areturn
      12: aload_0
      13: aload_0
      14: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      17: dup
      18: ifnull        27
      21: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      24: goto          29
      27: pop
      28: aconst_null
      29: invokestatic  #87                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      32: ifeq          50
      35: aload_0
      36: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      39: dup
      40: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      43: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      46: invokespecial #94                 // Method findValueFurthestLeft:()LDay18$Num$NumValue;
      49: areturn
      50: aload_0
      51: aload_0
      52: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      55: dup
      56: ifnull        65
      59: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      62: goto          67
      65: pop
      66: aconst_null
      67: invokestatic  #87                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      70: ifeq          85
      73: aload_0
      74: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      77: dup
      78: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      81: invokevirtual #96                 // Method Day18$Num$NumPair.findValueToRight:()LDay18$Num$NumValue;
      84: areturn
      85: aconst_null
      86: areturn

  public final Day18$Num$NumValue findValueToLeft();
    Code:
       0: aload_0
       1: instanceof    #24                 // class Day18$Num$NumValue
       4: ifeq          12
       7: aload_0
       8: checkcast     #24                 // class Day18$Num$NumValue
      11: areturn
      12: aload_0
      13: aload_0
      14: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      17: dup
      18: ifnull        27
      21: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      24: goto          29
      27: pop
      28: aconst_null
      29: invokestatic  #87                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      32: ifeq          47
      35: aload_0
      36: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      39: dup
      40: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      43: invokevirtual #99                 // Method Day18$Num$NumPair.findValueToLeft:()LDay18$Num$NumValue;
      46: areturn
      47: aload_0
      48: aload_0
      49: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      52: dup
      53: ifnull        62
      56: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      59: goto          64
      62: pop
      63: aconst_null
      64: invokestatic  #87                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      67: ifeq          85
      70: aload_0
      71: getfield      #17                 // Field parent:LDay18$Num$NumPair;
      74: dup
      75: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      78: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      81: invokespecial #102                // Method findValueFurthestRight:()LDay18$Num$NumValue;
      84: areturn
      85: aconst_null
      86: areturn

  private final Day18$Num$NumValue findValueFurthestLeft();
    Code:
       0: aload_0
       1: astore_1
       2: aload_1
       3: instanceof    #24                 // class Day18$Num$NumValue
       6: ifeq          16
       9: aload_0
      10: checkcast     #24                 // class Day18$Num$NumValue
      13: goto          44
      16: aload_1
      17: instanceof    #29                 // class Day18$Num$NumPair
      20: ifeq          36
      23: aload_0
      24: checkcast     #29                 // class Day18$Num$NumPair
      27: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      30: invokespecial #94                 // Method findValueFurthestLeft:()LDay18$Num$NumValue;
      33: goto          44
      36: new           #40                 // class kotlin/NoWhenBranchMatchedException
      39: dup
      40: invokespecial #41                 // Method kotlin/NoWhenBranchMatchedException."<init>":()V
      43: athrow
      44: areturn

  private final Day18$Num$NumValue findValueFurthestRight();
    Code:
       0: aload_0
       1: astore_1
       2: aload_1
       3: instanceof    #24                 // class Day18$Num$NumValue
       6: ifeq          16
       9: aload_0
      10: checkcast     #24                 // class Day18$Num$NumValue
      13: goto          44
      16: aload_1
      17: instanceof    #29                 // class Day18$Num$NumPair
      20: ifeq          36
      23: aload_0
      24: checkcast     #29                 // class Day18$Num$NumPair
      27: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      30: invokespecial #102                // Method findValueFurthestRight:()LDay18$Num$NumValue;
      33: goto          44
      36: new           #40                 // class kotlin/NoWhenBranchMatchedException
      39: dup
      40: invokespecial #41                 // Method kotlin/NoWhenBranchMatchedException."<init>":()V
      43: athrow
      44: areturn

  private final Day18$Num$NumValue findNextToSplit();
    Code:
       0: aload_0
       1: instanceof    #24                 // class Day18$Num$NumValue
       4: ifeq          24
       7: aload_0
       8: checkcast     #24                 // class Day18$Num$NumValue
      11: invokevirtual #106                // Method Day18$Num$NumValue.canSplit:()Z
      14: ifeq          24
      17: aload_0
      18: checkcast     #24                 // class Day18$Num$NumValue
      21: goto          60
      24: aload_0
      25: instanceof    #29                 // class Day18$Num$NumPair
      28: ifeq          59
      31: aload_0
      32: checkcast     #29                 // class Day18$Num$NumPair
      35: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      38: invokespecial #72                 // Method findNextToSplit:()LDay18$Num$NumValue;
      41: dup
      42: ifnonnull     60
      45: pop
      46: aload_0
      47: checkcast     #29                 // class Day18$Num$NumPair
      50: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      53: invokespecial #72                 // Method findNextToSplit:()LDay18$Num$NumValue;
      56: goto          60
      59: aconst_null
      60: areturn

  private final Day18$Num$NumPair findNextExplode(int);
    Code:
       0: aload_0
       1: instanceof    #29                 // class Day18$Num$NumPair
       4: ifeq          53
       7: iload_1
       8: iconst_4
       9: if_icmplt     19
      12: aload_0
      13: checkcast     #29                 // class Day18$Num$NumPair
      16: goto          54
      19: aload_0
      20: checkcast     #29                 // class Day18$Num$NumPair
      23: invokevirtual #33                 // Method Day18$Num$NumPair.getLeft:()LDay18$Num;
      26: iload_1
      27: iconst_1
      28: iadd
      29: invokespecial #110                // Method findNextExplode:(I)LDay18$Num$NumPair;
      32: dup
      33: ifnonnull     54
      36: pop
      37: aload_0
      38: checkcast     #29                 // class Day18$Num$NumPair
      41: invokevirtual #38                 // Method Day18$Num$NumPair.getRight:()LDay18$Num;
      44: iload_1
      45: iconst_1
      46: iadd
      47: invokespecial #110                // Method findNextExplode:(I)LDay18$Num$NumPair;
      50: goto          54
      53: aconst_null
      54: areturn

  static Day18$Num$NumPair findNextExplode$default(Day18$Num, int, int, java.lang.Object);
    Code:
       0: aload_3
       1: ifnull        14
       4: new           #113                // class java/lang/UnsupportedOperationException
       7: dup
       8: ldc           #115                // String Super calls with default arguments not supported in this target, function: findNextExplode
      10: invokespecial #118                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
      13: athrow
      14: iload_2
      15: iconst_1
      16: iand
      17: ifeq          22
      20: iconst_0
      21: istore_1
      22: aload_0
      23: iload_1
      24: invokespecial #110                // Method findNextExplode:(I)LDay18$Num$NumPair;
      27: areturn

  public Day18$Num(kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: aload_0
       1: invokespecial #120                // Method "<init>":()V
       4: return
}

Compiled from "day18.kt"
public final class Day18 {
  private final java.util.List<java.lang.String> input;

  public Day18();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: new           #10                 // class java/io/File
       8: dup
       9: ldc           #12                 // String ../Input/day18.txt
      11: invokespecial #15                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      14: aconst_null
      15: iconst_1
      16: aconst_null
      17: invokestatic  #21                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      20: putfield      #25                 // Field input:Ljava/util/List;
      23: return

  public final int part_1();
    Code:
       0: aload_0
       1: getfield      #25                 // Field input:Ljava/util/List;
       4: checkcast     #31                 // class java/lang/Iterable
       7: astore_1
       8: iconst_0
       9: istore_2
      10: aload_1
      11: astore_3
      12: new           #33                 // class java/util/ArrayList
      15: dup
      16: aload_1
      17: bipush        10
      19: invokestatic  #39                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      22: invokespecial #42                 // Method java/util/ArrayList."<init>":(I)V
      25: checkcast     #44                 // class java/util/Collection
      28: astore        4
      30: iconst_0
      31: istore        5
      33: aload_3
      34: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      39: astore        6
      41: aload         6
      43: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      48: ifeq          92
      51: aload         6
      53: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      58: astore        7
      60: aload         4
      62: aload         7
      64: checkcast     #60                 // class java/lang/String
      67: astore        8
      69: astore        10
      71: iconst_0
      72: istore        9
      74: aload_0
      75: aload         8
      77: invokespecial #64                 // Method parse:(Ljava/lang/String;)LDay18$Num;
      80: aload         10
      82: swap
      83: invokeinterface #68,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      88: pop
      89: goto          41
      92: aload         4
      94: checkcast     #70                 // class java/util/List
      97: nop
      98: checkcast     #31                 // class java/lang/Iterable
     101: astore_1
     102: nop
     103: iconst_0
     104: istore_2
     105: aload_1
     106: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     111: astore_3
     112: aload_3
     113: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     118: ifne          131
     121: new           #72                 // class java/lang/UnsupportedOperationException
     124: dup
     125: ldc           #74                 // String Empty collection can\'t be reduced.
     127: invokespecial #75                 // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     130: athrow
     131: aload_3
     132: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     137: astore        4
     139: aload_3
     140: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     145: ifeq          181
     148: aload         4
     150: aload_3
     151: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     156: checkcast     #77                 // class Day18$Num
     159: astore        5
     161: checkcast     #77                 // class Day18$Num
     164: astore        6
     166: iconst_0
     167: istore        7
     169: aload         6
     171: aload         5
     173: invokevirtual #81                 // Method Day18$Num.plus:(LDay18$Num;)LDay18$Num;
     176: astore        4
     178: goto          139
     181: aload         4
     183: checkcast     #77                 // class Day18$Num
     186: invokevirtual #84                 // Method Day18$Num.magnitude:()I
     189: ireturn

  public final int part_2();
    Code:
       0: aload_0
       1: getfield      #25                 // Field input:Ljava/util/List;
       4: checkcast     #44                 // class java/util/Collection
       7: invokestatic  #111                // Method kotlin/collections/CollectionsKt.getIndices:(Ljava/util/Collection;)Lkotlin/ranges/IntRange;
      10: checkcast     #31                 // class java/lang/Iterable
      13: astore_1
      14: iconst_0
      15: istore_2
      16: aload_1
      17: astore_3
      18: new           #33                 // class java/util/ArrayList
      21: dup
      22: invokespecial #112                // Method java/util/ArrayList."<init>":()V
      25: checkcast     #44                 // class java/util/Collection
      28: astore        4
      30: iconst_0
      31: istore        5
      33: aload_3
      34: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      39: astore        6
      41: aload         6
      43: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      48: ifeq          200
      51: aload         6
      53: checkcast     #114                // class kotlin/collections/IntIterator
      56: invokevirtual #117                // Method kotlin/collections/IntIterator.nextInt:()I
      59: istore        7
      61: iload         7
      63: istore        8
      65: iconst_0
      66: istore        9
      68: aload_0
      69: getfield      #25                 // Field input:Ljava/util/List;
      72: checkcast     #44                 // class java/util/Collection
      75: invokestatic  #111                // Method kotlin/collections/CollectionsKt.getIndices:(Ljava/util/Collection;)Lkotlin/ranges/IntRange;
      78: checkcast     #31                 // class java/lang/Iterable
      81: astore        10
      83: iconst_0
      84: istore        11
      86: aload         10
      88: astore        12
      90: new           #33                 // class java/util/ArrayList
      93: dup
      94: aload         10
      96: bipush        10
      98: invokestatic  #39                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     101: invokespecial #42                 // Method java/util/ArrayList."<init>":(I)V
     104: checkcast     #44                 // class java/util/Collection
     107: astore        13
     109: iconst_0
     110: istore        14
     112: aload         12
     114: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     119: astore        15
     121: aload         15
     123: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     128: ifeq          177
     131: aload         15
     133: checkcast     #114                // class kotlin/collections/IntIterator
     136: invokevirtual #117                // Method kotlin/collections/IntIterator.nextInt:()I
     139: istore        16
     141: aload         13
     143: iload         16
     145: istore        17
     147: astore        18
     149: iconst_0
     150: istore        19
     152: iload         8
     154: invokestatic  #123                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     157: iload         17
     159: invokestatic  #123                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     162: invokestatic  #129                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     165: aload         18
     167: swap
     168: invokeinterface #68,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     173: pop
     174: goto          121
     177: aload         13
     179: checkcast     #70                 // class java/util/List
     182: nop
     183: checkcast     #31                 // class java/lang/Iterable
     186: nop
     187: astore        8
     189: aload         4
     191: aload         8
     193: invokestatic  #133                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     196: pop
     197: goto          41
     200: aload         4
     202: checkcast     #70                 // class java/util/List
     205: nop
     206: checkcast     #31                 // class java/lang/Iterable
     209: astore_1
     210: nop
     211: iconst_0
     212: istore_2
     213: aload_1
     214: astore_3
     215: new           #33                 // class java/util/ArrayList
     218: dup
     219: invokespecial #112                // Method java/util/ArrayList."<init>":()V
     222: checkcast     #44                 // class java/util/Collection
     225: astore        4
     227: iconst_0
     228: istore        5
     230: aload_3
     231: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     236: astore        6
     238: aload         6
     240: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     245: ifeq          321
     248: aload         6
     250: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     255: astore        7
     257: aload         7
     259: checkcast     #135                // class kotlin/Pair
     262: astore        8
     264: iconst_0
     265: istore        9
     267: aload         8
     269: invokevirtual #138                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     272: checkcast     #140                // class java/lang/Number
     275: invokevirtual #143                // Method java/lang/Number.intValue:()I
     278: istore        10
     280: aload         8
     282: invokevirtual #146                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     285: checkcast     #140                // class java/lang/Number
     288: invokevirtual #143                // Method java/lang/Number.intValue:()I
     291: istore        11
     293: iload         10
     295: iload         11
     297: if_icmpeq     304
     300: iconst_1
     301: goto          305
     304: iconst_0
     305: ifeq          238
     308: aload         4
     310: aload         7
     312: invokeinterface #68,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     317: pop
     318: goto          238
     321: aload         4
     323: checkcast     #70                 // class java/util/List
     326: nop
     327: checkcast     #31                 // class java/lang/Iterable
     330: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     335: astore_2
     336: aload_2
     337: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     342: ifne          353
     345: new           #148                // class java/util/NoSuchElementException
     348: dup
     349: invokespecial #149                // Method java/util/NoSuchElementException."<init>":()V
     352: athrow
     353: aload_2
     354: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     359: checkcast     #135                // class kotlin/Pair
     362: astore_3
     363: iconst_0
     364: istore        4
     366: aload_3
     367: invokevirtual #138                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     370: checkcast     #140                // class java/lang/Number
     373: invokevirtual #143                // Method java/lang/Number.intValue:()I
     376: istore        5
     378: aload_3
     379: invokevirtual #146                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     382: checkcast     #140                // class java/lang/Number
     385: invokevirtual #143                // Method java/lang/Number.intValue:()I
     388: istore        6
     390: aload_0
     391: aload_0
     392: getfield      #25                 // Field input:Ljava/util/List;
     395: iload         5
     397: invokeinterface #153,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     402: checkcast     #60                 // class java/lang/String
     405: invokespecial #64                 // Method parse:(Ljava/lang/String;)LDay18$Num;
     408: aload_0
     409: aload_0
     410: getfield      #25                 // Field input:Ljava/util/List;
     413: iload         6
     415: invokeinterface #153,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     420: checkcast     #60                 // class java/lang/String
     423: invokespecial #64                 // Method parse:(Ljava/lang/String;)LDay18$Num;
     426: invokevirtual #81                 // Method Day18$Num.plus:(LDay18$Num;)LDay18$Num;
     429: invokevirtual #84                 // Method Day18$Num.magnitude:()I
     432: istore_3
     433: aload_2
     434: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     439: ifeq          538
     442: aload_2
     443: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     448: checkcast     #135                // class kotlin/Pair
     451: astore        4
     453: iconst_0
     454: istore        5
     456: aload         4
     458: invokevirtual #138                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     461: checkcast     #140                // class java/lang/Number
     464: invokevirtual #143                // Method java/lang/Number.intValue:()I
     467: istore        6
     469: aload         4
     471: invokevirtual #146                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     474: checkcast     #140                // class java/lang/Number
     477: invokevirtual #143                // Method java/lang/Number.intValue:()I
     480: istore        7
     482: aload_0
     483: aload_0
     484: getfield      #25                 // Field input:Ljava/util/List;
     487: iload         6
     489: invokeinterface #153,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     494: checkcast     #60                 // class java/lang/String
     497: invokespecial #64                 // Method parse:(Ljava/lang/String;)LDay18$Num;
     500: aload_0
     501: aload_0
     502: getfield      #25                 // Field input:Ljava/util/List;
     505: iload         7
     507: invokeinterface #153,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     512: checkcast     #60                 // class java/lang/String
     515: invokespecial #64                 // Method parse:(Ljava/lang/String;)LDay18$Num;
     518: invokevirtual #81                 // Method Day18$Num.plus:(LDay18$Num;)LDay18$Num;
     521: invokevirtual #84                 // Method Day18$Num.magnitude:()I
     524: istore        4
     526: iload_3
     527: iload         4
     529: if_icmpge     433
     532: iload         4
     534: istore_3
     535: goto          433
     538: iload_3
     539: ireturn

  private final Day18$Num parse(java.lang.String);
    Code:
       0: new           #171                // class kotlin/jvm/internal/Ref$IntRef
       3: dup
       4: invokespecial #172                // Method kotlin/jvm/internal/Ref$IntRef."<init>":()V
       7: astore_2
       8: aload_1
       9: aload_2
      10: invokestatic  #176                // Method parse$_parse:(Ljava/lang/String;Lkotlin/jvm/internal/Ref$IntRef;)LDay18$Num;
      13: areturn

  private static final Day18$Num parse$_parse(java.lang.String, kotlin.jvm.internal.Ref$IntRef);
    Code:
       0: aload_0
       1: aload_1
       2: getfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
       5: invokevirtual #185                // Method java/lang/String.charAt:(I)C
       8: bipush        91
      10: if_icmpne     78
      13: aload_1
      14: getfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
      17: istore_2
      18: aload_1
      19: iload_2
      20: iconst_1
      21: iadd
      22: putfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
      25: aload_0
      26: aload_1
      27: invokestatic  #176                // Method parse$_parse:(Ljava/lang/String;Lkotlin/jvm/internal/Ref$IntRef;)LDay18$Num;
      30: astore_2
      31: aload_1
      32: getfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
      35: istore_3
      36: aload_1
      37: iload_3
      38: iconst_1
      39: iadd
      40: putfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
      43: aload_0
      44: aload_1
      45: invokestatic  #176                // Method parse$_parse:(Ljava/lang/String;Lkotlin/jvm/internal/Ref$IntRef;)LDay18$Num;
      48: astore_3
      49: aload_1
      50: getfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
      53: istore        4
      55: aload_1
      56: iload         4
      58: iconst_1
      59: iadd
      60: putfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
      63: new           #187                // class Day18$Num$NumPair
      66: dup
      67: aload_2
      68: aload_3
      69: invokespecial #190                // Method Day18$Num$NumPair."<init>":(LDay18$Num;LDay18$Num;)V
      72: checkcast     #77                 // class Day18$Num
      75: goto          120
      78: new           #192                // class Day18$Num$NumValue
      81: dup
      82: aload_0
      83: aload_1
      84: getfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
      87: invokevirtual #185                // Method java/lang/String.charAt:(I)C
      90: invokestatic  #198                // Method kotlin/text/CharsKt.digitToInt:(C)I
      93: invokespecial #199                // Method Day18$Num$NumValue."<init>":(I)V
      96: astore_2
      97: aload_2
      98: astore_3
      99: iconst_0
     100: istore        4
     102: aload_1
     103: getfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
     106: istore        5
     108: aload_1
     109: iload         5
     111: iconst_1
     112: iadd
     113: putfield      #181                // Field kotlin/jvm/internal/Ref$IntRef.element:I
     116: aload_2
     117: checkcast     #77                 // class Day18$Num
     120: areturn
}

Compiled from "day18.kt"
public final class Day18$Num$NumValue extends Day18$Num {
  private int value;

  public Day18$Num$NumValue(int);
    Code:
       0: aload_0
       1: aconst_null
       2: invokespecial #9                  // Method Day18$Num."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       5: aload_0
       6: iload_1
       7: putfield      #13                 // Field value:I
      10: return

  public final int getValue();
    Code:
       0: aload_0
       1: getfield      #13                 // Field value:I
       4: ireturn

  public final void setValue(int);
    Code:
       0: aload_0
       1: iload_1
       2: putfield      #13                 // Field value:I
       5: return

  public java.lang.String toString();
    Code:
       0: aload_0
       1: getfield      #13                 // Field value:I
       4: invokestatic  #28                 // Method java/lang/String.valueOf:(I)Ljava/lang/String;
       7: areturn

  public final boolean canSplit();
    Code:
       0: aload_0
       1: getfield      #13                 // Field value:I
       4: bipush        10
       6: if_icmplt     13
       9: iconst_1
      10: goto          14
      13: iconst_0
      14: ireturn

  public final void split();
    Code:
       0: new           #34                 // class Day18$Num$NumPair
       3: dup
       4: new           #2                  // class Day18$Num$NumValue
       7: dup
       8: aload_0
       9: getfield      #13                 // Field value:I
      12: iconst_2
      13: idiv
      14: invokespecial #36                 // Method "<init>":(I)V
      17: checkcast     #4                  // class Day18$Num
      20: new           #2                  // class Day18$Num$NumValue
      23: dup
      24: aload_0
      25: getfield      #13                 // Field value:I
      28: iconst_1
      29: iadd
      30: iconst_2
      31: idiv
      32: invokespecial #36                 // Method "<init>":(I)V
      35: checkcast     #4                  // class Day18$Num
      38: invokespecial #39                 // Method Day18$Num$NumPair."<init>":(LDay18$Num;LDay18$Num;)V
      41: astore_1
      42: aload_0
      43: invokevirtual #43                 // Method getParent:()LDay18$Num$NumPair;
      46: dup
      47: ifnull        64
      50: aload_0
      51: checkcast     #4                  // class Day18$Num
      54: aload_1
      55: checkcast     #4                  // class Day18$Num
      58: invokevirtual #46                 // Method Day18$Num$NumPair.replaceWith:(LDay18$Num;LDay18$Num;)V
      61: goto          65
      64: pop
      65: return
}

Compiled from "day18.kt"
public final class Day18$Num$NumPair extends Day18$Num {
  private Day18$Num left;

  private Day18$Num right;

  public Day18$Num$NumPair(Day18$Num, Day18$Num);
    Code:
       0: aload_1
       1: ldc           #9                  // String left
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #17                 // String right
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: aconst_null
      14: invokespecial #20                 // Method Day18$Num."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
      17: aload_0
      18: aload_1
      19: putfield      #23                 // Field left:LDay18$Num;
      22: aload_0
      23: aload_2
      24: putfield      #25                 // Field right:LDay18$Num;
      27: nop
      28: aload_0
      29: getfield      #23                 // Field left:LDay18$Num;
      32: aload_0
      33: invokevirtual #29                 // Method Day18$Num.setParent:(LDay18$Num$NumPair;)V
      36: aload_0
      37: getfield      #25                 // Field right:LDay18$Num;
      40: aload_0
      41: invokevirtual #29                 // Method Day18$Num.setParent:(LDay18$Num$NumPair;)V
      44: nop
      45: return

  public final Day18$Num getLeft();
    Code:
       0: aload_0
       1: getfield      #23                 // Field left:LDay18$Num;
       4: areturn

  public final void setLeft(Day18$Num);
    Code:
       0: aload_1
       1: ldc           #37                 // String <set-?>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_1
       8: putfield      #23                 // Field left:LDay18$Num;
      11: return

  public final Day18$Num getRight();
    Code:
       0: aload_0
       1: getfield      #25                 // Field right:LDay18$Num;
       4: areturn

  public final void setRight(Day18$Num);
    Code:
       0: aload_1
       1: ldc           #37                 // String <set-?>
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_1
       8: putfield      #25                 // Field right:LDay18$Num;
      11: return

  public java.lang.String toString();
    Code:
       0: new           #43                 // class java/lang/StringBuilder
       3: dup
       4: invokespecial #46                 // Method java/lang/StringBuilder."<init>":()V
       7: bipush        91
       9: invokevirtual #50                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      12: aload_0
      13: getfield      #23                 // Field left:LDay18$Num;
      16: invokevirtual #53                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      19: bipush        44
      21: invokevirtual #50                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      24: aload_0
      25: getfield      #25                 // Field right:LDay18$Num;
      28: invokevirtual #53                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      31: bipush        93
      33: invokevirtual #50                 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      36: invokevirtual #55                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn

  public final void explode();
    Code:
       0: aload_0
       1: getfield      #23                 // Field left:LDay18$Num;
       4: instanceof    #58                 // class Day18$Num$NumValue
       7: ifeq          32
      10: aload_0
      11: getfield      #23                 // Field left:LDay18$Num;
      14: dup
      15: ldc           #60                 // String null cannot be cast to non-null type <root>.Day18.Num.NumValue
      17: invokestatic  #63                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
      20: checkcast     #58                 // class Day18$Num$NumValue
      23: invokevirtual #67                 // Method Day18$Num$NumValue.getValue:()I
      26: invokestatic  #73                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      29: goto          33
      32: aconst_null
      33: astore_1
      34: aload_0
      35: getfield      #25                 // Field right:LDay18$Num;
      38: instanceof    #58                 // class Day18$Num$NumValue
      41: ifeq          66
      44: aload_0
      45: getfield      #25                 // Field right:LDay18$Num;
      48: dup
      49: ldc           #60                 // String null cannot be cast to non-null type <root>.Day18.Num.NumValue
      51: invokestatic  #63                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
      54: checkcast     #58                 // class Day18$Num$NumValue
      57: invokevirtual #67                 // Method Day18$Num$NumValue.getValue:()I
      60: invokestatic  #73                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      63: goto          67
      66: aconst_null
      67: astore_2
      68: aload_0
      69: invokevirtual #77                 // Method findValueToLeft:()LDay18$Num$NumValue;
      72: dup
      73: ifnull        100
      76: astore_3
      77: iconst_0
      78: istore        4
      80: aload_3
      81: aload_3
      82: invokevirtual #67                 // Method Day18$Num$NumValue.getValue:()I
      85: aload_1
      86: dup
      87: invokestatic  #80                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      90: invokevirtual #83                 // Method java/lang/Integer.intValue:()I
      93: iadd
      94: invokevirtual #87                 // Method Day18$Num$NumValue.setValue:(I)V
      97: goto          102
     100: pop
     101: nop
     102: aload_0
     103: invokevirtual #90                 // Method findValueToRight:()LDay18$Num$NumValue;
     106: dup
     107: ifnull        134
     110: astore_3
     111: iconst_0
     112: istore        4
     114: aload_3
     115: aload_3
     116: invokevirtual #67                 // Method Day18$Num$NumValue.getValue:()I
     119: aload_2
     120: dup
     121: invokestatic  #80                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     124: invokevirtual #83                 // Method java/lang/Integer.intValue:()I
     127: iadd
     128: invokevirtual #87                 // Method Day18$Num$NumValue.setValue:(I)V
     131: goto          136
     134: pop
     135: nop
     136: aload_0
     137: invokevirtual #94                 // Method getParent:()LDay18$Num$NumPair;
     140: dup
     141: ifnull        165
     144: aload_0
     145: checkcast     #4                  // class Day18$Num
     148: new           #58                 // class Day18$Num$NumValue
     151: dup
     152: iconst_0
     153: invokespecial #96                 // Method Day18$Num$NumValue."<init>":(I)V
     156: checkcast     #4                  // class Day18$Num
     159: invokevirtual #99                 // Method replaceWith:(LDay18$Num;LDay18$Num;)V
     162: goto          166
     165: pop
     166: return

  public final void replaceWith(Day18$Num, Day18$Num);
    Code:
       0: aload_1
       1: ldc           #109                // String child
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #111                // String newValue
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: getfield      #23                 // Field left:LDay18$Num;
      16: aload_1
      17: invokestatic  #115                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      20: ifeq          31
      23: aload_0
      24: aload_2
      25: putfield      #23                 // Field left:LDay18$Num;
      28: goto          47
      31: aload_0
      32: getfield      #25                 // Field right:LDay18$Num;
      35: aload_1
      36: invokestatic  #115                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      39: ifeq          47
      42: aload_0
      43: aload_2
      44: putfield      #25                 // Field right:LDay18$Num;
      47: aload_2
      48: aload_0
      49: invokevirtual #29                 // Method Day18$Num.setParent:(LDay18$Num$NumPair;)V
      52: return
}

Compiled from "day18.kt"
public final class Day18Kt {
  public static final void print_day_18();
    Code:
       0: ldc           #8                  // String \u001b[33m
       2: astore_0
       3: ldc           #10                 // String \u001b[0m
       5: astore_1
       6: ldc           #12                 // String \u001b[32m
       8: astore_2
       9: new           #14                 // class java/lang/StringBuilder
      12: dup
      13: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      16: aload_0
      17: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      20: ldc           #23                 // String -
      22: checkcast     #25                 // class java/lang/CharSequence
      25: bipush        25
      27: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      30: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      33: ldc           #33                 // String Advent of Code - Day 18
      35: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      38: ldc           #23                 // String -
      40: checkcast     #25                 // class java/lang/CharSequence
      43: bipush        25
      45: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      48: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      51: aload_1
      52: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      55: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      58: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      61: swap
      62: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      65: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      68: aload_2
      69: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      72: invokestatic  #55                 // Method java/lang/Runtime.getRuntime:()Ljava/lang/Runtime;
      75: ldc           #57                 // String figlet Snailfish -c -f small
      77: invokevirtual #61                 // Method java/lang/Runtime.exec:(Ljava/lang/String;)Ljava/lang/Process;
      80: astore_3
      81: new           #63                 // class java/io/BufferedReader
      84: dup
      85: new           #65                 // class java/io/InputStreamReader
      88: dup
      89: aload_3
      90: invokevirtual #71                 // Method java/lang/Process.getInputStream:()Ljava/io/InputStream;
      93: invokespecial #74                 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V
      96: checkcast     #76                 // class java/io/Reader
      99: invokespecial #79                 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V
     102: astore        4
     104: aload         4
     106: checkcast     #76                 // class java/io/Reader
     109: invokedynamic #98,  0             // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     114: invokestatic  #104                // Method kotlin/io/TextStreamsKt.forEachLine:(Ljava/io/Reader;Lkotlin/jvm/functions/Function1;)V
     117: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     120: aload_1
     121: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     124: new           #14                 // class java/lang/StringBuilder
     127: dup
     128: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
     131: aload_0
     132: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     135: ldc           #23                 // String -
     137: checkcast     #25                 // class java/lang/CharSequence
     140: bipush        33
     142: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     145: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     148: ldc           #106                // String Output
     150: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     153: ldc           #23                 // String -
     155: checkcast     #25                 // class java/lang/CharSequence
     158: bipush        33
     160: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     163: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     166: aload_1
     167: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     170: bipush        10
     172: invokevirtual #109                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     175: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     178: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     181: swap
     182: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     185: return

  public static final void main();
    Code:
       0: invokestatic  #120                // Method print_day_18:()V
       3: new           #14                 // class java/lang/StringBuilder
       6: dup
       7: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      10: ldc           #122                // String Puzzle 1:
      12: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: new           #124                // class Day18
      18: dup
      19: invokespecial #125                // Method Day18."<init>":()V
      22: invokevirtual #129                // Method Day18.part_1:()I
      25: invokevirtual #132                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      28: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      31: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      34: swap
      35: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      38: new           #14                 // class java/lang/StringBuilder
      41: dup
      42: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      45: ldc           #134                // String Puzzle 2:
      47: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      50: new           #124                // class Day18
      53: dup
      54: invokespecial #125                // Method Day18."<init>":()V
      57: invokevirtual #137                // Method Day18.part_2:()I
      60: invokevirtual #132                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      63: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      66: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      69: swap
      70: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      73: new           #14                 // class java/lang/StringBuilder
      76: dup
      77: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      80: ldc           #139                // String \n\u001b[33m
      82: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      85: ldc           #141                // String =
      87: checkcast     #25                 // class java/lang/CharSequence
      90: bipush        72
      92: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      95: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      98: ldc           #143                // String \u001b[0m\n
     100: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     103: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     106: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     109: swap
     110: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     113: return

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

  private static final kotlin.Unit print_day_18$lambda$0(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #150                // String it
       3: invokestatic  #156                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: aload_0
      10: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      13: getstatic     #162                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      16: areturn
}


import java.io.*
fun print_day_9() {

    val yellow = "\u001B[33m"
    val reset = "\u001b[0m"
    val green = "\u001B[32m"
    println(yellow + "-".repeat(25) + "Advent of Code - Day 9" + "-".repeat(25) + reset)
    println(green)
    val process = Runtime.getRuntime().exec("figlet Smoke Basin -c -f small")
    val reader = BufferedReader(InputStreamReader(process.inputStream))
    reader.forEachLine { println(it) }
    println(reset)
    println(yellow + "-".repeat(33) + "Output" + "-".repeat(33) + reset + "\n")
}
fun main() {
    print_day_9()
    Day9().part_1()
    Day9().part_2()
    println("\n" + "\u001B[33m" + "=".repeat(72) + "\u001b[0m" + "\n")
}

class Day9 {

    data class Point(val x:Int, val y:Int) {
        fun neighbours(xBoundary: Int, yBoundary: Int): List<Point> =
            listOf(Point(x-1, y), Point(x+1, y), Point(x, y-1), Point(x, y+1) ).filter {
                it.x in 0 until xBoundary && it.y  in 0 until yBoundary
            }
    }

    val heightmap = File("../Input/day9.txt").readLines().map { it.toCharArray().map { c -> c.digitToInt() } }

    fun part_1() {
        val total = heightmap.foldIndexed(0) { yIndex, acc, list ->
            list.foldIndexed(acc) { xIndex, sum, height ->
                if (Point(xIndex, yIndex).neighbours(heightmap[0].size, heightmap.size).count { heightmap[it.y][it.x] <= height } == 0)
                    sum + heightmap[yIndex][xIndex] + 1
                else sum
            }
        }

        println("Puzzle 1: $total")
    }

    fun part_2() {

        fun getLowPoints() = heightmap.flatMapIndexed { yIndex, list ->
            list.mapIndexed { xIndex, height ->
                val smallerNeighbours = Point(xIndex, yIndex).neighbours(heightmap[0].size, heightmap.size).count { heightmap[it.y][it.x] <= height }
                if (smallerNeighbours == 0) Point(xIndex, yIndex) else null
            }.filterNotNull()
        }
        fun getBasinSize(p: Point): Int {
            val visited = mutableSetOf(p)
            val queue = mutableListOf(p)
            while (queue.isNotEmpty()) {
                val newNeighbors = queue.removeFirst()
                    .neighbours(heightmap[0].size, heightmap.size)
                    .filter { it !in visited }
                    .filter { heightmap[it.y][it.x] != 9 }
                visited.addAll(newNeighbors)
                queue.addAll(newNeighbors)
            }
            return visited.size
        }

        val answer = getLowPoints().map { getBasinSize(it) }
            .sortedDescending()
            .take(3)
            .reduce { total, next -> total * next }

        println("Puzzle 2: $answer")
    }
}

Compiled from "day09.kt"
public final class Day09Kt {
  public static final void print_day_9();
    Code:
       0: ldc           #8                  // String \u001b[33m
       2: astore_0
       3: ldc           #10                 // String \u001b[0m
       5: astore_1
       6: ldc           #12                 // String \u001b[32m
       8: astore_2
       9: new           #14                 // class java/lang/StringBuilder
      12: dup
      13: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      16: aload_0
      17: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      20: ldc           #23                 // String -
      22: checkcast     #25                 // class java/lang/CharSequence
      25: bipush        25
      27: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      30: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      33: ldc           #33                 // String Advent of Code - Day 9
      35: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      38: ldc           #23                 // String -
      40: checkcast     #25                 // class java/lang/CharSequence
      43: bipush        25
      45: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      48: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      51: aload_1
      52: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      55: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      58: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      61: swap
      62: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      65: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      68: aload_2
      69: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      72: invokestatic  #55                 // Method java/lang/Runtime.getRuntime:()Ljava/lang/Runtime;
      75: ldc           #57                 // String figlet Smoke Basin -c -f small
      77: invokevirtual #61                 // Method java/lang/Runtime.exec:(Ljava/lang/String;)Ljava/lang/Process;
      80: astore_3
      81: new           #63                 // class java/io/BufferedReader
      84: dup
      85: new           #65                 // class java/io/InputStreamReader
      88: dup
      89: aload_3
      90: invokevirtual #71                 // Method java/lang/Process.getInputStream:()Ljava/io/InputStream;
      93: invokespecial #74                 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V
      96: checkcast     #76                 // class java/io/Reader
      99: invokespecial #79                 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V
     102: astore        4
     104: aload         4
     106: checkcast     #76                 // class java/io/Reader
     109: invokedynamic #98,  0             // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     114: invokestatic  #104                // Method kotlin/io/TextStreamsKt.forEachLine:(Ljava/io/Reader;Lkotlin/jvm/functions/Function1;)V
     117: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     120: aload_1
     121: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     124: new           #14                 // class java/lang/StringBuilder
     127: dup
     128: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
     131: aload_0
     132: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     135: ldc           #23                 // String -
     137: checkcast     #25                 // class java/lang/CharSequence
     140: bipush        33
     142: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     145: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     148: ldc           #106                // String Output
     150: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     153: ldc           #23                 // String -
     155: checkcast     #25                 // class java/lang/CharSequence
     158: bipush        33
     160: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     163: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     166: aload_1
     167: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     170: bipush        10
     172: invokevirtual #109                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     175: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     178: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     181: swap
     182: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     185: return

  public static final void main();
    Code:
       0: invokestatic  #120                // Method print_day_9:()V
       3: new           #122                // class Day9
       6: dup
       7: invokespecial #123                // Method Day9."<init>":()V
      10: invokevirtual #126                // Method Day9.part_1:()V
      13: new           #122                // class Day9
      16: dup
      17: invokespecial #123                // Method Day9."<init>":()V
      20: invokevirtual #129                // Method Day9.part_2:()V
      23: new           #14                 // class java/lang/StringBuilder
      26: dup
      27: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      30: ldc           #131                // String \n\u001b[33m
      32: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      35: ldc           #133                // String =
      37: checkcast     #25                 // class java/lang/CharSequence
      40: bipush        72
      42: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      45: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      48: ldc           #135                // String \u001b[0m\n
      50: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      53: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      56: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      59: swap
      60: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      63: return

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

  private static final kotlin.Unit print_day_9$lambda$0(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #142                // String it
       3: invokestatic  #148                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: aload_0
      10: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      13: getstatic     #154                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      16: areturn
}


import java.io.*

fun print_day_8() {

    val yellow = "\u001B[33m"
    val reset = "\u001b[0m"
    val green = "\u001B[32m"
    println(yellow + "-".repeat(25) + "Advent of Code - Day 8" + "-".repeat(25) + reset)
    println(green)
    val process = Runtime.getRuntime().exec("figlet Seven Segment Search -c -f small")
    val reader = BufferedReader(InputStreamReader(process.inputStream))
    reader.forEachLine { println(it) }
    println(reset)

    println(yellow + "-".repeat(33) + "Output" + "-".repeat(33) + reset + "\n")
}
fun main() {
    print_day_8()
    Day8().part_1()
    Day8().part_2()
    println("\n" + "\u001B[33m" + "=".repeat(72) + "\u001b[0m" + "\n")
}

class Day8 {
    private val lines = File("../Input/day8.txt").readLines().map { it.split("|")[0].trim() to it.split("|")[1].trim() }

    fun part_1() {
        val uniqueLengths = listOf(2, 3, 4, 7)

        var totalUnique = 0
        for((_, output) in lines) {
            output.split(" ").forEach {
                if(it.length in uniqueLengths) totalUnique++
            }
        }
        println("Puzzle 1: " + totalUnique)
    }

    fun part_2() {
        var total = 0
        for((input, output) in lines) {
            val displays = mutableMapOf<String, Int>()
            val inputs = input.split(" ").map{ it.sortChars() }

            val one = inputs.first { it.length == 2 }
            val four = inputs.first { it.length == 4 }
            val seven = inputs.first { it.length == 3 }
            val eight = inputs.first { it.length == 7 }
            val nine = inputs.first { it.length == 6 && it.containsAll(four) }

            displays[one] = 1
            displays[four] = 4
            displays[seven] = 7
            displays[eight] = 8
            displays[nine] = 9
            displays[inputs.first { it.length == 6 && it.containsAll(seven) && !it.containsAll(four) }] = 0
            displays[inputs.first { it.length == 6 && !it.containsAll(one) }] = 6
            displays[inputs.first { it.length == 5 && it.containsAll(one) }] = 3
            displays[inputs.first { it.length == 5 && !it.containsAll(one) && nine.containsAll(it) }] = 5
            displays[inputs.first { it.length == 5 && !it.containsAll(one) && !nine.containsAll(it) }] = 2

            total += output.split(" ").fold("") { number, outputVal ->
                number + displays[outputVal.sortChars()].toString()
            }.toInt()
        }

        println("Puzzle 2: " + total)
    }

    private fun String.sortChars() = this.toCharArray().sorted().joinToString("")
    private fun String.containsAll(chars: String) = this.toList().containsAll(chars.toList())
}

Compiled from "day08.kt"
public final class Day08Kt {
  public static final void print_day_8();
    Code:
       0: ldc           #8                  // String \u001b[33m
       2: astore_0
       3: ldc           #10                 // String \u001b[0m
       5: astore_1
       6: ldc           #12                 // String \u001b[32m
       8: astore_2
       9: new           #14                 // class java/lang/StringBuilder
      12: dup
      13: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      16: aload_0
      17: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      20: ldc           #23                 // String -
      22: checkcast     #25                 // class java/lang/CharSequence
      25: bipush        25
      27: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      30: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      33: ldc           #33                 // String Advent of Code - Day 8
      35: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      38: ldc           #23                 // String -
      40: checkcast     #25                 // class java/lang/CharSequence
      43: bipush        25
      45: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      48: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      51: aload_1
      52: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      55: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      58: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      61: swap
      62: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      65: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      68: aload_2
      69: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      72: invokestatic  #55                 // Method java/lang/Runtime.getRuntime:()Ljava/lang/Runtime;
      75: ldc           #57                 // String figlet Seven Segment Search -c -f small
      77: invokevirtual #61                 // Method java/lang/Runtime.exec:(Ljava/lang/String;)Ljava/lang/Process;
      80: astore_3
      81: new           #63                 // class java/io/BufferedReader
      84: dup
      85: new           #65                 // class java/io/InputStreamReader
      88: dup
      89: aload_3
      90: invokevirtual #71                 // Method java/lang/Process.getInputStream:()Ljava/io/InputStream;
      93: invokespecial #74                 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V
      96: checkcast     #76                 // class java/io/Reader
      99: invokespecial #79                 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V
     102: astore        4
     104: aload         4
     106: checkcast     #76                 // class java/io/Reader
     109: invokedynamic #98,  0             // InvokeDynamic #0:invoke:()Lkotlin/jvm/functions/Function1;
     114: invokestatic  #104                // Method kotlin/io/TextStreamsKt.forEachLine:(Ljava/io/Reader;Lkotlin/jvm/functions/Function1;)V
     117: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     120: aload_1
     121: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     124: new           #14                 // class java/lang/StringBuilder
     127: dup
     128: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
     131: aload_0
     132: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     135: ldc           #23                 // String -
     137: checkcast     #25                 // class java/lang/CharSequence
     140: bipush        33
     142: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     145: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     148: ldc           #106                // String Output
     150: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     153: ldc           #23                 // String -
     155: checkcast     #25                 // class java/lang/CharSequence
     158: bipush        33
     160: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
     163: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     166: aload_1
     167: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     170: bipush        10
     172: invokevirtual #109                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     175: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     178: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
     181: swap
     182: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     185: return

  public static final void main();
    Code:
       0: invokestatic  #120                // Method print_day_8:()V
       3: new           #122                // class Day8
       6: dup
       7: invokespecial #123                // Method Day8."<init>":()V
      10: invokevirtual #126                // Method Day8.part_1:()V
      13: new           #122                // class Day8
      16: dup
      17: invokespecial #123                // Method Day8."<init>":()V
      20: invokevirtual #129                // Method Day8.part_2:()V
      23: new           #14                 // class java/lang/StringBuilder
      26: dup
      27: invokespecial #17                 // Method java/lang/StringBuilder."<init>":()V
      30: ldc           #131                // String \n\u001b[33m
      32: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      35: ldc           #133                // String =
      37: checkcast     #25                 // class java/lang/CharSequence
      40: bipush        72
      42: invokestatic  #31                 // Method kotlin/text/StringsKt.repeat:(Ljava/lang/CharSequence;I)Ljava/lang/String;
      45: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      48: ldc           #135                // String \u001b[0m\n
      50: invokevirtual #21                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      53: invokevirtual #37                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      56: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
      59: swap
      60: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      63: return

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

  private static final kotlin.Unit print_day_8$lambda$0(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #142                // String it
       3: invokestatic  #148                // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: aload_0
      10: invokevirtual #49                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      13: getstatic     #154                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
      16: areturn
}