package com.marcdenning.adventofcode.day12

import java.io.File
import kotlin.math.abs

fun main(args: Array<String>) {
    var ship = Ship(
        Coordinates(0, 0, 90),
        Coordinates(10, 1, 0)
    )

    File(args[0]).readLines().map { parseInstruction(it) }
        .forEach { ship = moveShipToWaypoint(ship, it) }

    println("Manhattan distance: ${abs(ship.shipCoordinates.x) + abs(ship.shipCoordinates.y)}")

}

fun moveShipToWaypoint(ship: Ship, instruction: Pair<Char, Int>): Ship {
    return when (instruction.first) {
        FORWARD -> {
            val xMovement = instruction.second * ship.waypointCoordinates.x
            val yMovement = instruction.second * ship.waypointCoordinates.y

            Ship(Coordinates(
                ship.shipCoordinates.x + xMovement,
                ship.shipCoordinates.y + yMovement,
                ship.shipCoordinates.orientation
            ), Coordinates(
                ship.waypointCoordinates.x,
                ship.waypointCoordinates.y,
                ship.waypointCoordinates.orientation
            ))
        }
        NORTH -> Ship(
            Coordinates(ship.shipCoordinates.x, ship.shipCoordinates.y, ship.shipCoordinates.orientation),
            Coordinates(ship.waypointCoordinates.x, ship.waypointCoordinates.y + instruction.second, ship.waypointCoordinates.orientation)
        )
        SOUTH -> Ship(
            Coordinates(ship.shipCoordinates.x, ship.shipCoordinates.y, ship.shipCoordinates.orientation),
            Coordinates(ship.waypointCoordinates.x, ship.waypointCoordinates.y - instruction.second, ship.waypointCoordinates.orientation)
        )
        EAST -> Ship(
            Coordinates(ship.shipCoordinates.x, ship.shipCoordinates.y, ship.shipCoordinates.orientation),
            Coordinates(ship.waypointCoordinates.x + instruction.second, ship.waypointCoordinates.y, ship.waypointCoordinates.orientation)
        )
        WEST -> Ship(
            Coordinates(ship.shipCoordinates.x, ship.shipCoordinates.y, ship.shipCoordinates.orientation),
            Coordinates(ship.waypointCoordinates.x - instruction.second, ship.waypointCoordinates.y, ship.waypointCoordinates.orientation)
        )
        LEFT -> when (instruction.second) {
            90 -> rotateWaypointLeft(ship)
            180 -> rotateWaypointLeft(rotateWaypointLeft(ship))
            270 -> rotateWaypointLeft(rotateWaypointLeft(rotateWaypointLeft(ship)))
            else -> throw Exception()
        }
        RIGHT -> when (instruction.second) {
            90 -> rotateWaypointRight(ship)
            180 -> rotateWaypointRight(rotateWaypointRight(ship))
            270 -> rotateWaypointRight(rotateWaypointRight(rotateWaypointRight(ship)))
            else -> throw Exception()
        }
        else -> throw Exception()
    }
}

fun rotateWaypointLeft(ship: Ship) = Ship(
    Coordinates(ship.shipCoordinates.x, ship.shipCoordinates.y, ship.shipCoordinates.orientation),
    Coordinates(-ship.waypointCoordinates.y, ship.waypointCoordinates.x, ship.waypointCoordinates.orientation)
)

fun rotateWaypointRight(ship: Ship) = Ship(
    Coordinates(ship.shipCoordinates.x, ship.shipCoordinates.y, ship.shipCoordinates.orientation),
    Coordinates(ship.waypointCoordinates.y, -ship.waypointCoordinates.x, ship.waypointCoordinates.orientation)
)

data class Ship(
    val shipCoordinates: Coordinates,
    val waypointCoordinates: Coordinates
)

