Created
October 2, 2020 01:03
-
-
Save nikolasrangel/89684043d1c33afe6646376415310ba3 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
defmodule RobotSimulator do | |
@doc """ | |
Create a Robot Simulator given an initial direction and position. | |
Valid directions are: `:north`, `:east`, `:south`, `:west` | |
""" | |
@valid_directions [:north, :south, :east, :west] | |
@spec create() :: {:north, {0,0}} | |
def create(), do: {:north, {0,0}} | |
@spec create(direction :: atom, position :: {integer, integer}) :: any | |
def create(direction, {x, y} = position) | |
when direction in @valid_directions and is_number(x) and is_number(y), | |
do: {direction, position} | |
def create(direction, _position) | |
when direction in @valid_directions, | |
do: {:error, "invalid position"} | |
# def create(direction, _position) | |
# when direction in @valid_directions, | |
# do: {:error, "invalid position"} | |
def create(_direction, _position), do: {:error, "invalid direction"} | |
@doc """ | |
Simulate the robot's movement given a string of instructions. | |
Valid instructions are: "R" (turn right), "L", (turn left), and "A" (advance) | |
""" | |
@spec simulate(robot :: any, instructions :: String.t()) :: any | |
def simulate(robot, "") do | |
robot | |
end | |
def simulate({:north, {x, y} = position}, instructions) do | |
{ command, rest } = String.split_at(instructions, 1) | |
case command do | |
"R" -> | |
simulate({:east, position}, rest) | |
"L" -> | |
simulate({:west, position}, rest) | |
"A" -> | |
simulate({:north, {x, y+1}}, rest) | |
_ -> | |
{:error, "invalid instruction"} | |
end | |
end | |
def simulate({:east, {x, y} = position}, instructions) do | |
{ command, rest } = String.split_at(instructions, 1) | |
case command do | |
"R" -> | |
simulate({:south, position}, rest) | |
"L" -> | |
simulate({:north, position}, rest) | |
"A" -> | |
simulate({:east, {x+1, y}}, rest) | |
_ -> | |
{:error, "invalid instruction"} | |
end | |
end | |
def simulate({:south, {x, y} = position}, instructions) do | |
{ command, rest } = String.split_at(instructions, 1) | |
case command do | |
"R" -> | |
simulate({:west, position}, rest) | |
"L" -> | |
simulate({:east, position}, rest) | |
"A" -> | |
simulate({:south, {x, y-1}}, rest) | |
_ -> | |
{:error, "invalid instruction"} | |
end | |
end | |
def simulate({:west, {x, y} = position}, instructions) do | |
{ command, rest } = String.split_at(instructions, 1) | |
case command do | |
"R" -> | |
simulate({:north, position}, rest) | |
"L" -> | |
simulate({:south, position}, rest) | |
"A" -> | |
simulate({:west, {x-1, y}}, rest) | |
_ -> | |
{:error, "invalid instruction"} | |
end | |
end | |
@doc """ | |
Return the robot's direction. | |
Valid directions are: `:north`, `:east`, `:south`, `:west` | |
""" | |
@spec direction(robot :: any) :: atom | |
def direction({ direction, _ }) do | |
direction | |
end | |
@doc """ | |
Return the robot's position. | |
""" | |
@spec position(robot :: any) :: {integer, integer} | |
def position({ _, position }) do | |
position | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment