package day8

import java.io.File

/*
* An entry has the following format: <representation of the ten digits> | <display output>
* i.e:
* acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf
*/
fun parseOnlyDigitsOutput(entries: List<String>): List<List<String>> =
  entries.map { entry -> entry.split(" | ")[1].split(" ") }

fun countOneFourSevenAndEights(listOfDisplayDigitRows: List<List<String>>): Int {
  val listOfSizes = listOf(2, 4, 3, 7) // The amount of signals that 1, 4, 7 and 8 require respectively
  return listOfDisplayDigitRows.sumOf { digitsRow -> digitsRow.count { digit -> listOfSizes.contains(digit.length) } }
}
/*
* Digits representation
*
*     0:      1:      2:      3:      4:
*    aaaa    ....    aaaa    aaaa    ....
*   b    c  .    c  .    c  .    c  b    c
*   b    c  .    c  .    c  .    c  b    c
*    ....    ....    dddd    dddd    dddd
*   e    f  .    f  e    .  .    f  .    f
*   e    f  .    f  e    .  .    f  .    f
*    gggg    ....    gggg    gggg    ....
*
*     5:      6:      7:      8:      9:
*    aaaa    aaaa    aaaa    aaaa    aaaa
*   b    .  b    .  .    c  b    c  b    c
*   b    .  b    .  .    c  b    c  b    c
*    dddd    dddd    ....    dddd    dddd
*   .    f  e    f  .    f  e    f  .    f
*   .    f  e    f  .    f  e    f  .    f
*    gggg    gggg    ....    gggg    gggg
*/
private val digitMap = mapOf(
  "abcefg" to 0,
  "cf" to 1,
  "acdeg" to 2,
  "acdfg" to 3,
  "bcdf" to 4,
  "abdfg" to 5,
  "abdefg" to 6,
  "acf" to 7,
  "abcdefg" to 8,
  "abcdfg" to 9,
)

/*
* The input contains the representation of all digits.
* With that information and the `digitMap` above we can already infer a few things:
* - Only edge 'b' appears 6 times
* - Only edge 'e' appears 4 times
* - Only edge 'f' appears 9 times
* - Edges 'a' and 'c' appear 8 times
* - Edges 'd' and 'g' appear 7 times
*
* Also comparing the edges of numbers we can disambiguate edges in the last two statements:
* - 7.edges - 4.edges = 'a'
* - 4.edges - 7.edges = 'b' and 'd'
*
* Although the last subtraction will produce two edges, we've already inferred 'b' so we can discard it in favour of 'd'
*/
fun computeEquivalenceMap(digitsSignals: String): Map<Char, Char> {
  val translations = mutableMapOf<Char, Char>()

  // Get some equivalences due to unique number of occurrences
  val occurrences = digitsSignals.replace(" ", "").groupingBy { it }.eachCount()
  occurrences.forEach { (c, n) ->
    if (n == 4) translations[c] = 'e'
    if (n == 6) translations[c] = 'b'
    if (n == 9) translations[c] = 'f'
  }

  // Get the rest by comparing numbers with subtle differences
  val signals = digitsSignals.split(" ").groupBy { it.length }
  val four = signals[4]!!.first().toSet() // 4 the only digit that requires four signals to be represented
  val seven = signals[3]!!.first().toSet()  // 7 the only digit that requires three signals to be represented

  // 7 - 4 will output edge 'a'
  val a = (seven - four).first()
  translations[a] = 'a'

  // 'c' is the other edge with 8 occurrences that is not 'a'
  val c = occurrences.entries.first { (c, n) -> n == 8 && c != a }.key
  translations[c] = 'c'

  // 4 - 7 will generate edges 'b' and 'd' but 'b' is already in the translations map
  val d = (four - seven).first { c -> !translations.contains(c) }
  translations[d] = 'd'

  // 'g' is the other edge with 7 occurrences that is not 'd'
  val g = occurrences.entries.first { (c, n) -> n == 7 && c != d }.key
  translations[g] = 'g'

  return translations
}

fun decipherSignal(entry: String): Int {
  val (signals, display) = entry.split(" | ")
  val equivalenceMap = computeEquivalenceMap(signals)
  val outputDigits = display
    .split(" ")
    .map { digit ->
      val translation = digit.map(equivalenceMap::get).sortedBy { it }.joinToString("")
      digitMap[translation]
    }

  return outputDigits.joinToString("").toInt()
}

fun main() {
  File("./input/day8.txt").useLines { lines ->
    val entries = lines.toList()
    val listOfDisplayDigitRows = parseOnlyDigitsOutput(entries)
    println("First part: ${countOneFourSevenAndEights(listOfDisplayDigitRows)}")
    println("First part: ${entries.sumOf { decipherSignal(it) }}")
  }
}

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

  public final int compare(T, T);
    Code:
       0: aload_1
       1: checkcast     #23                 // class java/lang/Character
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: checkcast     #25                 // class java/lang/Comparable
      12: aload_2
      13: checkcast     #23                 // class java/lang/Character
      16: astore_3
      17: astore        5
      19: iconst_0
      20: istore        4
      22: aload_3
      23: aload         5
      25: swap
      26: checkcast     #25                 // class java/lang/Comparable
      29: invokestatic  #31                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      32: ireturn
}

Compiled from "_Strings.kt"
public final class day8.Day8Kt$computeEquivalenceMap$$inlined$groupingBy$1 implements kotlin.collections.Grouping<java.lang.Character, java.lang.Character> {
  final java.lang.CharSequence $this_groupingBy;

  public day8.Day8Kt$computeEquivalenceMap$$inlined$groupingBy$1(java.lang.CharSequence);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #18                 // Field $this_groupingBy:Ljava/lang/CharSequence;
       5: aload_0
       6: invokespecial #21                 // Method java/lang/Object."<init>":()V
       9: return

  public java.util.Iterator<java.lang.Character> sourceIterator();
    Code:
       0: aload_0
       1: getfield      #18                 // Field $this_groupingBy:Ljava/lang/CharSequence;
       4: invokestatic  #33                 // Method kotlin/text/StringsKt.iterator:(Ljava/lang/CharSequence;)Lkotlin/collections/CharIterator;
       7: checkcast     #35                 // class java/util/Iterator
      10: areturn

  public java.lang.Character keyOf(char);
    Code:
       0: iload_1
       1: istore_2
       2: iconst_0
       3: istore_3
       4: iload_2
       5: invokestatic  #43                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
       8: areturn

  public java.lang.Object keyOf(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #40                 // class java/lang/Character
       5: invokevirtual #53                 // Method java/lang/Character.charValue:()C
       8: invokevirtual #55                 // Method keyOf:(C)Ljava/lang/Object;
      11: areturn
}

Compiled from "Day8.kt"
public final class day8.Day8Kt {
  private static final java.util.Map<java.lang.String, java.lang.Integer> digitMap;

  public static final java.util.List<java.util.List<java.lang.String>> parseOnlyDigitsOutput(java.util.List<java.lang.String>);
    Code:
       0: aload_0
       1: ldc           #10                 // String entries
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #18                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #20                 // class java/util/ArrayList
      18: dup
      19: aload_1
      20: bipush        10
      22: invokestatic  #26                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      25: invokespecial #30                 // Method java/util/ArrayList."<init>":(I)V
      28: checkcast     #32                 // class java/util/Collection
      31: astore        4
      33: iconst_0
      34: istore        5
      36: aload_3
      37: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      42: astore        6
      44: aload         6
      46: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      51: ifeq          147
      54: aload         6
      56: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      61: astore        7
      63: aload         4
      65: aload         7
      67: checkcast     #48                 // class java/lang/String
      70: astore        8
      72: astore        11
      74: iconst_0
      75: istore        9
      77: aload         8
      79: checkcast     #50                 // class java/lang/CharSequence
      82: iconst_1
      83: anewarray     #48                 // class java/lang/String
      86: astore        10
      88: aload         10
      90: iconst_0
      91: ldc           #52                 // String  |
      93: aastore
      94: aload         10
      96: iconst_0
      97: iconst_0
      98: bipush        6
     100: aconst_null
     101: invokestatic  #58                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     104: iconst_1
     105: invokeinterface #64,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     110: checkcast     #50                 // class java/lang/CharSequence
     113: iconst_1
     114: anewarray     #48                 // class java/lang/String
     117: astore        10
     119: aload         10
     121: iconst_0
     122: ldc           #66                 // String
     124: aastore
     125: aload         10
     127: iconst_0
     128: iconst_0
     129: bipush        6
     131: aconst_null
     132: invokestatic  #58                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     135: aload         11
     137: swap
     138: invokeinterface #70,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     143: pop
     144: goto          44
     147: aload         4
     149: checkcast     #60                 // class java/util/List
     152: nop
     153: areturn

