-
-
Save MHaroonBaig/d624cbc72b078ebd357d 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
""" | |
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