Skip to content

Instantly share code, notes, and snippets.

@bjjb
Created January 13, 2020 12:44
Show Gist options
  • Save bjjb/5fbe4d572a56d185fb010beebd7be0c6 to your computer and use it in GitHub Desktop.
Save bjjb/5fbe4d572a56d185fb010beebd7be0c6 to your computer and use it in GitHub Desktop.
Mars Rover
#!/usr/bin/env python
from enum import Enum, IntEnum
from typing import Dict, Callable
import unittest
class Direction(IntEnum):
NORTH = 0
EAST = 1
SOUTH = 2
WEST = 3
def __str__(self) -> str:
return self.name
@property
def x(self) -> int:
if self in (Direction.NORTH, Direction.SOUTH):
return 0
return 1 if self == Direction.EAST else -1
@property
def y(self) -> int:
if self in (Direction.EAST, Direction.WEST):
return 0
return 1 if self == Direction.NORTH else -1
class TestDirection(unittest.TestCase):
def test_x_is_0_for_north_and_south(self):
self.assertEqual(0, Direction.NORTH.x)
self.assertEqual(0, Direction.SOUTH.x)
def test_x_is_1_for_east(self):
self.assertEqual(1, Direction.EAST.x)
def test_x_is_minus_1_for_west(self):
self.assertEqual(-1, Direction.WEST.x)
def test_y_is_0_for_east_and_west(self):
self.assertEqual(0, Direction.EAST.y)
self.assertEqual(0, Direction.WEST.y)
def test_y_is_1_for_north(self):
self.assertEqual(1, Direction.NORTH.y)
def test_y_is_minus_1_for_south(self):
self.assertEqual(-1, Direction.SOUTH.y)
def test_string_values(self):
self.assertEqual("NORTH", str(Direction.NORTH))
self.assertEqual("SOUTH", str(Direction.SOUTH))
self.assertEqual("EAST", str(Direction.EAST))
self.assertEqual("WEST", str(Direction.WEST))
class Command(Enum):
FORWARD = "F"
BACK = "B"
LEFT = "L"
RIGHT = "R"
class Rover:
def __init__(self, x: int, y: int, d: Direction):
self.x = x
self.y = y
self.d = d
def __str__(self):
return f"({self.x}, {self.y}) {str(self.d)}"
def __forward(self):
self.x = self.x + self.d.x
self.y = self.y + self.d.y
def __back(self):
self.x = self.x - self.d.x
self.y = self.y - self.d.y
def __right(self):
self.d = Direction((self.d + 1) % 4)
def __left(self):
self.d = Direction((self.d - 1) % 4)
@property
def __commands(self) -> Dict[Command, Callable]:
return {
Command.FORWARD: self.__forward,
Command.BACK: self.__back,
Command.LEFT: self.__left,
Command.RIGHT: self.__right,
}
@property
def state(self) -> (int, int, Direction):
return (self.x, self.y, self.d)
def command(self, command: str):
for c in command:
self.__commands[Command(c)]()
return self.state
class TestRover(unittest.TestCase):
def test_moving_forward(self):
rover = Rover(0, 0, Direction.NORTH)
rover.command("F")
self.assertEqual((0, 1, Direction.NORTH), rover.state)
def test_moving_back(self):
rover = Rover(0, 0, Direction.NORTH)
rover.command("B")
self.assertEqual((0, -1, Direction.NORTH), rover.state)
def test_turning_left(self):
rover = Rover(0, 0, Direction.NORTH)
rover.command("L")
self.assertEqual((0, 0, Direction.WEST), rover.state)
def test_turning_right(self):
rover = Rover(0, 0, Direction.NORTH)
rover.command("R")
self.assertEqual((0, 0, Direction.EAST), rover.state)
def test_simple_mission(self):
rover = Rover(4, 2, Direction.EAST)
rover.command("FLFFFRFLB")
self.assertEqual("(6, 4) NORTH", str(rover))
if __name__ == "__main__":
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment