Design an elevator controller
Picture
One simulated car starts at floor 0 and receives a fixed batch requesting floors 2 and 5. A nearest-stop policy chooses the next destination. Movement and door transitions remain the controller’s responsibility.
Predict
Why keep choosing the next stop separate from moving one floor?
Walk through the small example
Scheduling policies can change without rewriting the safety-related state transitions in the simulation. The controller should still close doors before moving and open them only at a served stop.
Mental model and complete Python solution
Pending floors form a set, so repeated button presses do not duplicate stops. Each tick first closes open doors; otherwise it selects the nearest pending floor, moves one level, and opens on arrival. Ties favor the lower floor. The example serves finite batches; continuous nearby requests could starve a distant request. Passenger direction, capacity, emergencies, multiple cars, and physical interlocks are explicitly not modeled.
What the function promises: Floors are integers 0..top. request adds a stop; tick returns (floor, doors_open). This is a single-car educational simulator, never suitable for real elevator control.
class Elevator:
def __init__(self, top, start=0):
if type(top) is not int or top < 0 or not 0 <= start <= top:
raise ValueError("Invalid floor range")
self.top, self.floor = top, start
self.pending = set()
self.doors_open = False
def request(self, floor):
if type(floor) is not int or not 0 <= floor <= self.top:
raise ValueError("Floor out of range")
self.pending.add(floor)
def tick(self):
if self.doors_open:
self.doors_open = False
elif self.pending:
target = min(self.pending, key=lambda f: (abs(f-self.floor), f))
if target != self.floor:
self.floor += 1 if target > self.floor else -1
if self.floor == target:
self.pending.remove(target)
self.doors_open = True
return self.floor, self.doors_open
car = Elevator(5)
car.request(2)
car.request(5)
car.request(2)
assert car.tick() == (1, False)
assert car.tick() == (2, True)
assert car.tick() == (2, False)
assert car.tick() == (3, False)
assert car.tick() == (4, False)
assert car.tick() == (5, True)
assert not car.pending
Work and storage: Each scheduling decision scans P pending floors: O(P) time, O(P) storage. More advanced indexes and policies can reduce work or improve fairness, but must follow stated requirements.
When to recognize it: Separate selecting the next stop from moving the car and opening its doors.
Check before applying it: This is not a safety-certified controller. Real elevators require hardware interlocks, fault handling, passenger direction, and multi-car dispatch.
Change one rule
We add many cars and continuous hall requests with travel direction. Is one shared nearest-floor set sufficient?
See what changes
No. Separate hall calls from car destinations, define dispatch ownership and fairness, and coordinate assignments. A directional sweep may reduce reversal, while multi-car dispatch introduces another policy layer.
Connect
Swap the rule, not the whole feature: Nearest-stop, FIFO, and directional sweep are different scheduling policies.
Make legal actions visible: Movement and door states constrain legal actions.