package com.morninghacks.aoc2017

import java.lang.invoke.MethodHandles

private data class NodeFromLine(val id: String, val weight: Int, val childIds: List<String>)

private data class Node(val id: String, val weight: Int, var children: List<Node> = listOf(), val parent: Node? = null) {
    fun treeWeight() : Int = weight + children.sumBy(Node::treeWeight)
    override fun toString(): String {
        return "Node(id='$id', weight=$weight, children=$children)"
    }

}

fun solve(source: String): Pair<String,Pair<String,Int>> {
    //need two maps - id -> Node for all nodes
    val allNodes: List<NodeFromLine> = source.lines()
            .filter(String::isNotBlank)
            .map(::nodeFromLine)
    val nodesById: Map<String,NodeFromLine> = allNodes.associateBy(NodeFromLine::id)
    val parentsAndChildren: Map<String,List<NodeFromLine?>> = createParentChildRelationships(nodesById)
    val allChildren = parentsAndChildren.values.flatten().filterNotNull()
    val rootId: String = parentsAndChildren.keys.minus(allChildren.map(NodeFromLine::id)).first()

    //createTree
    val rootNodeFrom = nodesById.getValue(rootId)
    val rootNode = createTree(rootNodeFrom, nodesById)

    val unbalanced = findUnbalanceNode(rootNode)
    val unbalancedParent = unbalanced.parent
    val otherWeight = unbalancedParent!!.children.minus(unbalanced).first().treeWeight()
    val difference = otherWeight - unbalanced.treeWeight()

    return Pair(rootNode.id,Pair(unbalanced.id, Math.abs(unbalanced.weight + difference)))
}

private tailrec fun findUnbalanceNode(node: Node): Node {
    val nodesByWeight = node.children.groupBy(Node::treeWeight)
    if (nodesByWeight.size == 1) {
        return node
    } else {
        for (childNodes: List<Node> in nodesByWeight.values) {
            if (childNodes.size == 1) {
                return findUnbalanceNode(childNodes[0])
            }
        }
    }
    throw IllegalStateException()
}

private fun createTree(rootNfl: NodeFromLine, nodesById: Map<String,NodeFromLine>) : Node {
    fun createSubTree(nfl: NodeFromLine, parent: Node): Node {
        val node = Node(nfl.id, nfl.weight, parent = parent)
        node.children = nfl.childIds.map { childId -> createSubTree(nodesById.getValue(childId), node) }
        return node
    }
    val rootNode = Node(rootNfl.id, rootNfl.weight, parent = null)
    rootNode.children = rootNfl.childIds.map { childId -> createSubTree(nodesById.getValue(childId),rootNode) }
    return rootNode
}

private fun createParentChildRelationships(nodesById: Map<String,NodeFromLine>) : Map<String,List<NodeFromLine?>> {
    return nodesById.filter { (id,node) -> node.childIds.isNotEmpty() }
            .mapValues { (id,node)  -> node.childIds.map(nodesById::get) }
}

private fun nodeFromLine(line: String) : NodeFromLine {
    //Sample Line:  ugml (68) -> gyxo, ebii, jptl
    val id = line.subSequence(0,line.indexOf('(')).trim().toString()
    val weight = line.subSequence(line.indexOf('(') + 1, line.indexOf(')')).toString().toInt()
    val childIds : List<String> = if (line.contains('>')) {
        val childIdSection = line.subSequence(line.indexOf('>') + 1,line.length)
        childIdSection.split(",").map { s -> s.trim() }.toList()
    } else {
        listOf()
    }
    return NodeFromLine(id,weight,childIds)
}

fun main(args: Array<String>) {
    val input = MethodHandles.lookup().lookupClass().getResourceAsStream("/Day07Input.txt").bufferedReader().readText()
    println(solve(input))

}

Compiled from "Day07.kt"
public final class com.morninghacks.aoc2017.Day07Kt {
  public static final kotlin.Pair<java.lang.String, kotlin.Pair<java.lang.String, java.lang.Integer>> solve(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #10                 // String source
       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: invokestatic  #24                 // Method kotlin/text/StringsKt.lines:(Ljava/lang/CharSequence;)Ljava/util/List;
      13: checkcast     #26                 // class java/lang/Iterable
      16: astore_2
      17: nop
      18: iconst_0
      19: istore_3
      20: aload_2
      21: astore        4
      23: new           #28                 // class java/util/ArrayList
      26: dup
      27: invokespecial #32                 // Method java/util/ArrayList."<init>":()V
      30: checkcast     #34                 // class java/util/Collection
      33: astore        5
      35: iconst_0
      36: istore        6
      38: aload         4
      40: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      45: astore        7
      47: aload         7
      49: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      54: ifeq          109
      57: aload         7
      59: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      64: astore        8
      66: aload         8
      68: checkcast     #50                 // class java/lang/String
      71: astore        9
      73: iconst_0
      74: istore        10
      76: aload         9
      78: checkcast     #18                 // class java/lang/CharSequence
      81: invokestatic  #54                 // Method kotlin/text/StringsKt.isBlank:(Ljava/lang/CharSequence;)Z
      84: ifne          91
      87: iconst_1
      88: goto          92
      91: iconst_0
      92: nop
      93: ifeq          47
      96: aload         5
      98: aload         8
     100: invokeinterface #58,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     105: pop
     106: goto          47
     109: aload         5
     111: checkcast     #60                 // class java/util/List
     114: nop
     115: checkcast     #26                 // class java/lang/Iterable
     118: astore_2
     119: nop
     120: iconst_0
     121: istore_3
     122: aload_2
     123: astore        4
     125: new           #28                 // class java/util/ArrayList
     128: dup
     129: aload_2
     130: bipush        10
     132: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     135: invokespecial #69                 // Method java/util/ArrayList."<init>":(I)V
     138: checkcast     #34                 // class java/util/Collection
     141: astore        5
     143: iconst_0
     144: istore        6
     146: aload         4
     148: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     153: astore        7
     155: aload         7
     157: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     162: ifeq          205
     165: aload         7
     167: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     172: astore        8
     174: aload         5
     176: aload         8
     178: checkcast     #50                 // class java/lang/String
     181: astore        9
     183: astore        15
     185: iconst_0
     186: istore        10
     188: aload         9
     190: invokestatic  #73                 // Method nodeFromLine:(Ljava/lang/String;)Lcom/morninghacks/aoc2017/NodeFromLine;
     193: aload         15
     195: swap
     196: invokeinterface #58,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     201: pop
     202: goto          155
     205: aload         5
     207: checkcast     #60                 // class java/util/List
     210: nop
     211: astore_1
     212: aload_1
     213: checkcast     #26                 // class java/lang/Iterable
     216: astore_3
     217: iconst_0
     218: istore        4
     220: aload_3
     221: bipush        10
     223: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     226: invokestatic  #79                 // Method kotlin/collections/MapsKt.mapCapacity:(I)I
     229: bipush        16
     231: invokestatic  #85                 // Method kotlin/ranges/RangesKt.coerceAtLeast:(II)I
     234: istore        5
     236: aload_3
     237: astore        6
     239: new           #87                 // class java/util/LinkedHashMap
     242: dup
     243: iload         5
     245: invokespecial #88                 // Method java/util/LinkedHashMap."<init>":(I)V
     248: checkcast     #90                 // class java/util/Map
     251: astore        7
     253: iconst_0
     254: istore        8
     256: aload         6
     258: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     263: astore        9
     265: aload         9
     267: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     272: ifeq          317
     275: aload         9
     277: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     282: astore        10
     284: aload         7
     286: aload         10
     288: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
     291: astore        11
     293: astore        15
     295: iconst_0
     296: istore        12
     298: aload         11
     300: invokevirtual #96                 // Method com/morninghacks/aoc2017/NodeFromLine.getId:()Ljava/lang/String;
     303: aload         15
     305: swap
     306: aload         10
     308: invokeinterface #100,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     313: pop
     314: goto          265
     317: aload         7
     319: nop
     320: astore_2
     321: aload_2
     322: invokestatic  #104                // Method createParentChildRelationships:(Ljava/util/Map;)Ljava/util/Map;
     325: astore_3
     326: aload_3
     327: invokeinterface #108,  1          // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
     332: checkcast     #26                 // class java/lang/Iterable
     335: invokestatic  #112                // Method kotlin/collections/CollectionsKt.flatten:(Ljava/lang/Iterable;)Ljava/util/List;
     338: checkcast     #26                 // class java/lang/Iterable
     341: invokestatic  #115                // Method kotlin/collections/CollectionsKt.filterNotNull:(Ljava/lang/Iterable;)Ljava/util/List;
     344: astore        4
     346: aload_3
     347: invokeinterface #119,  1          // InterfaceMethod java/util/Map.keySet:()Ljava/util/Set;
     352: aload         4
     354: checkcast     #26                 // class java/lang/Iterable
     357: astore        6
     359: astore        15
     361: iconst_0
     362: istore        7
     364: aload         6
     366: astore        8
     368: new           #28                 // class java/util/ArrayList
     371: dup
     372: aload         6
     374: bipush        10
     376: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     379: invokespecial #69                 // Method java/util/ArrayList."<init>":(I)V
     382: checkcast     #34                 // class java/util/Collection
     385: astore        9
     387: iconst_0
     388: istore        10
     390: aload         8
     392: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     397: astore        11
     399: aload         11
     401: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     406: ifeq          449
     409: aload         11
     411: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     416: astore        12
     418: aload         9
     420: aload         12
     422: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
     425: astore        13
     427: astore        16
     429: iconst_0
     430: istore        14
     432: aload         13
     434: invokevirtual #96                 // Method com/morninghacks/aoc2017/NodeFromLine.getId:()Ljava/lang/String;
     437: aload         16
     439: swap
     440: invokeinterface #58,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     445: pop
     446: goto          399
     449: aload         9
     451: checkcast     #60                 // class java/util/List
     454: nop
     455: aload         15
     457: swap
     458: checkcast     #26                 // class java/lang/Iterable
     461: invokestatic  #125                // Method kotlin/collections/SetsKt.minus:(Ljava/util/Set;Ljava/lang/Iterable;)Ljava/util/Set;
     464: checkcast     #26                 // class java/lang/Iterable
     467: invokestatic  #129                // Method kotlin/collections/CollectionsKt.first:(Ljava/lang/Iterable;)Ljava/lang/Object;
     470: checkcast     #50                 // class java/lang/String
     473: astore        5
     475: aload_2
     476: aload         5
     478: invokestatic  #133                // Method kotlin/collections/MapsKt.getValue:(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
     481: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
     484: astore        6
     486: aload         6
     488: aload_2
     489: invokestatic  #137                // Method createTree:(Lcom/morninghacks/aoc2017/NodeFromLine;Ljava/util/Map;)Lcom/morninghacks/aoc2017/Node;
     492: astore        7
     494: aload         7
     496: invokestatic  #141                // Method findUnbalanceNode:(Lcom/morninghacks/aoc2017/Node;)Lcom/morninghacks/aoc2017/Node;
     499: astore        8
     501: aload         8
     503: invokevirtual #147                // Method com/morninghacks/aoc2017/Node.getParent:()Lcom/morninghacks/aoc2017/Node;
     506: astore        9
     508: aload         9
     510: dup
     511: invokestatic  #151                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     514: invokevirtual #155                // Method com/morninghacks/aoc2017/Node.getChildren:()Ljava/util/List;
     517: checkcast     #26                 // class java/lang/Iterable
     520: aload         8
     522: invokestatic  #158                // Method kotlin/collections/CollectionsKt.minus:(Ljava/lang/Iterable;Ljava/lang/Object;)Ljava/util/List;
     525: invokestatic  #161                // Method kotlin/collections/CollectionsKt.first:(Ljava/util/List;)Ljava/lang/Object;
     528: checkcast     #143                // class com/morninghacks/aoc2017/Node
     531: invokevirtual #165                // Method com/morninghacks/aoc2017/Node.treeWeight:()I
     534: istore        10
     536: iload         10
     538: aload         8
     540: invokevirtual #165                // Method com/morninghacks/aoc2017/Node.treeWeight:()I
     543: isub
     544: istore        11
     546: new           #167                // class kotlin/Pair
     549: dup
     550: aload         7
     552: invokevirtual #168                // Method com/morninghacks/aoc2017/Node.getId:()Ljava/lang/String;
     555: new           #167                // class kotlin/Pair
     558: dup
     559: aload         8
     561: invokevirtual #168                // Method com/morninghacks/aoc2017/Node.getId:()Ljava/lang/String;
     564: aload         8
     566: invokevirtual #171                // Method com/morninghacks/aoc2017/Node.getWeight:()I
     569: iload         11
     571: iadd
     572: invokestatic  #176                // Method java/lang/Math.abs:(I)I
     575: invokestatic  #182                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     578: invokespecial #185                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     581: invokespecial #185                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     584: areturn

  private static final com.morninghacks.aoc2017.Node findUnbalanceNode(com.morninghacks.aoc2017.Node);
    Code:
       0: aload_0
       1: invokevirtual #155                // Method com/morninghacks/aoc2017/Node.getChildren:()Ljava/util/List;
       4: checkcast     #26                 // class java/lang/Iterable
       7: astore_2
       8: iconst_0
       9: istore_3
      10: aload_2
      11: astore        4
      13: new           #87                 // class java/util/LinkedHashMap
      16: dup
      17: invokespecial #229                // Method java/util/LinkedHashMap."<init>":()V
      20: checkcast     #90                 // class java/util/Map
      23: astore        5
      25: iconst_0
      26: istore        6
      28: aload         4
      30: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      35: astore        7
      37: aload         7
      39: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      44: ifeq          152
      47: aload         7
      49: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      54: astore        8
      56: aload         8
      58: checkcast     #143                // class com/morninghacks/aoc2017/Node
      61: astore        9
      63: iconst_0
      64: istore        10
      66: aload         9
      68: invokevirtual #165                // Method com/morninghacks/aoc2017/Node.treeWeight:()I
      71: invokestatic  #182                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      74: astore        11
      76: aload         5
      78: astore        12
      80: iconst_0
      81: istore        13
      83: aload         12
      85: aload         11
      87: invokeinterface #233,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      92: astore        14
      94: aload         14
      96: ifnonnull     131
      99: iconst_0
     100: istore        15
     102: new           #28                 // class java/util/ArrayList
     105: dup
     106: invokespecial #32                 // Method java/util/ArrayList."<init>":()V
     109: checkcast     #60                 // class java/util/List
     112: astore        15
     114: aload         12
     116: aload         11
     118: aload         15
     120: invokeinterface #100,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     125: pop
     126: aload         15
     128: goto          133
     131: aload         14
     133: nop
     134: checkcast     #60                 // class java/util/List
     137: astore        9
     139: aload         9
     141: aload         8
     143: invokeinterface #234,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     148: pop
     149: goto          37
     152: aload         5
     154: nop
     155: astore_1
     156: aload_1
     157: invokeinterface #237,  1          // InterfaceMethod java/util/Map.size:()I
     162: iconst_1
     163: if_icmpne     168
     166: aload_0
     167: areturn
     168: aload_1
     169: invokeinterface #108,  1          // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
     174: invokeinterface #238,  1          // InterfaceMethod java/util/Collection.iterator:()Ljava/util/Iterator;
     179: astore_2
     180: aload_2
     181: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     186: ifeq          223
     189: aload_2
     190: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     195: checkcast     #60                 // class java/util/List
     198: astore_3
     199: aload_3
     200: invokeinterface #239,  1          // InterfaceMethod java/util/List.size:()I
     205: iconst_1
     206: if_icmpne     180
     209: aload_3
     210: iconst_0
     211: invokeinterface #242,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     216: checkcast     #143                // class com/morninghacks/aoc2017/Node
     219: astore_0
     220: goto          0
     223: new           #244                // class java/lang/IllegalStateException
     226: dup
     227: invokespecial #245                // Method java/lang/IllegalStateException."<init>":()V
     230: athrow

  private static final com.morninghacks.aoc2017.Node createTree(com.morninghacks.aoc2017.NodeFromLine, java.util.Map<java.lang.String, com.morninghacks.aoc2017.NodeFromLine>);
    Code:
       0: new           #143                // class com/morninghacks/aoc2017/Node
       3: dup
       4: aload_0
       5: invokevirtual #96                 // Method com/morninghacks/aoc2017/NodeFromLine.getId:()Ljava/lang/String;
       8: aload_0
       9: invokevirtual #262                // Method com/morninghacks/aoc2017/NodeFromLine.getWeight:()I
      12: aconst_null
      13: aconst_null
      14: iconst_4
      15: aconst_null
      16: invokespecial #265                // Method com/morninghacks/aoc2017/Node."<init>":(Ljava/lang/String;ILjava/util/List;Lcom/morninghacks/aoc2017/Node;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      19: astore_2
      20: aload_2
      21: aload_0
      22: invokevirtual #268                // Method com/morninghacks/aoc2017/NodeFromLine.getChildIds:()Ljava/util/List;
      25: checkcast     #26                 // class java/lang/Iterable
      28: astore_3
      29: astore        12
      31: iconst_0
      32: istore        4
      34: aload_3
      35: astore        5
      37: new           #28                 // class java/util/ArrayList
      40: dup
      41: aload_3
      42: bipush        10
      44: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      47: invokespecial #69                 // Method java/util/ArrayList."<init>":(I)V
      50: checkcast     #34                 // class java/util/Collection
      53: astore        6
      55: iconst_0
      56: istore        7
      58: aload         5
      60: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      65: astore        8
      67: aload         8
      69: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      74: ifeq          126
      77: aload         8
      79: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      84: astore        9
      86: aload         6
      88: aload         9
      90: checkcast     #50                 // class java/lang/String
      93: astore        10
      95: astore        13
      97: iconst_0
      98: istore        11
     100: aload_1
     101: aload_1
     102: aload         10
     104: invokestatic  #133                // Method kotlin/collections/MapsKt.getValue:(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
     107: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
     110: aload_2
     111: invokestatic  #272                // Method createTree$createSubTree:(Ljava/util/Map;Lcom/morninghacks/aoc2017/NodeFromLine;Lcom/morninghacks/aoc2017/Node;)Lcom/morninghacks/aoc2017/Node;
     114: aload         13
     116: swap
     117: invokeinterface #58,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     122: pop
     123: goto          67
     126: aload         6
     128: checkcast     #60                 // class java/util/List
     131: nop
     132: aload         12
     134: swap
     135: invokevirtual #276                // Method com/morninghacks/aoc2017/Node.setChildren:(Ljava/util/List;)V
     138: aload_2
     139: areturn

  private static final java.util.Map<java.lang.String, java.util.List<com.morninghacks.aoc2017.NodeFromLine>> createParentChildRelationships(java.util.Map<java.lang.String, com.morninghacks.aoc2017.NodeFromLine>);
    Code:
       0: aload_0
       1: astore_1
       2: iconst_0
       3: istore_2
       4: aload_1
       5: astore_3
       6: new           #87                 // class java/util/LinkedHashMap
       9: dup
      10: invokespecial #229                // Method java/util/LinkedHashMap."<init>":()V
      13: checkcast     #90                 // class java/util/Map
      16: astore        4
      18: iconst_0
      19: istore        5
      21: aload_3
      22: invokeinterface #283,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      27: invokeinterface #284,  1          // InterfaceMethod java/util/Set.iterator:()Ljava/util/Iterator;
      32: astore        6
      34: aload         6
      36: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      41: ifeq          137
      44: aload         6
      46: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      51: checkcast     #286                // class java/util/Map$Entry
      54: astore        7
      56: aload         7
      58: astore        8
      60: iconst_0
      61: istore        9
      63: aload         8
      65: invokeinterface #289,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
      70: checkcast     #50                 // class java/lang/String
      73: astore        10
      75: aload         8
      77: invokeinterface #291,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
      82: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
      85: astore        11
      87: aload         11
      89: invokevirtual #268                // Method com/morninghacks/aoc2017/NodeFromLine.getChildIds:()Ljava/util/List;
      92: checkcast     #34                 // class java/util/Collection
      95: invokeinterface #294,  1          // InterfaceMethod java/util/Collection.isEmpty:()Z
     100: ifne          107
     103: iconst_1
     104: goto          108
     107: iconst_0
     108: nop
     109: ifeq          34
     112: aload         4
     114: aload         7
     116: invokeinterface #289,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     121: aload         7
     123: invokeinterface #291,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     128: invokeinterface #100,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     133: pop
     134: goto          34
     137: aload         4
     139: nop
     140: astore_1
     141: nop
     142: iconst_0
     143: istore_2
     144: aload_1
     145: astore_3
     146: new           #87                 // class java/util/LinkedHashMap
     149: dup
     150: aload_1
     151: invokeinterface #237,  1          // InterfaceMethod java/util/Map.size:()I
     156: invokestatic  #79                 // Method kotlin/collections/MapsKt.mapCapacity:(I)I
     159: invokespecial #88                 // Method java/util/LinkedHashMap."<init>":(I)V
     162: checkcast     #90                 // class java/util/Map
     165: astore        4
     167: iconst_0
     168: istore        5
     170: aload_3
     171: invokeinterface #283,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
     176: checkcast     #26                 // class java/lang/Iterable
     179: astore        6
     181: iconst_0
     182: istore        7
     184: aload         6
     186: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     191: astore        8
     193: aload         8
     195: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     200: ifeq          402
     203: aload         8
     205: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     210: astore        9
     212: aload         4
     214: aload         9
     216: checkcast     #286                // class java/util/Map$Entry
     219: astore        10
     221: astore        11
     223: iconst_0
     224: istore        12
     226: aload         10
     228: invokeinterface #289,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     233: aload         11
     235: swap
     236: aload         9
     238: checkcast     #286                // class java/util/Map$Entry
     241: astore        13
     243: astore        28
     245: astore        27
     247: iconst_0
     248: istore        14
     250: aload         13
     252: invokeinterface #289,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     257: checkcast     #50                 // class java/lang/String
     260: astore        15
     262: aload         13
     264: invokeinterface #291,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     269: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
     272: astore        16
     274: aload         16
     276: invokevirtual #268                // Method com/morninghacks/aoc2017/NodeFromLine.getChildIds:()Ljava/util/List;
     279: checkcast     #26                 // class java/lang/Iterable
     282: astore        17
     284: iconst_0
     285: istore        18
     287: aload         17
     289: astore        19
     291: new           #28                 // class java/util/ArrayList
     294: dup
     295: aload         17
     297: bipush        10
     299: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     302: invokespecial #69                 // Method java/util/ArrayList."<init>":(I)V
     305: checkcast     #34                 // class java/util/Collection
     308: astore        20
     310: iconst_0
     311: istore        21
     313: aload         19
     315: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     320: astore        22
     322: aload         22
     324: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     329: ifeq          378
     332: aload         22
     334: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     339: astore        23
     341: aload         20
     343: aload         23
     345: checkcast     #50                 // class java/lang/String
     348: astore        24
     350: astore        25
     352: iconst_0
     353: istore        26
     355: aload_0
     356: aload         24
     358: invokeinterface #233,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     363: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
     366: aload         25
     368: swap
     369: invokeinterface #58,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     374: pop
     375: goto          322
     378: aload         20
     380: checkcast     #60                 // class java/util/List
     383: nop
     384: nop
     385: astore        29
     387: aload         27
     389: aload         28
     391: aload         29
     393: invokeinterface #100,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     398: pop
     399: goto          193
     402: aload         4
     404: nop
     405: nop
     406: areturn

  private static final com.morninghacks.aoc2017.NodeFromLine nodeFromLine(java.lang.String);
    Code:
       0: aload_0
       1: iconst_0
       2: aload_0
       3: checkcast     #18                 // class java/lang/CharSequence
       6: bipush        40
       8: iconst_0
       9: iconst_0
      10: bipush        6
      12: aconst_null
      13: invokestatic  #311                // Method kotlin/text/StringsKt.indexOf$default:(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
      16: invokevirtual #315                // Method java/lang/String.subSequence:(II)Ljava/lang/CharSequence;
      19: invokestatic  #319                // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
      22: invokevirtual #322                // Method java/lang/Object.toString:()Ljava/lang/String;
      25: astore_1
      26: aload_0
      27: aload_0
      28: checkcast     #18                 // class java/lang/CharSequence
      31: bipush        40
      33: iconst_0
      34: iconst_0
      35: bipush        6
      37: aconst_null
      38: invokestatic  #311                // Method kotlin/text/StringsKt.indexOf$default:(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
      41: iconst_1
      42: iadd
      43: aload_0
      44: checkcast     #18                 // class java/lang/CharSequence
      47: bipush        41
      49: iconst_0
      50: iconst_0
      51: bipush        6
      53: aconst_null
      54: invokestatic  #311                // Method kotlin/text/StringsKt.indexOf$default:(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
      57: invokevirtual #315                // Method java/lang/String.subSequence:(II)Ljava/lang/CharSequence;
      60: invokevirtual #322                // Method java/lang/Object.toString:()Ljava/lang/String;
      63: invokestatic  #326                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      66: istore_2
      67: aload_0
      68: checkcast     #18                 // class java/lang/CharSequence
      71: bipush        62
      73: iconst_0
      74: iconst_2
      75: aconst_null
      76: invokestatic  #330                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
      79: ifeq          248
      82: aload_0
      83: aload_0
      84: checkcast     #18                 // class java/lang/CharSequence
      87: bipush        62
      89: iconst_0
      90: iconst_0
      91: bipush        6
      93: aconst_null
      94: invokestatic  #311                // Method kotlin/text/StringsKt.indexOf$default:(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
      97: iconst_1
      98: iadd
      99: aload_0
     100: invokevirtual #333                // Method java/lang/String.length:()I
     103: invokevirtual #315                // Method java/lang/String.subSequence:(II)Ljava/lang/CharSequence;
     106: astore        4
     108: aload         4
     110: iconst_1
     111: anewarray     #50                 // class java/lang/String
     114: astore        5
     116: aload         5
     118: iconst_0
     119: ldc_w         #335                // String ,
     122: aastore
     123: aload         5
     125: iconst_0
     126: iconst_0
     127: bipush        6
     129: aconst_null
     130: invokestatic  #339                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     133: checkcast     #26                 // class java/lang/Iterable
     136: astore        5
     138: iconst_0
     139: istore        6
     141: aload         5
     143: astore        7
     145: new           #28                 // class java/util/ArrayList
     148: dup
     149: aload         5
     151: bipush        10
     153: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     156: invokespecial #69                 // Method java/util/ArrayList."<init>":(I)V
     159: checkcast     #34                 // class java/util/Collection
     162: astore        8
     164: iconst_0
     165: istore        9
     167: aload         7
     169: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     174: astore        10
     176: aload         10
     178: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     183: ifeq          233
     186: aload         10
     188: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     193: astore        11
     195: aload         8
     197: aload         11
     199: checkcast     #50                 // class java/lang/String
     202: astore        12
     204: astore        14
     206: iconst_0
     207: istore        13
     209: aload         12
     211: checkcast     #18                 // class java/lang/CharSequence
     214: invokestatic  #319                // Method kotlin/text/StringsKt.trim:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     217: invokevirtual #322                // Method java/lang/Object.toString:()Ljava/lang/String;
     220: nop
     221: aload         14
     223: swap
     224: invokeinterface #58,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     229: pop
     230: goto          176
     233: aload         8
     235: checkcast     #60                 // class java/util/List
     238: nop
     239: checkcast     #26                 // class java/lang/Iterable
     242: invokestatic  #342                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     245: goto          251
     248: invokestatic  #345                // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     251: astore_3
     252: new           #92                 // class com/morninghacks/aoc2017/NodeFromLine
     255: dup
     256: aload_1
     257: iload_2
     258: aload_3
     259: invokespecial #348                // Method com/morninghacks/aoc2017/NodeFromLine."<init>":(Ljava/lang/String;ILjava/util/List;)V
     262: areturn

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc_w         #359                // String args
       4: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: invokestatic  #365                // Method java/lang/invoke/MethodHandles.lookup:()Ljava/lang/invoke/MethodHandles$Lookup;
      10: invokevirtual #371                // Method java/lang/invoke/MethodHandles$Lookup.lookupClass:()Ljava/lang/Class;
      13: ldc_w         #373                // String /Day07Input.txt
      16: invokevirtual #379                // Method java/lang/Class.getResourceAsStream:(Ljava/lang/String;)Ljava/io/InputStream;
      19: dup
      20: ldc_w         #381                // String getResourceAsStream(...)
      23: invokestatic  #384                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      26: astore_2
      27: getstatic     #390                // Field kotlin/text/Charsets.UTF_8:Ljava/nio/charset/Charset;
      30: astore_3
      31: new           #392                // class java/io/InputStreamReader
      34: dup
      35: aload_2
      36: aload_3
      37: invokespecial #395                // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/nio/charset/Charset;)V
      40: checkcast     #397                // class java/io/Reader
      43: astore        4
      45: sipush        8192
      48: istore        5
      50: aload         4
      52: instanceof    #399                // class java/io/BufferedReader
      55: ifeq          66
      58: aload         4
      60: checkcast     #399                // class java/io/BufferedReader
      63: goto          77
      66: new           #399                // class java/io/BufferedReader
      69: dup
      70: aload         4
      72: iload         5
      74: invokespecial #402                // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;I)V
      77: checkcast     #397                // class java/io/Reader
      80: invokestatic  #408                // Method kotlin/io/TextStreamsKt.readText:(Ljava/io/Reader;)Ljava/lang/String;
      83: astore_1
      84: aload_1
      85: invokestatic  #410                // Method solve:(Ljava/lang/String;)Lkotlin/Pair;
      88: getstatic     #416                // Field java/lang/System.out:Ljava/io/PrintStream;
      91: swap
      92: invokevirtual #421                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      95: return

  private static final com.morninghacks.aoc2017.Node createTree$createSubTree(java.util.Map<java.lang.String, com.morninghacks.aoc2017.NodeFromLine>, com.morninghacks.aoc2017.NodeFromLine, com.morninghacks.aoc2017.Node);
    Code:
       0: new           #143                // class com/morninghacks/aoc2017/Node
       3: dup
       4: aload_1
       5: invokevirtual #96                 // Method com/morninghacks/aoc2017/NodeFromLine.getId:()Ljava/lang/String;
       8: aload_1
       9: invokevirtual #262                // Method com/morninghacks/aoc2017/NodeFromLine.getWeight:()I
      12: aconst_null
      13: aload_2
      14: iconst_4
      15: aconst_null
      16: invokespecial #265                // Method com/morninghacks/aoc2017/Node."<init>":(Ljava/lang/String;ILjava/util/List;Lcom/morninghacks/aoc2017/Node;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      19: astore_3
      20: aload_3
      21: aload_1
      22: invokevirtual #268                // Method com/morninghacks/aoc2017/NodeFromLine.getChildIds:()Ljava/util/List;
      25: checkcast     #26                 // class java/lang/Iterable
      28: astore        4
      30: astore        13
      32: iconst_0
      33: istore        5
      35: aload         4
      37: astore        6
      39: new           #28                 // class java/util/ArrayList
      42: dup
      43: aload         4
      45: bipush        10
      47: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      50: invokespecial #69                 // Method java/util/ArrayList."<init>":(I)V
      53: checkcast     #34                 // class java/util/Collection
      56: astore        7
      58: iconst_0
      59: istore        8
      61: aload         6
      63: invokeinterface #38,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      68: astore        9
      70: aload         9
      72: invokeinterface #44,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      77: ifeq          129
      80: aload         9
      82: invokeinterface #48,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      87: astore        10
      89: aload         7
      91: aload         10
      93: checkcast     #50                 // class java/lang/String
      96: astore        11
      98: astore        14
     100: iconst_0
     101: istore        12
     103: aload_0
     104: aload_0
     105: aload         11
     107: invokestatic  #133                // Method kotlin/collections/MapsKt.getValue:(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
     110: checkcast     #92                 // class com/morninghacks/aoc2017/NodeFromLine
     113: aload_3
     114: invokestatic  #272                // Method createTree$createSubTree:(Ljava/util/Map;Lcom/morninghacks/aoc2017/NodeFromLine;Lcom/morninghacks/aoc2017/Node;)Lcom/morninghacks/aoc2017/Node;
     117: aload         14
     119: swap
     120: invokeinterface #58,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     125: pop
     126: goto          70
     129: aload         7
     131: checkcast     #60                 // class java/util/List
     134: nop
     135: aload         13
     137: swap
     138: invokevirtual #276                // Method com/morninghacks/aoc2017/Node.setChildren:(Ljava/util/List;)V
     141: aload_3
     142: areturn
}


package com.morninghacks.aoc2017

import kotlin.math.roundToInt
import kotlin.math.sqrt

// let x be the target number
// let y next highest perfect square derived from multiplying odd numbers after and including x //
// let max distance = (square root of y) - 1

// let f(x) = max - ((y - x) % max)   <--- this fails for numbers like 10, 27, or 33
// if f(x) >= min then f(x) max - f(x)

fun manhattan(x: Int): Int {
    val y = nextOddPerfectSquareInclusive(x)
    val max = sqrt(y.toDouble()).roundToInt() - 1
    val min = max / 2
    val f = if (max == 0) 0 else max - ((y - x) % max) //for 33, f is 2, needs to be 4
    return if (f < min) max - f else f
}

fun nextOddPerfectSquareInclusive(x: Int): Int {
    for (i in 1..x step 2) {
        val iSquared = Math.pow(i.toDouble(), 2.toDouble()).roundToInt()
        val nextSquared = Math.pow((i + 2).toDouble(), 2.toDouble()).roundToInt()

        if (x == iSquared) return x
        else if (x > iSquared && x < nextSquared) return nextSquared
        else continue
    }
    throw IllegalStateException()
}

fun main(args: Array<String>) {
    println(manhattan(325489))
    println(createGridUntil(325489).values.max() ?: 0)
}

data class Point(val x: Int, val y: Int)

fun createGridUntil(target: Int) : Map<Point,Int>{
    val initial = Point(0, 0)
    val knownPointsAndScores = hashMapOf(initial to 1)
    var direction = Direction.RIGHT
    var currentPoint = initial
    var steps = 1
    var stepsRemainingBeforeTurn = steps

    while ((knownPointsAndScores[currentPoint] ?: 0) < target) {
        if (stepsRemainingBeforeTurn == 0 && (direction == Direction.UP || direction == Direction.DOWN)) {
            direction = direction.nextDirection()
            steps++
            stepsRemainingBeforeTurn = steps - 1
        } else if (stepsRemainingBeforeTurn == 0) {
            direction = direction.nextDirection()
            stepsRemainingBeforeTurn = steps - 1
        } else {
            stepsRemainingBeforeTurn--
        }

        currentPoint = direction.nextPoint(currentPoint)
        val score: Int = knownPointsAndScores.keys.intersect(adjacentPoints(currentPoint)).sumBy {
            knownPointsAndScores[it] ?: 0 }
        knownPointsAndScores[currentPoint] = score
    }
    return knownPointsAndScores
}

enum class Direction {
    UP {
        override fun nextDirection(): Direction = LEFT
        override fun nextPoint(point: Point) = Point(point.x, point.y + 1)
    },
    DOWN {
        override fun nextDirection(): Direction = RIGHT
        override fun nextPoint(point: Point) = Point(point.x, point.y - 1)

    },
    LEFT {
        override fun nextDirection(): Direction = DOWN
        override fun nextPoint(point: Point) = Point(point.x - 1, point.y)

    },
    RIGHT {
        override fun nextDirection(): Direction = UP
        override fun nextPoint(point: Point) = Point(point.x + 1, point.y)
    };

    abstract fun nextDirection(): Direction
    abstract fun nextPoint(point: Point): Point
}

fun adjacentPoints(point: Point): Set<Point> {
    val adjacentPoints = hashSetOf<Point>()
    for (x in -1..1) {
        for (y in -1..1) {
            adjacentPoints.add(Point(point.x + x, point.y + y))
        }
    }
    return adjacentPoints
}

Compiled from "Day03.kt"
public final class com.morninghacks.aoc2017.Day03Kt {
  public static final int manhattan(int);
    Code:
       0: iload_0
       1: invokestatic  #9                  // Method nextOddPerfectSquareInclusive:(I)I
       4: istore_1
       5: iload_1
       6: i2d
       7: invokestatic  #15                 // Method java/lang/Math.sqrt:(D)D
      10: invokestatic  #21                 // Method kotlin/math/MathKt.roundToInt:(D)I
      13: iconst_1
      14: isub
      15: istore_2
      16: iload_2
      17: iconst_2
      18: idiv
      19: istore_3
      20: iload_2
      21: ifne          28
      24: iconst_0
      25: goto          35
      28: iload_2
      29: iload_1
      30: iload_0
      31: isub
      32: iload_2
      33: irem
      34: isub
      35: istore        4
      37: iload         4
      39: iload_3
      40: if_icmpge     50
      43: iload_2
      44: iload         4
      46: isub
      47: goto          52
      50: iload         4
      52: ireturn

  public static final int nextOddPerfectSquareInclusive(int);
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_1
       3: iload_0
       4: iconst_2
       5: invokestatic  #33                 // Method kotlin/internal/ProgressionUtilKt.getProgressionLastElement:(III)I
       8: istore_2
       9: iload_1
      10: iload_2
      11: if_icmpgt     74
      14: iload_1
      15: i2d
      16: ldc2_w        #34                 // double 2.0d
      19: invokestatic  #39                 // Method java/lang/Math.pow:(DD)D
      22: invokestatic  #21                 // Method kotlin/math/MathKt.roundToInt:(D)I
      25: istore_3
      26: iload_1
      27: iconst_2
      28: iadd
      29: i2d
      30: ldc2_w        #34                 // double 2.0d
      33: invokestatic  #39                 // Method java/lang/Math.pow:(DD)D
      36: invokestatic  #21                 // Method kotlin/math/MathKt.roundToInt:(D)I
      39: istore        4
      41: iload_0
      42: iload_3
      43: if_icmpne     48
      46: iload_0
      47: ireturn
      48: iload_0
      49: iload_3
      50: if_icmple     62
      53: iload_0
      54: iload         4
      56: if_icmpge     62
      59: iload         4
      61: ireturn
      62: nop
      63: iload_1
      64: iload_2
      65: if_icmpeq     74
      68: iinc          1, 2
      71: goto          14
      74: new           #41                 // class java/lang/IllegalStateException
      77: dup
      78: invokespecial #45                 // Method java/lang/IllegalStateException."<init>":()V
      81: athrow

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #53                 // String args
       3: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #60                 // int 325489
       8: invokestatic  #62                 // Method manhattan:(I)I
      11: istore_1
      12: getstatic     #68                 // Field java/lang/System.out:Ljava/io/PrintStream;
      15: iload_1
      16: invokevirtual #74                 // Method java/io/PrintStream.println:(I)V
      19: ldc           #60                 // int 325489
      21: invokestatic  #78                 // Method createGridUntil:(I)Ljava/util/Map;
      24: invokeinterface #84,  1           // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
      29: checkcast     #86                 // class java/lang/Iterable
      32: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.maxOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
      35: checkcast     #94                 // class java/lang/Number
      38: invokevirtual #98                 // Method java/lang/Number.intValue:()I
      41: istore_1
      42: getstatic     #68                 // Field java/lang/System.out:Ljava/io/PrintStream;
      45: iload_1
      46: invokevirtual #74                 // Method java/io/PrintStream.println:(I)V
      49: return