  public static final int countOneFourSevenAndEights(java.util.List<? extends java.util.List<java.lang.String>>);
    Code:
       0: aload_0
       1: ldc           #89                 // String listOfDisplayDigitRows
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_4
       7: anewarray     #91                 // class java/lang/Integer
      10: astore_2
      11: aload_2
      12: iconst_0
      13: iconst_2
      14: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      17: aastore
      18: aload_2
      19: iconst_1
      20: iconst_4
      21: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      24: aastore
      25: aload_2
      26: iconst_2
      27: iconst_3
      28: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      31: aastore
      32: aload_2
      33: iconst_3
      34: bipush        7
      36: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      39: aastore
      40: aload_2
      41: invokestatic  #99                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      44: astore_1
      45: aload_0
      46: checkcast     #18                 // class java/lang/Iterable
      49: astore_2
      50: iconst_0
      51: istore_3
      52: aload_2
      53: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      58: astore        4
      60: aload         4
      62: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      67: ifeq          213
      70: aload         4
      72: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      77: astore        5
      79: iload_3
      80: aload         5
      82: checkcast     #60                 // class java/util/List
      85: astore        6
      87: istore        15
      89: iconst_0
      90: istore        7
      92: aload         6
      94: checkcast     #18                 // class java/lang/Iterable
      97: astore        8
      99: iconst_0
     100: istore        9
     102: aload         8
     104: instanceof    #32                 // class java/util/Collection
     107: ifeq          127
     110: aload         8
     112: checkcast     #32                 // class java/util/Collection
     115: invokeinterface #102,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     120: ifeq          127
     123: iconst_0
     124: goto          201
     127: iconst_0
     128: istore        10
     130: aload         8
     132: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     137: astore        11
     139: aload         11
     141: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     146: ifeq          199
     149: aload         11
     151: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     156: astore        12
     158: aload         12
     160: checkcast     #48                 // class java/lang/String
     163: astore        13
     165: iconst_0
     166: istore        14
     168: aload_1
     169: aload         13
     171: invokevirtual #106                // Method java/lang/String.length:()I
     174: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     177: invokeinterface #109,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
     182: ifeq          139
     185: iinc          10, 1
     188: iload         10
     190: ifge          139
     193: invokestatic  #113                // Method kotlin/collections/CollectionsKt.throwCountOverflow:()V
     196: goto          139
     199: iload         10
     201: nop
     202: istore        16
     204: iload         15
     206: iload         16
     208: iadd
     209: istore_3
     210: goto          60
     213: iload_3
     214: ireturn

  public static final java.util.Map<java.lang.Character, java.lang.Character> computeEquivalenceMap(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #127                // String digitsSignals
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #129                // class java/util/LinkedHashMap
       9: dup
      10: invokespecial #131                // Method java/util/LinkedHashMap."<init>":()V
      13: checkcast     #133                // class java/util/Map
      16: astore_1
      17: aload_0
      18: ldc           #66                 // String
      20: ldc           #135                // String
      22: iconst_0
      23: iconst_4
      24: aconst_null
      25: invokestatic  #139                // Method kotlin/text/StringsKt.replace$default:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Ljava/lang/String;
      28: checkcast     #50                 // class java/lang/CharSequence
      31: astore_3
      32: iconst_0
      33: istore        4
      35: new           #141                // class day8/Day8Kt$computeEquivalenceMap$$inlined$groupingBy$1
      38: dup
      39: aload_3
      40: invokespecial #144                // Method day8/Day8Kt$computeEquivalenceMap$$inlined$groupingBy$1."<init>":(Ljava/lang/CharSequence;)V
      43: checkcast     #146                // class kotlin/collections/Grouping
      46: invokestatic  #152                // Method kotlin/collections/GroupingKt.eachCount:(Lkotlin/collections/Grouping;)Ljava/util/Map;
      49: astore_2
      50: aload_2
      51: astore_3
      52: iconst_0
      53: istore        4
      55: aload_3
      56: invokeinterface #156,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      61: invokeinterface #159,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      66: astore        5
      68: aload         5
      70: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      75: ifeq          206
      78: aload         5
      80: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      85: checkcast     #161                // class java/util/Map$Entry
      88: astore        6
      90: aload         6
      92: astore        7
      94: iconst_0
      95: istore        8
      97: aload         7
      99: invokeinterface #164,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     104: checkcast     #166                // class java/lang/Character
     107: invokevirtual #170                // Method java/lang/Character.charValue:()C
     110: istore        9
     112: aload         7
     114: invokeinterface #173,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     119: checkcast     #175                // class java/lang/Number
     122: invokevirtual #178                // Method java/lang/Number.intValue:()I
     125: istore        10
     127: iload         10
     129: iconst_4
     130: if_icmpne     151
     133: iload         9
     135: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     138: aload_1
     139: swap
     140: bipush        101
     142: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     145: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     150: pop
     151: iload         10
     153: bipush        6
     155: if_icmpne     176
     158: iload         9
     160: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     163: aload_1
     164: swap
     165: bipush        98
     167: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     170: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     175: pop
     176: iload         10
     178: bipush        9
     180: if_icmpne     201
     183: iload         9
     185: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     188: aload_1
     189: swap
     190: bipush        102
     192: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     195: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     200: pop
     201: nop
     202: nop
     203: goto          68
     206: nop
     207: aload_0
     208: checkcast     #50                 // class java/lang/CharSequence
     211: iconst_1
     212: anewarray     #48                 // class java/lang/String
     215: astore        4
     217: aload         4
     219: iconst_0
     220: ldc           #66                 // String
     222: aastore
     223: aload         4
     225: iconst_0
     226: iconst_0
     227: bipush        6
     229: aconst_null
     230: invokestatic  #58                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     233: checkcast     #18                 // class java/lang/Iterable
     236: astore        4
     238: iconst_0
     239: istore        5
     241: aload         4
     243: astore        6
     245: new           #129                // class java/util/LinkedHashMap
     248: dup
     249: invokespecial #131                // Method java/util/LinkedHashMap."<init>":()V
     252: checkcast     #133                // class java/util/Map
     255: astore        7
     257: iconst_0
     258: istore        8
     260: aload         6
     262: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     267: astore        9
     269: aload         9
     271: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     276: ifeq          384
     279: aload         9
     281: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     286: astore        10
     288: aload         10
     290: checkcast     #48                 // class java/lang/String
     293: astore        11
     295: iconst_0
     296: istore        12
     298: aload         11
     300: invokevirtual #106                // Method java/lang/String.length:()I
     303: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     306: astore        13
     308: aload         7
     310: astore        14
     312: iconst_0
     313: istore        15
     315: aload         14
     317: aload         13
     319: invokeinterface #188,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     324: astore        16
     326: aload         16
     328: ifnonnull     363
     331: iconst_0
     332: istore        17
     334: new           #20                 // class java/util/ArrayList
     337: dup
     338: invokespecial #189                // Method java/util/ArrayList."<init>":()V
     341: checkcast     #60                 // class java/util/List
     344: astore        17
     346: aload         14
     348: aload         13
     350: aload         17
     352: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     357: pop
     358: aload         17
     360: goto          365
     363: aload         16
     365: nop
     366: checkcast     #60                 // class java/util/List
     369: astore        11
     371: aload         11
     373: aload         10
     375: invokeinterface #190,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     380: pop
     381: goto          269
     384: aload         7
     386: nop
     387: astore_3
     388: aload_3
     389: iconst_4
     390: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     393: invokeinterface #188,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     398: dup
     399: invokestatic  #194                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     402: checkcast     #60                 // class java/util/List
     405: invokestatic  #198                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     408: checkcast     #50                 // class java/lang/CharSequence
     411: invokestatic  #202                // Method kotlin/text/StringsKt.toSet:(Ljava/lang/CharSequence;)Ljava/util/Set;
     414: astore        4
     416: aload_3
     417: iconst_3
     418: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     421: invokeinterface #188,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     426: dup
     427: invokestatic  #194                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     430: checkcast     #60                 // class java/util/List
     433: invokestatic  #198                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     436: checkcast     #50                 // class java/lang/CharSequence
     439: invokestatic  #202                // Method kotlin/text/StringsKt.toSet:(Ljava/lang/CharSequence;)Ljava/util/Set;
     442: astore        5
     444: aload         5
     446: aload         4
     448: checkcast     #18                 // class java/lang/Iterable
     451: invokestatic  #208                // Method kotlin/collections/SetsKt.minus:(Ljava/util/Set;Ljava/lang/Iterable;)Ljava/util/Set;
     454: checkcast     #18                 // class java/lang/Iterable
     457: invokestatic  #211                // Method kotlin/collections/CollectionsKt.first:(Ljava/lang/Iterable;)Ljava/lang/Object;
     460: checkcast     #166                // class java/lang/Character
     463: invokevirtual #170                // Method java/lang/Character.charValue:()C
     466: istore        6
     468: iload         6
     470: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     473: astore        8
     475: aload_1
     476: aload         8
     478: bipush        97
     480: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     483: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     488: pop
     489: aload_2
     490: invokeinterface #156,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     495: checkcast     #18                 // class java/lang/Iterable
     498: astore        8
     500: iconst_0
     501: istore        9
     503: aload         8
     505: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     510: astore        10
     512: aload         10
     514: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     519: ifeq          598
     522: aload         10
     524: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     529: astore        11
     531: aload         11
     533: checkcast     #161                // class java/util/Map$Entry
     536: astore        12
     538: iconst_0
     539: istore        13
     541: aload         12
     543: invokeinterface #164,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     548: checkcast     #166                // class java/lang/Character
     551: invokevirtual #170                // Method java/lang/Character.charValue:()C
     554: istore        14
     556: aload         12
     558: invokeinterface #173,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     563: checkcast     #175                // class java/lang/Number
     566: invokevirtual #178                // Method java/lang/Number.intValue:()I
     569: istore        15
     571: iload         15
     573: bipush        8
     575: if_icmpne     589
     578: iload         14
     580: iload         6
     582: if_icmpeq     589
     585: iconst_1
     586: goto          590
     589: iconst_0
     590: ifeq          512
     593: aload         11
     595: goto          608
     598: new           #213                // class java/util/NoSuchElementException
     601: dup
     602: ldc           #215                // String Collection contains no element matching the predicate.
     604: invokespecial #218                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
     607: athrow
     608: checkcast     #161                // class java/util/Map$Entry
     611: invokeinterface #164,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     616: checkcast     #166                // class java/lang/Character
     619: invokevirtual #170                // Method java/lang/Character.charValue:()C
     622: istore        7
     624: iload         7
     626: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     629: astore        9
     631: aload_1
     632: aload         9
     634: bipush        99
     636: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     639: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     644: pop
     645: aload         4
     647: aload         5
     649: checkcast     #18                 // class java/lang/Iterable
     652: invokestatic  #208                // Method kotlin/collections/SetsKt.minus:(Ljava/util/Set;Ljava/lang/Iterable;)Ljava/util/Set;
     655: checkcast     #18                 // class java/lang/Iterable
     658: astore        9
     660: iconst_0
     661: istore        10
     663: aload         9
     665: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     670: astore        11
     672: aload         11
     674: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     679: ifeq          732
     682: aload         11
     684: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     689: astore        12
     691: aload         12
     693: checkcast     #166                // class java/lang/Character
     696: invokevirtual #170                // Method java/lang/Character.charValue:()C
     699: istore        13
     701: iconst_0
     702: istore        14
     704: iload         13
     706: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     709: aload_1
     710: swap
     711: invokeinterface #221,  2          // InterfaceMethod java/util/Map.containsKey:(Ljava/lang/Object;)Z
     716: ifne          723
     719: iconst_1
     720: goto          724
     723: iconst_0
     724: ifeq          672
     727: aload         12
     729: goto          742
     732: new           #213                // class java/util/NoSuchElementException
     735: dup
     736: ldc           #215                // String Collection contains no element matching the predicate.
     738: invokespecial #218                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
     741: athrow
     742: checkcast     #166                // class java/lang/Character
     745: invokevirtual #170                // Method java/lang/Character.charValue:()C
     748: istore        8
     750: iload         8
     752: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     755: astore        10
     757: aload_1
     758: aload         10
     760: bipush        100
     762: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     765: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     770: pop
     771: aload_2
     772: invokeinterface #156,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     777: checkcast     #18                 // class java/lang/Iterable
     780: astore        10
     782: iconst_0
     783: istore        11
     785: aload         10
     787: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     792: astore        12
     794: aload         12
     796: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     801: ifeq          880
     804: aload         12
     806: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     811: astore        13
     813: aload         13
     815: checkcast     #161                // class java/util/Map$Entry
     818: astore        14
     820: iconst_0
     821: istore        15
     823: aload         14
     825: invokeinterface #164,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     830: checkcast     #166                // class java/lang/Character
     833: invokevirtual #170                // Method java/lang/Character.charValue:()C
     836: istore        16
     838: aload         14
     840: invokeinterface #173,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     845: checkcast     #175                // class java/lang/Number
     848: invokevirtual #178                // Method java/lang/Number.intValue:()I
     851: istore        17
     853: iload         17
     855: bipush        7
     857: if_icmpne     871
     860: iload         16
     862: iload         8
     864: if_icmpeq     871
     867: iconst_1
     868: goto          872
     871: iconst_0
     872: ifeq          794
     875: aload         13
     877: goto          890
     880: new           #213                // class java/util/NoSuchElementException
     883: dup
     884: ldc           #215                // String Collection contains no element matching the predicate.
     886: invokespecial #218                // Method java/util/NoSuchElementException."<init>":(Ljava/lang/String;)V
     889: athrow
     890: checkcast     #161                // class java/util/Map$Entry
     893: invokeinterface #164,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     898: checkcast     #166                // class java/lang/Character
     901: invokevirtual #170                // Method java/lang/Character.charValue:()C
     904: istore        9
     906: iload         9
     908: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     911: astore        11
     913: aload_1
     914: aload         11
     916: bipush        103
     918: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     921: invokeinterface #185,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     926: pop
     927: aload_1
     928: areturn

  public static final int decipherSignal(java.lang.String);
    Code:
       0: aload_0
       1: ldc_w         #263                // String entry
       4: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: checkcast     #50                 // class java/lang/CharSequence
      11: iconst_1
      12: anewarray     #48                 // class java/lang/String
      15: astore_2
      16: aload_2
      17: iconst_0
      18: ldc           #52                 // String  |
      20: aastore
      21: aload_2
      22: iconst_0
      23: iconst_0
      24: bipush        6
      26: aconst_null
      27: invokestatic  #58                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      30: astore_1
      31: aload_1
      32: iconst_0
      33: invokeinterface #64,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      38: checkcast     #48                 // class java/lang/String
      41: astore_2
      42: aload_1
      43: iconst_1
      44: invokeinterface #64,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      49: checkcast     #48                 // class java/lang/String
      52: astore_3
      53: aload_2
      54: invokestatic  #265                // Method computeEquivalenceMap:(Ljava/lang/String;)Ljava/util/Map;
      57: astore        4
      59: aload_3
      60: checkcast     #50                 // class java/lang/CharSequence
      63: iconst_1
      64: anewarray     #48                 // class java/lang/String
      67: astore        6
      69: aload         6
      71: iconst_0
      72: ldc           #66                 // String
      74: aastore
      75: aload         6
      77: iconst_0
      78: iconst_0
      79: bipush        6
      81: aconst_null
      82: invokestatic  #58                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      85: checkcast     #18                 // class java/lang/Iterable
      88: astore        6
      90: nop
      91: iconst_0
      92: istore        7
      94: aload         6
      96: astore        8
      98: new           #20                 // class java/util/ArrayList
     101: dup
     102: aload         6
     104: bipush        10
     106: invokestatic  #26                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     109: invokespecial #30                 // Method java/util/ArrayList."<init>":(I)V
     112: checkcast     #32                 // class java/util/Collection
     115: astore        9
     117: iconst_0
     118: istore        10
     120: aload         8
     122: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     127: astore        11
     129: aload         11
     131: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     136: ifeq          341
     139: aload         11
     141: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     146: astore        12
     148: aload         9
     150: aload         12
     152: checkcast     #48                 // class java/lang/String
     155: astore        13
     157: astore        26
     159: iconst_0
     160: istore        14
     162: aload         13
     164: checkcast     #50                 // class java/lang/CharSequence
     167: astore        15
     169: iconst_0
     170: istore        16
     172: aload         15
     174: astore        17
     176: new           #20                 // class java/util/ArrayList
     179: dup
     180: aload         15
     182: invokeinterface #266,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     187: invokespecial #30                 // Method java/util/ArrayList."<init>":(I)V
     190: checkcast     #32                 // class java/util/Collection
     193: astore        18
     195: iconst_0
     196: istore        19
     198: iconst_0
     199: istore        20
     201: iload         20
     203: aload         17
     205: invokeinterface #266,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     210: if_icmpge     265
     213: aload         17
     215: iload         20
     217: invokeinterface #270,  2          // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     222: istore        21
     224: aload         18
     226: iload         21
     228: istore        22
     230: astore        23
     232: iconst_0
     233: istore        24
     235: aload         4
     237: iload         22
     239: invokestatic  #181                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     242: invokeinterface #188,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     247: checkcast     #166                // class java/lang/Character
     250: aload         23
     252: swap
     253: invokeinterface #70,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     258: pop
     259: iinc          20, 1
     262: goto          201
     265: aload         18
     267: checkcast     #60                 // class java/util/List
     270: nop
     271: checkcast     #18                 // class java/lang/Iterable
     274: astore        15
     276: nop
     277: iconst_0
     278: istore        16
     280: aload         15
     282: new           #272                // class day8/Day8Kt$decipherSignal$lambda$10$$inlined$sortedBy$1
     285: dup
     286: invokespecial #273                // Method day8/Day8Kt$decipherSignal$lambda$10$$inlined$sortedBy$1."<init>":()V
     289: checkcast     #275                // class java/util/Comparator
     292: invokestatic  #279                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
     295: checkcast     #18                 // class java/lang/Iterable
     298: ldc           #135                // String
     300: checkcast     #50                 // class java/lang/CharSequence
     303: aconst_null
     304: aconst_null
     305: iconst_0
     306: aconst_null
     307: aconst_null
     308: bipush        62
     310: aconst_null
     311: invokestatic  #283                // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     314: astore        25
     316: getstatic     #286                // Field digitMap:Ljava/util/Map;
     319: aload         25
     321: invokeinterface #188,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     326: checkcast     #91                 // class java/lang/Integer
     329: aload         26
     331: swap
     332: invokeinterface #70,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     337: pop
     338: goto          129
     341: aload         9
     343: checkcast     #60                 // class java/util/List
     346: nop
     347: astore        5
     349: aload         5
     351: checkcast     #18                 // class java/lang/Iterable
     354: ldc           #135                // String
     356: checkcast     #50                 // class java/lang/CharSequence
     359: aconst_null
     360: aconst_null
     361: iconst_0
     362: aconst_null
     363: aconst_null
     364: bipush        62
     366: aconst_null
     367: invokestatic  #283                // Method kotlin/collections/CollectionsKt.joinToString$default:(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
     370: invokestatic  #289                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     373: ireturn

  public static final void main();
    Code:
       0: new           #303                // class java/io/File
       3: dup
       4: ldc_w         #305                // String ./input/day8.txt
       7: invokespecial #306                // Method java/io/File."<init>":(Ljava/lang/String;)V
      10: astore_0
      11: getstatic     #312                // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      14: astore_1
      15: iconst_0
      16: istore_2
      17: aload_0
      18: astore_3
      19: sipush        8192
      22: istore        4
      24: aload_3
      25: astore        5
      27: new           #314                // class java/io/InputStreamReader
      30: dup
      31: new           #316                // class java/io/FileInputStream
      34: dup
      35: aload         5
      37: invokespecial #319                // Method java/io/FileInputStream."<init>":(Ljava/io/File;)V
      40: checkcast     #321                // class java/io/InputStream
      43: aload_1
      44: invokespecial #324                // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/nio/charset/Charset;)V
      47: checkcast     #326                // class java/io/Reader
      50: astore        5
      52: aload         5
      54: instanceof    #328                // class java/io/BufferedReader
      57: ifeq          68
      60: aload         5
      62: checkcast     #328                // class java/io/BufferedReader
      65: goto          79
      68: new           #328                // class java/io/BufferedReader
      71: dup
      72: aload         5
      74: iload         4
      76: invokespecial #331                // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;I)V
      79: checkcast     #333                // class java/io/Closeable
      82: astore_3
      83: aconst_null
      84: astore        4
      86: nop
      87: aload_3
      88: checkcast     #328                // class java/io/BufferedReader
      91: astore        5
      93: iconst_0
      94: istore        6
      96: aload         5
      98: invokestatic  #339                // Method kotlin/io/TextStreamsKt.lineSequence:(Ljava/io/BufferedReader;)Lkotlin/sequences/Sequence;
     101: astore        7
     103: iconst_0
     104: istore        8
     106: aload         7
     108: invokestatic  #345                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
     111: astore        9
     113: aload         9
     115: invokestatic  #347                // Method parseOnlyDigitsOutput:(Ljava/util/List;)Ljava/util/List;
     118: astore        10
     120: new           #349                // class java/lang/StringBuilder
     123: dup
     124: invokespecial #350                // Method java/lang/StringBuilder."<init>":()V
     127: ldc_w         #352                // String First part:
     130: invokevirtual #356                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     133: aload         10
     135: invokestatic  #358                // Method countOneFourSevenAndEights:(Ljava/util/List;)I
     138: invokevirtual #361                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     141: invokevirtual #365                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     144: getstatic     #371                // Field java/lang/System.out:Ljava/io/PrintStream;
     147: swap
     148: invokevirtual #376                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     151: new           #349                // class java/lang/StringBuilder
     154: dup
     155: invokespecial #350                // Method java/lang/StringBuilder."<init>":()V
     158: ldc_w         #352                // String First part:
     161: invokevirtual #356                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     164: aload         9
     166: checkcast     #18                 // class java/lang/Iterable
     169: astore        11
     171: astore        12
     173: iconst_0
     174: istore        13
     176: aload         11
     178: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     183: astore        14
     185: aload         14
     187: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     192: ifeq          235
     195: aload         14
     197: invokeinterface #46,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     202: astore        15
     204: iload         13
     206: aload         15
     208: checkcast     #48                 // class java/lang/String
     211: astore        16
     213: istore        17
     215: iconst_0
     216: istore        18
     218: aload         16
     220: invokestatic  #378                // Method decipherSignal:(Ljava/lang/String;)I
     223: istore        19
     225: iload         17
     227: iload         19
     229: iadd
     230: istore        13
     232: goto          185
     235: iload         13
     237: istore        17
     239: aload         12
     241: iload         17
     243: invokevirtual #361                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     246: invokevirtual #365                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     249: getstatic     #371                // Field java/lang/System.out:Ljava/io/PrintStream;
     252: swap
     253: invokevirtual #376                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     256: nop
     257: getstatic     #384                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     260: astore        5
     262: aload_3
     263: aload         4
     265: invokestatic  #390                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     268: goto          291
     271: astore        6
     273: aload         6
     275: astore        4
     277: aload         6
     279: athrow
     280: astore        6
     282: aload_3
     283: aload         4
     285: invokestatic  #390                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     288: aload         6
     290: athrow
     291: nop
     292: return
    Exception table:
       from    to  target type
          86   262   271   Class java/lang/Throwable
          86   262   280   any
         271   280   280   any
         280   282   280   any

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

  static {};
    Code:
       0: bipush        10
       2: anewarray     #413                // class kotlin/Pair
       5: astore_0
       6: aload_0
       7: iconst_0
       8: ldc_w         #415                // String abcefg
      11: iconst_0
      12: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      15: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      18: aastore
      19: aload_0
      20: iconst_1
      21: ldc_w         #423                // String cf
      24: iconst_1
      25: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      28: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      31: aastore
      32: aload_0
      33: iconst_2
      34: ldc_w         #425                // String acdeg
      37: iconst_2
      38: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      41: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      44: aastore
      45: aload_0
      46: iconst_3
      47: ldc_w         #427                // String acdfg
      50: iconst_3
      51: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      54: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      57: aastore
      58: aload_0
      59: iconst_4
      60: ldc_w         #429                // String bcdf
      63: iconst_4
      64: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      67: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      70: aastore
      71: aload_0
      72: iconst_5
      73: ldc_w         #431                // String abdfg
      76: iconst_5
      77: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      80: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      83: aastore
      84: aload_0
      85: bipush        6
      87: ldc_w         #433                // String abdefg
      90: bipush        6
      92: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      95: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      98: aastore
      99: aload_0
     100: bipush        7
     102: ldc_w         #435                // String acf
     105: bipush        7
     107: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     110: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     113: aastore
     114: aload_0
     115: bipush        8
     117: ldc_w         #437                // String abcdefg
     120: bipush        8
     122: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     125: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     128: aastore
     129: aload_0
     130: bipush        9
     132: ldc_w         #439                // String abcdfg
     135: bipush        9
     137: invokestatic  #95                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     140: invokestatic  #421                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     143: aastore
     144: aload_0
     145: invokestatic  #445                // Method kotlin/collections/MapsKt.mapOf:([Lkotlin/Pair;)Ljava/util/Map;
     148: putstatic     #286                // Field digitMap:Ljava/util/Map;
     151: return
}


package day6

import java.io.File

fun parseInput(line: String) = line.split(",").map { it.toInt() }

data class LanternFish(val daysToEngender: Int) {
  fun ageOneDay(): List<LanternFish> =
    if (daysToEngender == 0) listOf(LanternFish(6), LanternFish(8))
    else listOf(LanternFish(daysToEngender - 1))
}

fun naivelyCountLanternfishPopulationAfterNDays(listOfDays: List<Int>, days: Int): Int {
  tailrec fun loop(lanternFish: List<LanternFish>, remainingDays: Int): List<LanternFish> =
    if (remainingDays == 0) lanternFish
    else loop(lanternFish.flatMap { it.ageOneDay() }, remainingDays - 1)

  return loop(listOfDays.map { LanternFish(it) }, days).count()
}

fun countLanternfishPopulationAfterNDays(listOfDays: List<Int>, days: Int): Long {
  // cluster population by remaining days to give birth; 9 days for the first time, then 7 days
  val clusters = listOfDays.groupingBy { it }.eachCount()
  val population = Array(9) { clusters.getOrDefault(it, 0).toLong() }

  repeat(days) {
    val births = population[0]
    (1..8).forEach { i -> population[i - 1] = population[i] } // reduce days to give birth of population
    population[6] += births
    population[8] = births
  }

  return population.sum()
}

fun main() {
  File("./input/day6.txt").useLines { lines ->
    val lanternFish = parseInput(lines.first())
    println("First part: ${countLanternfishPopulationAfterNDays(lanternFish, 80)}")
    println("Second part: ${countLanternfishPopulationAfterNDays(lanternFish, 256)}")
  }
}

Compiled from "_Collections.kt"
public final class day6.Day6Kt$countLanternfishPopulationAfterNDays$$inlined$groupingBy$1 implements kotlin.collections.Grouping<java.lang.Integer, java.lang.Integer> {
  final java.lang.Iterable $this_groupingBy;

