-
-
Save waynejo/d97585f8134cb6dde831033793f89feb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.FileInputStream | |
import scala.io.StdIn | |
@main def solve12() = | |
enum Direction(val degree: Int, val dx: Int, val dy: Int) { | |
case north extends Direction(0, 0, 1) | |
case south extends Direction(180, 0, -1) | |
case east extends Direction(90, 1, 0) | |
case west extends Direction(270, -1, 0) | |
def rotate(degree: Int): Direction = { | |
val rotatedDegree = (this.degree + (degree + 360)) % 360 | |
rotatedDegree match { | |
case 0 => | |
Direction.north | |
case 90 => | |
Direction.east | |
case 180 => | |
Direction.south | |
case 270 => | |
Direction.west | |
} | |
} | |
} | |
enum Code { | |
case north | |
case south | |
case east | |
case west | |
case left | |
case right | |
case forward | |
} | |
case class Command(code: Code, operand: Int) | |
case class Ship(direction: Direction = Direction.east, x: Int = 0, y: Int = 0) | |
case class Waypoint(x: Int = 10, y: Int = 1) { | |
def rotate(degree: Int): Waypoint = { | |
(degree + 360) % 360 match { | |
case 0 => | |
this | |
case 90 => | |
Waypoint(x = y, y = -x) | |
case 180 => | |
Waypoint(x = -x, y = -y) | |
case 270 => | |
Waypoint(x = -y, y = x) | |
} | |
} | |
} | |
object Command { | |
def apply(line: String): Command = { | |
val code = line.head match { | |
case 'N' => | |
Code.north | |
case 'S' => | |
Code.south | |
case 'E' => | |
Code.east | |
case 'W' => | |
Code.west | |
case 'L' => | |
Code.left | |
case 'R' => | |
Code.right | |
case 'F' => | |
Code.forward | |
} | |
val operand = line.tail.toInt | |
Command(code, operand) | |
} | |
} | |
def solve1(ship: Ship, commands: Vector[Command]): Int = { | |
commands.headOption match { | |
case Some(command) => | |
command.code match { | |
case Code.north => | |
solve1(ship.copy(y = ship.y + command.operand), commands.tail) | |
case Code.south => | |
solve1(ship.copy(y = ship.y - command.operand), commands.tail) | |
case Code.east => | |
solve1(ship.copy(x = ship.x + command.operand), commands.tail) | |
case Code.west => | |
solve1(ship.copy(x = ship.x - command.operand), commands.tail) | |
case Code.left => | |
solve1(ship.copy(direction = ship.direction.rotate(-command.operand)), commands.tail) | |
case Code.right => | |
solve1(ship.copy(direction = ship.direction.rotate(command.operand)), commands.tail) | |
case Code.forward => | |
val x = ship.x + ship.direction.dx * command.operand | |
val y = ship.y + ship.direction.dy * command.operand | |
solve1(ship.copy(x = x, y = y), commands.tail) | |
} | |
case _ => | |
ship.x.abs + ship.y.abs | |
} | |
} | |
def solve2(ship: Ship, waypoint: Waypoint, commands: Vector[Command]): Int = { | |
commands.headOption match { | |
case Some(command) => | |
command.code match { | |
case Code.north => | |
solve2(ship, waypoint.copy(y = waypoint.y + command.operand), commands.tail) | |
case Code.south => | |
solve2(ship, waypoint.copy(y = waypoint.y - command.operand), commands.tail) | |
case Code.east => | |
solve2(ship, waypoint.copy(x = waypoint.x + command.operand), commands.tail) | |
case Code.west => | |
solve2(ship, waypoint.copy(x = waypoint.x - command.operand), commands.tail) | |
case Code.left => | |
solve2(ship, waypoint.rotate(-command.operand), commands.tail) | |
case Code.right => | |
solve2(ship, waypoint.rotate(command.operand), commands.tail) | |
case Code.forward => | |
val x = ship.x + waypoint.x * command.operand | |
val y = ship.y + waypoint.y * command.operand | |
solve2(ship.copy(x = x, y = y), waypoint, commands.tail) | |
} | |
case _ => | |
ship.x.abs + ship.y.abs | |
} | |
} | |
val in = new FileInputStream("example12-1.in") | |
System.setIn(in) | |
val inputs = Iterator.continually(StdIn.readLine()).takeWhile(_ != null).toVector | |
val commands = inputs.map { line => Command(line) } | |
val answer1 = solve1(Ship(), commands) | |
println(answer1) | |
val answer2 = solve2(Ship(), Waypoint(), commands) | |
println(answer2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment