Scala algorithm: Mars Rover
Published
Algorithm goal
The Mars rover receives commands one at a time: Move, turn Left, turn Right. Moving means you move by 1 cell in the direction you are facing, and turning means changing the direction you are facing, but not moving.
Create a program to model this in order to compute the current position and heading after accepting a sequence of commands.
As starting state, you receive the position (x, y), and the facing. As output, you also receive that.
Test cases in Scala
assert(
RoverState(x = 1, y = 2, facing = Facing.N).accept(Command.M) ==
RoverState(x = 1, y = 1, facing = Facing.N)
)
assert(
RoverState(x = 1, y = 2, facing = Facing.E).accept(Command.M) ==
RoverState(x = 2, y = 2, facing = Facing.E)
)
assert(
RoverState(x = 1, y = 2, facing = Facing.S).accept(Command.M) ==
RoverState(x = 1, y = 3, facing = Facing.S)
)
assert(
RoverState(x = 1, y = 2, facing = Facing.W).accept(Command.M) ==
RoverState(x = 0, y = 2, facing = Facing.W)
)
assert(
RoverState(x = 1, y = 2, facing = Facing.W)
.accept(Command.M)
.accept(Command.L) == RoverState(x = 0, y = 2, facing = Facing.S)
)
assert(
RoverState(x = 1, y = 2, facing = Facing.W)
.accept(Command.M)
.accept(Command.L)
.accept(Command.M) ==
RoverState(x = 0, y = 3, facing = Facing.S)
)
assert(
RoverState(x = 1, y = 2, facing = Facing.W)
.accept(Command.M)
.accept(Command.L)
.accept(Command.M)
.renderString == "0 3 S"
)
Algorithm in Scala
34 lines of Scala (compatible versions 2.13 & 3.0), showing how concise Scala can be!
Explanation
This is more of a modelling challenge: how do you best model in Scala for comprehension?
A sealed abstract class is a great way to represent a set of possibilities with their own pre-defined values. Similar to Java enum but with several differences in terms of type safety: you can limit who can extend this class by marking it as sealed. (this is © from www.scala-algorithms.com)
Another concept applied heavily is immutability, such that we never modify the existing object, only emit new ones. As such, testing becomes significantly easier and more obvious
Scala concepts & Hints
Pattern Matching
Pattern matching in Scala lets you quickly identify what you are looking for in a data, and also extract it.
State machine
A state machine is the use of `sealed trait` to represent all the possible states (and transitions) of a 'machine' in a hierarchical form.