Compiled from "Day12b.kt"
public final class com.marcdenning.adventofcode.day12.Day12bKt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aconst_null
       7: astore_1
       8: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
      11: dup
      12: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
      15: dup
      16: lconst_0
      17: lconst_0
      18: bipush        90
      20: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
      23: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
      26: dup
      27: ldc2_w        #24                 // long 10l
      30: lconst_1
      31: iconst_0
      32: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
      35: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
      38: astore_1
      39: new           #30                 // class java/io/File
      42: dup
      43: aload_0
      44: iconst_0
      45: aaload
      46: invokespecial #33                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      49: aconst_null
      50: iconst_1
      51: aconst_null
      52: invokestatic  #39                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      55: checkcast     #41                 // class java/lang/Iterable
      58: astore_2
      59: iconst_0
      60: istore_3
      61: aload_2
      62: astore        4
      64: new           #43                 // class java/util/ArrayList
      67: dup
      68: aload_2
      69: bipush        10
      71: invokestatic  #49                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      74: invokespecial #52                 // Method java/util/ArrayList."<init>":(I)V
      77: checkcast     #54                 // class java/util/Collection
      80: astore        5
      82: iconst_0
      83: istore        6
      85: aload         4
      87: invokeinterface #58,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      92: astore        7
      94: aload         7
      96: invokeinterface #64,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     101: ifeq          144
     104: aload         7
     106: invokeinterface #68,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     111: astore        8
     113: aload         5
     115: aload         8
     117: checkcast     #70                 // class java/lang/String
     120: astore        9
     122: astore        11
     124: iconst_0
     125: istore        10
     127: aload         9
     129: invokestatic  #76                 // Method com/marcdenning/adventofcode/day12/Day12aKt.parseInstruction:(Ljava/lang/String;)Lkotlin/Pair;
     132: aload         11
     134: swap
     135: invokeinterface #80,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     140: pop
     141: goto          94
     144: aload         5
     146: checkcast     #82                 // class java/util/List
     149: nop
     150: checkcast     #41                 // class java/lang/Iterable
     153: astore_2
     154: nop
     155: iconst_0
     156: istore_3
     157: aload_2
     158: invokeinterface #58,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     163: astore        4
     165: aload         4
     167: invokeinterface #64,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     172: ifeq          205
     175: aload         4
     177: invokeinterface #68,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     182: astore        5
     184: aload         5
     186: checkcast     #84                 // class kotlin/Pair
     189: astore        6
     191: iconst_0
     192: istore        7
     194: aload_1
     195: aload         6
     197: invokestatic  #88                 // Method moveShipToWaypoint:(Lcom/marcdenning/adventofcode/day12/Ship;Lkotlin/Pair;)Lcom/marcdenning/adventofcode/day12/Ship;
     200: astore_1
     201: nop
     202: goto          165
     205: nop
     206: new           #90                 // class java/lang/StringBuilder
     209: dup
     210: invokespecial #93                 // Method java/lang/StringBuilder."<init>":()V
     213: ldc           #95                 // String Manhattan distance:
     215: invokevirtual #99                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     218: aload_1
     219: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     222: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     225: invokestatic  #113                // Method java/lang/Math.abs:(J)J
     228: aload_1
     229: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     232: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     235: invokestatic  #113                // Method java/lang/Math.abs:(J)J
     238: ladd
     239: invokevirtual #119                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     242: invokevirtual #123                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     245: getstatic     #129                // Field java/lang/System.out:Ljava/io/PrintStream;
     248: swap
     249: invokevirtual #135                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     252: return

  public static final com.marcdenning.adventofcode.day12.Ship moveShipToWaypoint(com.marcdenning.adventofcode.day12.Ship, kotlin.Pair<java.lang.Character, java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #158                // String ship
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #160                // String instruction
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: invokevirtual #163                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      16: checkcast     #165                // class java/lang/Character
      19: invokevirtual #169                // Method java/lang/Character.charValue:()C
      22: lookupswitch  { // 7
                    69: 352
                    70: 88
                    76: 506
                    78: 198
                    82: 590
                    83: 275
                    87: 429
               default: 674
          }
      88: aload_1
      89: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
      92: checkcast     #174                // class java/lang/Number
      95: invokevirtual #177                // Method java/lang/Number.longValue:()J
      98: aload_0
      99: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     102: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     105: lmul
     106: lstore_2
     107: aload_1
     108: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     111: checkcast     #174                // class java/lang/Number
     114: invokevirtual #177                // Method java/lang/Number.longValue:()J
     117: aload_0
     118: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     121: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     124: lmul
     125: lstore        4
     127: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
     130: dup
     131: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     134: dup
     135: aload_0
     136: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     139: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     142: lload_2
     143: ladd
     144: aload_0
     145: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     148: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     151: lload         4
     153: ladd
     154: aload_0
     155: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     158: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     161: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     164: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     167: dup
     168: aload_0
     169: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     172: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     175: aload_0
     176: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     179: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     182: aload_0
     183: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     186: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     189: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     192: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
     195: goto          682
     198: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
     201: dup
     202: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     205: dup
     206: aload_0
     207: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     210: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     213: aload_0
     214: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     217: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     220: aload_0
     221: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     224: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     227: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     230: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     233: dup
     234: aload_0
     235: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     238: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     241: aload_0
     242: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     245: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     248: aload_1
     249: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     252: checkcast     #174                // class java/lang/Number
     255: invokevirtual #177                // Method java/lang/Number.longValue:()J
     258: ladd
     259: aload_0
     260: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     263: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     266: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     269: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
     272: goto          682
     275: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
     278: dup
     279: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     282: dup
     283: aload_0
     284: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     287: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     290: aload_0
     291: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     294: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     297: aload_0
     298: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     301: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     304: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     307: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     310: dup
     311: aload_0
     312: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     315: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     318: aload_0
     319: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     322: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     325: aload_1
     326: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     329: checkcast     #174                // class java/lang/Number
     332: invokevirtual #177                // Method java/lang/Number.longValue:()J
     335: lsub
     336: aload_0
     337: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     340: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     343: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     346: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
     349: goto          682
     352: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
     355: dup
     356: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     359: dup
     360: aload_0
     361: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     364: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     367: aload_0
     368: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     371: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     374: aload_0
     375: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     378: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     381: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     384: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     387: dup
     388: aload_0
     389: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     392: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     395: aload_1
     396: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     399: checkcast     #174                // class java/lang/Number
     402: invokevirtual #177                // Method java/lang/Number.longValue:()J
     405: ladd
     406: aload_0
     407: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     410: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     413: aload_0
     414: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     417: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     420: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     423: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
     426: goto          682
     429: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
     432: dup
     433: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     436: dup
     437: aload_0
     438: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     441: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     444: aload_0
     445: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     448: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     451: aload_0
     452: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     455: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     458: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     461: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
     464: dup
     465: aload_0
     466: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     469: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     472: aload_1
     473: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     476: checkcast     #174                // class java/lang/Number
     479: invokevirtual #177                // Method java/lang/Number.longValue:()J
     482: lsub
     483: aload_0
     484: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     487: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     490: aload_0
     491: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
     494: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     497: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     500: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
     503: goto          682
     506: aload_1
     507: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     510: checkcast     #174                // class java/lang/Number
     513: invokevirtual #187                // Method java/lang/Number.intValue:()I
     516: lookupswitch  { // 3
                    90: 552
                   180: 559
                   270: 569
               default: 582
          }
     552: aload_0
     553: invokestatic  #191                // Method rotateWaypointLeft:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     556: goto          682
     559: aload_0
     560: invokestatic  #191                // Method rotateWaypointLeft:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     563: invokestatic  #191                // Method rotateWaypointLeft:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     566: goto          682
     569: aload_0
     570: invokestatic  #191                // Method rotateWaypointLeft:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     573: invokestatic  #191                // Method rotateWaypointLeft:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     576: invokestatic  #191                // Method rotateWaypointLeft:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     579: goto          682
     582: new           #193                // class java/lang/Exception
     585: dup
     586: invokespecial #194                // Method java/lang/Exception."<init>":()V
     589: athrow
     590: aload_1
     591: invokevirtual #172                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     594: checkcast     #174                // class java/lang/Number
     597: invokevirtual #187                // Method java/lang/Number.intValue:()I
     600: lookupswitch  { // 3
                    90: 636
                   180: 643
                   270: 653
               default: 666
          }
     636: aload_0
     637: invokestatic  #197                // Method rotateWaypointRight:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     640: goto          682
     643: aload_0
     644: invokestatic  #197                // Method rotateWaypointRight:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     647: invokestatic  #197                // Method rotateWaypointRight:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     650: goto          682
     653: aload_0
     654: invokestatic  #197                // Method rotateWaypointRight:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     657: invokestatic  #197                // Method rotateWaypointRight:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     660: invokestatic  #197                // Method rotateWaypointRight:(Lcom/marcdenning/adventofcode/day12/Ship;)Lcom/marcdenning/adventofcode/day12/Ship;
     663: goto          682
     666: new           #193                // class java/lang/Exception
     669: dup
     670: invokespecial #194                // Method java/lang/Exception."<init>":()V
     673: athrow
     674: new           #193                // class java/lang/Exception
     677: dup
     678: invokespecial #194                // Method java/lang/Exception."<init>":()V
     681: athrow
     682: areturn

  public static final com.marcdenning.adventofcode.day12.Ship rotateWaypointLeft(com.marcdenning.adventofcode.day12.Ship);
    Code:
       0: aload_0
       1: ldc           #158                // String ship
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
       9: dup
      10: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
      13: dup
      14: aload_0
      15: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      18: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
      21: aload_0
      22: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      25: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
      28: aload_0
      29: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      32: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
      35: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
      38: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
      41: dup
      42: aload_0
      43: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      46: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
      49: lneg
      50: aload_0
      51: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      54: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
      57: aload_0
      58: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      61: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
      64: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
      67: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
      70: areturn

  public static final com.marcdenning.adventofcode.day12.Ship rotateWaypointRight(com.marcdenning.adventofcode.day12.Ship);
    Code:
       0: aload_0
       1: ldc           #158                // String ship
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class com/marcdenning/adventofcode/day12/Ship
       9: dup
      10: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
      13: dup
      14: aload_0
      15: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      18: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
      21: aload_0
      22: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      25: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
      28: aload_0
      29: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Ship.getShipCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      32: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
      35: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
      38: new           #19                 // class com/marcdenning/adventofcode/day12/Coordinates
      41: dup
      42: aload_0
      43: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      46: invokevirtual #116                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
      49: aload_0
      50: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      53: invokevirtual #107                // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
      56: lneg
      57: aload_0
      58: invokevirtual #180                // Method com/marcdenning/adventofcode/day12/Ship.getWaypointCoordinates:()Lcom/marcdenning/adventofcode/day12/Coordinates;
      61: invokevirtual #184                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
      64: invokespecial #23                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
      67: invokespecial #28                 // Method com/marcdenning/adventofcode/day12/Ship."<init>":(Lcom/marcdenning/adventofcode/day12/Coordinates;Lcom/marcdenning/adventofcode/day12/Coordinates;)V
      70: areturn
}