  public day6.Day6Kt$countLanternfishPopulationAfterNDays$$inlined$groupingBy$1(java.lang.Iterable);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #18                 // Field $this_groupingBy:Ljava/lang/Iterable;
       5: aload_0
       6: invokespecial #21                 // Method java/lang/Object."<init>":()V
       9: return

  public java.util.Iterator<java.lang.Integer> sourceIterator();
    Code:
       0: aload_0
       1: getfield      #18                 // Field $this_groupingBy:Ljava/lang/Iterable;
       4: invokeinterface #32,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
       9: areturn

  public java.lang.Integer keyOf(java.lang.Integer);
    Code:
       0: aload_1
       1: checkcast     #37                 // class java/lang/Number
       4: invokevirtual #41                 // Method java/lang/Number.intValue:()I
       7: istore_2
       8: iconst_0
       9: istore_3
      10: iload_2
      11: invokestatic  #47                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: areturn
}

Compiled from "Day6.kt"
public final class day6.Day6Kt {
  public static final java.util.List<java.lang.Integer> parseInput(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String line
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #18                 // class java/lang/CharSequence
      10: iconst_1
      11: anewarray     #20                 // class java/lang/String
      14: astore_1
      15: aload_1
      16: iconst_0
      17: ldc           #22                 // String ,
      19: aastore
      20: aload_1
      21: iconst_0
      22: iconst_0
      23: bipush        6
      25: aconst_null
      26: invokestatic  #28                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      29: checkcast     #30                 // class java/lang/Iterable
      32: astore_1
      33: iconst_0
      34: istore_2
      35: aload_1
      36: astore_3
      37: new           #32                 // class java/util/ArrayList
      40: dup
      41: aload_1
      42: bipush        10
      44: invokestatic  #38                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      47: invokespecial #42                 // Method java/util/ArrayList."<init>":(I)V
      50: checkcast     #44                 // class java/util/Collection
      53: astore        4
      55: iconst_0
      56: istore        5
      58: aload_3
      59: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      64: astore        6
      66: aload         6
      68: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      73: ifeq          120
      76: aload         6
      78: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      83: astore        7
      85: aload         4
      87: aload         7
      89: checkcast     #20                 // class java/lang/String
      92: astore        8
      94: astore        10
      96: iconst_0
      97: istore        9
      99: aload         8
     101: invokestatic  #64                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
     104: nop
     105: invokestatic  #68                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     108: aload         10
     110: swap
     111: invokeinterface #72,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     116: pop
     117: goto          66
     120: aload         4
     122: checkcast     #74                 // class java/util/List
     125: nop
     126: areturn

  public static final int naivelyCountLanternfishPopulationAfterNDays(java.util.List<java.lang.Integer>, int);
    Code:
       0: aload_0
       1: ldc           #92                 // String listOfDays
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #30                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: astore        4
      16: new           #32                 // class java/util/ArrayList
      19: dup
      20: aload_2
      21: bipush        10
      23: invokestatic  #38                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      26: invokespecial #42                 // Method java/util/ArrayList."<init>":(I)V
      29: checkcast     #44                 // class java/util/Collection
      32: astore        5
      34: iconst_0
      35: istore        6
      37: aload         4
      39: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      44: astore        7
      46: aload         7
      48: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          103
      56: aload         7
      58: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: astore        8
      65: aload         5
      67: aload         8
      69: checkcast     #94                 // class java/lang/Number
      72: invokevirtual #98                 // Method java/lang/Number.intValue:()I
      75: istore        9
      77: astore        11
      79: iconst_0
      80: istore        10
      82: new           #100                // class day6/LanternFish
      85: dup
      86: iload         9
      88: invokespecial #101                // Method day6/LanternFish."<init>":(I)V
      91: aload         11
      93: swap
      94: invokeinterface #72,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      99: pop
     100: goto          46
     103: aload         5
     105: checkcast     #74                 // class java/util/List
     108: nop
     109: iload_1
     110: invokestatic  #105                // Method naivelyCountLanternfishPopulationAfterNDays$loop:(Ljava/util/List;I)Ljava/util/List;
     113: checkcast     #44                 // class java/util/Collection
     116: invokeinterface #108,  1          // InterfaceMethod java/util/Collection.size:()I
     121: ireturn

  public static final long countLanternfishPopulationAfterNDays(java.util.List<java.lang.Integer>, int);
    Code:
       0: aload_0
       1: ldc           #92                 // String listOfDays
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #30                 // class java/lang/Iterable
      10: astore_3
      11: iconst_0
      12: istore        4
      14: new           #116                // class day6/Day6Kt$countLanternfishPopulationAfterNDays$$inlined$groupingBy$1
      17: dup
      18: aload_3
      19: invokespecial #119                // Method day6/Day6Kt$countLanternfishPopulationAfterNDays$$inlined$groupingBy$1."<init>":(Ljava/lang/Iterable;)V
      22: checkcast     #121                // class kotlin/collections/Grouping
      25: invokestatic  #127                // Method kotlin/collections/GroupingKt.eachCount:(Lkotlin/collections/Grouping;)Ljava/util/Map;
      28: astore_2
      29: iconst_0
      30: istore        4
      32: bipush        9
      34: anewarray     #129                // class java/lang/Long
      37: astore        5
      39: iload         4
      41: bipush        9
      43: if_icmpge     86
      46: iload         4
      48: istore        6
      50: aload         5
      52: iload         6
      54: aload_2
      55: iload         6
      57: invokestatic  #68                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      60: iconst_0
      61: invokestatic  #68                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      64: invokeinterface #135,  3          // InterfaceMethod java/util/Map.getOrDefault:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      69: checkcast     #94                 // class java/lang/Number
      72: invokevirtual #98                 // Method java/lang/Number.intValue:()I
      75: i2l
      76: invokestatic  #138                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
      79: aastore
      80: iinc          4, 1
      83: goto          39
      86: aload         5
      88: astore_3
      89: iconst_0
      90: istore        4
      92: iload         4
      94: iload_1
      95: if_icmpge     215
      98: iload         4
     100: istore        5
     102: iconst_0
     103: istore        6
     105: aload_3
     106: iconst_0
     107: aaload
     108: invokevirtual #142                // Method java/lang/Long.longValue:()J
     111: lstore        7
     113: new           #144                // class kotlin/ranges/IntRange
     116: dup
     117: iconst_1
     118: bipush        8
     120: invokespecial #147                // Method kotlin/ranges/IntRange."<init>":(II)V
     123: checkcast     #30                 // class java/lang/Iterable
     126: astore        9
     128: iconst_0
     129: istore        10
     131: aload         9
     133: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     138: astore        11
     140: aload         11
     142: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     147: ifeq          181
     150: aload         11
     152: checkcast     #149                // class kotlin/collections/IntIterator
     155: invokevirtual #152                // Method kotlin/collections/IntIterator.nextInt:()I
     158: istore        12
     160: iload         12
     162: istore        13
     164: iconst_0
     165: istore        14
     167: aload_3
     168: iload         13
     170: iconst_1
     171: isub
     172: aload_3
     173: iload         13
     175: aaload
     176: aastore
     177: nop
     178: goto          140
     181: nop
     182: aload_3
     183: bipush        6
     185: aload_3
     186: bipush        6
     188: aaload
     189: invokevirtual #142                // Method java/lang/Long.longValue:()J
     192: lload         7
     194: ladd
     195: invokestatic  #138                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     198: aastore
     199: aload_3
     200: bipush        8
     202: lload         7
     204: invokestatic  #138                // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     207: aastore
     208: nop
     209: iinc          4, 1
     212: goto          92
     215: aload_3
     216: invokestatic  #158                // Method kotlin/collections/ArraysKt.sumOfLong:([Ljava/lang/Long;)J
     219: lreturn

  public static final void main();
    Code:
       0: new           #179                // class java/io/File
       3: dup
       4: ldc           #181                // String ./input/day6.txt
       6: invokespecial #184                // Method java/io/File."<init>":(Ljava/lang/String;)V
       9: astore_0
      10: getstatic     #190                // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      13: astore_1
      14: iconst_0
      15: istore_2
      16: aload_0
      17: astore_3
      18: sipush        8192
      21: istore        4
      23: aload_3
      24: astore        5
      26: new           #192                // class java/io/InputStreamReader
      29: dup
      30: new           #194                // class java/io/FileInputStream
      33: dup
      34: aload         5
      36: invokespecial #197                // Method java/io/FileInputStream."<init>":(Ljava/io/File;)V
      39: checkcast     #199                // class java/io/InputStream
      42: aload_1
      43: invokespecial #202                // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/nio/charset/Charset;)V
      46: checkcast     #204                // class java/io/Reader
      49: astore        5
      51: aload         5
      53: instanceof    #206                // class java/io/BufferedReader
      56: ifeq          67
      59: aload         5
      61: checkcast     #206                // class java/io/BufferedReader
      64: goto          78
      67: new           #206                // class java/io/BufferedReader
      70: dup
      71: aload         5
      73: iload         4
      75: invokespecial #209                // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;I)V
      78: checkcast     #211                // class java/io/Closeable
      81: astore_3
      82: aconst_null
      83: astore        4
      85: nop
      86: aload_3
      87: checkcast     #206                // class java/io/BufferedReader
      90: astore        5
      92: iconst_0
      93: istore        6
      95: aload         5
      97: invokestatic  #217                // Method kotlin/io/TextStreamsKt.lineSequence:(Ljava/io/BufferedReader;)Lkotlin/sequences/Sequence;
     100: astore        7
     102: iconst_0
     103: istore        8
     105: aload         7
     107: invokestatic  #223                // Method kotlin/sequences/SequencesKt.first:(Lkotlin/sequences/Sequence;)Ljava/lang/Object;
     110: checkcast     #20                 // class java/lang/String
     113: invokestatic  #225                // Method parseInput:(Ljava/lang/String;)Ljava/util/List;
     116: astore        9
     118: new           #227                // class java/lang/StringBuilder
     121: dup
     122: invokespecial #229                // Method java/lang/StringBuilder."<init>":()V
     125: ldc           #231                // String First part:
     127: invokevirtual #235                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     130: aload         9
     132: bipush        80
     134: invokestatic  #237                // Method countLanternfishPopulationAfterNDays:(Ljava/util/List;I)J
     137: invokevirtual #240                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     140: invokevirtual #244                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     143: getstatic     #250                // Field java/lang/System.out:Ljava/io/PrintStream;
     146: swap
     147: invokevirtual #256                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     150: new           #227                // class java/lang/StringBuilder
     153: dup
     154: invokespecial #229                // Method java/lang/StringBuilder."<init>":()V
     157: ldc_w         #258                // String Second part:
     160: invokevirtual #235                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     163: aload         9
     165: sipush        256
     168: invokestatic  #237                // Method countLanternfishPopulationAfterNDays:(Ljava/util/List;I)J
     171: invokevirtual #240                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     174: invokevirtual #244                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     177: getstatic     #250                // Field java/lang/System.out:Ljava/io/PrintStream;
     180: swap
     181: invokevirtual #256                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     184: nop
     185: getstatic     #264                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     188: astore        5
     190: aload_3
     191: aload         4
     193: invokestatic  #270                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     196: goto          219
     199: astore        6
     201: aload         6
     203: astore        4
     205: aload         6
     207: athrow
     208: astore        6
     210: aload_3
     211: aload         4
     213: invokestatic  #270                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     216: aload         6
     218: athrow
     219: nop
     220: return
    Exception table:
       from    to  target type
          85   190   199   Class java/lang/Throwable
          85   190   208   any
         199   208   208   any
         208   210   208   any

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

  private static final java.util.List<day6.LanternFish> naivelyCountLanternfishPopulationAfterNDays$loop(java.util.List<day6.LanternFish>, int);
    Code:
       0: iload_1
       1: ifne          8
       4: aload_0
       5: goto          111
       8: aload_0
       9: checkcast     #30                 // class java/lang/Iterable
      12: astore_3
      13: iconst_0
      14: istore        4
      16: aload_3
      17: astore        5
      19: new           #32                 // class java/util/ArrayList
      22: dup
      23: invokespecial #292                // Method java/util/ArrayList."<init>":()V
      26: checkcast     #44                 // class java/util/Collection
      29: astore        6
      31: iconst_0
      32: istore        7
      34: aload         5
      36: invokeinterface #48,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      41: astore        8
      43: aload         8
      45: invokeinterface #54,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      50: ifeq          93
      53: aload         8
      55: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      60: astore        9
      62: aload         9
      64: checkcast     #100                // class day6/LanternFish
      67: astore        10
      69: iconst_0
      70: istore        11
      72: aload         10
      74: invokevirtual #296                // Method day6/LanternFish.ageOneDay:()Ljava/util/List;
      77: checkcast     #30                 // class java/lang/Iterable
      80: astore        10
      82: aload         6
      84: aload         10
      86: invokestatic  #300                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
      89: pop
      90: goto          43
      93: aload         6
      95: checkcast     #74                 // class java/util/List
      98: nop
      99: astore_2
     100: iload_1
     101: iconst_1
     102: isub
     103: istore_3
     104: aload_2
     105: astore_0
     106: iload_3
     107: istore_1
     108: goto          0
     111: areturn
}


package day18

import java.io.File

sealed interface SnailFishNumber {
  val magnitude: Int
}

class SnailNumber(override var magnitude: Int) : SnailFishNumber {
  val isSplittable: Boolean
    get() = magnitude > 9

