mardi 16 mars 2021

Design a Parking Lot

I have tried to design the parking lot problem. Here is the problem statement.

Design a parking lot with multiple floors where customers can park their cars. Each parking floor will have many parking spots. The system should support multiple types of parking spots such as Compact, Large, Handicapped, Motorcycle, etc. The system should support parking for different types of vehicles like car, truck, van, motorcycle, etc. -motorbikes can only be parked at motorbike spots -cars can be parked at compact or large spots -Electric car can be parked at compact, large or electric spots -trucks and vans can only be parked in LargeSpot.

Below are some of the classes I have created.

public abstract class ParkingSpot {

    private ParkingSpotType type;

    private boolean isFree;

    private Vehicle vehicle;

    public ParkingSpot (ParkingSpotType type) {
        this.type = type;
    }
    
    public boolean isFree() {
        return this.isFree;
    }

    public void assignVehicle(Vehicle vehicle) {
        this.vehicle = vehicle;
        this.isFree = false;
    }

    public void removeVehicle() {
        this.vehicle = null;
        isFree = true;
    }

    public ParkingSpotType getType() {
        return this.type;
    }

    public Vehicle getVehicle() {
        return this.vehicle;
    }
}

public class CompactParkingSpot extends ParkingSpot {

    public CompactParkingSpot(ParkingSpotType type) {
        super(ParkingSpotType.COMPACT);
    }

}

public class ElectricParkingSpot extends ParkingSpot {

    public ElectricParkingSpot(ParkingSpotType type) {
        super(ParkingSpotType.ELECTRIC);
    }

}

public class HandicappedParkingSpot extends ParkingSpot {

    public HandicappedParkingSpot(ParkingSpotType type) {
        super(ParkingSpotType.HANDICAPPED);
    }

}

public class LargeParkingSpot extends ParkingSpot {

    public LargeParkingSpot(ParkingSpotType type) {
        super(ParkingSpotType.LARGE);
    }
}

public class MotorBikeParkingSpot extends ParkingSpot {

    public MotorBikeParkingSpot(ParkingSpotType type) {
        super(ParkingSpotType.MOTORBIKE);
    }

}

public enum ParkingSpotType {
    HANDICAPPED, MOTORBIKE, COMPACT, LARGE, ELECTRIC
}

Similarly I have created models for different Vehicles and Enum for VehicleTypes.

Below is partial implementation of ParkingLot and PrkingFloor classes.

public class ParkingLot {

    private List<ParkingFloor> prkingFloor;

    // This count values would be incremented every time a vehicle is parked
    private int compactParkingSpotCount;
    private int electricParkingSpotCount;
    // private int handicappedParkingSpotCount;
    private int largeParkingSpotCount;
    private int motorBikeParkingSpotCount;

    private int maxAvailableCompactParkingSpots;
    private int maxAvailableElectricParkingSpots;
    // private int maxAvailableHandicappedParkingSpots;
    private int maxAvailableLargeParkingSpots;
    private int maxAvailableMotorBikeParkingSpots;

    public boolean isFull(VehicleType type) {
        // trucks and vans can only be parked in LargeSpot
        if (type == VehicleType.TRUCK || type == VehicleType.VAN) {
            return largeParkingSpotCount >= maxAvailableLargeParkingSpots;
        }

        // motorbikes can only be parked at motorbike spots
        if (type == VehicleType.MOTORBIKE) {
            return motorBikeParkingSpotCount >= maxAvailableMotorBikeParkingSpots;
        }

        // cars can be parked at compact or large spots
        if (type == VehicleType.CAR) {
            return (compactParkingSpotCount + largeParkingSpotCount) >= (maxAvailableCompactParkingSpots
                    + maxAvailableLargeParkingSpots);
        }

        // electric car can be parked at compact, large or electric spots
        return (compactParkingSpotCount + largeParkingSpotCount
                + electricParkingSpotCount) >= (maxAvailableCompactParkingSpots + maxAvailableLargeParkingSpots
                        + maxAvailableElectricParkingSpots);
    }

    // increment the parking spot count based on the vehicle type
    private void incrementSpotCount(VehicleType type) {
        if (type == VehicleType.TRUCK || type == VehicleType.VAN) {
            largeParkingSpotCount++;
        } else if (type == VehicleType.MOTORBIKE) {
            motorBikeParkingSpotCount++;
        } else if (type == VehicleType.CAR) {
            if (compactParkingSpotCount < maxAvailableCompactParkingSpots) {
                compactParkingSpotCount++;
            } else {
                largeParkingSpotCount++;
            }
        } else { // electric car
            if (electricParkingSpotCount < maxAvailableElectricParkingSpots) {
                electricParkingSpotCount++;
            } else if (compactParkingSpotCount < maxAvailableCompactParkingSpots) {
                compactParkingSpotCount++;
            } else {
                largeParkingSpotCount++;
            }
        }
    }

}


public class ParkingFloor {

    private String name;

    private Map<String, HandicappedParkingSpot> handicappedParkingSpots;
    private Map<String, CompactParkingSpot> compactparkingSpots;
    private Map<String, LargeParkingSpot> largeparkingSpots;
    private Map<String, MotorBikeParkingSpot> motorbikeParkingSpots;
    private Map<String, ElectricParkingSpot> electricParkingSpots;

    public void addParkingSpot(ParkingSpot spot) {
        switch (spot.getType()) {
        case HANDICAPPED:
            handicappedParkingSpots.put(spot.getNumber(), (HandicappedParkingSpot) spot);
            break;
        case COMPACT:
            compactparkingSpots.put(spot.getNumber(), (CompactParkingSpot) spot);
            break;
        case LARGE:
            largeparkingSpots.put(spot.getNumber(), (LargeParkingSpot) spot);
            break;
        case MOTORBIKE:
            motorbikeParkingSpots.put(spot.getNumber(), (MotorBikeParkingSpot) spot);
            break;
        case ELECTRIC:
            electricParkingSpots.put(spot.getNumber(), (ElectricParkingSpot) spot);
            break;
        default:
            System.out.println("Wrong parking spot type!");
        }
    }

    public void assignVehicleToSpot(Vehicle vehicle, ParkingSpot spot) {
        spot.assignVehicle(vehicle);
        switch (spot.getType()) {
        case HANDICAPPED:
            // updateDisplayBoardForHandicapped(spot);
            break;
        case COMPACT:
            // updateDisplayBoardForCompact(spot);
            break;
        case LARGE:
            // updateDisplayBoardForLarge(spot);
            break;
        case MOTORBIKE:
            // updateDisplayBoardForMotorbike(spot);
            break;
        case ELECTRIC:
            // updateDisplayBoardForCompact(spot);
            break;
        default:
            System.out.println("Wrong parking spot type!");
        }
    }

}

I am not able to figure out strategy for assigning a parking spot to a vehicle. I can come up with two different approaches:

  1. While initializing parking floor, add all the parkingSpots with flag isFree as true. When I have to assign a parking spot to a vehicle, I need to search through all the key/value pairs of hashMap(compactparkingSpots/largeparkingSpots etc, present in parkingFloor Object) and check for a free slot. That I think is ineffective and every vehicle will wait till our program searches for applicable free parkingSpot.
  2. While adding parkingSpots to parkingFloor, increment id for each spot. So, if floor 1 has 5 compactparkingSpots with ids 1 to 5, floor 2 will have another 5 compactparkingSpots with ids 5 to 10. Similarly, all floors will have parkingSpots with incremental ids. We can sore id of next free parkingSpot. So if 5 compactparkingSpots are full, next available id is 6. In that case also, we will have to iterate through each floor to check which floor has compactparkingSpot with id 6. This also I think is inefficient.

I am not able to come up with an efficient Strategy to assign suitable parkingSpot to a Vehicle in fast and efficient manner.

Please help me with the right Strategy.

Aucun commentaire:

Enregistrer un commentaire