Skip to content

Instantly share code, notes, and snippets.

@tecoholic
Created June 2, 2015 18:32
Show Gist options
  • Select an option

  • Save tecoholic/c25dc7bec16fba00ab5a to your computer and use it in GitHub Desktop.

Select an option

Save tecoholic/c25dc7bec16fba00ab5a to your computer and use it in GitHub Desktop.
###############################################################################
# Filename: marsrover.py
# Author: Arunmozhi
# Email: [email protected]
# Date: 29 May 2015
###############################################################################
import sys
from math import sqrt
class Rover:
def __init__(self,pos):
self.x = int(pos[0])
self.y = int(pos[1])
self.d = pos[2]
self.directions = ['N','E', 'S', 'W']
def turn_left(self):
if self.directions.index(self.d) == 0:
self.d = self.directions[3]
else:
self.d = self.directions[self.directions.index(self.d)-1]
def turn_right(self):
if self.directions.index(self.d) == 3:
self.d = self.directions[0]
else:
self.d = self.directions[self.directions.index(self.d)+1]
def move(self):
if self.d == 'N':
self.y += 1
elif self.d == 'S':
self.y -= 1
elif self.d == 'E':
self.x += 1
else:
self.x -= 1
def follow_instructions(self, ins):
steps = list(ins.strip())
for step in steps:
if step == 'L':
self.turn_left()
elif step == 'R':
self.turn_right()
elif step == 'M':
self.move()
def rover_is_inside( plat, rover ):
"""function to check whether the given rover is inside the plateau or not"""
# return (0 <= rover.x <= plat['x']) and (0 <= rover.y <= plat['y'])
return sqrt( rover.x*rover.x + rover.y*rover.y ) <= plat['radius']
def run_rovers(filename):
plat = { 'x' : 0, 'y' : 0 }
infile = open(filename, 'r')
outfile = open("output.txt", 'w')
parts = infile.readline().split()
plat.x = int(parts[0])
plat.y = int(parts[1])
# create the first rover object so others can be iteratively overwritten
rover = Rover(infile.readline().split())
nextIsRover = False
# read two lines at a time and plot rover positions
for line in infile:
if nextIsRover:
rover = Rover(line.split())
nextIsRover = False
else:
rover.follow_instructions(line)
if rover_is_inside( plat, rover ):
outfile.write(" ".join([str(rover.x), str(rover.y), rover.d])+"\n")
else:
outfile.write("Sorry, this rover is off the plateau and lying in the valley :(\n")
nextIsRover = True
infile.close()
outfile.write('============\n')
outfile.close()
if __name__ == "__main__":
if len(sys.argv) != 2:
print "Usage: python marsrover.py <filename>"
else:
run_rovers(sys.argv[1])
print "The current locations of mars rovers can be read from <output.txt>"
import unittest
from marsrover import Rover, rover_is_inside
# test cases
# 1. rover class
# a. turn left
# b. turn right
# c. move
# d. follow instructions
# 2. run rovers
# basically file IO
#
class MarsRoverTest(unittest.TestCase):
def test_turnright(self):
rover = Rover(['0', '0', 'N'])
rover.turn_right()
self.assertEqual(rover.d, "E")
rover.turn_right()
self.assertEqual(rover.d, "S")
rover.turn_right()
self.assertEqual(rover.d, "W")
rover.turn_right()
self.assertEqual(rover.d, "N")
def test_turnleft(self):
rover = Rover(['0', '0', 'N'])
rover.turn_left()
self.assertEqual(rover.d, "W")
rover.turn_left()
self.assertEqual(rover.d, "S")
rover.turn_left()
self.assertEqual(rover.d, "E")
rover.turn_left()
self.assertEqual(rover.d, "N")
def test_move(self):
# move for all 4 directions
rover = Rover(['0', '0', 'N'])
rover.move()
self.assertEqual( rover.x, 0)
self.assertEqual( rover.y, 1)
rover.turn_right()
rover.move()
self.assertEqual( rover.x, 1)
self.assertEqual( rover.y, 1)
rover.turn_right()
rover.move()
self.assertEqual( rover.x, 1)
self.assertEqual( rover.y, 0)
rover.turn_right()
rover.move()
self.assertEqual( rover.x, 0)
self.assertEqual( rover.y, 0)
def test_followinstructions(self):
# commands:
# L, R, M
rover = Rover(['3', '3', 'N'])
rover.follow_instructions('L')
self.assertEqual( rover.d, 'W' )
rover.follow_instructions( 'R' )
self.assertEqual( rover.d, 'N' )
rover.follow_instructions( 'M' )
self.assertEqual( rover.x, 3 )
self.assertEqual( rover.y, 4 )
# test 2 letter combinations
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'LL' )
self.assertEqual( rover.d, 'S' )
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'LR' )
self.assertEqual( rover.d, 'N' )
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'LM' )
self.assertEqual( rover.d, 'W' )
self.assertEqual( rover.x, 2 )
self.assertEqual( rover.y, 3 )
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'RL' )
self.assertEqual( rover.d, 'N')
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'RR' )
self.assertEqual( rover.d, 'S')
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'RM' )
self.assertEqual( rover.d, 'E' )
self.assertEqual( rover.x, 4 )
self.assertEqual( rover.y, 3 )
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'ML' )
self.assertEqual( rover.d, 'W')
self.assertEqual( rover.x, 3 )
self.assertEqual( rover.y, 4 )
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'MR' )
self.assertEqual( rover.d, 'E')
self.assertEqual( rover.x, 3 )
self.assertEqual( rover.y, 4 )
rover = Rover(['3', '3', 'N'])
rover.follow_instructions( 'MM' )
self.assertEqual( rover.d, 'N' )
self.assertEqual( rover.x, 3 )
self.assertEqual( rover.y, 5 )
"""
class RoverIsInsideTest(unittest.TestCase):
def test_roverisinside(self):
plat = { 'x' : 3, 'y': 3 }
rover = Rover(['0', '0', 'N'])
self.assertTrue( rover_is_inside(plat, rover))
rover = Rover(['0', '3', 'N'])
self.assertTrue( rover_is_inside(plat, rover))
rover = Rover(['3', '0', 'N'])
self.assertTrue( rover_is_inside(plat, rover))
rover = Rover(['3', '3', 'N'])
self.assertTrue( rover_is_inside(plat, rover))
rover = Rover(['0', '4', 'N'])
self.assertFalse( rover_is_inside(plat, rover))
rover = Rover(['5', '0', 'N'])
self.assertFalse( rover_is_inside(plat, rover))
rover = Rover(['5', '5', 'N'])
self.assertFalse( rover_is_inside(plat, rover))
"""
class RoverIsInsideCircle(unittest.TestCase):
def test_roverisinside(self):
plat = { "radius" : 5 }
rover = Rover(['0', '0', 'N'])
self.assertTrue(rover_is_inside(plat, rover))
rover = Rover(['5', '0', 'N'])
self.assertTrue(rover_is_inside(plat, rover))
rover = Rover(['0', '5', 'N'])
self.assertTrue(rover_is_inside(plat, rover))
rover = Rover(['5', '5', 'N'])
self.assertFalse(rover_is_inside(plat, rover))
@tecoholic
Copy link
Author

The function rover_is_inside is presently considering plateau to be circular. Comment or uncomment the return statement for rectangle or circular as required. Similarly their unittests as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment