Skip to content

Instantly share code, notes, and snippets.

@typehorror
Last active July 28, 2016 17:11
Show Gist options
  • Save typehorror/e6c3361fd18941e60159abdd6f68029a to your computer and use it in GitHub Desktop.
Save typehorror/e6c3361fd18941e60159abdd6f68029a to your computer and use it in GitHub Desktop.
Optimize the elevator controller
"""
Elevator Exercise.
Edit the ElevatorController implementation, focusing on
the ElevatorController.call(Passenger) method.
Run the elevator script try to increase your score.
python elevators.py
> score: 51
"""
class Elevator(object):
"""Represent an elevator."""
def __init__(self, name, floor=0):
"""Initialize the elvator."""
self.name = name
self.floor = floor
self.passengers = []
self.destinations = []
self.points = 0
@property
def direction(self):
"""Return the current direction of the elevator."""
if self.destinations:
if self.destinations[0] > self.floor:
return 'up'
elif self.destinations[0] < self.floor:
return 'down'
return 'still'
def add_destination(self, destination):
"""Add a new destination to the destination queue."""
self.destinations.append(destination)
if self.direction == 'up':
self.destinations.sort()
else:
self.destinations.sort(reverse=True)
def distance(self, destination):
"""Return the current distance from a given floor."""
return abs(self.floor - destination)
def load(self, passenger):
"""A paslsenger enters the elevator and presses the destination."""
print '{}: Loading passenger at floor {} going to {}'.format(
self.name,
self.floor,
passenger.destination
)
self.passengers.append(passenger)
self.add_destination(passenger.destination)
self.points += 1
def drop(self, passenger):
"""Drop a passenger."""
self.passengers.remove(passenger)
print '{}: Droping passenger at floor {}'.format(self.name, self.floor)
self.points += 1
def tick(self):
"""Rendering cycle."""
# Elevator arrive at one of its destinations
if self.destinations and self.floor == self.destinations[0]:
self.destinations.pop(0)
# check and dorp any passenger who arrived at its destination
for passenger in self.passengers:
if passenger.has_arrived(self.floor):
self.drop(passenger)
# If the direction is up, move the elevator up
if self.direction == 'up':
self.floor += 1
# If the direction is down, move the elevator down
elif self.direction == 'down':
self.floor -= 1
class Passenger(object):
"""An elevator Passenger."""
def __init__(self, floor, destination):
"""Initialize a new passenger at a given floor and destination."""
self.floor = floor
self.destination = destination
@property
def direction(self):
"""Return the direction the passenger wants to go."""
if self.destination > self.floor:
return 'up'
return 'down'
def has_arrived(self, floor):
"""Return True if the passenger has arrived to its destination."""
return floor == self.destination
class ElevatorController(object):
"""Central controller unit for elevator."""
def __init__(self, elevators):
"""Initialize the controller."""
self.elevators = elevators
self.passengers = []
def tick(self):
"""Rendering cycle for all the elevators."""
for elevator in self.elevators:
elevator.tick()
for passenger in self.passengers:
if passenger.floor == elevator.floor and \
elevator.direction in [passenger.direction, 'still']:
elevator.load(passenger)
self.passengers.remove(passenger)
@property
def score(self):
"""Return the sum of points each elevators collected."""
return sum(e.points for e in self.elevators)
def call(self, passenger):
"""
Someone called an elevator.
Elevator methods:
elevator.floor: The floor where the elevator is
elevator.destinations: an array containing the list of destinations
for the elevator
elevator.direction: Can either be 'up', 'down' or 'still'
elevator.add_destination(int): Add a new destination to the
destination queue.
elevator.distance(int): return the distance from the elevator
from a given floor
elevator.load(Passenger): Load a passenger.
"""
self.passengers.append(passenger)
self.elevators[0].add_destination(passenger.destination)
elevator_controller = ElevatorController([Elevator('A'), Elevator('B')])
requests = [
(3, 34), (28, 75), (90, 86), (10, 13), (27, 37), (98, 53), (38, 65),
(80, 39), (5, 38), (52, 15), (99, 85), (18, 76), (81, 71), (88, 3),
(78, 96), (34, 77), (99, 46), (85, 57), (65, 26), (97, 35), (88, 26),
(48, 30), (44, 28), (35, 14), (48, 89), (3, 2), (96, 13), (80, 13),
(2, 29), (55, 33), (17, 50), (38, 37), (95, 89), (80, 4), (49, 97),
(98, 66), (40, 71), (59, 27), (32, 35), (84, 62), (35, 88), (70, 32),
(56, 19), (63, 52), (23, 73), (22, 51), (62, 41), (82, 84), (26, 91),
(64, 34), (56, 37), (49, 8), (76, 96), (77, 38), (78, 29), (47, 84),
(79, 58), (43, 61), (20, 34), (28, 78), (8, 53), (87, 13), (98, 95),
(36, 41), (100, 50), (96, 49), (44, 61), (40, 33), (28, 83), (18, 85),
(46, 69), (2, 85), (77, 13), (96, 83), (49, 16), (64, 31), (50, 62),
(68, 79), (63, 61), (55, 5), (1, 29), (64, 16), (75, 56), (57, 75),
(16, 51), (23, 92), (60, 33), (18, 0), (2, 23), (30, 33), (93, 75),
(23, 22), (15, 80), (20, 64), (79, 88), (8, 50), (67, 28), (100, 35),
(13, 20), (87, 23)
]
for i in range(500):
elevator_controller.tick()
if i % 4 == 0 and requests:
passenger = Passenger(*requests.pop())
elevator_controller.call(passenger)
print 'score:', elevator_controller.score
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment