enum ElevatorState { MOVING_UP, MOVING_DOWN, IDLE } enum Direction { UP, DOWN } class Request { private int sourceFloor; private Direction direction; public Request(int sourceFloor, Direction direction) { this.sourceFloor = sourceFloor; this.direction = direction; } public int getSourceFloor() { return sourceFloor; } public Direction getDirection() { return direction; } } class Elevator { private int currentFloor; private ElevatorState state; private TreeSet upRequests = new TreeSet<>(); private TreeSet downRequests = new TreeSet<>(Comparator.reverseOrder()); public Elevator() { this.currentFloor = 0; this.state = ElevatorState.IDLE; } public void addRequest(int floor) { if (floor > currentFloor) { upRequests.add(floor); } else if (floor < currentFloor) { downRequests.add(floor); } } public void addInternalRequest(int destinationFloor) { addRequest(destinationFloor); } /** * Simulates the elevator's state transition. * * IDLE: * - Move to MOVING_UP if upRequests exist * - Move to MOVING_DOWN if no upRequests but downRequests exist * * MOVING_UP: * - Increment currentFloor * - Stop if currentFloor is in upRequests, remove it, allow destination input * - If upRequests are empty, switch to MOVING_DOWN if downRequests exist * - Else, return to IDLE * * MOVING_DOWN: * - Decrement currentFloor * - Stop if currentFloor is in downRequests, remove it, allow destination input * - If downRequests are empty, switch to MOVING_UP if upRequests exist * - Else, return to IDLE */ public void step() { if (state == ElevatorState.IDLE) { if (!upRequests.isEmpty()) { state = ElevatorState.MOVING_UP; } else if (!downRequests.isEmpty()) { state = ElevatorState.MOVING_DOWN; } else { return; } } if (state == ElevatorState.MOVING_UP) { currentFloor++; System.out.println("Elevator moving up to floor: " + currentFloor); if (upRequests.remove(currentFloor)) { System.out.println("Stopping at floor: " + currentFloor); int destination = simulateUserDestination(); addInternalRequest(destination); } if (upRequests.isEmpty() && !downRequests.isEmpty()) { state = ElevatorState.MOVING_DOWN; } else if (upRequests.isEmpty()) { state = ElevatorState.IDLE; } } else if (state == ElevatorState.MOVING_DOWN) { currentFloor--; System.out.println("Elevator moving down to floor: " + currentFloor); if (downRequests.remove(currentFloor)) { System.out.println("Stopping at floor: " + currentFloor); int destination = simulateUserDestination(); addInternalRequest(destination); } if (downRequests.isEmpty() && !upRequests.isEmpty()) { state = ElevatorState.MOVING_UP; } else if (downRequests.isEmpty()) { state = ElevatorState.IDLE; } } } private int simulateUserDestination() { Random random = new Random(); int destination = random.nextInt(10); while (destination == currentFloor) { destination = random.nextInt(10); } System.out.println("User entered destination floor: " + destination); return destination; } public int getCurrentFloor() { return currentFloor; } public ElevatorState getState() { return state; } } class ElevatorController { private List elevators; public ElevatorController(int numberOfElevators) { elevators = new ArrayList<>(); for (int i = 0; i < numberOfElevators; i++) { elevators.add(new Elevator()); } } public void handleExternalRequest(Request request) { Elevator bestElevator = findBestElevator(request.getSourceFloor(), request.getDirection()); bestElevator.addRequest(request.getSourceFloor()); } /** * Selects the best elevator for the request. * Priority is given to elevators that: * - Are IDLE * - Are moving in the same direction as the request and heading towards the request floor * - Otherwise, selects the closest elevator by default */ private Elevator findBestElevator(int floor, Direction direction) { Elevator selected = null; int minDistance = Integer.MAX_VALUE; for (Elevator elevator : elevators) { int distance = Math.abs(elevator.getCurrentFloor() - floor); boolean suitable = false; if (elevator.getState() == ElevatorState.IDLE) { suitable = true; } else if (elevator.getState() == ElevatorState.MOVING_UP && direction == Direction.UP && elevator.getCurrentFloor() <= floor) { suitable = true; } else if (elevator.getState() == ElevatorState.MOVING_DOWN && direction == Direction.DOWN && elevator.getCurrentFloor() >= floor) { suitable = true; } if (suitable && distance < minDistance) { minDistance = distance; selected = elevator; } } return selected != null ? selected : elevators.get(0); } public void stepAllElevators() { for (Elevator elevator : elevators) { elevator.step(); System.out.println("Elevator at floor: " + elevator.getCurrentFloor() + " State: " + elevator.getState()); } } } /** * ElevatorSystemDemo demonstrates the elevator system by initializing a controller, * submitting some example external requests, and simulating the elevator steps over time. */ public class ElevatorSystemDemo { public static void main(String[] args) throws InterruptedException { ElevatorController controller = new ElevatorController(3); controller.handleExternalRequest(new Request(5, Direction.UP)); controller.handleExternalRequest(new Request(2, Direction.DOWN)); for (int i = 0; i < 15; i++) { System.out.println("Step " + i); controller.stepAllElevators(); Thread.sleep(1000); } } }