Skip to content

Instantly share code, notes, and snippets.

@MHaroonBaig
Forked from axs/elevator.py
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MHaroonBaig/d624cbc72b078ebd357d to your computer and use it in GitHub Desktop.
Save MHaroonBaig/d624cbc72b078ebd357d to your computer and use it in GitHub Desktop.
"""
This was written using Python 2.7.2
This requires the attached gziped blist library and the numpy library
or you can install blist and numpy from commandline with
easy_install blist or pip install blist
easy_install numpy or pip install numpy
Description:
The Elevator takes an ElevatorAlgorithm when instanciated and
reads in raw commands from file and to create a list of Command objects
Each algorithm is then used to create path logic
The elevator then displays the path and distance
"""
import blist
import itertools as itools
import operator as oper
import numpy as np
class Command(object):
def __init__(self,strcommand):
self.strcommand = strcommand
self.paths = []
self.initialfloor = 0
self.__parseCommand()
def __parseCommand(self):
ini, rest = self.strcommand.split(':')
self.initialfloor = int(ini)
self.paths = [ map(int,i.split('-')) for i in rest.split(',')]
class elevator(object):
def __init__ (self,algorithm):
self.algo = algorithm
self.commands= []
def readinput(self,file):
with open(file,mode='r') as fh:
self.rawcommands = fh.readlines()
self.commands = [ Command(rc) for rc in self.rawcommands ]
def output(self):
print "\n".join( [ self.algo.calculate(c) for c in self.commands ] )
class ElevatorAlgorithm(object):
def calculate(self,c):
raise NotImplementedError('Method must be implemented by subclass')
def display(self,floorpath):
route = " ".join( map(str, floorpath))
distance = np.sum(np.abs(np.diff(floorpath)))
return "%s (%i)" %(route,distance)
class ModeA(ElevatorAlgorithm):
"""
this creates a path list which the elevator travels and sums the differences between floors
to obtain total distance
"""
def __init__ (self,**kwargs):
super(ModeA, self).__init__(**kwargs)
def calculate(self,cmdobj):
floorpath = [cmdobj.initialfloor]
floorpath.extend(np.ravel(cmdobj.paths))
return self.display(floorpath)
class ModeB(ElevatorAlgorithm):
"""
this creates a path list which the elevator travels and the direction (up or down)
as long as we are going in the same direction we put the floors in a sortedset depending on direction
then sum the differences between floors to obtain total distance
"""
def __init__ (self,**kwargs):
super(ModeB, self).__init__(**kwargs)
def calculate(self,cmdobj):
floors = [ [ cmdobj.initialfloor,cmdobj.paths[0][0] ] ]
floors.extend(cmdobj.paths)
directions = [np.sign(np.diff(i))[0] for i in floors]
yy=[(a,b) for a,b in zip( directions, floors )]
fullroute=[]
for key, items in itools.groupby(yy, oper.itemgetter(0)):
route = [subitem[1] for subitem in items]
fullroute.append( list(blist.sortedset(np.ravel(route),key=lambda i: key * i)) )
#flatten list of lists
flatroute = [i for i in itools.chain.from_iterable(fullroute) ]
#remove consecutive duplicates
floorpath = [x[0] for x in itools.groupby(flatroute)]
return self.display(floorpath)
if __name__ == '__main__':
inputfile = 'input.txt'
print "\n~~~~~~~~~ Model A ~~~~~~~~~~~~~~~~~\n"
e = elevator(ModeA())
e.readinput(inputfile)
e.output()
print "\n\n~~~~~~~~~ Model B ~~~~~~~~~~~~~~~~~\n"
b = elevator( ModeB() )
b.readinput(inputfile)
b.output()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment