Last active
July 28, 2016 17:11
-
-
Save typehorror/e6c3361fd18941e60159abdd6f68029a to your computer and use it in GitHub Desktop.
Optimize the elevator controller
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
""" | |
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