Machine Coding Problem

Airport Management System

maco60macoAllinfrastructureresource-allocation-(gates)
Commonly Asked By:AmadeusSabreBoeing

Functional Scope (In-Scope)

  • Interval-Scheduling Gate Allocation: Models gate allocations as scheduled non-overlapping intervals, accounting for turnaround buffers.
  • Physical Aircraft Compatibility: Gate searches ensure gates match flight wingspans, jet bridge alignments, and boarding types.
  • Reactive Delay Cascades: Handles incoming flight delay propagation, shifting intervals dynamically and triggering automatic gate reassignments.
  • Resource Dispatch: Coordinates ground crew turnarounds and allocates baggage carousel belts.

Explicit Boundaries (Out-of-Scope)

  • Low-Level ATC Telemetry Sockets: Live radar socket connections or analog air-traffic communication structures are out-of-scope.
  • Global Reservation Inventory: Excludes live passenger booking, seating management, and ticket transaction processors.

Clean reference designs demonstrating interval-scheduling gate assignments in Java and Python:

// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

enum AircraftType { SMALL, MEDIUM, LARGE }

class Flight {
    private final String flightNumber;
    private final AircraftType aircraftType;
    private final long scheduledTime;
    private final long duration;
    private long delay;

    public Flight(String flightNumber, AircraftType aircraftType, long scheduledTime, long duration) {
        this.flightNumber = flightNumber;
        this.aircraftType = aircraftType;
        this.scheduledTime = scheduledTime;
        this.duration = duration;
        this.delay = 0;
    }

    public String getFlightNumber() { return flightNumber; }
    public AircraftType getAircraftType() { return aircraftType; }
    public long getScheduledTime() { return scheduledTime; }
    public long getDuration() { return duration; }
    
    public synchronized long getDelay() { return delay; }
    public synchronized void addDelay(long delayMillis) {
        this.delay += delayMillis;
    }

    public synchronized long getActualStartTime() {
        return scheduledTime + delay;
    }

    public synchronized long getActualEndTime() {
        return scheduledTime + delay + duration;
    }
}

class TimeInterval {
    public final long start;
    public final long end;
    public final String flightNumber;

    public TimeInterval(long start, long end, String flightNumber) {
        this.start = start;
        this.end = end;
        this.flightNumber = flightNumber;
    }
}

class Gate {
    private final String id;
    private final Set<AircraftType> compatibleTypes;
    private final List<TimeInterval> schedule = new ArrayList<>();
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public Gate(String id, Set<AircraftType> compatibleTypes) {
        this.id = id;
        this.compatibleTypes = new HashSet<>(compatibleTypes);
    }

    public String getId() { return id; }
    
    public boolean isCompatible(AircraftType type) {
        return compatibleTypes.contains(type);
    }

    public boolean hasConflict(long start, long end) {
        lock.readLock().lock();
        try {
            for (TimeInterval interval : schedule) {
                if (Math.max(interval.start, start) < Math.min(interval.end, end)) {
                    return true;
                }
            }
            return false;
        } finally {
            lock.readLock().unlock();
        }
    }

    public void bookInterval(long start, long end, String flightNumber) {
        lock.writeLock().lock();
        try {
            schedule.add(new TimeInterval(start, end, flightNumber));
        } finally {
            lock.writeLock().unlock();
        }
    }

    public void removeInterval(String flightNumber) {
        lock.writeLock().lock();
        try {
            schedule.removeIf(ti -> ti.flightNumber.equals(flightNumber));
        } finally {
            lock.writeLock().unlock();
        }
    }

    public List<TimeInterval> getSchedule() {
        lock.readLock().lock();
        try {
            return new ArrayList<>(schedule);
        } finally {
            lock.readLock().unlock();
        }
    }
}

class GateAssignmentService {
    private final List<Gate> gates = new ArrayList<>();
    private final Map<String, Gate> flightToGateMap = new ConcurrentHashMap<>();
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