  override fun toString(): String = magnitude.toString()

  fun split(parent: SnailPair): SnailPair =
    SnailPair(parent, SnailNumber(magnitude / 2), SnailNumber(magnitude - (magnitude / 2)))
}

class SnailPair(var parent: SnailPair?) : SnailFishNumber {
  constructor(parent: SnailPair?, left: SnailPair, right: SnailPair) : this(parent) {
    left.parent = this
    this.left = left
    right.parent = this
    this.right = right
  }
  constructor(parent: SnailPair?, left: SnailFishNumber, right: SnailFishNumber) : this(parent) {
    this.left = left
    this.right = right
  }

  lateinit var left: SnailFishNumber
  lateinit var right: SnailFishNumber

  private val isExploitable
    get() = left is SnailNumber && right is SnailNumber
  override val magnitude: Int
    get() = 3 * left.magnitude + 2 * right.magnitude

  override fun toString(): String = "[$left,$right]"

  fun reduceOnce(): Boolean = exploit(0) || split()

  fun reduce() {
    do { val hasReduced = reduceOnce() } while (hasReduced)
  }

  private fun split(): Boolean =
    when { // Returning true breaks the recursion
      (left as? SnailNumber)?.isSplittable ?: false -> {
        left = (left as SnailNumber).split(this)
        true
      }
      (left as? SnailPair)?.split() ?: false -> true
      (right as? SnailNumber)?.isSplittable ?: false -> {
        right = (right as SnailNumber).split(this)
        true
      }
      else -> (right as? SnailPair)?.split() ?: false
    }