package com.marcdenning.adventofcode.day12

import java.io.File
import java.util.regex.Pattern
import kotlin.math.abs

const val FORWARD = 'F'
const val NORTH = 'N'
const val SOUTH = 'S'
const val EAST = 'E'
const val WEST = 'W'
const val RIGHT = 'R'
const val LEFT = 'L'

fun main(args: Array<String>) {
    var currentCoordinates = Coordinates(0, 0, 90)
    File(args[0]).readLines().map { parseInstruction(it) }
        .forEach { currentCoordinates = moveShipScalar(currentCoordinates, it) }

    println("Manhattan distance: ${abs(currentCoordinates.x) + abs(currentCoordinates.y)}")
}

fun parseInstruction(instruction: String): Pair<Char, Int> {
    val matcher = Pattern.compile("(\\w){1}(\\d+)").matcher(instruction)

    matcher.matches()
    return Pair(matcher.group(1)[0], matcher.group(2).toInt())
}

fun moveShipScalar(startingCoordinates: Coordinates, instruction: Pair<Char, Int>): Coordinates {
    return when (instruction.first) {
        FORWARD -> {
            return when (startingCoordinates.orientation) {
                0 -> Coordinates(startingCoordinates.x, startingCoordinates.y + instruction.second, startingCoordinates.orientation)
                90 -> Coordinates(startingCoordinates.x + instruction.second, startingCoordinates.y, startingCoordinates.orientation)
                180 -> Coordinates(startingCoordinates.x, startingCoordinates.y - instruction.second, startingCoordinates.orientation)
                270 -> Coordinates(startingCoordinates.x - instruction.second, startingCoordinates.y, startingCoordinates.orientation)
                else -> throw Exception()
            }
        }
        NORTH -> Coordinates(startingCoordinates.x, startingCoordinates.y + instruction.second, startingCoordinates.orientation)
        SOUTH -> Coordinates(startingCoordinates.x, startingCoordinates.y - instruction.second, startingCoordinates.orientation)
        EAST -> Coordinates(startingCoordinates.x + instruction.second, startingCoordinates.y, startingCoordinates.orientation)
        WEST -> Coordinates(startingCoordinates.x - instruction.second, startingCoordinates.y, startingCoordinates.orientation)
        RIGHT -> Coordinates(startingCoordinates.x, startingCoordinates.y, (startingCoordinates.orientation + instruction.second) % 360)
        LEFT -> {
            var newOrientation = startingCoordinates.orientation - instruction.second

            if (newOrientation < 0) {
                newOrientation += 360
            }
            Coordinates(startingCoordinates.x, startingCoordinates.y, newOrientation)
        }
        else -> throw Exception()
    }
}

data class Coordinates(
    val x: Long,
    val y: Long,
    val orientation: Int
)

Compiled from "Day12a.kt"
public final class com.marcdenning.adventofcode.day12.Day12aKt {
  public static final char FORWARD;

  public static final char NORTH;

  public static final char SOUTH;

  public static final char EAST;

  public static final char WEST;

  public static final char RIGHT;