    public void addGate(Gate gate) {
        rwLock.writeLock().lock();
        try {
            gates.add(gate);
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public Gate assignGate(Flight flight, long turnaroundBuffer) throws Exception {
        rwLock.writeLock().lock();
        try {
            long occupationStart = flight.getActualStartTime();
            long occupationEnd = flight.getActualEndTime() + turnaroundBuffer;

            for (Gate gate : gates) {
                if (gate.isCompatible(flight.getAircraftType()) && !gate.hasConflict(occupationStart, occupationEnd)) {
                    gate.bookInterval(occupationStart, occupationEnd, flight.getFlightNumber());
                    flightToGateMap.put(flight.getFlightNumber(), gate);
                    return gate;
                }
            }
            throw new IllegalStateException("No compatible gate available for flight: " + flight.getFlightNumber());
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public void handleFlightDelay(Flight flight, long delayMillis, long turnaroundBuffer) throws Exception {
        rwLock.writeLock().lock();
        try {
            Gate gate = flightToGateMap.get(flight.getFlightNumber());
            if (gate == null) {
                throw new IllegalArgumentException("Flight " + flight.getFlightNumber() + " is not currently assigned to a gate.");
            }

            // Remove old schedule interval
            gate.removeInterval(flight.getFlightNumber());
            flight.addDelay(delayMillis);

            long newStart = flight.getActualStartTime();
            long newEnd = flight.getActualEndTime() + turnaroundBuffer;

            // Attempt to keep same gate if conflict free, otherwise migrates
            if (!gate.hasConflict(newStart, newEnd)) {
                gate.bookInterval(newStart, newEnd, flight.getFlightNumber());
                System.out.println("[ATC] Delayed Flight " + flight.getFlightNumber() + " kept original Gate " + gate.getId());
            } else {
                System.out.println("[ATC] Delayed Flight " + flight.getFlightNumber() + " conflicted with Gate " + gate.getId() + ". Reassigning...");
                flightToGateMap.remove(flight.getFlightNumber());
                Gate newGate = assignGate(flight, turnaroundBuffer);
                System.out.println("[ATC] Migrated Flight " + flight.getFlightNumber() + " to new Gate " + newGate.getId());
            }
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public Gate getAssignedGate(String flightNumber) {
        return flightToGateMap.get(flightNumber);
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("=== INITIALIZING AIRPORT MANAGEMENT ===");
        GateAssignmentService gas = new GateAssignmentService();

        // Register Gates
        // G1: Compatible with Medium and Large jets
        Gate g1 = new Gate("G1", new HashSet<>(Arrays.asList(AircraftType.MEDIUM, AircraftType.LARGE)));
        // G2: Compatible with Medium and Small jets
        Gate g2 = new Gate("G2", new HashSet<>(Arrays.asList(AircraftType.SMALL, AircraftType.MEDIUM)));
        
        gas.addGate(g1);
        gas.addGate(g2);

        long now = System.currentTimeMillis();
        long hour = 3600 * 1000;
        long buffer = 15 * 60 * 1000; // 15 mins buffer

        System.out.println("\\n=== 1. SCHEDULING INITIAL FLIGHTS ===");
        Flight f1 = new Flight("AA101", AircraftType.LARGE, now, 2 * hour);
        Flight f2 = new Flight("UA202", AircraftType.MEDIUM, now + hour, hour);

        try {
            Gate assign1 = gas.assignGate(f1, buffer);
            System.out.println("Assigned " + f1.getFlightNumber() + " to Gate " + assign1.getId());
            
            Gate assign2 = gas.assignGate(f2, buffer);
            System.out.println("Assigned " + f2.getFlightNumber() + " to Gate " + assign2.getId());
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }

        System.out.println("\\n=== 2. HANDLING CONFLICT WITH DELAY ===");
        // Flight AA101 (large, occupying G1 from now to now+2h) is delayed by 1 hour.
        // It now occupies from now+1h to now+3h.
        // This conflicts with G1 scheduling.
        try {
            System.out.println("Adding 1 hour delay to Flight AA101...");
            gas.handleFlightDelay(f1, hour, buffer);
        } catch (Exception e) {
            System.out.println("Delay handling failed: " + e.getMessage());
        }
    }
}