  private fun exploit(level: Int): Boolean {
    fun sumToLeft(amount: Int, current: SnailPair, parent: SnailPair?) {
      if (parent == null) return
      else if (parent.left == current) sumToLeft(amount, parent, parent.parent)
      else {
        var leftNumber = parent.left
        while (leftNumber is SnailPair) leftNumber = leftNumber.right
        (leftNumber as SnailNumber).magnitude += amount
      }
    }

    fun sumToRight(amount: Int, current: SnailPair, parent: SnailPair?) {
      if (parent == null) return
      else if (parent.right == current) sumToRight(amount, parent, parent.parent)
      else {
        var rightNumber = parent.right
        while (rightNumber is SnailPair) rightNumber = rightNumber.left
        (rightNumber as SnailNumber).magnitude += amount
      }
    }

    fun exploit(pair: SnailPair) {
      sumToLeft((pair.left as SnailNumber).magnitude, pair, this)
      sumToRight((pair.right as SnailNumber).magnitude, pair, this)
    }

    return when {
      level >= 3 && (left as? SnailPair)?.isExploitable ?: false -> {
        exploit(left as SnailPair)
        left = SnailNumber(0)
        true
      }
      level >= 3 && (right as? SnailPair)?.isExploitable ?: false -> {
        exploit(right as SnailPair)
        right = SnailNumber(0)
        true
      }
      else -> (((left as? SnailPair)?.exploit(level + 1)) ?: false) || (((right as? SnailPair)?.exploit(level + 1)) ?: false)
    }
  }
}

fun parseSnailFishNumber(line: String): SnailPair {
  fun parseSnailFishNumber(input: Iterator<Char>, parent: SnailPair?): SnailFishNumber =
    when (val c = input.next()) {
      '[' -> {
        val pair = SnailPair(parent)
        pair.left = parseSnailFishNumber(input, pair)
        input.next() // ignoring comma
        pair.right = parseSnailFishNumber(input, pair)
        input.next() // consuming the closing ']'
        pair
      }
      // gotta be a digit since numbers greater than 9 are not allowed (must be split)
      else -> SnailNumber(c.digitToInt())
    }

  return parseSnailFishNumber(line.iterator(), null) as SnailPair // The root is always a Pair
}

fun sum(n1: SnailPair, n2: SnailPair): SnailPair {
  val result = SnailPair(null, n1, n2)
  result.reduce()
  return result
}

fun main() {
  File("./input/day18.txt").useLines { lines ->
    val input = lines.toList()
    println(input.map { parseSnailFishNumber(it) }.reduce(::sum).magnitude)

    println(input
      .flatMap { x -> input.filterNot { it == x }.map { y -> x to y } }
      .maxOf { (x, y) -> sum(parseSnailFishNumber(x), parseSnailFishNumber(y)).magnitude })
  }
}

Compiled from "Day18.kt"
public final class day18.Day18Kt {
  public static final day18.SnailPair parseSnailFishNumber(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #9                  // String line
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #17                 // class java/lang/CharSequence
      10: invokestatic  #23                 // Method kotlin/text/StringsKt.iterator:(Ljava/lang/CharSequence;)Lkotlin/collections/CharIterator;
      13: checkcast     #25                 // class java/util/Iterator
      16: aconst_null
      17: invokestatic  #29                 // Method parseSnailFishNumber$parseSnailFishNumber:(Ljava/util/Iterator;Lday18/SnailPair;)Lday18/SnailFishNumber;
      20: dup
      21: ldc           #31                 // String null cannot be cast to non-null type day18.SnailPair
      23: invokestatic  #34                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
      26: checkcast     #36                 // class day18/SnailPair
      29: areturn

  public static final day18.SnailPair sum(day18.SnailPair, day18.SnailPair);
    Code:
       0: aload_0
       1: ldc           #41                 // String n1
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #43                 // String n2
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: new           #36                 // class day18/SnailPair
      15: dup
      16: aconst_null
      17: aload_0
      18: aload_1
      19: invokespecial #47                 // Method day18/SnailPair."<init>":(Lday18/SnailPair;Lday18/SnailPair;Lday18/SnailPair;)V
      22: astore_2
      23: aload_2
      24: invokevirtual #51                 // Method day18/SnailPair.reduce:()V
      27: aload_2
      28: areturn

  public static final void main();
    Code:
       0: new           #58                 // class java/io/File
       3: dup
       4: ldc           #60                 // String ./input/day18.txt
       6: invokespecial #63                 // Method java/io/File."<init>":(Ljava/lang/String;)V
       9: astore_0
      10: getstatic     #69                 // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      13: astore_1
      14: iconst_0
      15: istore_2
      16: aload_0
      17: astore_3
      18: sipush        8192
      21: istore        4
      23: aload_3
      24: astore        5
      26: new           #71                 // class java/io/InputStreamReader
      29: dup
      30: new           #73                 // class java/io/FileInputStream
      33: dup
      34: aload         5
      36: invokespecial #76                 // Method java/io/FileInputStream."<init>":(Ljava/io/File;)V
      39: checkcast     #78                 // class java/io/InputStream
      42: aload_1
      43: invokespecial #81                 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/nio/charset/Charset;)V
      46: checkcast     #83                 // class java/io/Reader
      49: astore        5
      51: aload         5
      53: instanceof    #85                 // class java/io/BufferedReader
      56: ifeq          67
      59: aload         5
      61: checkcast     #85                 // class java/io/BufferedReader
      64: goto          78
      67: new           #85                 // class java/io/BufferedReader
      70: dup
      71: aload         5
      73: iload         4
      75: invokespecial #88                 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;I)V
      78: checkcast     #90                 // class java/io/Closeable
      81: astore_3
      82: aconst_null
      83: astore        4
      85: nop
      86: aload_3
      87: checkcast     #85                 // class java/io/BufferedReader
      90: astore        5
      92: iconst_0
      93: istore        6
      95: aload         5
      97: invokestatic  #96                 // Method kotlin/io/TextStreamsKt.lineSequence:(Ljava/io/BufferedReader;)Lkotlin/sequences/Sequence;
     100: astore        7
     102: iconst_0
     103: istore        8
     105: aload         7
     107: invokestatic  #102                // Method kotlin/sequences/SequencesKt.toList:(Lkotlin/sequences/Sequence;)Ljava/util/List;
     110: astore        9
     112: aload         9
     114: checkcast     #104                // class java/lang/Iterable
     117: astore        10
     119: iconst_0
     120: istore        11
     122: aload         10
     124: astore        12
     126: new           #106                // class java/util/ArrayList
     129: dup
     130: aload         10
     132: bipush        10
     134: invokestatic  #112                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     137: invokespecial #115                // Method java/util/ArrayList."<init>":(I)V
     140: checkcast     #117                // class java/util/Collection
     143: astore        13
     145: iconst_0
     146: istore        14
     148: aload         12
     150: invokeinterface #120,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     155: astore        15
     157: aload         15
     159: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     164: ifeq          207
     167: aload         15
     169: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     174: astore        16
     176: aload         13
     178: aload         16
     180: checkcast     #130                // class java/lang/String
     183: astore        17
     185: astore        18
     187: iconst_0
     188: istore        19
     190: aload         17
     192: invokestatic  #132                // Method parseSnailFishNumber:(Ljava/lang/String;)Lday18/SnailPair;
     195: aload         18
     197: swap
     198: invokeinterface #136,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     203: pop
     204: goto          157
     207: aload         13
     209: checkcast     #138                // class java/util/List
     212: nop
     213: checkcast     #104                // class java/lang/Iterable
     216: astore        10
     218: nop
     219: iconst_0
     220: istore        11
     222: aload         10
     224: invokeinterface #120,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     229: astore        12
     231: aload         12
     233: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     238: ifne          251
     241: new           #140                // class java/lang/UnsupportedOperationException
     244: dup
     245: ldc           #142                // String Empty collection can\'t be reduced.
     247: invokespecial #143                // Method java/lang/UnsupportedOperationException."<init>":(Ljava/lang/String;)V
     250: athrow
     251: aload         12
     253: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     258: astore        13
     260: aload         12
     262: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     267: ifeq          304
     270: aload         13
     272: aload         12
     274: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     279: checkcast     #36                 // class day18/SnailPair
     282: astore        14
     284: checkcast     #36                 // class day18/SnailPair
     287: astore        15
     289: iconst_0
     290: istore        16
     292: aload         15
     294: aload         14
     296: invokestatic  #145                // Method sum:(Lday18/SnailPair;Lday18/SnailPair;)Lday18/SnailPair;
     299: astore        13
     301: goto          260
     304: aload         13
     306: checkcast     #36                 // class day18/SnailPair
     309: invokevirtual #149                // Method day18/SnailPair.getMagnitude:()I
     312: istore        10
     314: getstatic     #155                // Field java/lang/System.out:Ljava/io/PrintStream;
     317: iload         10
     319: invokevirtual #160                // Method java/io/PrintStream.println:(I)V
     322: aload         9
     324: checkcast     #104                // class java/lang/Iterable
     327: astore        10
     329: nop
     330: iconst_0
     331: istore        11
     333: aload         10
     335: astore        12
     337: new           #106                // class java/util/ArrayList
     340: dup
     341: invokespecial #162                // Method java/util/ArrayList."<init>":()V
     344: checkcast     #117                // class java/util/Collection
     347: astore        13
     349: iconst_0
     350: istore        14
     352: aload         12
     354: invokeinterface #120,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     359: astore        15
     361: aload         15
     363: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     368: ifeq          605
     371: aload         15
     373: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     378: astore        16
     380: aload         16
     382: checkcast     #130                // class java/lang/String
     385: astore        17
     387: iconst_0
     388: istore        19
     390: aload         9
     392: checkcast     #104                // class java/lang/Iterable
     395: astore        20
     397: iconst_0
     398: istore        21
     400: aload         20
     402: astore        22
     404: new           #106                // class java/util/ArrayList
     407: dup
     408: invokespecial #162                // Method java/util/ArrayList."<init>":()V
     411: checkcast     #117                // class java/util/Collection
     414: astore        23
     416: iconst_0
     417: istore        24
     419: aload         22
     421: invokeinterface #120,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     426: astore        25
     428: aload         25
     430: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     435: ifeq          480
     438: aload         25
     440: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     445: astore        26
     447: aload         26
     449: checkcast     #130                // class java/lang/String
     452: astore        27
     454: iconst_0
     455: istore        28
     457: aload         27
     459: aload         17
     461: invokestatic  #166                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     464: ifne          428
     467: aload         23
     469: aload         26
     471: invokeinterface #136,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     476: pop
     477: goto          428
     480: aload         23
     482: checkcast     #138                // class java/util/List
     485: nop
     486: checkcast     #104                // class java/lang/Iterable
     489: astore        20
     491: nop
     492: iconst_0
     493: istore        21
     495: aload         20
     497: astore        22
     499: new           #106                // class java/util/ArrayList
     502: dup
     503: aload         20
     505: bipush        10
     507: invokestatic  #112                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     510: invokespecial #115                // Method java/util/ArrayList."<init>":(I)V
     513: checkcast     #117                // class java/util/Collection
     516: astore        23
     518: iconst_0
     519: istore        24
     521: aload         22
     523: invokeinterface #120,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     528: astore        25
     530: aload         25
     532: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     537: ifeq          582
     540: aload         25
     542: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     547: astore        26
     549: aload         23
     551: aload         26
     553: checkcast     #130                // class java/lang/String
     556: astore        27
     558: astore        29
     560: iconst_0
     561: istore        28
     563: aload         17
     565: aload         27
     567: invokestatic  #172                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     570: aload         29
     572: swap
     573: invokeinterface #136,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     578: pop
     579: goto          530
     582: aload         23
     584: checkcast     #138                // class java/util/List
     587: nop
     588: checkcast     #104                // class java/lang/Iterable
     591: nop
     592: astore        17
     594: aload         13
     596: aload         17
     598: invokestatic  #176                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     601: pop
     602: goto          361
     605: aload         13
     607: checkcast     #138                // class java/util/List
     610: nop
     611: checkcast     #104                // class java/lang/Iterable
     614: invokeinterface #120,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     619: astore        11
     621: aload         11
     623: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     628: ifne          639
     631: new           #178                // class java/util/NoSuchElementException
     634: dup
     635: invokespecial #179                // Method java/util/NoSuchElementException."<init>":()V
     638: athrow
     639: aload         11
     641: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     646: checkcast     #181                // class kotlin/Pair
     649: astore        12
     651: iconst_0
     652: istore        13
     654: aload         12
     656: invokevirtual #184                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     659: checkcast     #130                // class java/lang/String
     662: astore        14
     664: aload         12
     666: invokevirtual #187                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     669: checkcast     #130                // class java/lang/String
     672: astore        15
     674: aload         14
     676: invokestatic  #132                // Method parseSnailFishNumber:(Ljava/lang/String;)Lday18/SnailPair;
     679: aload         15
     681: invokestatic  #132                // Method parseSnailFishNumber:(Ljava/lang/String;)Lday18/SnailPair;
     684: invokestatic  #145                // Method sum:(Lday18/SnailPair;Lday18/SnailPair;)Lday18/SnailPair;
     687: invokevirtual #149                // Method day18/SnailPair.getMagnitude:()I
     690: istore        12
     692: aload         11
     694: invokeinterface #124,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     699: ifeq          769
     702: aload         11
     704: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     709: checkcast     #181                // class kotlin/Pair
     712: astore        13
     714: iconst_0
     715: istore        14
     717: aload         13
     719: invokevirtual #184                // Method kotlin/Pair.component1:()Ljava/lang/Object;
     722: checkcast     #130                // class java/lang/String
     725: astore        15
     727: aload         13
     729: invokevirtual #187                // Method kotlin/Pair.component2:()Ljava/lang/Object;
     732: checkcast     #130                // class java/lang/String
     735: astore        16
     737: aload         15
     739: invokestatic  #132                // Method parseSnailFishNumber:(Ljava/lang/String;)Lday18/SnailPair;
     742: aload         16
     744: invokestatic  #132                // Method parseSnailFishNumber:(Ljava/lang/String;)Lday18/SnailPair;
     747: invokestatic  #145                // Method sum:(Lday18/SnailPair;Lday18/SnailPair;)Lday18/SnailPair;
     750: invokevirtual #149                // Method day18/SnailPair.getMagnitude:()I
     753: istore        13
     755: iload         12
     757: iload         13
     759: if_icmpge     692
     762: iload         13
     764: istore        12
     766: goto          692
     769: iload         12
     771: istore        10
     773: getstatic     #155                // Field java/lang/System.out:Ljava/io/PrintStream;
     776: iload         10
     778: invokevirtual #160                // Method java/io/PrintStream.println:(I)V
     781: nop
     782: getstatic     #193                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     785: astore        5
     787: aload_3
     788: aload         4
     790: invokestatic  #199                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     793: goto          816
     796: astore        6
     798: aload         6
     800: astore        4
     802: aload         6
     804: athrow
     805: astore        6
     807: aload_3
     808: aload         4
     810: invokestatic  #199                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     813: aload         6
     815: athrow
     816: nop
     817: return
    Exception table:
       from    to  target type
          85   787   796   Class java/lang/Throwable
          85   787   805   any
         796   805   805   any
         805   807   805   any

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

  private static final day18.SnailFishNumber parseSnailFishNumber$parseSnailFishNumber(java.util.Iterator<java.lang.Character>, day18.SnailPair);
    Code:
       0: aload_0
       1: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
       6: checkcast     #259                // class java/lang/Character
       9: invokevirtual #263                // Method java/lang/Character.charValue:()C
      12: istore_2
      13: iload_2
      14: bipush        91
      16: if_icmpne     67
      19: new           #36                 // class day18/SnailPair
      22: dup
      23: aload_1
      24: invokespecial #266                // Method day18/SnailPair."<init>":(Lday18/SnailPair;)V
      27: astore_3
      28: aload_3
      29: aload_0
      30: aload_3
      31: invokestatic  #29                 // Method parseSnailFishNumber$parseSnailFishNumber:(Ljava/util/Iterator;Lday18/SnailPair;)Lday18/SnailFishNumber;
      34: invokevirtual #270                // Method day18/SnailPair.setLeft:(Lday18/SnailFishNumber;)V
      37: aload_0
      38: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      43: pop
      44: aload_3
      45: aload_0
      46: aload_3
      47: invokestatic  #29                 // Method parseSnailFishNumber$parseSnailFishNumber:(Ljava/util/Iterator;Lday18/SnailPair;)Lday18/SnailFishNumber;
      50: invokevirtual #273                // Method day18/SnailPair.setRight:(Lday18/SnailFishNumber;)V
      53: aload_0
      54: invokeinterface #128,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      59: pop
      60: aload_3
      61: checkcast     #275                // class day18/SnailFishNumber
      64: goto          81
      67: new           #277                // class day18/SnailNumber
      70: dup
      71: iload_2
      72: invokestatic  #283                // Method kotlin/text/CharsKt.digitToInt:(C)I
      75: invokespecial #284                // Method day18/SnailNumber."<init>":(I)V
      78: checkcast     #275                // class day18/SnailFishNumber
      81: areturn
}