# Design an Elevator System — High-Level & Low-Level Design Interview Problems

Source: https://www.skillbyai.com/en/design-interviews/elevator

> Requests, cars and scheduling.

## Requests, state and dispatch

Clarify: N elevators, M floors; hall calls (floor plus direction) and car calls (destination pressed inside); capacity limits; maybe maintenance mode. Model: `ElevatorCar` with current floor, `Direction` (UP, DOWN, IDLE), door state and a set of target stops; a `Dispatcher` assigns hall calls to cars using a `SchedulingStrategy`. A common policy is **SCAN/LOOK**: keep moving in one direction serving stops, reverse when none remain ahead. Assignment can pick the car that can reach the floor soonest while moving in the requested direction. Each car processes its own stop set; the dispatcher only decides who serves a hall call.

## Car with LOOK-style movement

Python sketch; one simulation step per call.

```python
from enum import Enum

class Direction(Enum):
    UP = 1
    DOWN = -1
    IDLE = 0

class ElevatorCar:
    def __init__(self, car_id: int, floor: int = 0):
        self.car_id = car_id
        self.floor = floor
        self.direction = Direction.IDLE
        self.stops: set[int] = set()

    def add_stop(self, floor: int) -> None:
        self.stops.add(floor)

    def step(self) -> None:
        if self.floor in self.stops:
            self.stops.discard(self.floor)   # open doors here
        if not self.stops:
            self.direction = Direction.IDLE
            return
        ahead = [s for s in self.stops if (s - self.floor) * self.direction.value > 0]
        if self.direction == Direction.IDLE or not ahead:
            nearest = min(self.stops, key=lambda s: abs(s - self.floor))
            self.direction = Direction.UP if nearest > self.floor else Direction.DOWN
        self.floor += self.direction.value

class Dispatcher:
    def __init__(self, cars: list[ElevatorCar]):
        self.cars = cars

    def hall_call(self, floor: int) -> ElevatorCar:
        best = min(self.cars, key=lambda c: abs(c.floor - floor))  # simple strategy
        best.add_stop(floor)
        return best
```

## Keep the strategy pluggable

Start with nearest-car dispatch, then show how a SchedulingStrategy interface lets you swap in direction-aware or energy-saving policies.

**Quiz:** In the LOOK policy, when does the car reverse direction?

- [ ] Only at the top and bottom floors
- [ ] After every floor
- [x] When no requested stops remain ahead in the current direction
- [ ] When a random timer fires

*Answer:* When no requested stops remain ahead in the current direction. LOOK reverses at the last request, not the building edge.
