enum VehicleSize {
COMPACT,
STANDARD,
LARGE
}
enum SpotType {
COMPACT,
STANDARD,
LARGE,
HANDICAPPED
}
class Vehicle {
private String vehiId; // vehicle number
private VehicleSize vehiSize;
private boolean isDisable;
private LocalDateTime start;
private Spot spot;
public Vehicle(String id, VehicleSize size, boolean isDisable) {
this.vehiId = id;
this.vehiSize = size;
this.isDisable = isDisable;
}
// getter and setter
public String getId() {
return vehiId;
}
public VehicleSize getSize() {
return vehiSize;
}
public boolean getIsDisable() {
return isDisable;
}
public LocalTime getStart() {
return start;
}
public void setStart() {
this.start = LocalDateTime.now();
}
public Spot getSpot() {
return spot;
}
public void setSpot(Spot spot) {
this.spot = spot;
}
}
class Spot {
private int spotId;
private SpotType spotType;
private boolean isAvailable;
private int floor;
private int row;
private int col;
public Spot(int spotId, SpotType spotType, int floor, int row, int col) {
this.spotId = spotId;
this.spotType = spotType;
this.isAvailable = true;
this.floor = floor;
this.row = row;
this.col = col;
}
// getter and setter
public SpotType getSpotId() {
return spotId;
}
public SpotType getType() {
return spotType;
}
// spot availability checking
public boolean getIsAvailable() {
return isAvailable;
}
public void setIsAvailable(boolean isAvailable) {
this.isAvailable = isAvailable;
}
public int getFloor() {
return floor;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
}
class Floor {
private int number;
private int totalRows;
private int totalCols;
private List<Spot> allCompaSpots;
private List<Spot> allStanSpots;
private List<Spot> allLargeSpots;
private List<Spot> allHandiSpots;
private List<Spot> availableCompaSpots;
private List<Spot> availableStanSpots;
private List<Spot> availableLargeSpots;
private List<Spot> availableHandiSpots;
//private List<Vehicle> vehicles;
public Floor(int number, int totalRows, int totalCols, List<Spot> all...spots, List<Spot> available...Spots, List<Vehicle> vehicles) {
this.number = number;
this.totalRows = totalRows;
this.totalCols = totalCols;
this.allCompaSpots = allCompaSpots;
this.allStanSpots = allStanSpots;
this.allLargeSpots = allLargeSpots;
this.allHandiSpots = allHandiSpots;
this.availableCompaSpots = availableCompaSpots;
this.availableStanSpots = availableStanSpots;
this.availableLargeSpots = availableLargeSpots;
this.availableHandiSpots = availableHandiSpots;
//this.vehicles = vehicles;
}
public boolean isFullCurrLevel() {
return (availableCompaSpots.size() == 0)
&& (availableStanSpots.size() == 0)
&& (availableHandiSpots.size() == 0);
}
public Spot removeAnAvaSpot(SpotType spotType) {
if (spotType == SpotType.COMPACT) {
return removeAnAvaCompaSpot();
} else if (spotType == SpotType.STANDARD) {
return removeAnAvaStanSpot();
} else if (spotType == SpotType.LARGE) {
return removeAnAvaLargeSpot();
} else {
return removeAnAvaHandiSpot();
}
}
public Spot removeAnAvaCompaSpot() {
if (availableCompaSpots.size() == 0) {
return null;
}
Spot availableCompaSpot = availableCompaSpots.get(availableCompaSpots.size() - 1);
availableCompaSpots.remove(availableCompaSpots.size() - 1);
availableCompaSpot.setIsAvailable(false);
return availableCompaSpot;
}
public Spot removeAnAvaStanSpot() {
if (availableStanSpots.size() == 0) {
return null;
}
Spot availableStanSpot = availableStanSpots.get(availableStanSpots.size() - 1);
availableStanSpots.remove(availableStanSpots.size() - 1);
availableStanSpot.setIsAvailable(false);
return availableStanSpot;
}
public Spot removeAnAvaLargeSpot() {
if (availableLargeSpots.size() == 0) {
return null;
}
Spot availableLargeSpot = availableLargeSpots.get(availableLargeSpots.size() - 1);
availableLargeSpots.remove(availableLargeSpots.size() - 1);
availableLargeSpot.setIsAvailable(false);
return availableLargeSpot;
}
public Spot removeAnAvaHandiSpot() {
if (availableHandiSpots.size() == 0) {
return null;
}
Spot availableHandiSpot = availableHandiSpots.get(availableHandiSpots.size() - 1);
availableHandiSpots.remove(availableHandiSpots.size() - 1);
availableHandiSpot.setIsAvailable(false);
return availableHandiSpot;
}
public void addAnAvaSpot(Spot spot) {
spot.setIsAvailable(true);
if (spot.getType() == SpotType.COMPACT) {
availableCompaSpots.add(spot);
} else if (spot.getType() == SpotType.STANDARD) {
availableStanSpots.add(spot);
} else if (spot.getType() == SpotType.LARGE) {
availableLargeSpots.add(spot);
} else {
availableHandiSpots.add(spot);
}
}
// public List<Vehicle> getVehicles() {
// return vehicles;
// }
}
class ParkingSystem {
private List<Floor> floors;
private int totalSpots;
private int availCompaCount;
private int availStanCount;
private int availLargeCount;
private int availHandiCount;
private static final double MINIMUM_FEE = 3.0; // Minimum fee for any parking duration
public ParkingSystem(List<Floor> floors, int totalSpots, int currSpots) {
this.floors = floors;
this.totalSpots = totalSpots;
this.currSpots = currSpots;
}
public boolean isFull() {
return ((availCompaCount == 0) && (availStanCount == 0) && (availLargeCount == 0) && (availHandiCount == 0));
}
public boolean parking(Vehicle vehicle) {
Spot currSpot = findASpot(vehicle);
if (currSpot == null) {
return false;
} else {
vehicle.setStart();
vehicle.setSpot(currSpot);
return true;
}
}
public Spot findASpot(Vehicle vehicle) {
VehicleSize currVehiSize = vehicle.vehiSize;
for (Floor floor : floors) {
if (vehicle.isDisable) {
if (floor.availableHandiSpots.size() != 0) {
return floor.removeAnAvaSpot(HANDICAPPED);
}
}
if (currVehiSize == VehicleSize.COMPACT) {
if (floor.availableCompaSpots.size() != 0) {
return floor.removeAnAvaSpot(COMPACT);
} else if (floor.availableCompaSpots.size() != 0) {
return floor.removeAnAvaSpot(STANDARD);
} else {
return null;
}
} else if (currVehiSize == VehicleSize.STANDARD) {
if (floor.availableStanSpots.size() != 0) {
return floor.removeAnAvaSpot(STANDARD);
} else if (floor.availableLargeSpots.size() != 0) {
return floor.removeAnAvaSpot(LARGE);
} else {
return null;
}
} else {
if (floor.availableLargeSpots.size() != 0) {
return floor.removeAnAvaSpot(Large);
} else {
return null;
}
}
}
}
public double leave(Vehicle vehicle) {
double pay = calculatePrice(vehicle);
Spot currSpot = vehicle.getSpot();
Floor floor = floors.get(currSpot.getFloor());
floor.addAnAvaSpot(currSpot);
return pay;
}
public double calculatePrice(Vehicle vehicle) {
LocalDateTime start = vehicle.getStart();
SpotType type = vehicle.getSpot().getType();
double pricePerHour = 0.0;
if (type == SpotType.COMPACT) {
pricePerHour = 2.0;
} else if (type == SpotType.STANDARD) {
pricePerHour = 2.0;
} else if (type == SpotType.LARGE) {
pricePerHour = 3.0;
} else {
pricePerHour = 1.5;
}
Duration duration = Duration.between(start, LocalDateTime.now());
int hoursParked = duration.toHours();
double totalPrice = hoursParked * pricePerHour;
if (totalPrice < MINIMUM_FEE) {
return MINIMUM_FEE; // Return the minimum fee if parking duration is less than pricing threshold
}
return totalPrice;
}
}