Created
March 18, 2014 02:08
-
-
Save UberMouse/9612311 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
package rover | |
/** | |
* Created by wyntl1 on 18/03/14. | |
*/ | |
class TurnDirection | |
case class Left() extends TurnDirection | |
case class Right() extends TurnDirection | |
abstract class Direction() { | |
def move(pos:Point, forward:Boolean):Point | |
def turn(dir:TurnDirection):Direction | |
} | |
case class North() extends Direction { | |
def move(pos:Point, forward:Boolean) = Point(pos.x, pos.y+(if(forward) 1 else -1)) | |
def turn(dir:TurnDirection) = dir match { | |
case Left() => West() | |
case Right() => East() | |
} | |
} | |
case class East() extends Direction { | |
def move(pos:Point, forward:Boolean) = Point(pos.x+(if(forward) 1 else -1), pos.y) | |
def turn(dir:TurnDirection) = dir match { | |
case Left() => North() | |
case Right() => South() | |
} | |
} | |
case class South() extends Direction { | |
def move(pos:Point, forward:Boolean) = Point(pos.x, pos.y-(if(forward) 1 else -1)) | |
def turn(dir:TurnDirection) = dir match { | |
case Left() => East() | |
case Right() => West() | |
} | |
} | |
case class West() extends Direction { | |
def move(pos:Point, forward:Boolean) = Point(pos.x-(if(forward) 1 else -1), pos.y) | |
def turn(dir:TurnDirection) = dir match { | |
case Left() => South() | |
case Right() => North() | |
} | |
} |
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
package rover | |
import scala.collection.mutable | |
/** | |
* Created by wyntl1 on 18/03/14. | |
*/ | |
case class Point(x:Int, y:Int) | |
case class Planet(height:Int, width:Int, obstacles:List[Point] = List[Point]()) | |
case class InvalidMove() extends Exception() | |
class Rover(val position:Point, val direction:Direction, val planet:Planet) { | |
def processCommands(commands:List[String]):(Rover, String) = { | |
val doneCommands = new mutable.Queue[String]() | |
val toProcessCommands = new mutable.Queue[String]() | |
commands.foreach(toProcessCommands.enqueue(_)) | |
try { | |
val rover = commands.map { | |
case "f" => moveForward _ | |
case "b" => moveBackward _ | |
case "l" => rotateLeft _ | |
case "r" => rotateRight _ | |
}.foldLeft(this) { case (rover, command) => | |
doneCommands.enqueue(toProcessCommands.dequeue()) | |
command(rover) | |
} | |
(rover, s"OK: ${doneCommands.mkString(" ")}") | |
} | |
catch { | |
case e:InvalidMove => return (this, s"NOK: ${toProcessCommands.mkString(" ")}") | |
} | |
} | |
def rotateLeft( r:Rover = this) = updateRover(r.position, dir = r.direction.turn(Left()), r.planet) | |
def rotateRight( r:Rover = this) = updateRover(r.position, dir = r.direction.turn(Right()), r.planet) | |
def moveForward( r:Rover = this) = updateRover(r.direction.move(r.position, forward = true), r.direction, r.planet) | |
def moveBackward(r:Rover = this) = updateRover(r.direction.move(r.position, forward = false), r.direction, r.planet) | |
private def updateRover(x:Int, y:Int, dir:Direction, p:Planet):Rover = { | |
if(p.obstacles.contains(Point(x, y))) throw new InvalidMove() | |
Rover(if(x <= p.width) x else x-p.width, | |
if(y <= p.height) y else y-p.height, | |
dir, | |
p) | |
} | |
private def updateRover(p:Point, dir:Direction, planet:Planet):Rover = updateRover(p.x, p.y, dir, planet) | |
override def toString = s"Rover($position, $direction)" | |
} | |
object Rover { | |
def apply(x:Int, y:Int, dir:Direction, p:Planet) = new Rover(Point(x, y), dir, p) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment