Skip to content

Instantly share code, notes, and snippets.

@axs
Created June 23, 2014 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save axs/a3433292f6d81d8a08df to your computer and use it in GitHub Desktop.
Save axs/a3433292f6d81d8a08df 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()
@axs
Copy link
Author

axs commented Jun 24, 2014

The Elevator Problem
Imagine a high-rise building that has 12 floors and exactly one elevator. The elevator can travel to all floors in the building and it receives commands in the following format:
-
For example, if the elevator receives the commands 4-1, 3-2, 1-5, and 6-8 it would mean that someone will get on at floor 4 and off at floor 1, someone else will get on at floor 3 and off at floor 2, and so on. In addition, the elevator can operate in two unique modes (described below), which specify the priority and optimizations that the elevator should use when completing a set of commands.
Your task is to write a program that requires an argument for the name of a text file containing multiple sets of commands as an input, and for each set of commands writes to standard output both the path that the elevator will take and the total distance in floors that the elevator must travel. In addition, your program must accept an argument to specify which mode the elevator will operate in throughout the application lifecycle. The mode argument should follow the filename argument.
Your program must support both of the following modes.
Mode A
Mode A is very inefficient and only allows for transporting one person at a time. If Doug calls the elevator on floor 4 and wants to go to floor 1, and Alan subsequently calls the elevator on floor 3 and wants to go to floor 2, the elevator will go pick up Doug and take him to floor 1 before picking up Alan and taking him to floor 2.
In this example the system receives the commands 4-1, 3-2 and tells the elevator to travel from its current floor to floors 4, 1, 3, and 2. If the elevator starts at floor 1, its total distance traveled will be 9 floors.
Mode B
Mode B allows for operating the elevator more efficiently. Similar to Mode A, the elevator in Mode B will acknowledge each command in the order it is received. However Mode B supports transporting more people at once and if any consecutive requests to travel in the same direction are received, the elevator can handle them all in one trip. If in the example above Doug and Alan had requested the elevator in Mode B, the elevator would have picked up Doug on 4, picked up Alan on 3, dropped off Alan on 2, and finally dropped off Doug on 1.
In other words, the commands 4-1, 3-2 can be merged because they are consecutive requests to travel from a higher floor to a lower floor. Test Input
10:8-1
9:1-5,1-6,1-5
2:4-1,4-2,6-8
3:7-9,3-7,5-8,7-11,11-1
7:11-6,10-5,6-8,7-4,12-7,8-9
6:1-8,6-8
Each line of your text file should consist of the initial floor location of the elevator, a colon “:”, and one or more commands that are delimited with a comma “,”. Each line represents a set of commands that should be processed exclusively and sequentially and the result of processing one line should not influence the result of the next.
Expected Output

Mode A
10 8 1 (9)
9 1 5 1 6 1 5 (30)
2 4 1 4 2 6 8 (16)
3 7 9 3 7 5 8 7 11 1 (36)
7 11 6 10 5 6 8 7 4 12 7 8 9 (40)
6 1 8 6 8 (16)

Mode B
10 8 1 (9)
9 1 5 6 (13)
2 4 2 1 6 8 (12)
3 5 7 8 9 11 1 (18)
7 11 10 6 5 6 8 12 7 4 8 9 (30)
6 1 6 8 (12)
For each set of commands the system should print to standard output a single line consisting of a space-delimited list of floors followed by the total distance in floors that the elevator travels, in parenthesis “(“ and “)”. The list of floors should begin with the initial floor location followed by the visited floors in the order that the elevator visits them.

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