  public static final java.util.Map<com.morninghacks.aoc2017.Point, java.lang.Integer> createGridUntil(int);
    Code:
       0: new           #102                // class com/morninghacks/aoc2017/Point
       3: dup
       4: iconst_0
       5: iconst_0
       6: invokespecial #105                // Method com/morninghacks/aoc2017/Point."<init>":(II)V
       9: astore_1
      10: iconst_1
      11: anewarray     #107                // class kotlin/Pair
      14: astore_3
      15: aload_3
      16: iconst_0
      17: aload_1
      18: iconst_1
      19: invokestatic  #113                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      22: invokestatic  #119                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      25: aastore
      26: aload_3
      27: invokestatic  #125                // Method kotlin/collections/MapsKt.hashMapOf:([Lkotlin/Pair;)Ljava/util/HashMap;
      30: astore_2
      31: getstatic     #131                // Field com/morninghacks/aoc2017/Direction.RIGHT:Lcom/morninghacks/aoc2017/Direction;
      34: astore_3
      35: aload_1
      36: astore        4
      38: iconst_1
      39: istore        5
      41: iload         5
      43: istore        6
      45: aload_2
      46: aload         4
      48: invokevirtual #137                // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
      51: checkcast     #109                // class java/lang/Integer
      54: dup
      55: ifnull        64
      58: invokevirtual #138                // Method java/lang/Integer.intValue:()I
      61: goto          66
      64: pop
      65: iconst_0
      66: iload_0
      67: if_icmpge     277
      70: iload         6
      72: ifne          106
      75: aload_3
      76: getstatic     #141                // Field com/morninghacks/aoc2017/Direction.UP:Lcom/morninghacks/aoc2017/Direction;
      79: if_acmpeq     89
      82: aload_3
      83: getstatic     #144                // Field com/morninghacks/aoc2017/Direction.DOWN:Lcom/morninghacks/aoc2017/Direction;
      86: if_acmpne     106
      89: aload_3
      90: invokevirtual #148                // Method com/morninghacks/aoc2017/Direction.nextDirection:()Lcom/morninghacks/aoc2017/Direction;
      93: astore_3
      94: iinc          5, 1
      97: iload         5
      99: iconst_1
     100: isub
     101: istore        6
     103: goto          131
     106: iload         6
     108: ifne          125
     111: aload_3
     112: invokevirtual #148                // Method com/morninghacks/aoc2017/Direction.nextDirection:()Lcom/morninghacks/aoc2017/Direction;
     115: astore_3
     116: iload         5
     118: iconst_1
     119: isub
     120: istore        6
     122: goto          131
     125: iload         6
     127: iinc          6, -1
     130: pop
     131: aload_3
     132: aload         4
     134: invokevirtual #152                // Method com/morninghacks/aoc2017/Direction.nextPoint:(Lcom/morninghacks/aoc2017/Point;)Lcom/morninghacks/aoc2017/Point;
     137: astore        4
     139: aload_2
     140: invokevirtual #156                // Method java/util/HashMap.keySet:()Ljava/util/Set;
     143: dup
     144: ldc           #158                // String <get-keys>(...)
     146: invokestatic  #161                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     149: checkcast     #86                 // class java/lang/Iterable
     152: aload         4
     154: invokestatic  #165                // Method adjacentPoints:(Lcom/morninghacks/aoc2017/Point;)Ljava/util/Set;
     157: checkcast     #86                 // class java/lang/Iterable
     160: invokestatic  #169                // Method kotlin/collections/CollectionsKt.intersect:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/Set;
     163: checkcast     #86                 // class java/lang/Iterable
     166: astore        8
     168: iconst_0
     169: istore        9
     171: iconst_0
     172: istore        10
     174: aload         8
     176: invokeinterface #173,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     181: astore        11
     183: aload         11
     185: invokeinterface #179,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     190: ifeq          249
     193: aload         11
     195: invokeinterface #183,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     200: astore        12
     202: iload         10
     204: aload         12
     206: checkcast     #102                // class com/morninghacks/aoc2017/Point
     209: astore        13
     211: istore        15
     213: iconst_0
     214: istore        14
     216: aload_2
     217: aload         13
     219: invokevirtual #137                // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     222: checkcast     #109                // class java/lang/Integer
     225: dup
     226: ifnull        235
     229: invokevirtual #138                // Method java/lang/Integer.intValue:()I
     232: goto          237
     235: pop
     236: iconst_0
     237: istore        16
     239: iload         15
     241: iload         16
     243: iadd
     244: istore        10
     246: goto          183
     249: iload         10
     251: istore        7
     253: iload         7
     255: invokestatic  #113                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     258: astore        9
     260: aload_2
     261: checkcast     #80                 // class java/util/Map
     264: aload         4
     266: aload         9
     268: invokeinterface #187,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     273: pop
     274: goto          45
     277: aload_2
     278: checkcast     #80                 // class java/util/Map
     281: areturn

  public static final java.util.Set<com.morninghacks.aoc2017.Point> adjacentPoints(com.morninghacks.aoc2017.Point);
    Code:
       0: aload_0
       1: ldc           #208                // String point
       3: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #210                // class java/util/HashSet
       9: dup
      10: invokespecial #211                // Method java/util/HashSet."<init>":()V
      13: astore_1
      14: iconst_m1
      15: istore_2
      16: iload_2
      17: iconst_2
      18: if_icmpge     64
      21: iconst_m1
      22: istore_3
      23: iload_3
      24: iconst_2
      25: if_icmpge     58
      28: aload_1
      29: new           #102                // class com/morninghacks/aoc2017/Point
      32: dup
      33: aload_0
      34: invokevirtual #214                // Method com/morninghacks/aoc2017/Point.getX:()I
      37: iload_2
      38: iadd
      39: aload_0
      40: invokevirtual #217                // Method com/morninghacks/aoc2017/Point.getY:()I
      43: iload_3
      44: iadd
      45: invokespecial #105                // Method com/morninghacks/aoc2017/Point."<init>":(II)V
      48: invokevirtual #221                // Method java/util/HashSet.add:(Ljava/lang/Object;)Z
      51: pop
      52: iinc          3, 1
      55: goto          23
      58: iinc          2, 1
      61: goto          16
      64: aload_1
      65: checkcast     #223                // class java/util/Set
      68: areturn
}


package com.morninghacks.aoc2017

import kotlin.math.abs

/*
Part One:

The spreadsheet consists of rows of apparently-random numbers. To make sure the recovery process is on the right track, they need you to calculate the spreadsheet's checksum. For each row, determine the difference between the largest value and the smallest value; the checksum is the sum of all of these differences.

For example, given the following spreadsheet:

5 1 9 5
7 5 3
2 4 6 8

    The first row's largest and smallest values are 9 and 1, and their difference is 8.
    The second row's largest and smallest values are 7 and 3, and their difference is 4.
    The third row's difference is 6.

In this example, the spreadsheet's checksum would be 8 + 4 + 6 = 18.

========================================================================================================================

Part Two:

It sounds like the goal is to find the only two numbers in each row where one evenly divides the other - that is, where the result of the division operation is a whole number. They would like you to find those numbers on each line, divide them, and add up each line's result.

For example, given the following spreadsheet:

5 9 2 8
9 4 7 3
3 8 6 5

    In the first row, the only two numbers that evenly divide are 8 and 2; the result of this division is 4.
    In the second row, the two numbers are 9 and 3; the result is 3.
    In the third row, the result is 2.

In this example, the sum of the results would be 4 + 3 + 2 = 9.
 */

fun checksum(spreadsheet: String, lineSummer: (List<Int>) -> Int = ::minAndMax): Int {
    val lines = spreadsheet.split("\n")
    val rows: List<List<Int>> = lines.map { line -> line.split(Regex("""\s""")).map { num -> Integer.valueOf(num) } }

    return rows.fold(0, { sum: Int, list ->  sum + lineSummer(list)})
}

fun minAndMax(list: List<Int>): Int {
    return abs((list.max() ?: 0)  - (list.min() ?: 0))
}

fun evenlyDivides(list: List<Int>): Int {
    val pair : Pair<Int,Int>? = allPairs(list).find { it -> it.first % it.second == 0 || it.second % it.first == 0 }
    return when {
        pair == null -> 0
        pair.first > pair.second -> pair.first / pair.second
        else -> pair.second / pair.first
    }
}

fun <T> allPairs(list: List<T>): List<Pair<T, T>> {
    val pairs = arrayListOf<Pair<T, T>>()
    for ((index, left) in list.withIndex()) {
        if (index != list.size - 1) {
            list.subList(index + 1, list.size).mapTo(pairs) { left to it }
        }
    }
    return pairs
}

fun main(args: Array<String>) {
    val input = """5806	6444	1281	38	267	1835	223	4912	5995	230	4395	2986	6048	4719	216	1201
74	127	226	84	174	280	94	159	198	305	124	106	205	99	177	294
1332	52	54	655	56	170	843	707	1273	1163	89	23	43	1300	1383	1229
5653	236	1944	3807	5356	246	222	1999	4872	206	5265	5397	5220	5538	286	917
3512	3132	2826	3664	2814	549	3408	3384	142	120	160	114	1395	2074	1816	2357
100	2000	112	103	2122	113	92	522	1650	929	1281	2286	2259	1068	1089	651
646	490	297	60	424	234	48	491	245	523	229	189	174	627	441	598
2321	555	2413	2378	157	27	194	2512	117	140	2287	277	2635	1374	1496	1698
101	1177	104	89	542	2033	1724	1197	474	1041	1803	770	87	1869	1183	553
1393	92	105	1395	1000	85	391	1360	1529	1367	1063	688	642	102	999	638
4627	223	188	5529	2406	4980	2384	2024	4610	279	249	2331	4660	4350	3264	242
769	779	502	75	1105	53	55	931	1056	1195	65	292	1234	1164	678	1032
2554	75	4406	484	2285	226	5666	245	4972	3739	5185	1543	230	236	3621	5387
826	4028	4274	163	5303	4610	145	5779	157	4994	5053	186	5060	3082	2186	4882
588	345	67	286	743	54	802	776	29	44	107	63	303	372	41	810
128	2088	3422	111	3312	740	3024	1946	920	131	112	477	3386	2392	1108	2741"""
    println(checksum(input, ::minAndMax))
    println(checksum(input, ::evenlyDivides))

}

Compiled from "Day02.kt"
final class com.morninghacks.aoc2017.Day02Kt$checksum$1 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function1<java.util.List<? extends java.lang.Integer>, java.lang.Integer> {
  public static final com.morninghacks.aoc2017.Day02Kt$checksum$1 INSTANCE;

  com.morninghacks.aoc2017.Day02Kt$checksum$1();
    Code:
       0: aload_0
       1: iconst_1
       2: ldc           #11                 // class com/morninghacks/aoc2017/Day02Kt
       4: ldc           #13                 // String minAndMax
       6: ldc           #15                 // String minAndMax(Ljava/util/List;)I
       8: iconst_1
       9: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      12: return

  public final java.lang.Integer invoke(java.util.List<java.lang.Integer>);
    Code:
       0: aload_1
       1: ldc           #25                 // String p0
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokestatic  #34                 // Method com/morninghacks/aoc2017/Day02Kt.minAndMax:(Ljava/util/List;)I
      10: invokestatic  #40                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      13: areturn