  public static final char LEFT;

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aconst_null
       7: astore_1
       8: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
      11: dup
      12: lconst_0
      13: lconst_0
      14: bipush        90
      16: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
      19: astore_1
      20: new           #23                 // class java/io/File
      23: dup
      24: aload_0
      25: iconst_0
      26: aaload
      27: invokespecial #26                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      30: aconst_null
      31: iconst_1
      32: aconst_null
      33: invokestatic  #32                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      36: checkcast     #34                 // class java/lang/Iterable
      39: astore_2
      40: iconst_0
      41: istore_3
      42: aload_2
      43: astore        4
      45: new           #36                 // class java/util/ArrayList
      48: dup
      49: aload_2
      50: bipush        10
      52: invokestatic  #42                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      55: invokespecial #45                 // Method java/util/ArrayList."<init>":(I)V
      58: checkcast     #47                 // class java/util/Collection
      61: astore        5
      63: iconst_0
      64: istore        6
      66: aload         4
      68: invokeinterface #51,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      73: astore        7
      75: aload         7
      77: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      82: ifeq          125
      85: aload         7
      87: invokeinterface #61,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      92: astore        8
      94: aload         5
      96: aload         8
      98: checkcast     #63                 // class java/lang/String
     101: astore        9
     103: astore        11
     105: iconst_0
     106: istore        10
     108: aload         9
     110: invokestatic  #67                 // Method parseInstruction:(Ljava/lang/String;)Lkotlin/Pair;
     113: aload         11
     115: swap
     116: invokeinterface #71,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     121: pop
     122: goto          75
     125: aload         5
     127: checkcast     #73                 // class java/util/List
     130: nop
     131: checkcast     #34                 // class java/lang/Iterable
     134: astore_2
     135: nop
     136: iconst_0
     137: istore_3
     138: aload_2
     139: invokeinterface #51,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     144: astore        4
     146: aload         4
     148: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     153: ifeq          186
     156: aload         4
     158: invokeinterface #61,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     163: astore        5
     165: aload         5
     167: checkcast     #75                 // class kotlin/Pair
     170: astore        6
     172: iconst_0
     173: istore        7
     175: aload_1
     176: aload         6
     178: invokestatic  #79                 // Method moveShipScalar:(Lcom/marcdenning/adventofcode/day12/Coordinates;Lkotlin/Pair;)Lcom/marcdenning/adventofcode/day12/Coordinates;
     181: astore_1
     182: nop
     183: goto          146
     186: nop
     187: new           #81                 // class java/lang/StringBuilder
     190: dup
     191: invokespecial #84                 // Method java/lang/StringBuilder."<init>":()V
     194: ldc           #86                 // String Manhattan distance:
     196: invokevirtual #90                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     199: aload_1
     200: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     203: invokestatic  #100                // Method java/lang/Math.abs:(J)J
     206: aload_1
     207: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     210: invokestatic  #100                // Method java/lang/Math.abs:(J)J
     213: ladd
     214: invokevirtual #106                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     217: invokevirtual #110                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     220: getstatic     #116                // Field java/lang/System.out:Ljava/io/PrintStream;
     223: swap
     224: invokevirtual #122                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     227: return

  public static final kotlin.Pair<java.lang.Character, java.lang.Integer> parseInstruction(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #146                // String instruction
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #148                // String (\\w){1}(\\d+)
       8: invokestatic  #154                // Method java/util/regex/Pattern.compile:(Ljava/lang/String;)Ljava/util/regex/Pattern;
      11: aload_0
      12: checkcast     #156                // class java/lang/CharSequence
      15: invokevirtual #160                // Method java/util/regex/Pattern.matcher:(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;
      18: astore_1
      19: aload_1
      20: invokevirtual #165                // Method java/util/regex/Matcher.matches:()Z
      23: pop
      24: new           #75                 // class kotlin/Pair
      27: dup
      28: aload_1
      29: iconst_1
      30: invokevirtual #169                // Method java/util/regex/Matcher.group:(I)Ljava/lang/String;
      33: iconst_0
      34: invokevirtual #173                // Method java/lang/String.charAt:(I)C
      37: invokestatic  #179                // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      40: aload_1
      41: iconst_2
      42: invokevirtual #169                // Method java/util/regex/Matcher.group:(I)Ljava/lang/String;
      45: dup
      46: ldc           #181                // String group(...)
      48: invokestatic  #184                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      51: invokestatic  #190                // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      54: invokestatic  #193                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      57: invokespecial #196                // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      60: areturn

  public static final com.marcdenning.adventofcode.day12.Coordinates moveShipScalar(com.marcdenning.adventofcode.day12.Coordinates, kotlin.Pair<java.lang.Character, java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #200                // String startingCoordinates
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #146                // String instruction
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_1
      13: invokevirtual #203                // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
      16: checkcast     #175                // class java/lang/Character
      19: invokevirtual #207                // Method java/lang/Character.charValue:()C
      22: lookupswitch  { // 7
                    69: 343
                    70: 88
                    76: 446
                    78: 277
                    82: 409
                    83: 310
                    87: 376
               default: 491
          }
      88: aload_0
      89: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
      92: lookupswitch  { // 4
                     0: 136
                    90: 169
                   180: 202
                   270: 235
               default: 268
          }
     136: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     139: dup
     140: aload_0
     141: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     144: aload_0
     145: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     148: aload_1
     149: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     152: checkcast     #216                // class java/lang/Number
     155: invokevirtual #219                // Method java/lang/Number.longValue:()J
     158: ladd
     159: aload_0
     160: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     163: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     166: goto          276
     169: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     172: dup
     173: aload_0
     174: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     177: aload_1
     178: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     181: checkcast     #216                // class java/lang/Number
     184: invokevirtual #219                // Method java/lang/Number.longValue:()J
     187: ladd
     188: aload_0
     189: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     192: aload_0
     193: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     196: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     199: goto          276
     202: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     205: dup
     206: aload_0
     207: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     210: aload_0
     211: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     214: aload_1
     215: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     218: checkcast     #216                // class java/lang/Number
     221: invokevirtual #219                // Method java/lang/Number.longValue:()J
     224: lsub
     225: aload_0
     226: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     229: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     232: goto          276
     235: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     238: dup
     239: aload_0
     240: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     243: aload_1
     244: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     247: checkcast     #216                // class java/lang/Number
     250: invokevirtual #219                // Method java/lang/Number.longValue:()J
     253: lsub
     254: aload_0
     255: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     258: aload_0
     259: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     262: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     265: goto          276
     268: new           #221                // class java/lang/Exception
     271: dup
     272: invokespecial #222                // Method java/lang/Exception."<init>":()V
     275: athrow
     276: areturn
     277: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     280: dup
     281: aload_0
     282: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     285: aload_0
     286: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     289: aload_1
     290: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     293: checkcast     #216                // class java/lang/Number
     296: invokevirtual #219                // Method java/lang/Number.longValue:()J
     299: ladd
     300: aload_0
     301: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     304: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     307: goto          499
     310: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     313: dup
     314: aload_0
     315: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     318: aload_0
     319: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     322: aload_1
     323: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     326: checkcast     #216                // class java/lang/Number
     329: invokevirtual #219                // Method java/lang/Number.longValue:()J
     332: lsub
     333: aload_0
     334: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     337: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     340: goto          499
     343: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     346: dup
     347: aload_0
     348: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     351: aload_1
     352: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     355: checkcast     #216                // class java/lang/Number
     358: invokevirtual #219                // Method java/lang/Number.longValue:()J
     361: ladd
     362: aload_0
     363: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     366: aload_0
     367: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     370: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     373: goto          499
     376: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     379: dup
     380: aload_0
     381: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     384: aload_1
     385: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     388: checkcast     #216                // class java/lang/Number
     391: invokevirtual #219                // Method java/lang/Number.longValue:()J
     394: lsub
     395: aload_0
     396: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     399: aload_0
     400: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     403: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     406: goto          499
     409: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     412: dup
     413: aload_0
     414: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     417: aload_0
     418: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     421: aload_0
     422: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     425: aload_1
     426: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     429: checkcast     #216                // class java/lang/Number
     432: invokevirtual #225                // Method java/lang/Number.intValue:()I
     435: iadd
     436: sipush        360
     439: irem
     440: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     443: goto          499
     446: aload_0
     447: invokevirtual #211                // Method com/marcdenning/adventofcode/day12/Coordinates.getOrientation:()I
     450: aload_1
     451: invokevirtual #214                // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     454: checkcast     #216                // class java/lang/Number
     457: invokevirtual #225                // Method java/lang/Number.intValue:()I
     460: isub
     461: istore_2
     462: iload_2
     463: ifge          472
     466: iload_2
     467: sipush        360
     470: iadd
     471: istore_2
     472: new           #17                 // class com/marcdenning/adventofcode/day12/Coordinates
     475: dup
     476: aload_0
     477: invokevirtual #94                 // Method com/marcdenning/adventofcode/day12/Coordinates.getX:()J
     480: aload_0
     481: invokevirtual #103                // Method com/marcdenning/adventofcode/day12/Coordinates.getY:()J
     484: iload_2
     485: invokespecial #21                 // Method com/marcdenning/adventofcode/day12/Coordinates."<init>":(JJI)V
     488: goto          499
     491: new           #221                // class java/lang/Exception
     494: dup
     495: invokespecial #222                // Method java/lang/Exception."<init>":()V
     498: athrow
     499: areturn
}


package com.marcdenning.adventofcode.day05

import java.io.File
import java.util.*
import java.util.regex.MatchResult
import java.util.stream.Stream

private const val NUMBER_OF_ROWS = 128
private const val NUMBER_OF_COLUMNS = 8

fun main(args: Array<String>) {
    Scanner(File(args[0])).use { scanner ->
        val maxSeatId = scanner.findAll("[BF]{7}[LR]{3}")
            .map(::getSeatId)
            .max { o1, o2 -> o1 - o2 }
            .orElseThrow()

        println("Max seat ID: $maxSeatId")
    }
}

fun extractRow(seat: String) = seat.substring(0..6)

fun extractColumn(seat: String) = seat.substring(7..9)

fun determineRow(specifier: String, index: Int, lower: Int, upper: Int): Int {
    if (index == specifier.length - 1) {
        return if (specifier[index] == 'F') lower else upper
    } else if (specifier[index] == 'F') {
        return determineRow(specifier, index + 1, lower, lower + ((upper - lower) / 2))
    } else {
        return determineRow(specifier, index + 1, upper - ((upper - lower) / 2), upper)
    }
}

fun determineColumn(specifier: String, index: Int, lower: Int, upper: Int): Int {
    if (index == specifier.length - 1) {
        return if (specifier[index] == 'L') lower else upper
    } else if (specifier[index] == 'L') {
        return determineColumn(specifier, index + 1, lower, lower + ((upper - lower) / 2))
    } else {
        return determineColumn(specifier, index + 1, upper - ((upper - lower) / 2), upper)
    }
}

fun getSeatId(matchResult: MatchResult): Int {
    val rowId = extractRow(matchResult.group())
    val columnId = extractColumn(matchResult.group())

    return 8 * determineRow(rowId, 0, 0, NUMBER_OF_ROWS - 1) +
            determineColumn(columnId, 0, 0, NUMBER_OF_COLUMNS - 1)
}

Compiled from "Day05a.kt"
final class com.marcdenning.adventofcode.day05.Day05aKt$main$1$maxSeatId$1 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function1<java.util.regex.MatchResult, java.lang.Integer> {
  public static final com.marcdenning.adventofcode.day05.Day05aKt$main$1$maxSeatId$1 INSTANCE;

  com.marcdenning.adventofcode.day05.Day05aKt$main$1$maxSeatId$1();
    Code:
       0: aload_0
       1: iconst_1
       2: ldc           #11                 // class com/marcdenning/adventofcode/day05/Day05aKt
       4: ldc           #13                 // String getSeatId
       6: ldc           #15                 // String getSeatId(Ljava/util/regex/MatchResult;)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.regex.MatchResult);
    Code:
       0: aload_1
       1: ldc           #24                 // String p0
       3: invokestatic  #30                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokestatic  #33                 // Method com/marcdenning/adventofcode/day05/Day05aKt.getSeatId:(Ljava/util/regex/MatchResult;)I
      10: invokestatic  #39                 // 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     #43                 // class java/util/regex/MatchResult
       5: invokevirtual #45                 // Method invoke:(Ljava/util/regex/MatchResult;)Ljava/lang/Integer;
       8: areturn

  static {};
    Code:
       0: new           #2                  // class com/marcdenning/adventofcode/day05/Day05aKt$main$1$maxSeatId$1
       3: dup
       4: invokespecial #50                 // Method "<init>":()V
       7: putstatic     #53                 // Field INSTANCE:Lcom/marcdenning/adventofcode/day05/Day05aKt$main$1$maxSeatId$1;
      10: return
}

Compiled from "Day05a.kt"
public final class com.marcdenning.adventofcode.day05.Day05aKt {
  private static final int NUMBER_OF_ROWS;

  private static final int NUMBER_OF_COLUMNS;

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #11                 // String args
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #19                 // class java/util/Scanner
       9: dup
      10: new           #21                 // class java/io/File
      13: dup
      14: aload_0
      15: iconst_0
      16: aaload
      17: invokespecial #25                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      20: invokespecial #28                 // Method java/util/Scanner."<init>":(Ljava/io/File;)V
      23: checkcast     #30                 // class java/io/Closeable
      26: astore_1
      27: aconst_null
      28: astore_2
      29: nop
      30: aload_1
      31: checkcast     #19                 // class java/util/Scanner
      34: astore_3
      35: iconst_0
      36: istore        4
      38: aload_3
      39: ldc           #32                 // String [BF]{7}[LR]{3}
      41: invokevirtual #36                 // Method java/util/Scanner.findAll:(Ljava/lang/String;)Ljava/util/stream/Stream;
      44: getstatic     #42                 // Field com/marcdenning/adventofcode/day05/Day05aKt$main$1$maxSeatId$1.INSTANCE:Lcom/marcdenning/adventofcode/day05/Day05aKt$main$1$maxSeatId$1;
      47: checkcast     #44                 // class kotlin/jvm/functions/Function1
      50: invokedynamic #64,  0             // InvokeDynamic #0:apply:(Lkotlin/jvm/functions/Function1;)Ljava/util/function/Function;
      55: invokeinterface #70,  2           // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
      60: invokedynamic #83,  0             // InvokeDynamic #1:invoke:()Lkotlin/jvm/functions/Function2;
      65: invokedynamic #94,  0             // InvokeDynamic #2:compare:(Lkotlin/jvm/functions/Function2;)Ljava/util/Comparator;
      70: invokeinterface #98,  2           // InterfaceMethod java/util/stream/Stream.max:(Ljava/util/Comparator;)Ljava/util/Optional;
      75: invokevirtual #104                // Method java/util/Optional.orElseThrow:()Ljava/lang/Object;
      78: checkcast     #106                // class java/lang/Integer
      81: astore        5
      83: new           #108                // class java/lang/StringBuilder
      86: dup
      87: invokespecial #111                // Method java/lang/StringBuilder."<init>":()V
      90: ldc           #113                // String Max seat ID:
      92: invokevirtual #117                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      95: aload         5
      97: invokevirtual #120                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     100: invokevirtual #124                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     103: getstatic     #130                // Field java/lang/System.out:Ljava/io/PrintStream;
     106: swap
     107: invokevirtual #136                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     110: nop
     111: getstatic     #141                // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
     114: astore_3
     115: aload_1
     116: aload_2
     117: invokestatic  #147                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     120: goto          141
     123: astore        4
     125: aload         4
     127: astore_2
     128: aload         4
     130: athrow
     131: astore        4
     133: aload_1
     134: aload_2
     135: invokestatic  #147                // Method kotlin/io/CloseableKt.closeFinally:(Ljava/io/Closeable;Ljava/lang/Throwable;)V
     138: aload         4
     140: athrow
     141: return
    Exception table:
       from    to  target type
          29   115   123   Class java/lang/Throwable
          29   115   131   any
         123   131   131   any
         131   133   131   any

  public static final java.lang.String extractRow(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #159                // String seat
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: new           #161                // class kotlin/ranges/IntRange
      10: dup
      11: iconst_0
      12: bipush        6
      14: invokespecial #164                // Method kotlin/ranges/IntRange."<init>":(II)V
      17: invokestatic  #170                // Method kotlin/text/StringsKt.substring:(Ljava/lang/String;Lkotlin/ranges/IntRange;)Ljava/lang/String;
      20: areturn

  public static final java.lang.String extractColumn(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #159                // String seat
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: new           #161                // class kotlin/ranges/IntRange
      10: dup
      11: bipush        7
      13: bipush        9
      15: invokespecial #164                // Method kotlin/ranges/IntRange."<init>":(II)V
      18: invokestatic  #170                // Method kotlin/text/StringsKt.substring:(Ljava/lang/String;Lkotlin/ranges/IntRange;)Ljava/lang/String;
      21: areturn

  public static final int determineRow(java.lang.String, int, int, int);
    Code:
       0: aload_0
       1: ldc           #176                // String specifier
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: aload_0
       8: invokevirtual #182                // Method java/lang/String.length:()I
      11: iconst_1
      12: isub
      13: if_icmpne     32
      16: aload_0
      17: iload_1
      18: invokevirtual #186                // Method java/lang/String.charAt:(I)C
      21: bipush        70
      23: if_icmpne     30
      26: iload_2
      27: goto          31
      30: iload_3
      31: ireturn
      32: aload_0
      33: iload_1
      34: invokevirtual #186                // Method java/lang/String.charAt:(I)C
      37: bipush        70
      39: if_icmpne     58
      42: aload_0
      43: iload_1
      44: iconst_1
      45: iadd
      46: iload_2
      47: iload_2
      48: iload_3
      49: iload_2
      50: isub
      51: iconst_2
      52: idiv
      53: iadd
      54: invokestatic  #188                // Method determineRow:(Ljava/lang/String;III)I
      57: ireturn
      58: aload_0
      59: iload_1
      60: iconst_1
      61: iadd
      62: iload_3
      63: iload_3
      64: iload_2
      65: isub
      66: iconst_2
      67: idiv
      68: isub
      69: iload_3
      70: invokestatic  #188                // Method determineRow:(Ljava/lang/String;III)I
      73: ireturn

  public static final int determineColumn(java.lang.String, int, int, int);
    Code:
       0: aload_0
       1: ldc           #176                // String specifier
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: aload_0
       8: invokevirtual #182                // Method java/lang/String.length:()I
      11: iconst_1
      12: isub
      13: if_icmpne     32
      16: aload_0
      17: iload_1
      18: invokevirtual #186                // Method java/lang/String.charAt:(I)C
      21: bipush        76
      23: if_icmpne     30
      26: iload_2
      27: goto          31
      30: iload_3
      31: ireturn
      32: aload_0
      33: iload_1
      34: invokevirtual #186                // Method java/lang/String.charAt:(I)C
      37: bipush        76
      39: if_icmpne     58
      42: aload_0
      43: iload_1
      44: iconst_1
      45: iadd
      46: iload_2
      47: iload_2
      48: iload_3
      49: iload_2
      50: isub
      51: iconst_2
      52: idiv
      53: iadd
      54: invokestatic  #194                // Method determineColumn:(Ljava/lang/String;III)I
      57: ireturn
      58: aload_0
      59: iload_1
      60: iconst_1
      61: iadd
      62: iload_3
      63: iload_3
      64: iload_2
      65: isub
      66: iconst_2
      67: idiv
      68: isub
      69: iload_3
      70: invokestatic  #194                // Method determineColumn:(Ljava/lang/String;III)I
      73: ireturn

  public static final int getSeatId(java.util.regex.MatchResult);
    Code:
       0: aload_0
       1: ldc           #198                // String matchResult
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokeinterface #203,  1          // InterfaceMethod java/util/regex/MatchResult.group:()Ljava/lang/String;
      12: dup
      13: ldc           #205                // String group(...)
      15: invokestatic  #208                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      18: invokestatic  #210                // Method extractRow:(Ljava/lang/String;)Ljava/lang/String;
      21: astore_1
      22: aload_0
      23: invokeinterface #203,  1          // InterfaceMethod java/util/regex/MatchResult.group:()Ljava/lang/String;
      28: dup
      29: ldc           #205                // String group(...)
      31: invokestatic  #208                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      34: invokestatic  #212                // Method extractColumn:(Ljava/lang/String;)Ljava/lang/String;
      37: astore_2
      38: bipush        8
      40: aload_1
      41: iconst_0
      42: iconst_0
      43: bipush        127
      45: invokestatic  #188                // Method determineRow:(Ljava/lang/String;III)I
      48: imul
      49: aload_2
      50: iconst_0
      51: iconst_0
      52: bipush        7
      54: invokestatic  #194                // Method determineColumn:(Ljava/lang/String;III)I
      57: iadd
      58: ireturn

  private static final java.lang.Integer main$lambda$3$lambda$0(kotlin.jvm.functions.Function1, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: invokeinterface #217,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
       7: checkcast     #106                // class java/lang/Integer
      10: areturn

  private static final int main$lambda$3$lambda$1(java.lang.Integer, java.lang.Integer);
    Code:
       0: aload_0
       1: invokevirtual #224                // Method java/lang/Integer.intValue:()I
       4: aload_1
       5: invokestatic  #227                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
       8: aload_1
       9: invokevirtual #224                // Method java/lang/Integer.intValue:()I
      12: isub
      13: ireturn

  private static final int main$lambda$3$lambda$2(kotlin.jvm.functions.Function2, java.lang.Object, java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: aload_2
       3: invokeinterface #233,  3          // InterfaceMethod kotlin/jvm/functions/Function2.invoke:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
       8: checkcast     #235                // class java/lang/Number
      11: invokevirtual #236                // Method java/lang/Number.intValue:()I
      14: ireturn
}


package com.marcdenning.adventofcode.day18

import java.io.File

fun main(args: Array<String>) {
    val sum = File(args[0]).readLines().map { evaluateExpressionInverse(it) }.sum()

    println("Sum of all operations: $sum")
}

fun evaluateExpressionInverse(expression: String) = evaluateExpressionTree(buildTreeFromExpression(expression))

fun buildTreeFromExpression(expression: String): ExpressionNode {
    val expressionTree = ExpressionNode('+', ExpressionNode('0'))
    var currentNode = expressionTree

    for (char in expression) {
        if (char != ' ') {
            currentNode = currentNode.addChar(char)
        }
    }
    return expressionTree
}

fun evaluateExpressionTree(node: ExpressionNode): Long {
    if (node.left == null && node.right == null) {
        return ("" + node.char).toLong()
    }
    return when (node.char) {
        '+' -> evaluateExpressionTree(node.left!!) + evaluateExpressionTree(node.right!!)
        '*' -> evaluateExpressionTree(node.left!!) * evaluateExpressionTree(node.right!!)
        else -> throw Exception()
    }
}

data class ExpressionNode(
    var char: Char,
    var left: ExpressionNode? = null,
    var right: ExpressionNode? = null
) {
    fun addChar(newChar: Char): ExpressionNode {
        return when {
            char.isDigit() && (newChar == '+' || newChar == '*') -> {
                left = ExpressionNode(char)
                char = newChar
                this
            }
            (char == '+' || char == '*') && (newChar.isDigit() || newChar == '(') -> {
                right = ExpressionNode(newChar)
                right!!
            }
            char == '(' && newChar.isDigit() -> {
                left = ExpressionNode(newChar)
                this
            }
            char == '(' && (newChar == '+' || newChar == '*') -> {
                char = newChar
                this
            }
            newChar == ')' -> this
            else -> throw Exception()
        }
    }
}

Compiled from "Day18b.kt"
public final class com.marcdenning.adventofcode.day18.Day18bKt {
  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #9                  // String args
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #17                 // class java/io/File
       9: dup
      10: aload_0
      11: iconst_0
      12: aaload
      13: invokespecial #21                 // Method java/io/File."<init>":(Ljava/lang/String;)V
      16: aconst_null
      17: iconst_1
      18: aconst_null
      19: invokestatic  #27                 // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      22: checkcast     #29                 // class java/lang/Iterable
      25: astore_3
      26: iconst_0
      27: istore        4
      29: aload_3
      30: astore        5
      32: new           #31                 // class java/util/ArrayList
      35: dup
      36: aload_3
      37: bipush        10
      39: invokestatic  #37                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      42: invokespecial #40                 // Method java/util/ArrayList."<init>":(I)V
      45: checkcast     #42                 // class java/util/Collection
      48: astore        6
      50: iconst_0
      51: istore        7
      53: aload         5
      55: invokeinterface #46,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      60: astore        8
      62: aload         8
      64: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      69: ifeq          115
      72: aload         8
      74: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      79: astore        9
      81: aload         6
      83: aload         9
      85: checkcast     #58                 // class java/lang/String
      88: astore        10
      90: astore        12
      92: iconst_0
      93: istore        11
      95: aload         10
      97: invokestatic  #62                 // Method evaluateExpressionInverse:(Ljava/lang/String;)J
     100: invokestatic  #68                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     103: aload         12
     105: swap
     106: invokeinterface #72,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     111: pop
     112: goto          62
     115: aload         6
     117: checkcast     #74                 // class java/util/List
     120: nop
     121: checkcast     #29                 // class java/lang/Iterable
     124: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.sumOfLong:(Ljava/lang/Iterable;)J
     127: lstore_1
     128: new           #80                 // class java/lang/StringBuilder
     131: dup
     132: invokespecial #83                 // Method java/lang/StringBuilder."<init>":()V
     135: ldc           #85                 // String Sum of all operations:
     137: invokevirtual #89                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     140: lload_1
     141: invokevirtual #92                 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     144: invokevirtual #96                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     147: getstatic     #102                // Field java/lang/System.out:Ljava/io/PrintStream;
     150: swap
     151: invokevirtual #108                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     154: return

  public static final long evaluateExpressionInverse(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #127                // String expression
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #131                // Method buildTreeFromExpression:(Ljava/lang/String;)Lcom/marcdenning/adventofcode/day18/ExpressionNode;
      10: invokestatic  #135                // Method evaluateExpressionTree:(Lcom/marcdenning/adventofcode/day18/ExpressionNode;)J
      13: lreturn

  public static final com.marcdenning.adventofcode.day18.ExpressionNode buildTreeFromExpression(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #127                // String expression
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #137                // class com/marcdenning/adventofcode/day18/ExpressionNode
       9: dup
      10: bipush        43
      12: new           #137                // class com/marcdenning/adventofcode/day18/ExpressionNode
      15: dup
      16: bipush        48
      18: aconst_null
      19: aconst_null
      20: bipush        6
      22: aconst_null
      23: invokespecial #140                // Method com/marcdenning/adventofcode/day18/ExpressionNode."<init>":(CLcom/marcdenning/adventofcode/day18/ExpressionNode;Lcom/marcdenning/adventofcode/day18/ExpressionNode;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      26: aconst_null
      27: iconst_4
      28: aconst_null
      29: invokespecial #140                // Method com/marcdenning/adventofcode/day18/ExpressionNode."<init>":(CLcom/marcdenning/adventofcode/day18/ExpressionNode;Lcom/marcdenning/adventofcode/day18/ExpressionNode;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      32: astore_1
      33: aload_1
      34: astore_2
      35: iconst_0
      36: istore_3
      37: aload_0
      38: invokevirtual #144                // Method java/lang/String.length:()I
      41: istore        4
      43: iload_3
      44: iload         4
      46: if_icmpge     76
      49: aload_0
      50: iload_3
      51: invokevirtual #148                // Method java/lang/String.charAt:(I)C
      54: istore        5
      56: iload         5
      58: bipush        32
      60: if_icmpeq     70
      63: aload_2
      64: iload         5
      66: invokevirtual #152                // Method com/marcdenning/adventofcode/day18/ExpressionNode.addChar:(C)Lcom/marcdenning/adventofcode/day18/ExpressionNode;
      69: astore_2
      70: iinc          3, 1
      73: goto          43
      76: aload_1
      77: areturn

  public static final long evaluateExpressionTree(com.marcdenning.adventofcode.day18.ExpressionNode);
    Code:
       0: aload_0
       1: ldc           #159                // String node
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #163                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getLeft:()Lcom/marcdenning/adventofcode/day18/ExpressionNode;
      10: ifnonnull     46
      13: aload_0
      14: invokevirtual #166                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getRight:()Lcom/marcdenning/adventofcode/day18/ExpressionNode;
      17: ifnonnull     46
      20: new           #80                 // class java/lang/StringBuilder
      23: dup
      24: invokespecial #83                 // Method java/lang/StringBuilder."<init>":()V
      27: ldc           #168                // String
      29: invokevirtual #89                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      32: aload_0
      33: invokevirtual #172                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getChar:()C
      36: invokevirtual #175                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      39: invokevirtual #96                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      42: invokestatic  #178                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
      45: lreturn
      46: aload_0
      47: invokevirtual #172                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getChar:()C
      50: tableswitch   { // 42 to 43
                    42: 98
                    43: 72
               default: 124
          }
      72: aload_0
      73: invokevirtual #163                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getLeft:()Lcom/marcdenning/adventofcode/day18/ExpressionNode;
      76: dup
      77: invokestatic  #181                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      80: invokestatic  #135                // Method evaluateExpressionTree:(Lcom/marcdenning/adventofcode/day18/ExpressionNode;)J
      83: aload_0
      84: invokevirtual #166                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getRight:()Lcom/marcdenning/adventofcode/day18/ExpressionNode;
      87: dup
      88: invokestatic  #181                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      91: invokestatic  #135                // Method evaluateExpressionTree:(Lcom/marcdenning/adventofcode/day18/ExpressionNode;)J
      94: ladd
      95: goto          132
      98: aload_0
      99: invokevirtual #163                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getLeft:()Lcom/marcdenning/adventofcode/day18/ExpressionNode;
     102: dup
     103: invokestatic  #181                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     106: invokestatic  #135                // Method evaluateExpressionTree:(Lcom/marcdenning/adventofcode/day18/ExpressionNode;)J
     109: aload_0
     110: invokevirtual #166                // Method com/marcdenning/adventofcode/day18/ExpressionNode.getRight:()Lcom/marcdenning/adventofcode/day18/ExpressionNode;
     113: dup
     114: invokestatic  #181                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     117: invokestatic  #135                // Method evaluateExpressionTree:(Lcom/marcdenning/adventofcode/day18/ExpressionNode;)J
     120: lmul
     121: goto          132
     124: new           #183                // class java/lang/Exception
     127: dup
     128: invokespecial #184                // Method java/lang/Exception."<init>":()V
     131: athrow
     132: lreturn
}