  public java.lang.Object invoke(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #44                 // class java/util/List
       5: invokevirtual #46                 // Method invoke:(Ljava/util/List;)Ljava/lang/Integer;
       8: areturn

  static {};
    Code:
       0: new           #2                  // class com/morninghacks/aoc2017/Day02Kt$checksum$1
       3: dup
       4: invokespecial #51                 // Method "<init>":()V
       7: putstatic     #54                 // Field INSTANCE:Lcom/morninghacks/aoc2017/Day02Kt$checksum$1;
      10: return
}

Compiled from "Day02.kt"
public final class com.morninghacks.aoc2017.Day02Kt {
  public static final int checksum(java.lang.String, kotlin.jvm.functions.Function1<? super java.util.List<java.lang.Integer>, java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #10                 // String spreadsheet
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #18                 // String lineSummer
       9: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #20                 // class java/lang/CharSequence
      16: iconst_1
      17: anewarray     #22                 // class java/lang/String
      20: astore_3
      21: aload_3
      22: iconst_0
      23: ldc           #24                 // String \n
      25: aastore
      26: aload_3
      27: iconst_0
      28: iconst_0
      29: bipush        6
      31: aconst_null
      32: invokestatic  #30                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      35: astore_2
      36: aload_2
      37: checkcast     #32                 // class java/lang/Iterable
      40: astore        4
      42: iconst_0
      43: istore        5
      45: aload         4
      47: astore        6
      49: new           #34                 // class java/util/ArrayList
      52: dup
      53: aload         4
      55: bipush        10
      57: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      60: invokespecial #44                 // Method java/util/ArrayList."<init>":(I)V
      63: checkcast     #46                 // class java/util/Collection
      66: astore        7
      68: iconst_0
      69: istore        8
      71: aload         6
      73: invokeinterface #50,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      78: astore        9
      80: aload         9
      82: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      87: ifeq          256
      90: aload         9
      92: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      97: astore        10
      99: aload         7
     101: aload         10
     103: checkcast     #22                 // class java/lang/String
     106: astore        11
     108: astore        23
     110: iconst_0
     111: istore        12
     113: aload         11
     115: checkcast     #20                 // class java/lang/CharSequence
     118: astore        13
     120: new           #62                 // class kotlin/text/Regex
     123: dup
     124: ldc           #64                 // String \\s
     126: invokespecial #67                 // Method kotlin/text/Regex."<init>":(Ljava/lang/String;)V
     129: astore        14
     131: iconst_0
     132: istore        15
     134: aload         14
     136: aload         13
     138: iload         15
     140: invokevirtual #71                 // Method kotlin/text/Regex.split:(Ljava/lang/CharSequence;I)Ljava/util/List;
     143: checkcast     #32                 // class java/lang/Iterable
     146: astore        13
     148: nop
     149: iconst_0
     150: istore        14
     152: aload         13
     154: astore        15
     156: new           #34                 // class java/util/ArrayList
     159: dup
     160: aload         13
     162: bipush        10
     164: invokestatic  #40                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     167: invokespecial #44                 // Method java/util/ArrayList."<init>":(I)V
     170: checkcast     #46                 // class java/util/Collection
     173: astore        16
     175: iconst_0
     176: istore        17
     178: aload         15
     180: invokeinterface #50,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     185: astore        18
     187: aload         18
     189: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     194: ifeq          237
     197: aload         18
     199: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     204: astore        19
     206: aload         16
     208: aload         19
     210: checkcast     #22                 // class java/lang/String
     213: astore        20
     215: astore        21
     217: iconst_0
     218: istore        22
     220: aload         20
     222: invokestatic  #77                 // Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;
     225: aload         21
     227: swap
     228: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     233: pop
     234: goto          187
     237: aload         16
     239: checkcast     #83                 // class java/util/List
     242: nop
     243: nop
     244: aload         23
     246: swap
     247: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     252: pop
     253: goto          80
     256: aload         7
     258: checkcast     #83                 // class java/util/List
     261: nop
     262: astore_3
     263: aload_3
     264: checkcast     #32                 // class java/lang/Iterable
     267: astore        4
     269: iconst_0
     270: istore        5
     272: iconst_0
     273: istore        6
     275: iload         5
     277: istore        7
     279: aload         4
     281: invokeinterface #50,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     286: astore        8
     288: aload         8
     290: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     295: ifeq          343
     298: aload         8
     300: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     305: astore        9
     307: iload         7
     309: aload         9
     311: checkcast     #83                 // class java/util/List
     314: astore        10
     316: istore        11
     318: iconst_0
     319: istore        12
     321: iload         11
     323: aload_1
     324: aload         10
     326: invokeinterface #89,  2           // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
     331: checkcast     #91                 // class java/lang/Number
     334: invokevirtual #95                 // Method java/lang/Number.intValue:()I
     337: iadd
     338: istore        7
     340: goto          288
     343: iload         7
     345: ireturn

  public static int checksum$default(java.lang.String, kotlin.jvm.functions.Function1, int, java.lang.Object);
    Code:
       0: iload_2
       1: iconst_2
       2: iand
       3: ifeq          13
       6: getstatic     #132                // Field com/morninghacks/aoc2017/Day02Kt$checksum$1.INSTANCE:Lcom/morninghacks/aoc2017/Day02Kt$checksum$1;
       9: checkcast     #85                 // class kotlin/jvm/functions/Function1
      12: astore_1
      13: aload_0
      14: aload_1
      15: invokestatic  #134                // Method checksum:(Ljava/lang/String;Lkotlin/jvm/functions/Function1;)I
      18: ireturn

  public static final int minAndMax(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #138                // String list
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #32                 // class java/lang/Iterable
      10: invokestatic  #142                // Method kotlin/collections/CollectionsKt.maxOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
      13: checkcast     #91                 // class java/lang/Number
      16: invokevirtual #95                 // Method java/lang/Number.intValue:()I
      19: aload_0
      20: checkcast     #32                 // class java/lang/Iterable
      23: invokestatic  #145                // Method kotlin/collections/CollectionsKt.minOrThrow:(Ljava/lang/Iterable;)Ljava/lang/Comparable;
      26: checkcast     #91                 // class java/lang/Number
      29: invokevirtual #95                 // Method java/lang/Number.intValue:()I
      32: isub
      33: invokestatic  #151                // Method java/lang/Math.abs:(I)I
      36: ireturn

  public static final int evenlyDivides(java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #138                // String list
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #156                // Method allPairs:(Ljava/util/List;)Ljava/util/List;
      10: checkcast     #32                 // class java/lang/Iterable
      13: astore_2
      14: aload_2
      15: invokeinterface #50,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      20: astore_3
      21: aload_3
      22: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      27: ifeq          113
      30: aload_3
      31: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      36: astore        4
      38: aload         4
      40: checkcast     #158                // class kotlin/Pair
      43: astore        5
      45: iconst_0
      46: istore        6
      48: aload         5
      50: invokevirtual #161                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      53: checkcast     #91                 // class java/lang/Number
      56: invokevirtual #95                 // Method java/lang/Number.intValue:()I
      59: aload         5
      61: invokevirtual #164                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      64: checkcast     #91                 // class java/lang/Number
      67: invokevirtual #95                 // Method java/lang/Number.intValue:()I
      70: irem
      71: ifeq          100
      74: aload         5
      76: invokevirtual #164                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      79: checkcast     #91                 // class java/lang/Number
      82: invokevirtual #95                 // Method java/lang/Number.intValue:()I
      85: aload         5
      87: invokevirtual #161                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      90: checkcast     #91                 // class java/lang/Number
      93: invokevirtual #95                 // Method java/lang/Number.intValue:()I
      96: irem
      97: ifne          104
     100: iconst_1
     101: goto          105
     104: iconst_0
     105: ifeq          21
     108: aload         4
     110: goto          114
     113: aconst_null
     114: checkcast     #158                // class kotlin/Pair
     117: astore_1
     118: nop
     119: aload_1
     120: ifnonnull     127
     123: iconst_0
     124: goto          195
     127: aload_1
     128: invokevirtual #161                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     131: checkcast     #91                 // class java/lang/Number
     134: invokevirtual #95                 // Method java/lang/Number.intValue:()I
     137: aload_1
     138: invokevirtual #164                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     141: checkcast     #91                 // class java/lang/Number
     144: invokevirtual #95                 // Method java/lang/Number.intValue:()I
     147: if_icmple     174
     150: aload_1
     151: invokevirtual #161                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     154: checkcast     #91                 // class java/lang/Number
     157: invokevirtual #95                 // Method java/lang/Number.intValue:()I
     160: aload_1
     161: invokevirtual #164                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     164: checkcast     #91                 // class java/lang/Number
     167: invokevirtual #95                 // Method java/lang/Number.intValue:()I
     170: idiv
     171: goto          195
     174: aload_1
     175: invokevirtual #164                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     178: checkcast     #91                 // class java/lang/Number
     181: invokevirtual #95                 // Method java/lang/Number.intValue:()I
     184: aload_1
     185: invokevirtual #161                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     188: checkcast     #91                 // class java/lang/Number
     191: invokevirtual #95                 // Method java/lang/Number.intValue:()I
     194: idiv
     195: ireturn

  public static final <T> java.util.List<kotlin.Pair<T, T>> allPairs(java.util.List<? extends T>);
    Code:
       0: aload_0
       1: ldc           #138                // String list
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #34                 // class java/util/ArrayList
       9: dup
      10: invokespecial #172                // Method java/util/ArrayList."<init>":()V
      13: astore_1
      14: aload_0
      15: checkcast     #32                 // class java/lang/Iterable
      18: invokeinterface #50,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      23: astore_2
      24: iconst_0
      25: istore_3
      26: aload_2
      27: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      32: ifeq          155
      35: iload_3
      36: istore        4
      38: iload_3
      39: iconst_1
      40: iadd
      41: istore_3
      42: aload_2
      43: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      48: astore        5
      50: iload         4
      52: aload_0
      53: invokeinterface #175,  1          // InterfaceMethod java/util/List.size:()I
      58: iconst_1
      59: isub
      60: if_icmpeq     26
      63: aload_0
      64: iload         4
      66: iconst_1
      67: iadd
      68: aload_0
      69: invokeinterface #175,  1          // InterfaceMethod java/util/List.size:()I
      74: invokeinterface #179,  3          // InterfaceMethod java/util/List.subList:(II)Ljava/util/List;
      79: checkcast     #32                 // class java/lang/Iterable
      82: astore        6
      84: iconst_0
      85: istore        7
      87: aload         6
      89: invokeinterface #50,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      94: astore        8
      96: aload         8
      98: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     103: ifeq          147
     106: aload         8
     108: invokeinterface #60,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     113: astore        9
     115: aload_1
     116: checkcast     #46                 // class java/util/Collection
     119: aload         9
     121: astore        10
     123: astore        12
     125: iconst_0
     126: istore        11
     128: aload         5
     130: aload         10
     132: invokestatic  #185                // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
     135: aload         12
     137: swap
     138: invokeinterface #81,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     143: pop
     144: goto          96
     147: aload_1
     148: checkcast     #46                 // class java/util/Collection
     151: pop
     152: goto          26
     155: aload_1
     156: checkcast     #83                 // class java/util/List
     159: areturn

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #196                // String args
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #198                // String 5806\t6444\t1281\t38\t267\t1835\t223\t4912\t5995\t230\t4395\t2986\t6048\t4719\t216\t1201\n74\t127\t226\t84\t174\t280\t94\t159\t198\t305\t124\t106\t205\t99\t177\t294\n1332\t52\t54\t655\t56\t170\t843\t707\t1273\t1163\t89\t23\t43\t1300\t1383\t1229\n5653\t236\t1944\t3807\t5356\t246\t222\t1999\t4872\t206\t5265\t5397\t5220\t5538\t286\t917\n3512\t3132\t2826\t3664\t2814\t549\t3408\t3384\t142\t120\t160\t114\t1395\t2074\t1816\t2357\n100\t2000\t112\t103\t2122\t113\t92\t522\t1650\t929\t1281\t2286\t2259\t1068\t1089\t651\n646\t490\t297\t60\t424\t234\t48\t491\t245\t523\t229\t189\t174\t627\t441\t598\n2321\t555\t2413\t2378\t157\t27\t194\t2512\t117\t140\t2287\t277\t2635\t1374\t1496\t1698\n101\t1177\t104\t89\t542\t2033\t1724\t1197\t474\t1041\t1803\t770\t87\t1869\t1183\t553\n1393\t92\t105\t1395\t1000\t85\t391\t1360\t1529\t1367\t1063\t688\t642\t102\t999\t638\n4627\t223\t188\t5529\t2406\t4980\t2384\t2024\t4610\t279\t249\t2331\t4660\t4350\t3264\t242\n769\t779\t502\t75\t1105\t53\t55\t931\t1056\t1195\t65\t292\t1234\t1164\t678\t1032\n2554\t75\t4406\t484\t2285\t226\t5666\t245\t4972\t3739\t5185\t1543\t230\t236\t3621\t5387\n826\t4028\t4274\t163\t5303\t4610\t145\t5779\t157\t4994\t5053\t186\t5060\t3082\t2186\t4882\n588\t345\t67\t286\t743\t54\t802\t776\t29\t44\t107\t63\t303\t372\t41\t810\n128\t2088\t3422\t111\t3312\t740\t3024\t1946\t920\t131\t112\t477\t3386\t2392\t1108\t2741
       8: astore_1
       9: aload_1
      10: getstatic     #203                // Field com/morninghacks/aoc2017/Day02Kt$main$1.INSTANCE:Lcom/morninghacks/aoc2017/Day02Kt$main$1;
      13: checkcast     #85                 // class kotlin/jvm/functions/Function1
      16: invokestatic  #134                // Method checksum:(Ljava/lang/String;Lkotlin/jvm/functions/Function1;)I
      19: istore_2
      20: getstatic     #209                // Field java/lang/System.out:Ljava/io/PrintStream;
      23: iload_2
      24: invokevirtual #214                // Method java/io/PrintStream.println:(I)V
      27: aload_1
      28: getstatic     #219                // Field com/morninghacks/aoc2017/Day02Kt$main$2.INSTANCE:Lcom/morninghacks/aoc2017/Day02Kt$main$2;
      31: checkcast     #85                 // class kotlin/jvm/functions/Function1
      34: invokestatic  #134                // Method checksum:(Ljava/lang/String;Lkotlin/jvm/functions/Function1;)I
      37: istore_2
      38: getstatic     #209                // Field java/lang/System.out:Ljava/io/PrintStream;
      41: iload_2
      42: invokevirtual #214                // Method java/io/PrintStream.println:(I)V
      45: return
}

Compiled from "Day02.kt"
final class com.morninghacks.aoc2017.Day02Kt$main$2 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function1<java.util.List<? extends java.lang.Integer>, java.lang.Integer> {
  public static final com.morninghacks.aoc2017.Day02Kt$main$2 INSTANCE;

  com.morninghacks.aoc2017.Day02Kt$main$2();
    Code:
       0: aload_0
       1: iconst_1
       2: ldc           #11                 // class com/morninghacks/aoc2017/Day02Kt
       4: ldc           #13                 // String evenlyDivides
       6: ldc           #15                 // String evenlyDivides(Ljava/util/List;)I
       8: iconst_1
       9: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      12: return

  public final java.lang.Integer invoke(java.util.List<java.lang.Integer>);
    Code:
       0: aload_1
       1: ldc           #25                 // String p0
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokestatic  #34                 // Method com/morninghacks/aoc2017/Day02Kt.evenlyDivides:(Ljava/util/List;)I
      10: invokestatic  #40                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      13: areturn

  public java.lang.Object invoke(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #44                 // class java/util/List
       5: invokevirtual #46                 // Method invoke:(Ljava/util/List;)Ljava/lang/Integer;
       8: areturn

  static {};
    Code:
       0: new           #2                  // class com/morninghacks/aoc2017/Day02Kt$main$2
       3: dup
       4: invokespecial #51                 // Method "<init>":()V
       7: putstatic     #54                 // Field INSTANCE:Lcom/morninghacks/aoc2017/Day02Kt$main$2;
      10: return
}

Compiled from "Day02.kt"
final class com.morninghacks.aoc2017.Day02Kt$main$1 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function1<java.util.List<? extends java.lang.Integer>, java.lang.Integer> {
  public static final com.morninghacks.aoc2017.Day02Kt$main$1 INSTANCE;

  com.morninghacks.aoc2017.Day02Kt$main$1();
    Code:
       0: aload_0
       1: iconst_1
       2: ldc           #11                 // class com/morninghacks/aoc2017/Day02Kt
       4: ldc           #13                 // String minAndMax
       6: ldc           #15                 // String minAndMax(Ljava/util/List;)I
       8: iconst_1
       9: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      12: return

  public final java.lang.Integer invoke(java.util.List<java.lang.Integer>);
    Code:
       0: aload_1
       1: ldc           #25                 // String p0
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokestatic  #34                 // Method com/morninghacks/aoc2017/Day02Kt.minAndMax:(Ljava/util/List;)I
      10: invokestatic  #40                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      13: areturn

  public java.lang.Object invoke(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #44                 // class java/util/List
       5: invokevirtual #46                 // Method invoke:(Ljava/util/List;)Ljava/lang/Integer;
       8: areturn

  static {};
    Code:
       0: new           #2                  // class com/morninghacks/aoc2017/Day02Kt$main$1
       3: dup
       4: invokespecial #51                 // Method "<init>":()V
       7: putstatic     #54                 // Field INSTANCE:Lcom/morninghacks/aoc2017/Day02Kt$main$1;
      10: return
}