· 6 years ago · Dec 20, 2019, 01:44 PM
1{"errors":[],"files":[{"path":"EX05ParkingLot.iml","contents":"<file in binary format or unable to read file>"},{"path":"src/ee/taltech/iti0202/parking/car/Car.java","contents":"package ee.taltech.iti0202.parking.car;\nimport ee.taltech.iti0202.parking.City;\nimport ee.taltech.iti0202.parking.parkinglot.ParkingLot;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Represents a car with priority and size.\n * The size can be one of 1, 2, 4 (the code doesn't have to validate it).\n * This class implements Comparable interface.\n * This allows objects to be sorted in priority queue (or for sorting in general).\n * Cars with highest priority will be taken first, then with the \"priority\" priority\n * and then all the common cars.\n * If there are cars with the same priority, prefer cars with lower size.\n * So highest-1 (priority status-size) comes before highest-2 which comes before priority-1.\n */\npublic class Car implements Comparable<Car> {\n\n private int value = 1;\n\n private ParkingLot parkingLot;\n\n public enum PriorityStatus {\n HIGHEST, PRIORITY, COMMON\n }\n\n private final Map<String, Integer> priority = new HashMap<>() {{\n put(\"HIGHEST\", 1);\n put(\"PRIORITY\", 2);\n put(\"COMMON\", 3);\n }};\n private PriorityStatus status;\n private int size;\n private boolean parked;\n private boolean wantsToBe;\n\n @Override\n public int compareTo(Car o) {\n\n if (priority.get(this.getPriorityStatus().toString()) > priority.get(o.getPriorityStatus().toString())) {\n return 1;\n } else {\n if (priority.get(this.getPriorityStatus().toString()) < priority.get(o.getPriorityStatus().toString())) {\n return -1;\n } else {\n if (this.getSize() > o.getSize()) {\n return 1;\n } else if (this.getSize() < o.getSize()) {\n return -1;\n }\n return 0;\n }\n }\n }\n\n\n public Car(PriorityStatus status, int size) {\n this.parked = false;\n this.size = size;\n this.status = status;\n this.wantsToBe = true;\n }\n\n /**\n * Gets the priority of the car.\n *\n * @return PriorityStatus\n */\n public PriorityStatus getPriorityStatus() {\n return status;\n }\n\n /**\n * Gets the size of the car.\n *\n * @return Size.\n */\n\n public void setSize(int size) {\n this.size = size;\n }\n\n /**\n * Finish parking. This car has finished parking.\n * The car should be removed from parking lot\n * (its slots will be empty).\n * Returns false, if the car is not parked currently.\n * Otherwise returns true.\n *\n * @return True if the car was parking, false otherwise.\n */\n\n public boolean unpark() {\n\n if (getParkingLot() != null) {\n this.parked = false;\n this.wantsToBe = false;\n City.decreasePark(this);\n parkingLot.depark();\n this.setParkingLot(null);\n return true;\n }\n\n return false;\n }\n\n public boolean isWantsToBe() {\n return wantsToBe;\n }\n\n public void setWantsToBe(boolean bool) {\n this.wantsToBe = bool;\n }\n\n public void setParked(boolean state) {\n this.parked = state;\n }\n\n public boolean isParked() {\n return parked;\n }\n\n public ParkingLot getParkingLot() {\n return parkingLot;\n }\n\n public void setParkingLot(ParkingLot lot) {\n this.parkingLot = lot;\n }\n\n public int getValue() {\n return value;\n }\n\n public void setValue(int i) {\n this.value = i;\n }\n\n public int getSize() {\n return size;\n }\n\n public int getRelativeSize() {\n return value * size;\n }\n\n @Override\n public String toString() {\n return this.getPriorityStatus().toString().substring(0, 1) + this.getSize();\n }\n\n}\n"},{"path":"src/ee/taltech/iti0202/parking/City.java","contents":"package ee.taltech.iti0202.parking;\nimport ee.taltech.iti0202.parking.car.Car;\nimport ee.taltech.iti0202.parking.parkinglot.MultiLevelParkingLot;\nimport ee.taltech.iti0202.parking.parkinglot.ParkingLot;\nimport ee.taltech.iti0202.parking.parkinglot.PriorityParkingLot;\nimport ee.taltech.iti0202.parking.parkinglot.SmallCarParkingLot;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.stream.Collectors;\nimport java.util.stream.IntStream;\n\nimport static java.lang.System.out; //sout\n\n\npublic class City {\n\n static Map<String, Integer> carsInLot;\n static ArrayList<ParkingLot> parkingLots;\n String name;\n\n public City(String name) {\n System.gc();\n this.name = name;\n parkingLots = new ArrayList<>();\n carsInLot = new HashMap<>() {{\n put(\"H1\", 0);\n put(\"H2\", 0);\n put(\"H4\", 0);\n put(\"P1\", 0);\n put(\"P2\", 0);\n put(\"P4\", 0);\n put(\"C1\", 0);\n put(\"C2\", 0);\n put(\"C4\", 0);\n }};\n }\n\n /**\n * Gets all parking lots in this city.b\n *\n * @return List of parking lots.\n **/\n public static List<ParkingLot> getParkingLots() {\n return parkingLots;\n }\n\n public static void decreasePark(Car car) {\n carsInLot.put(car.toString(), carsInLot.get(car.toString()) - 1);\n }\n\n /**\n * Return a map where for every priority-size pair a count of cars is mapped.\n * Keys are in format XY\n * where X = {H, P, C} (highest, priority, common)\n * Y = {1, 2, 4} size\n *\n * @return map with priority-size counts\n */\n\n public static Map<String, Integer> getParkedCarCountBySizeAndPriority() {\n return carsInLot;\n }\n\n public static void main(String[] args) {\n long startTime = System.currentTimeMillis();\n City tallinn = new City(\"Tallinn\");\n SmallCarParkingLot small = new SmallCarParkingLot(1, 1);\n tallinn.addParkingLot(small);\n IntStream.range(0, 1000).mapToObj(i -> h1()).forEach(tallinn::parkCar);\n out.print(tallinn.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 1));\n float estimatedTime = (System.currentTimeMillis() - startTime) / 1000f;\n out.println(\"\\tin sec:\\t\" + estimatedTime);\n out.println(small.times);\n }\n\n /**\n * Gets car count in queue by priority status and size.\n *\n * @param priorityStatus (highest, priority, common)\n * @param size (1, 2, 4)\n * @return Count of cars in queue.\n */\n public int getCarCountInQueue(Car.PriorityStatus priorityStatus, int size) {\n int amount = 0;\n for (ParkingLot lot : getParkingLots()) {\n amount += lot.getQueueCars().stream().filter(c -> c.getSize() == size)\n .filter(c -> c.getPriorityStatus() == priorityStatus).count();\n }\n return amount;\n }\n\n /**\n * Gets parked car count by priority status and size.\n *\n * @param priorityStatus (highest, priority, common)\n * @param size (1, 2, 4)\n * @return Count of parked cars.\n */\n public int getParkedCarCount(Car.PriorityStatus priorityStatus, int size) {\n int amount = 0;\n for (ParkingLot lot : getParkingLots()) {\n amount += lot.getParkedCars().parallelStream().filter(c -> c.getSize() == size)\n .filter(c -> c.getPriorityStatus() == priorityStatus).count();\n }\n return amount;\n }\n\n private static Car h1() {\n return new Car(Car.PriorityStatus.HIGHEST, 1);\n }\n\n private static Car h2() {\n return new Car(Car.PriorityStatus.HIGHEST, 2);\n }\n\n private static void parkAll(City tallinn, Car c1, Car ch2, Car ch3, Car ch4) {\n\n out.print(tallinn.parkCar(c1));\n out.print(\"\\t\");\n out.print(tallinn.parkCar(ch2));\n out.print(\"\\t\");\n out.print(tallinn.parkCar(ch3));\n out.print(\"\\t\");\n out.print(tallinn.parkCar(ch4));\n out.print(\"\\n\");\n }\n\n private static void multiParkingLotAddThenRemoveAndAddAgain(City tallinn, Car c1, Car ch2,\n Car ch3, Car ch4, MultiLevelParkingLot multi) {\n tallinn.addParkingLot(multi);\n\n out.println(c1.getRelativeSize());\n out.println(c1.getParkingLot());\n out.println(c1.isParked());\n out.println(c1.isWantsToBe());\n\n parkAll(tallinn, c1, ch2, ch3, ch4);\n\n multi(multi);\n\n out.println(c1.unpark());\n out.println(ch3.unpark());\n out.println(ch2.unpark());\n\n multi(multi);\n\n parkAll(tallinn, c1, ch2, ch3, ch4);\n\n out.println(c1.getRelativeSize());\n out.println(c1.getParkingLot());\n out.println(c1.isParked());\n out.println(c1.isWantsToBe());\n\n multi(multi);\n }\n\n private static void multi(MultiLevelParkingLot multiLevelParkingLot) {\n out.println();\n out.println(\"Multi:\");\n out.println();\n out.println(\"Table: \");\n out.println(multiLevelParkingLot.getTable());\n out.print(\"Parked cars: \");\n out.println(multiLevelParkingLot.getParkedCars());\n out.print(\"Queue cars:\\t\");\n out.println(multiLevelParkingLot.getQueueCars());\n out.println();\n }\n\n\n private static void small(SmallCarParkingLot smallCarParkingLot) {\n out.println();\n out.println(\"Small:\");\n out.println();\n out.println(\"Table: \");\n out.println(smallCarParkingLot.getTable());\n out.print(\"Parked cars: \");\n out.println(smallCarParkingLot.getParkedCars());\n out.print(\"Queue cars: \");\n out.println(smallCarParkingLot.getQueueCars());\n out.println();\n }\n\n private static void medium(PriorityParkingLot priorityParkingLot) {\n out.println();\n out.println(\"Medium:\");\n out.println();\n out.println(\"Table: \");\n out.println(priorityParkingLot.getTable());\n out.print(\"Parked cars:\\t\");\n out.println(priorityParkingLot.getParkedCars());\n out.print(\"Queue cars:\\t\");\n out.println(priorityParkingLot.getQueueCars());\n out.println();\n }\n\n /**\n * Adds a parking lot.\n * A parking lot can exist only once.\n *\n * @param parkingLot Parking lot to be added.\n * @return true if parking lot was added.\n */\n\n public boolean addParkingLot(ParkingLot parkingLot) {\n if (parkingLots.contains(parkingLot)) {\n return false;\n }\n parkingLots.add(parkingLot);\n return true;\n\n }\n\n /**\n * Tries to send a car to a parking lot.\n * If the parking lot accepts this car\n * the car will be added to the queue of the parking lot.\n * The chosen parking lot is returned.\n * If several parking lots can take the car, use the one\n * with the smallest queue.\n * If several have the same size queue, use the one\n * which was added earlier.\n * Or empty in case the car cannot be parked anywhere\n * or the car has already been parked or is in queue.\n *\n * @param car Car to be sent to parking lot\n * @return Parking lot where the car will be sent into queue.\n * empty() in case no parking lot is suitable.\n */\n public Optional<ParkingLot> parkCar(Car car) {\n car.setWantsToBe(true);\n if (!getParkingLots().isEmpty() && getParkingLots().parallelStream()\n .filter(x -> x.getQueueCars().contains(car))\n .noneMatch(x -> x.getParkedCars().contains(car)) && !car.isParked()) {\n getParkingLots().forEach(x -> x.setProcessQueue(x.getSpaceAvailable() != 0));\n getParkingLots().forEach(x -> x.buffer = car);\n List<ParkingLot> temp = getParkingLots().parallelStream().filter(ParkingLot::accepts)\n .collect(Collectors.toList());\n if (temp.isEmpty()) {\n return Optional.empty();\n }\n ParkingLot best = null;\n for (ParkingLot lot : temp) {\n if (best == null) {\n best = lot;\n } else if (best.getQueueLen() > lot.getQueueLen()) {\n best = lot;\n }\n }\n Optional<ParkingLot> lotOptional = Optional.of(best);\n boolean success = lotOptional.get().addToQueue(car);\n best.processQueue();\n if (success) {\n car.setParkingLot(best);\n return lotOptional;\n }\n }\n return Optional.empty();\n }\n}\n"},{"path":"src/ee/taltech/iti0202/parking/parkinglot/MultiLevelParkingLot.java","contents":"package ee.taltech.iti0202.parking.parkinglot;\n\nimport ee.taltech.iti0202.parking.car.Car;\n\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Modern parking lot located under ground.\n * The parking lot has several levels.\n * Always prefer the smallest level (starting from 1).\n * If the car cannot fit to a level, then proceed to the next level.\n * <p>\n * This parking lot only accepts maximum 10 vehicle in the queue.\n * So, if there queue already has 10 cars, this parking lot should not\n * be available for new cars.\n */\n\npublic class MultiLevelParkingLot extends ParkingLot {\n\n /**\n * Initialize the parking slot with the given width and height.\n *\n * @param height Length of verical side.\n * @param width Length of horizontal side.\n * @param levels Number of levels.\n */\n private Integer levels;\n\n public MultiLevelParkingLot(int height, int width, int levels) {\n super(height, width);\n this.levels = levels;\n this.setSpaceAvailable(height * width * levels * 2);\n }\n\n @Override\n public int getSize() {\n return getHeight() * getWidth() * levels;\n }\n\n @Override\n public void processQueue() {\n\n\n List<Car> temp = new LinkedList<>(getQueueCars(\"\"));\n for (Car car : temp) {\n if (!car.isWantsToBe()) {\n depark();\n } else if (this.getSpaceAvailable() >= car.getSize()) {\n queueToLot(car);\n\n }\n }\n\n }\n\n\n /**\n * Here you have to override getTable() method.\n * The method gets a string for each level\n * separated by \"---\":\n * <p>\n * P3P3..\n * P3P3..\n * ......\n * ......\n * ---\n * ......\n * ......\n * ......\n * ......\n * <p>\n * This has 2 levels and there is a large (size 2) car on first level.\n *\n * @return String representation of multilevel parking lot\n */\n\n @Override\n public String getTable() {\n processQueue();\n this.setNeedUpdate(false);\n StringBuilder layers = new StringBuilder();\n List<Car> original = List.copyOf(getParkedCars(\"\"));\n clearTemp();\n\n for (int i = 0; i < levels; i++) {\n layers.append(super.getTable());\n if (i + 1 < levels) {\n layers.append(\"---\\n\");\n }\n List<Car> temp = new ArrayList<>(getParkedCars(\"\"));\n temp.removeAll(getTemp());\n setParkedCars(temp);\n }\n\n setParkedCars(original);\n this.setNeedUpdate(true);\n return layers.toString();\n\n }\n\n @Override\n public boolean accepts() {\n return this.getQueueCars().size() < 10 && super.accepts();\n }\n}\n"},{"path":"src/ee/taltech/iti0202/parking/parkinglot/ParkingLot.java","contents":"package ee.taltech.iti0202.parking.parkinglot;\nimport ee.taltech.iti0202.parking.City;\nimport ee.taltech.iti0202.parking.car.Car;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.PriorityQueue;\n\n\n/**\n * xxxxxxx\n * Parking lot is a rectangular area with fixed with and height.\n * Well, rather 2 dimensions on the ground,ä\n * but as you represent in on the screen, then height can be seen as\n * the vertical axis.u,\n * The rectangle is filled with parking slots.z\n * 3 x 4 parking lot has 12ty7y slots.\n * The size of a slot is 2 units.\n * This means, that carr with size 2 fits there perfectly.\n * Car with size 1 takes half the slot, so it could be\n * theoretically shared between 2 small cars.\n * Car with size 4 takes two consecutive slots.,\n * <p>\n * Each concrete parking lot type (subclass)\n * has its own rules about which cars it accepts\n * in its queue and how the queue is pddrodcessedd.\n * See the class description for more information.\n */\n\npublic abstract class ParkingLot {\n\n private final int width;\n private final int height;\n\n public int times = 0;\n private List<Car> carList;\n private PriorityQueue<Car> carQueue;\n public Car buffer;\n private int spaceAvailable;\n private List<Car> temp;\n private boolean needUpdate = true;\n private boolean newWorldOrder = false;\n private boolean getParkedBoy = false;\n private boolean processQueue = true;\n\n /**\n * Initialize the parking slot/s with the given width and height.\n *\n * @param height Length of vertical side.\n * @param width Length of horizontal side.\n */\n public ParkingLot(int height, int width) {\n this.width = width;\n this.height = height;\n this.spaceAvailable = height * width * 2;\n this.carList = new ArrayList<>();\n this.carQueue = new PriorityQueue<>();\n clearTemp();\n }\n\n public boolean isProcessQueue() {\n return processQueue;\n }\n\n public void setProcessQueue(boolean b) {\n this.processQueue = b;\n }\n\n public void setNewWorldOrder(boolean bool) {\n this.newWorldOrder = bool;\n }\n\n public void setGetParkedBoy(boolean bool) {\n this.getParkedBoy = bool;\n }\n\n public int getSize() {\n return height * width;\n }\n\n public void clearTemp() {\n this.temp = new ArrayList<>();\n }\n\n public List<Car> getTemp() {\n return temp;\n\n }\n\n public void setNeedUpdate(boolean state) {\n this.needUpdate = state;\n }\n\n public int getQueueLen() {\n return this.getQueueCars(\"\").size();\n }\n\n public void setBuffer(Car car) {\n this.buffer = car;\n }\n\n public int getWidth() {\n return width;\n }\n\n public int getHeight() {\n return height;\n }\n\n public int getSpaceAvailable() {\n return this.spaceAvailable;\n }\n\n public void setSpaceAvailable(Integer integer) {\n this.spaceAvailable = integer;\n }\n\n\n public void queueToLot(Car car) {\n\n this.spaceAvailable -= car.getRelativeSize();\n car.setParked(true);\n this.carQueue.remove(car);\n List<Car> newList = new ArrayList<>(List.copyOf(carList));\n newList.add(car);\n setParkedCars(newList);\n }\n\n public void lotToQueue(Car car) {\n this.spaceAvailable += car.getRelativeSize();\n car.setParked(false);\n this.carQueue.add(car);\n List<Car> newList = new ArrayList<>(List.copyOf(carList));\n newList.remove(car);\n setParkedCars(newList);\n }\n\n public void depark() {\n List<Car> temp = new ArrayList<>(getParkedCars(\"Hi mom!\"));\n for (Car car1 : temp) {\n if (!car1.isWantsToBe()) {\n lotToQueue(car1);\n }\n }\n temp = new ArrayList<>(getQueueCars(\"Hi dad!\"));\n for (Car car1 : temp) {\n if (!car1.isWantsToBe()) {\n this.carQueue.remove(car1);\n City.decreasePark(car1);\n }\n }\n }\n\n public boolean addToQueue(Car car) {\n setBuffer(car);\n if (car.getParkingLot() != null\n || getQueueCars(\"\").contains(car)\n || City.getParkingLots().stream().anyMatch(x -> x.getParkedCars().contains(car))\n || !accepts() || car.isParked()) {\n return false;\n }\n City.getParkedCarCountBySizeAndPriority().put(car.toString(),\n City.getParkedCarCountBySizeAndPriority().get(car.toString()) + 1);\n carQueue.add(car);\n car.setParkingLot(this);\n return true;\n }\n\n /**\n * Processes the queue.\n * <p>\n * The cars are taken from the queue in specified order.\n * If the first car in the queue cannot be parked\n * the process will wait. Also, if the queue is empty, process waits.\n * Otherwise the process should be \"running\" all the time.\n * In reality you should call this method from other methods\n * which could initialize the process.\n */\n public abstract void processQueue();\n\n\n /**\n * Returns a list of parked cars in the order they were received from the queue.\n *\n * @return A list of parked cars.\n */\n public List<Car> getParkedCars() {\n processQueue();\n return carList;\n }\n\n public List<Car> getParkedCars(String mom) {\n return carList;\n }\n\n public void setParkedCars(List<Car> cars) {\n this.carList = cars;\n }\n\n public List<Car> getQueueCars() {\n processQueue();\n return new ArrayList<>(carQueue);\n }\n\n public List<Car> getQueueCars(String dad) {\n return new ArrayList<>(carQueue);\n }\n\n /**\n * Returns string presentation of the parking lot.\n * <p>\n * Each slot takes 2x2 chars.\n * Size 1 is represented fby 1x2 (height, width) area\n * Empty slot is represented by dots (.):\n * <p>\n * Empty table with width 3, height 2:\n * ......\n * ......\n * ......\n * ......\n * <p>\n * One large priority car:\n * P3P3..\n * P3P3..\n * ......\n * ......\n * <p>\n * + one small highest priority car:\n * P3P3H1\n * P3P3..\n * ......\n * ......\n * <p>\n * + medium common car:\n * P3P3H1\n * P3P3..\n * C2....\n * C2....\n *\n * @return String representation of the parking lot\n */\n\n public String getTable() {\n\n if (needUpdate) {\n processQueue();\n }\n\n String[][] canvas = new String[height * 2][width];\n for (int y = 0; y < height * 2; y++) {\n for (int x = 0; x < width; x++) {\n canvas[y][x] = \"..\";\n }\n }\n\n\n for (Car car : getParkedCars(\"\")) {\n boolean go = true;\n for (int x = 0; x < width; x++) {\n for (int y = 0; y < height * 2; y++) {\n if (go) {\n if (car.getRelativeSize() == 1 && !(newWorldOrder && y % 2 == 1)) {\n if (canvas[y][x].equals(\"..\")) {\n if (getParkedBoy && y % 2 == 1) {\n if (canvas[y - 1][x].equals(car.toString())) {\n canvas[y][x] = car.toString();\n temp.add(car);\n go = false;\n }\n } else {\n canvas[y][x] = car.toString();\n temp.add(car);\n go = false;\n }\n\n }\n } else if (car.getRelativeSize() == 2 && y % 2 == 0) {\n if (y + 1 < canvas.length\n && canvas[y][x].equals(\"..\")\n && canvas[y + 1][x].equals(\"..\")) {\n if (getParkedBoy && car.getSize() == 1) {\n canvas[y][x] = car.toString();\n canvas[y + 1][x] = \"__\";\n } else {\n canvas[y][x] = car.toString();\n canvas[y + 1][x] = car.toString();\n }\n\n temp.add(car);\n go = false;\n }\n\n } else if (car.getRelativeSize() == 4 && y % 2 == 0) {\n if (x + 1 < canvas[y].length\n && canvas[y][x].equals(\"..\")\n && canvas[y][x + 1].equals(\"..\")\n && y + 1 < canvas.length && canvas[y][x].equals(\"..\")\n && canvas[y + 1][x].equals(\"..\")\n && canvas[y + 1][x + 1].equals(\"..\")) {\n\n canvas[y][x] = car.toString();\n canvas[y][x + 1] = car.toString();\n canvas[y + 1][x + 1] = car.toString();\n canvas[y + 1][x] = car.toString();\n temp.add(car);\n go = false;\n } else if (canvas[y][x].equals(\"..\")\n && y + 3 < canvas.length\n && canvas[y + 1][x].equals(\"..\")\n && canvas[y + 2][x].equals(\"..\")\n && canvas[y + 3][x].equals(\"..\")) {\n\n canvas[y][x] = car.toString();\n canvas[y + 1][x] = car.toString();\n canvas[y + 2][x] = car.toString();\n canvas[y + 3][x] = car.toString();\n temp.add(car);\n go = false;\n\n } else if (canvas[y][x].equals(\"..\")\n && x + 3 < canvas[y].length\n && canvas[y][x + 1].equals(\"..\")\n && canvas[y][x + 2].equals(\"..\")\n && canvas[y][x + 3].equals(\"..\")) {\n\n canvas[y][x] = car.toString();\n canvas[y][x + 1] = car.toString();\n canvas[y][x + 2] = car.toString();\n canvas[y][x + 3] = car.toString();\n temp.add(car);\n go = false;\n\n }\n }\n }\n }\n }\n }\n\n StringBuilder sb = new StringBuilder();\n for (String[] s : canvas) {\n for (String c : s) {\n sb.append(c);\n\n }\n sb.append(\"\\n\");\n }\n\n return sb.toString();\n }\n\n public boolean accepts() {\n return !buffer.isParked() && City.getParkingLots().stream()\n .noneMatch(x -> x.getParkedCars(\"\").contains(buffer))\n && City.getParkingLots().stream().noneMatch(x -> x.getQueueCars(\"\").contains(buffer));\n }\n\n\n}\n"},{"path":"src/ee/taltech/iti0202/parking/parkinglot/PriorityParkingLot.java","contents":"package ee.taltech.iti0202.parking.parkinglot;\n\nimport ee.taltech.iti0202.parking.car.Car;\n\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n/**\n * xxx xxx\n * Accepts all cars if the queue size is less than 5.\n * Small car (size 1) with the highest priority can park alone.\n * Otherwise small cars (size 1) can share a slot ifd they have the same priority.\n * If there are cars with highest priority in the queue, then cars with common priority (if parked)\n * will be sent to the queue to make room for highest priority cars (life is unfair).\n */\npublic class PriorityParkingLot extends ParkingLot {\n /**\n * Initialize the parking slot with the given width and height.\n *\n * @param height Length of vertical side.\n * @param width Length of horizontal side.\n */\n public PriorityParkingLot(int height, int width) {\n super(height, width);\n }\n\n @Override\n public void processQueue() {\n\n List<Car> temp = new ArrayList<>(getQueueCars(\"Hi dad!\"));\n boolean possible;\n Car remove = null;\n for (Car car : temp) {\n possible = true;\n\n if (car.getRelativeSize() == 1 && car.getPriorityStatus() == Car.PriorityStatus.HIGHEST) {\n car.setValue(2);\n }\n\n if (car.getPriorityStatus() == Car.PriorityStatus.HIGHEST && getParkedCars(\"\")\n .stream().anyMatch(c -> c.getPriorityStatus() != Car.PriorityStatus.HIGHEST)\n && this.getSpaceAvailable() < car.getRelativeSize()) {\n if (this.getSpaceAvailable() < car.getRelativeSize()) {\n while (this.getSpaceAvailable() < car.getRelativeSize()) {\n List<Car> all = getParkedCars(\"\").stream()\n .filter(x -> x.getPriorityStatus() == Car.PriorityStatus.COMMON)\n .sorted(Comparator.comparing(Car::getSize))\n .collect(Collectors.toList());\n if (!all.isEmpty()) {\n remove = all.get(0);\n }\n if (remove == null) {\n possible = false;\n break;\n }\n lotToQueue(remove);\n }\n }\n if (possible) queueToLot(car);\n } else {\n if (this.getSpaceAvailable() >= car.getRelativeSize()) {\n queueToLot(car);\n }\n\n }\n }\n }\n\n @Override\n public boolean accepts() {\n return this.getQueueCars().size() < 5 && super.accepts();\n }\n\n @Override\n public String getTable() {\n setGetParkedBoy(true);\n String answer = super.getTable();\n setGetParkedBoy(false);\n return answer.replace(\"__\", \"..\");\n }\n}\n"},{"path":"src/ee/taltech/iti0202/parking/parkinglot/SmallCarParkingLot.java","contents":"package ee.taltech.iti0202.parking.parkinglot;\n\nimport ee.taltech.iti0202.parking.car.Car;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * This parking lot only accepts smal cars (size 1).\n * Each parking slot only accepts one cr.\n */\n\npublic class SmallCarParkingLot extends ParkingLot {\n /**\n * Initialize the parking slot with the given width and height.\n *\n * @param height\n * @param width\n */\n public SmallCarParkingLot(int height, int width) {\n super(height, width);\n System.gc();\n setSpaceAvailable(getSpaceAvailable() / 2);\n }\n\n @Override\n public void processQueue() {\n if (isProcessQueue()) {\n times += 1;\n\n List<Car> temp = new ArrayList<>(getQueueCars(\"\"));\n\n for (Car car : temp) {\n if (this.getSpaceAvailable() >= getQueueCars(\"\").get(0).getSize()) {\n queueToLot(car);\n }\n }\n }\n\n }\n\n @Override\n public boolean accepts() {\n return buffer != null && buffer.getSize() == 1 && super.accepts();\n }\n\n @Override\n public String getTable() {\n setNewWorldOrder(true);\n String table = super.getTable();\n setNewWorldOrder(false);\n return table;\n\n }\n}\n"}],"testFiles":[{"path":".gitkeep","contents":"<file in binary format or unable to read file>"},{"path":"checkstyle.xml","contents":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE module PUBLIC \"-//Puppy Crawl//DTD Check Configuration 1.2//EN\" \"http://www.puppycrawl.com/dtds/configuration_1_2.dtd\">\n<!--\n\n Checkstyle configuration that checks the sun coding conventions from:\n\n - the Java Language Specification at\n http://java.sun.com/docs/books/jls/second_edition/html/index.html\n\n - the Sun Code Conventions at http://java.sun.com/docs/codeconv/\n\n - the Javadoc guidelines at\n http://java.sun.com/j2se/javadoc/writingdoccomments/index.html\n\n - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html\n\n - some best practices\n\n Checkstyle is very configurable. Be sure to read the documentation at\n http://checkstyle.sf.net (or in your downloaded distribution).\n\n Most Checks are configurable, be sure to consult the documentation.\n\n To completely disable a check, just comment it out or delete it from the file.\n\n Finally, it is worth reading the documentation.\n\n-->\n<module name=\"Checker\">\n <property name=\"charset\" value=\"UTF-8\"/>\n <!--\n If you set the basedir property below, then all reported file\n names will be relative to the specified directory. See\n http://checkstyle.sourceforge.net/5.x/config.html#Checker\n\n <property name=\"basedir\" value=\"${basedir}\"/>\n -->\n\n <!-- Checks that a package-info.java file exists for each package. -->\n <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->\n <!--\n <module name=\"JavadocPackage\"/>\n -->\n\n <!-- Checks whether files end with a new line. -->\n <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->\n <module name=\"NewlineAtEndOfFile\">\n <property name=\"fileExtensions\" value=\"java, xml, py, css, fxml\"/>\n </module>\n\n <!-- Checks that property files contain the same keys. -->\n <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->\n <module name=\"Translation\"/>\n\n <!-- Checks for Size Violations. -->\n <!-- See http://checkstyle.sf.net/config_sizes.html -->\n <module name=\"FileLength\"/>\n\n <!-- Checks for whitespace -->\n <!-- See http://checkstyle.sf.net/config_whitespace.html -->\n <module name=\"FileTabCharacter\"/>\n\n <!-- Miscellaneous other checks. -->\n <!-- See http://checkstyle.sf.net/config_misc.html -->\n <module name=\"RegexpSingleline\">\n <property name=\"format\" value=\"\\s+$\"/>\n <property name=\"minimum\" value=\"0\"/>\n <property name=\"maximum\" value=\"0\"/>\n <property name=\"message\" value=\"Line has trailing spaces.\"/>\n </module>\n\n <module name=\"TreeWalker\">\n\n <!-- Checks for Javadoc comments. -->\n <!-- See http://checkstyle.sf.net/config_javadoc.html -->\n\n\n <!-- Checks for Naming Conventions. -->\n <!-- See http://checkstyle.sf.net/config_naming.html -->\n <module name=\"ConstantName\"/>\n <!--\n <module name=\"LocalFinalVariableName\"/>\n -->\n <module name=\"LocalVariableName\"/>\n <module name=\"MemberName\"/>\n <module name=\"MethodName\"/>\n <module name=\"PackageName\"/>\n <module name=\"ParameterName\"/>\n <module name=\"StaticVariableName\"/>\n <module name=\"TypeName\"/>\n\n\n <!-- Checks for Headers -->\n <!-- See http://checkstyle.sf.net/config_header.html -->\n <!-- <module name=\"Header\"> -->\n <!-- The follow property value demonstrates the ability -->\n <!-- to have access to ANT properties. In this case it uses -->\n <!-- the ${basedir} property to allow Checkstyle to be run -->\n <!-- from any directory within a project. See property -->\n <!-- expansion, -->\n <!-- http://checkstyle.sf.net/config.html#properties -->\n <!-- <property -->\n <!-- name=\"headerFile\" -->\n <!-- value=\"${basedir}/java.header\"/> -->\n <!-- </module> -->\n\n <!-- Following interprets the header file as regular expressions. -->\n <!-- <module name=\"RegexpHeader\"/> -->\n\n\n <!-- Checks for imports -->\n <!-- See http://checkstyle.sf.net/config_import.html -->\n <module name=\"AvoidStarImport\"/>\n <module name=\"IllegalImport\"/> <!-- defaults to sun.* packages -->\n <module name=\"RedundantImport\"/>\n <module name=\"UnusedImports\"/>\n\n\n <!-- Checks for Size Violations. -->\n <!-- See http://checkstyle.sf.net/config_sizes.html -->\n <module name=\"LineLength\">\n <property name=\"max\" value=\"120\"/>\n </module>\n <module name=\"MethodLength\"/>\n <module name=\"ParameterNumber\"/>\n\n\n <!-- Checks for whitespace -->\n <!-- See http://checkstyle.sf.net/config_whitespace.html -->\n <module name=\"EmptyForIteratorPad\"/>\n <module name=\"GenericWhitespace\"/>\n <module name=\"MethodParamPad\"/>\n <module name=\"NoWhitespaceAfter\"/>\n <module name=\"NoWhitespaceBefore\"/>\n <module name=\"OperatorWrap\"/>\n <module name=\"ParenPad\"/>\n <module name=\"TypecastParenPad\"/>\n <module name=\"WhitespaceAfter\"/>\n <module name=\"WhitespaceAround\"/>\n\n\n <!-- Modifier Checks -->\n <!-- See http://checkstyle.sf.net/config_modifiers.html -->\n <module name=\"ModifierOrder\"/>\n <module name=\"RedundantModifier\"/>\n\n\n <!-- Checks for blocks. You know, those {}'s -->\n <!-- See http://checkstyle.sf.net/config_blocks.html -->\n <module name=\"AvoidNestedBlocks\"/>\n <module name=\"EmptyBlock\"/>\n <module name=\"LeftCurly\"/>\n <module name=\"NeedBraces\">\n <property name=\"allowSingleLineStatement\" value=\"true\"/>\n </module>\n <module name=\"RightCurly\"/>\n\n\n <!-- Checks for common coding problems -->\n <!-- See http://checkstyle.sf.net/config_coding.html -->\n <!-- module name=\"AvoidInlineConditionals\"/ -->\n <module name=\"EmptyStatement\"/>\n <module name=\"EqualsHashCode\"/>\n <!--\n <module name=\"HiddenField\">\n <property name=\"ignoreSetter\" value=\"true\"/>\n </module>\n -->\n <module name=\"IllegalInstantiation\"/>\n <module name=\"InnerAssignment\"/>\n <module name=\"MagicNumber\">\n <property name=\"ignoreNumbers\" value=\"-5,-4,-3,-2,-1,0,1,2,3,4,5,10,100,1000\"/>\n </module>\n <module name=\"MissingSwitchDefault\"/>\n <module name=\"SimplifyBooleanExpression\"/>\n <module name=\"SimplifyBooleanReturn\"/>\n\n <!-- Checks for class design -->\n <!-- See http://checkstyle.sf.net/config_design.html -->\n <!--\n <module name=\"DesignForExtension\"/>\n -->\n <module name=\"FinalClass\"/>\n <!--\n <module name=\"HideUtilityClassConstructor\"/>\n -->\n <module name=\"InterfaceIsType\"/>\n <!--\n <module name=\"VisibilityModifier\"/>\n -->\n\n\n <!-- Miscellaneous other checks. -->\n <!-- See http://checkstyle.sf.net/config_misc.html -->\n <module name=\"ArrayTypeStyle\"/>\n <!--\n <module name=\"FinalParameters\"/>\n -->\n <module name=\"TodoComment\"/>\n <module name=\"UpperEll\"/>\n\n </module>\n\n\n</module>"},{"path":"parking.md","contents":"# Parking\n\nMoodul: ``EX05ParkingLot``\n\nPakk: ``ee.taltech.iti0202.parking``\n\n`Ülesandel pole veel teste.`\n\nSa oled saanud vastutusrikka ülesande: luua infosüsteem linna parkimisaladele. (10 minutit hiljem.) Ja siis sa realiseeridki selle.\n\n## Üldine\n\nLinnas võib olla mitu parkimisala (ParkingLot). Antud süsteemi raames tuleb realiseerida kolm erinevat tüüpi parkimisala. Igal parkimisalal on omad reeglid, kuidas sõidukeid sinna paigutatakse. Sõidukil on kaks omadust: prioriteet ja suurus. Neid tuleb arvesse võtta vastavalt parkimisala reeglitele. \n\nÜldised reeglid:\n\n- parkimisala on ristkülikukujuline\n- parkimisala loomisel antakse sellele kaasa külgede pikkus\n- parkimisala on nagu tabel, kus iga lahter on parkimiskoht. Kui parkimisala külgede pikkused on 2 ja 4, siis selles on 2 x 4 = 8 parkimiskohta\n- sõidukite võimalikud suurused on 1, 2, 4. seda ei pea ülesandes valideerima\n- suurus 2 täidab ära ühe parkimiskoha. Seega 1 täidab ära pool, 4 täidab ära kaks parkimiskohta\n- sõltuvalt parkimisala reeglitest saab suurusega 1 sõidukeid panna ühele parkimisalale kaks tükki\n- suurusega 4 sõiduk võtab kaks kõrvutiolevat parkimiskohta (vahet pole, millises suunas)\n- sõidukitel on prioriteedid\n- kui sõiduk lisatakse linna, siis otsitakse sõidukile sobiv parkimisala ning lisatakse selle parkimisala ootejärjekorda\n- kõik linna parkimisalad käiakse läbi ja vaadatakase, millisesse auto sobib (parkimisala võib omada mingit reeglit, mis ei luba sõidukil selles parkimisalas üldse parkida). \n- kui auto ei sobi parklasse, siis ei panda teda üldse järjekorda.\n- kui auto sobib parklasse, siis saadetakse ta vastava parkla järjekorda (`addToQueue()`).\n- kui sõiduk sobib mitmesse parklasse, tuleb ta saata sellesse, kus on järjekord kõige lühem\n- kui ka selliseid on mitu tükki, siis tuleb sõiduk saata sellesse parklasse, mis lisati linna kõige varem.\n- see, kuidas täpselt te sõidukid parklasse paigutate, ei ole selles ülesandes väga oluline. St sobivad igasugused \"mõistlikud\" paigutused. Seega näiteks sobib variant, kus hakkate järjest täitma. Ei pruugi sobida selline, kus hakkate sõidukeid keskele paigutama (näiteks panete mõne suure keskele ja seejärel teised suured enam ei mahu).\n- sõidukeid võetakse ootejärjekorrast prioriteetide alusel.\n- kõigepealt võetakse `HIGHEST` prioriteediga sõidukid, siis `PRIORITY` ja seejärel `COMMON`.\n- kui kaks sõidukit on sama prioriteediga, siis eelistatakse väiksemaid sõidkueid. Ehk siis järjekord oleks selline: `HIGHEST-1`, `HIGHEST-2`, .., `PRIORITY-1`, ...\n- kui kaks sõidukit on sama prioriteedi ja sama suurusega, siis pole vahet, mis järjekorras neid võtta.\n- sõiduk saab korraga olla vaid ühes parklas\n- ühte parkla isendit (instantsi) võib olla vaid üks (sama tüüpi parklat võib mitu olla). Näiteks kui luua parkla, siis ei saa seda lisada linna mitu korda. Samas võib linnas olla mitu SmallCarParkingLot tüüpi parklat (aga need peavad olema erinevad isendid).\n\nAllpool on erinevate klasside mallid. Sealt näeb ära ka pakid, kus klassid paiknevad. Antud ülesande lahendamiseks on teil vaja klassidesse lisada täiendavaid meetodeid.\n\n\n## City\n\n```java\npackage ee.taltech.iti0202.parking;\n\nimport ee.taltech.iti0202.parking.car.Car;\nimport ee.taltech.iti0202.parking.parkinglot.ParkingLot;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Optional;\n\npublic class City {\n public City(String name) {\n }\n\n /**\n * Adds a parking lot.\n * A parking lot can exist only once.\n * @param parkingLot Parking lot to be added.\n * @return true if parking lot was added.\n */\n public boolean addParkingLot(ParkingLot parkingLot) {\n return true;\n }\n\n /**\n * Tries to send a car to a parking lot.\n * If the parking lot accepts this car\n * the car will be added to the queue of the parking lot.\n * The chosen parking lot is returned.\n * If several parking lots can take the car, use the one\n * with the smallest queue.\n * If several have the same size queue, use the one\n * which was added earlier.\n * Or empty in case the car cannot be parked anywhere\n * or the car has already been parked or is in queue.\n * @param car Car to be sent to parking lot\n * @return Parking lot where the car will be sent into queue.\n * empty() in case no parking lot is suitable.\n */\n public Optional<ParkingLot> parkCar(Car car) {\n return Optional.empty();\n }\n \n /**\n * Gets all parking lots in a city.\n * @return List of parking lots.\n */\n public List<ParkingLot> getParkingLots() {\n return parkingLots;\n }\n\n /**\n * Return a map where for every priority-size pair a count of cars is mapped.\n * Keys are in format XY\n * where X = {H, P, C} (highest, priority, common)\n * Y = {1, 2, 4} size\n * @return map with priority-size counts\n */\n public Map<String, Integer> getParkedCarCountBySizeAndPriority() {\n return null;\n }\n\n /**\n * Gets car count in queue by priority status and size.\n * @param priorityStatus (highest, priority, common)\n * @param size (1, 2, 4)\n * @return Count of cars in queue.\n */\n public int getCarCountInQueue(Car.PriorityStatus priorityStatus, int size) {\n return -1;\n }\n\n /**\n * Gets parked car count by priority status and size.\n * @param priorityStatus (highest, priority, common)\n * @param size (1, 2, 4)\n * @return Count of parked cars.\n */\n public int getParkedCarCount(Car.PriorityStatus priorityStatus, int size) {\n return -1;\n }\n}\n```\n\n## ParkingLot\n\n```java\npackage ee.taltech.iti0202.parking.parkinglot;\n\n\nimport ee.taltech.iti0202.parking.car.Car;\n\nimport java.util.*;\n\n/**\n * Parking lot is a rectangular area with fixed with and height.\n * Well, rather 2 dimensions on the ground,\n * but as you represent in on the screen, then height can be seen as\n * the vertical axis.\n * The rectangle is filled with parking slots.\n * 3 x 4 parking lot has 12 slots.\n * The size of a slot is 2 units.\n * This means, that car with size 2 fits there perfectly.\n * Car with size 1 takes half the slot, so it could be\n * theoretically shared between 2 small cars.\n * Car with size 4 takes two consecutive slots.\n *\n * Each concrete parking lot type (subclass)\n * has its own rules about which cars it accepts\n * in its queue and how the queue is processed.\n * See the class description for more information.\n */\nabstract public class ParkingLot {\n\n private final int width;\n private final int height;\n\n /**\n * Initialize the parking slot with the given width and height.\n *\n * @param height Length of vertical side.\n * @param width Length of horizontal side.\n */\n public ParkingLot(int height, int width) {\n this.width = width;\n this.height = height;\n }\n\n\n /**\n * Adds a car to priority queue.\n * Car can be in a queue only once.\n * @param car Car to be added\n */\n public boolean addToQueue(Car car) {\n return true;\n }\n\n /**\n * Processes the queue.\n *\n * The cars are taken from the queue in specified order.\n * If the first car in the queue cannot be parked\n * the process will wait. Also, if the queue is empty, process waits.\n * Otherwise the process should be \"running\" all the time.\n * In reality you should call this method from other methods\n * which could initialize the process.\n *\n */\n abstract public void processQueue();\n\n\n\n /**\n * Returns a list of parked cars in the order they were received from the queue.\n * @return A list of parked cars.\n */\n public List<Car> getParkedCars() {\n return null;\n }\n\n /**\n * Returns string presentation of the parking lot.\n *\n * Each slot takes 2x2 chars.\n * Size 1 is represented by 1x2 (height, width) area\n * Empty slot is represented by dots (.):\n *\n * Empty table with width 3, height 2:\n * ......\n * ......\n * ......\n * ......\n *\n * One large priority car:\n * P4P4..\n * P4P4..\n * ......\n * ......\n *\n * + one small highest priority car:\n * P4P4H1\n * P4P4..\n * ......\n * ......\n *\n * + medium common car:\n * P4P4H1\n * P4P4..\n * C2....\n * C2....\n *\n * @return String representation of the parking lot\n */\n public String getTable() {\n return \"\";\n }\n\n}\n\n\n```\n\n### SmallCarParkingLot\n\n```java\npackage ee.taltech.iti0202.parking.parkinglot;\n\n/**\n * This parking lot only accepts small cars (size 1).\n * Each parking slot only accepts one car.\n */\npublic class SmallCarParkingLot extends ParkingLot {\n /**\n * Initialize the parking slot with the given width and height.\n *\n * @param height\n * @param width\n */\n public SmallCarParkingLot(int height, int width) {\n super(height, width);\n }\n\n @Override\n public void processQueue() {\n \n }\n}\n```\n\n### PriorityParkingLot\n\n```java\npackage ee.taltech.iti0202.parking.parkinglot;\n\n/**\n * Accepts all cars if the queue size is less than 5.\n * (So the maximum number of cars in the queue is 5.)\n * Small car (size 1) with the highest priority can park alone.\n * Otherwise small cars (size 1) can share a slot if they have the same priority.\n * If there is a cars with the highest priority in the queue and there is no room to fit the car, \n * then cars with common priority (if parked) are sent to the queue \n * to make room for the highest priority car (life is unfair).\n *\n */\npublic class PriorityParkingLot extends ParkingLot {\n /**\n * Initialize the parking slot with the given width and height.\n *\n * @param height Length of vertical side.\n * @param width Length of horizontal side.\n */\n public PriorityParkingLot(int height, int width) {\n super(height, width);\n }\n\n @Override\n public void processQueue() {\n\n }\n}\n```\n\n### MultiLevelParkingLot\n\n```java\n\npackage ee.taltech.iti0202.parking.parkinglot;\n\n/**\n * Modern parking lot located under ground.\n * The parking lot has several levels.\n * Always prefer the smallest level (starting from 1).\n * If the car cannot fit to a level, then proceed to the next level.\n * \n * This parking lot only accepts maximum 10 vehicle in the queue.\n * So, if there queue already has 10 cars, this parking lot should not\n * be available for new cars.\n *\n */\npublic class MultiLevelParkingLot extends ParkingLot {\n /**\n * Initialize the parking slot with the given width and height.\n *\n * @param height Length of verical side.\n * @param width Length of horizontal side.\n * @param levels Number of levels.\n */\n public MultiLevelParkingLot(int height, int width, int levels) {\n super(height, width);\n }\n\n @Override\n public void processQueue() {\n\n }\n\n /**\n * Here you have to override getTable() method.\n * The method gets a string for each level\n * separated by \"---\":\n *\n * P4P4..\n * P4P4..\n * ......\n * ......\n * ---\n * ......\n * ......\n * ......\n * ......\n *\n * This has 2 levels and there is a large (size 2) car on first level.\n *\n * @return String representation of multilevel parking lot\n */\n @Override\n public String getTable() {\n return super.getTable();\n }\n}\n\n\n```\n## Car\n\n```java\npackage ee.taltech.iti0202.parking.car;\n\n/**\n * Represents a car with priority and size.\n * The size can be one of 1, 2, 4 (the code doesn't have to validate it).\n * This class implements Comparable interface.\n * This allows objects to be sorted in priority queue (or for sorting in general).\n * Cars with highest priority will be taken first, then with the \"priority\" priority\n * and then all the common cars.\n * If there are cars with the same priority, prefer cars with lower size.\n * So highest-1 (priority status-size) comes before highest-2 which comes before priority-1.\n */\npublic class Car implements Comparable<Car> {\n\n public enum PriorityStatus {\n HIGHEST, PRIORITY, COMMON\n }\n\n @Override\n public int compareTo(Car o) {\n return 0;\n }\n\n public Car(PriorityStatus status, int size) {\n }\n\n /**\n * Gets the priority of the car.\n * @return PriorityStatus\n */\n public PriorityStatus getPriorityStatus() {\n return PriorityStatus.COMMON;\n }\n\n /**\n * Gets the size of the car.\n * @return Size.\n */\n public int getSize() {\n return 0;\n }\n\n /**\n * Finish parking. This car has finished parking.\n * The car should be removed from parking lot\n * (its slots will be empty).\n * Returns false, if the car is not parked currently.\n * Otherwise returns true.\n * @return True if the car was parking, false otherwise.\n */\n public boolean unpark() {\n return true;\n }\n}\n\n\n```\n\n## Näide\n\nNatuke näiteid:\n\n```java\nCity tallinn = new City(\"Tallinn\");\nCity tartu = new City(\"Tartu\");\n\nSmallCarParkingLot europark = new SmallCarParkingLot(4, 2);\ntallinn.addParkingLot(europark);\nCar ch1 = new Car(Car.PriorityStatus.HIGHEST, 1);\nCar ch2 = new Car(Car.PriorityStatus.HIGHEST, 2);\nCar ch4 = new Car(Car.PriorityStatus.HIGHEST, 4);\nCar cp1 = new Car(Car.PriorityStatus.PRIORITY, 1);\nCar cp2 = new Car(Car.PriorityStatus.PRIORITY, 2);\n\n\nPriorityQueue<Car> priorityQueue = new PriorityQueue<>();\npriorityQueue.add(cp1);\npriorityQueue.add(ch2);\npriorityQueue.add(cp2);\npriorityQueue.add(ch1);\npriorityQueue.add(ch4);\nwhile (!priorityQueue.isEmpty()) {\n System.out.println(priorityQueue.poll());\n}\n/*\nH1\nH2\nH4\nP1\nP2\n */\n\nSystem.out.println(tartu.parkCar(ch1)); // Optional.empty\nSystem.out.println(tallinn.parkCar(ch2)); // Optional.empty\nSystem.out.println(tallinn.parkCar(ch1)); // Optional[europark]\nSystem.out.println(tallinn.parkCar(ch1)); // Optional.empty\nSystem.out.println(europark.getParkedCars()); //[H1]\n\nPriorityParkingLot priorityParkingLot = new PriorityParkingLot(1, 3);\n\ntallinn.addParkingLot(priorityParkingLot);\n\nSystem.out.println(tallinn.parkCar(ch4)); // Optional[priorityParkingLot]\nCar cc4 = new Car(Car.PriorityStatus.COMMON, 4);\nCar cp4 = new Car(Car.PriorityStatus.PRIORITY, 4);\nSystem.out.println(tallinn.parkCar(cc4)); // Optional[priorityParkingLot]\nSystem.out.println(tallinn.parkCar(cp4)); // Optional[priorityParkingLot]\nCar ch42 = new Car(Car.PriorityStatus.HIGHEST, 4);\nSystem.out.println(tallinn.parkCar(ch42)); // Optional[priorityParkingLot]\n\nSystem.out.println(priorityParkingLot.getTable());\n/*\nH4H4..\nH4H4..\n\n */\n\n// let's send one car home\nSystem.out.println(ch4.unpark()); // true\n\n// now another H4 parks\nSystem.out.println(priorityParkingLot.getTable());\n/*\nH4H4..\nH4H4..\n\n */\n\nSystem.out.println(ch4.unpark()); // false, there's no such car parked\nSystem.out.println(ch42.unpark()); // true\n\nSystem.out.println(priorityParkingLot.getTable());\n/*\nP4P4..\nP4P4..\n\n */\nMultiLevelParkingLot multiLevelParkingLot = new MultiLevelParkingLot(1, 2, 2);\nmultiLevelParkingLot.addToQueue(new Car(Car.PriorityStatus.COMMON, 2));\nmultiLevelParkingLot.addToQueue(new Car(Car.PriorityStatus.COMMON, 1));\nSystem.out.println(multiLevelParkingLot.getTable());\n/*\nC2C1\nC2..\n---\n....\n....\n\n */\nmultiLevelParkingLot.addToQueue(new Car(Car.PriorityStatus.HIGHEST, 1));\nmultiLevelParkingLot.addToQueue(new Car(Car.PriorityStatus.HIGHEST, 2));\nmultiLevelParkingLot.addToQueue(new Car(Car.PriorityStatus.COMMON, 2));\nmultiLevelParkingLot.addToQueue(new Car(Car.PriorityStatus.HIGHEST, 2));\nSystem.out.println(multiLevelParkingLot.getTable());\n/*\nC2C1\nC2H1\n---\nH2C2\nH2C2\n\n */\n```"},{"path":"parking_old.rst","contents":"Parking\n=======\n\nMoodul: ``EX05ParkingLot``\n\nPakk: ``ee.taltech.iti0202.parking``\n\nKesklinnas töötab üks piisavalt suur parkla, ning sina (sinu programm) vastutad\nselle eduka teeninduse osutamise eest. Kuigi parkla on suur, kõikidele autodele, kes\nsoovivad seal parkida, kohti ei ole.\n\nAutod on erinevatest suurustest ja staatustest. On olemas kolm suurust:\n\n- 1 (SmallCar)\n- 2 (MediumCar)\n- 3 (BigCar)\n\n...ja kolm staatust:\n\n- H (highest)\n- P (priority)\n- C (common).\n\nProgrammis parkla on antud 2-ruumilise massiivina, mis koosneb *string*-itest.\n(Kui koht on vaba, siis seda tähistatakse **tühikuga** -> \" \", vastasel juhul\nsellel kohal on vastava auto märk. Listis (ehk ootejärjekorras) auto on nähtav kujul\nnt \"H1\" - see tähendab, et tegemist on väikse \"highest\"-staatuse autoga.\n\nSinu ülesandeks on paigutada tulevaid autosid korrektselt vastavalt järgmisetele\nreeglitele:\n\n- Suur (big) auto vajab 2 kõrvuti kohta\n- Keskimne (medium) mahub täpselt ühele kohale\n- Väiksel (small) autol piisab 1/2 kohast. See tähendab, et kui on vaja parkida 2\n väikest autot, aga ainult üks koht on vaba, siis see on täitsa võimalik\n- Juhul, kui ühel nendest väikestest autodest on \"Highest\" staatus, siis seda saab\n parkida ainult üksi\n- Kui mõlemad autod on kas \"Priority\" või \"Common\" staatusega, siis nad võivad parkida koos\n- Sa ei saa panna ühele kohale paari, milles üks on \"Priority\" ja teine - \"Common\"!\n- Kui rohkem vabu kohti ei ole ja seal on veel jäänud \"Highest\" staatusega autod ootama,\n sul on õigus paluda \"Common\" staatusega autosid, et nad sõidaks parklast ootejärjekorda \n ja vabastaks parkimiskoha \"Highest\" staatusega autodele\n- Kui ühel kohal on kaks \"Common\" autot, siis mõlemad peavad ära minema\n- Kui on pargitud suur \"Common\" auto ehk ta võtab kaks parkimiskoha, siis \n tuleb kindlasti eemaldada auto mõlematest kohtadest\n- Sa pead proovima paigutada võimalikult palju \"Highest\" staatusega autosid, nii et\n ühtki nendest ei jääks järjekorras ootama\n- \"Priority\" autodel ei ole mingit väga erilist eelist, kuid nad saavad koha enne \"Common\"\n autosid\n- Järelikult, \"Highest\" staatusega autod, lisaks oma eelisele, saavad koha varem, kui\n \"Priority\" autod\n\nAutode järjekord, mis satub parkimisala sisse koos parkimisala loomisega, peab olema sorteeritud järgmiselt:\nHighest -> Priority -> Common. Autode järjekorda kujutab ```PriorityQueue`` andmetüüp ehk *Prioriteet järjekord*.\nVaikimisi PriorityQueue sorteerib enda väärtused kasvavas järjekorras.\n\n``PriorityQueue`` kasutab ``Comparator``-it ning võrdlemiseks objekt peab omama võrdlemisvõimalusi\n(teiste sõnadega, objekti klass peab olema *Comparable* ehk implementeerima *Comparable* interface-it.\nSeoses sellega, tuleb kirjutada ``compareTo(Object o)`` meetod ümber vastavas klassis. Seda meetodit\nkasutabki ``PriorityQueue()`` oma *Comparator*-is. Prioriteet järjekorra loomisel, mis edaspidi\nhakkab hoidma *Car* objektid, ei pea eraldi kirjutama võrdlemistingimusi, sest kõik need on juba\n``compareTo()`` meetodis kirjeldatud.\n\n**PriorityQueue näidis**\nOletame, et soovime luua järgims prioriteet järjekorda autodega:\n\n.. code-block:: java\n\n SmallCar car = new SmallCar(Car.Status.P);\n BigCar car1 = new BigCar(Car.Status.C);\n MediumCar car2 = new MediumCar(Car.Status.H);\n BigCar car3 = new BigCar(Car.Status.H);\n \n PriorityQueue<Car> cars = new PriorityQueue<>();\n \n cars.add(car3);\n cars.add(car);\n cars.add(car1);\n cars.add(car2);\n \nKui ``compareTo(Car car2)`` töötab õigesti ning kui võtame autod ühekaupa järjekorrast, siis\non näha, et tulemust prinditakse nõutud prioriteedis vastavalt staatusele:\n\n.. code-block:: java\n\n while (cars.iterator().hasNext()) {\n Car currentCar = cars.iterator().next();\n System.out.println(currentCar);\n cars.remove(currentCar);\n }\n \nKonsoolis näeme järgmist:\n\n.. code-block:: java\n\n H3\n H2\n P1\n C3\n\nKlass ``ParkingLot``\n--------------------\n\nAsukoht: ``ee.taltech.iti0202.parkinglot.ParkingLot``\n\nKirjeldab parkimisala. Parkimisala kujutatakse kaheruumilise *String[][]* massiivina (``parkingLot``) ning ootejärjekorras\nolevad autod antakse ette *PriorityQueue<Car>*-ina (``carsInQueue``).\n\nKonstruktoris tuleb vaikimisi määrata info autode ootejärjekorras ja pargitud autode kohta. See tähendab, et\nIlma parkimise korraldamiseta saaks juba mingit infot selle kohta kätte. (nt kui peale *ParkingLot* objekti\nloomist kohe küsida infot ootejärjekorras olevate autode kohta -> rakendada \n``public Map<String, Integer> getWaitingCars()`` meetodid, siis peaks saama *HashMap*-i\njust sattunud autodega.\n\n- ``public void parkNewCarFromOutside(Car car)`` - meetod, mis kasutatakse enamasti siis, kui põhihulk autosid (``carsInQueue``) on juba\n pargitud ja soovitakse parkida veel. Tagastab *String[][]* ``parkingLot`` ja kui parkimine õnnestub, siis uuendatud ehk\n koos just lisatud autoga. Kui autot ei saanud lisada, siis see tuleb panna ootejärjekorda!\n\n- ``private boolean removeCommonCar()`` - meetod, mille abil saab nö \"paluda\", et väike auto sõidaks parkimiskohast ära, kui\n on vaja parkida *Highest*-staatusega autot\n\n- ``public String[][] manageParking()`` - meetod, mis kasutatakse peamiselt siis, kui hakatakse parkima parkimisala loomisel\n sinna sattunud autosid. Tulemusena tagastab parkimisala koos pargitud autodega\n\n- ``public Map<String, Integer> getParkedCars()`` - meetod, mis tagastab *Map<String, Integer>* infoga sellest, et kui palju\n ja milliseid autosid on pargitud. Võtmeks on täht, mis vastab auto staatusele ehk kas **H**, **P** või **C**\n\n- ``public Map<String, Integer> getWaitingCars()`` - teeb sama, mis eelmine meetod, aga nüüd tuleb tagastada info ootejärjekorras\n olevate autode kohta\n\n- ``public String toString()`` - meetod, mis määrab, et *String*-i kujul parkimisala näeb välja nii, et iga rida on\n sellisel kujul : [H3|H3|H2]\n\nMall\n~~~~\n\n.. code-block:: java\n\n package ee.taltech.iti0202.parkinglot;\n\n public class ParkingLot {\n\n private String[][] parkingLot;\n private PriorityQueue<Car> carsInQueue;\n\n public ParkingLot(String[][] parkingLot, List<Car> carsInQueue) {\n\n }\n\n \n /**\n * Park a car given as a parameter considering current situation on parking lot.\n * If car cannot be parked, then add it to waiting list.\n *\n * @param car Car object.\n * @return String[][] parking lot with newly parked car (if that was possible).\n */\n public String[][] parkNewCarFromOutside(Car car) {\n return this.parkingLot;\n }\n\n\n private boolean removeCommonCar() {\n return false;\n }\n\n \n /**\n * Mostly used to park some amount of cars from waiting list, which must be sorted by rule H->P->C before parking.\n * @return String[][] parking lot.\n */\n public String[][] manageParking() {\n return this.parkingLot;\n }\n \n \n /**\n * Adds chosen car String-representation to parking lot.\n * @param row row index\n * @param col column index\n * @param car car to park as a string\n */\n public void putCar(int row, int col, String car) {\n \n }\n \n \n public String[][] getParkingLot() {\n return null;\n }\n\n\n public Map<String, Integer> getParkedCars() {\n return null;\n }\n\n\n public Map<String, Integer> getWaitingCars() {\n return null;\n }\n \n \n public String toString() {\n return \"\";\n }\n\n }\n\n\nAbstraktne klass ``Car``\n------------------------\n\nAsukoht: ``ee.taltech.iti0202.car.Car``\n\nÜldiselt kirjeldab autot ilma suurust täpsustamata. Tegelekult, kõik autode objektidega seotud funktsionaalsus on kirjeldatud\nselles klassis.\n\n- ``public enum Status`` - *enum*-tüüpi objekt, mille abil määratakse auto staatus auto objekti loomisel\n\n- ``public abstract void parkingStrategy(ParkingLot parkingLot, int row, int col)`` - abstraktne meetod, mille\n funktsionaalsus muutub vastavalt auto suurusele. Tegeleb sellega, et aitab valida õiget strateegiat, kuidas\n peaks auto parkima. ``int row`` on hetke rea indeks, ``int col`` on hetke veeru indeks ning ``parkingLot``\n ongi praeguse parkimisala objekt, mille kaudu saab ligi ka parkimisala massiivile.\n\n- ``public String toString()`` - tagastab *String*-i kujul nt \"H1\" - see tähendab, et tegemist on väikse \"highest\"-staatuse\n autoga. Teiste sõnedega, rakendades seda meetodid auto objektile, saame lühidalt kirjutatud info selle auto kohta -\n staatus ja suurus\n\n- ``public int compareTo(Car car)`` - meetod, mis kasutatakse nt objektide sorteerimisel ``Collections.sort()`` abil ja mida\n tuleb enda programmi raames sobivamaks muuta ehk käsiti ümber kirjutada. Meetod peab tagastama ainult **kolm** võimalikut\n väärtust: **1** juhul, kui teise auto staatus on kõrgem, **0** juhul, kui mõlemate autode staatused on samad ning\n **-1**, kui esimese auto staatus on teisest kõrgem\n\n\nMall\n~~~~\n\n.. code-block:: java\n\n package ee.taltech.iti0202.car;\n\n public abstract class Car implements Comparable<Car> {\n\n public enum Status {\n H, P, C\n }\n\n private Status status;\n\n Car(Status status) {\n\n }\n\n\n public Status getStatus() {\n return status;\n }\n\n\n public void setStatus(Status status) {\n\n }\n \n /**\n * Park the car considering its size and parking rules.\n */\n public abstract void parkCar(ParkingLot parkingLot, int row, int col);\n\n\n @Override\n public String toString() {\n return \"\";\n }\n\n\n @Override\n public int compareTo(Car secondCar) {\n return -1;\n }\n }\n\nKlass ``SmallCar``\n------------------\n\nAsukoht: ``ee.taltech.iti0202.car.SmallCar``\n\nKirjeldab väikest autot ja laiendab ``Car`` klassi ning järelikult pärineb kõik funktsionaalsus. Konstruktor töötab\npeaklassi konstruktori moodi.\n\n- ``public void parkingStrategy(String[][] parkingLot, int row, int col)`` - meetod, mida\n tuleb ümber kirjutada täpselt selle auto klassi jaoks vastavalt sellele, kuidas\n on reeglites kirjeldatud väikse auto parkimine.\n\nMall\n~~~~\n\n.. code-block:: java\n\n package ee.taltech.iti0202.car;\n\n public class SmallCar extends Car {\n\n public SmallCar(Status status) {\n\n }\n \n @Override\n public void parkCar(ParkingLot parkingLot, int row, int col) {\n \n }\n }\n\n\nKlass ``MediumCar``\n-------------------\n\nAsukoht: ``ee.taltech.iti0202.car.MediumCar``\n\nKirjeldab keskmist autot ja laiendab ``Car`` klassi ning järelikult pärineb kõik funktsionaalsus. Konstruktor töötab\npeaklassi konstruktori moodi.\n\n- ``public void parkingStrategy(String[][] parkingLot, int row, int col)`` - meetod, mida\n tuleb ümber kirjutada täpselt selle auto klassi jaoks vastavalt sellele, kuidas\n on reeglites kirjeldatud keskmise auto parkimine.\n\nMall\n~~~~\n\n.. code-block:: java\n\n package ee.taltech.iti0202.car;\n\n public class MediumCar extends Car {\n\n public MediumCar(Status status) {\n\n }\n \n \n @Override\n public void parkCar(ParkingLot parkingLot, int row, int col) {\n \n }\n }\n\n\nKlass ``BigCar``\n----------------\n\nAsukoht: ``ee.taltech.iti0202.car.BigCar``\n\nKirjeldab väikest autot ja laiendab ``Car`` klassi ning järelikult pärineb kõik funktsionaalsus. Konstruktor töötab\npeaklassi konstruktori moodi.\n\n- ``public void parkingStrategy(String[][] parkingLot, int row, int col)`` - meetod, mida\n tuleb ümber kirjutada täpselt selle auto klassi jaoks vastavalt sellele, kuidas\n on reeglites kirjeldatud suure auto parkimine.\n\nMall\n~~~~\n\n.. code-block:: java\n\n package ee.taltech.iti0202.car;\n\n public class BigCar extends Car {\n\n public BigCar(Status status) {\n\n }\n \n \n @Override\n public void parkCar(ParkingLot parkingLot, int row, int col) {\n \n }\n }\n\n\n\n"},{"path":"src/ee/taltech/iti0202/parking/.gitkeep","contents":"<file in binary format or unable to read file>"},{"path":"src/ee/taltech/iti0202/parking/ParkingLotTest.java","contents":"package ee.taltech.iti0202.parking;\n\nimport ee.taltech.iti0202.parking.car.Car;\nimport static org.testng.Assert.*;\n\nimport static org.hamcrest.MatcherAssert.*;\nimport static org.hamcrest.Matcher.*;\n\nimport ee.taltech.iti0202.parking.parkinglot.MultiLevelParkingLot;\nimport ee.taltech.iti0202.parking.parkinglot.ParkingLot;\nimport ee.taltech.iti0202.parking.parkinglot.PriorityParkingLot;\nimport ee.taltech.iti0202.parking.parkinglot.SmallCarParkingLot;\nimport ee.ttu.java.studenttester.annotations.Gradable;\nimport ee.ttu.java.studenttester.annotations.TestContextConfiguration;\nimport ee.ttu.java.studenttester.enums.ReportMode;\nimport org.testng.annotations.Test;\n\nimport java.util.*;\nimport java.util.stream.Collectors;\nimport java.util.stream.IntStream;\n\n@TestContextConfiguration(mode = ReportMode.VERBOSE)\npublic class ParkingLotTest {\n class CarSetup {\n // H1, H2, H4, P1, P2, P4, C1, C2, C4\n Map<String, Integer> counts = new HashMap<>(Map.of(\n \"H1\", 0, \"H2\", 0, \"H4\", 0,\n \"P1\", 0, \"P2\", 0, \"P4\", 0,\n \"C1\", 0, \"C2\", 0, \"C4\", 0));\n CarSetup() {}\n CarSetup(String key, int value) {\n counts.put(key, value);\n }\n CarSetup(int h1, int h2, int h4, int p1, int p2, int p4, int c1, int c2, int c4) {\n counts.put(\"H1\", h1);\n counts.put(\"H2\", h2);\n counts.put(\"H4\", h4);\n counts.put(\"P1\", p1);\n counts.put(\"P2\", p2);\n counts.put(\"P4\", p4);\n counts.put(\"C1\", c1);\n counts.put(\"C2\", c2);\n counts.put(\"C4\", c4);\n }\n CarSetup add(String key, int value) {\n counts.put(key, counts.get(key) + value);\n return this;\n }\n CarSetup add(String key) {\n return add(key, 1);\n }\n\n /**\n * Each key will point to how many \"dots\" (or occurrences) it has on the table string.\n * H2: 2 => H2: 4\n * H4: 2 => H4: 8\n * @return\n */\n Map<String, Integer> getMapWithDotCounts() {\n Map<String, Integer> map = new HashMap<>(counts);\n for (String p : new String[]{\"H\", \"P\", \"C\"}) {\n map.put(p + \"2\", map.get(p + \"2\") * 2);\n map.put(p + \"4\", map.get(p + \"4\") * 4);\n }\n return map;\n }\n\n }\n @Test(timeOut = 1000)\n public void testCar() {\n for (Car.PriorityStatus p : Car.PriorityStatus.values()) {\n for (int size : new int[]{1, 2, 4}) {\n Car car = new Car(p, size);\n assertEquals(car.getPriorityStatus(), p);\n assertEquals(car.getSize(), size);\n }\n }\n }\n\n @Test(timeOut = 1000)\n public void testCarCompareToPriorities() {\n assertTrue(h1().compareTo(p2()) < 0, \"H1 should come before P2\");\n assertTrue(p2().compareTo(h1()) > 0, \"H1 should come before P2\");\n assertTrue(h1().compareTo(c4()) < 0, \"H1 should come before C4\");\n assertTrue(c4().compareTo(h1()) > 0, \"H1 should come before C4\");\n assertTrue(p2().compareTo(c4()) < 0, \"P2 should come before C4\");\n assertTrue(c4().compareTo(p2()) > 0, \"P2 should come before C4\");\n }\n\n @Test(timeOut = 1000)\n public void testCarCompareToSizes() {\n for (Car.PriorityStatus p : Car.PriorityStatus.values()) {\n assertTrue(new Car(p, 1).compareTo(new Car(p, 2)) < 0, \"size 1 should come before 2\");\n assertTrue(new Car(p, 2).compareTo(new Car(p, 1)) > 0, \"size 1 should come before 2\");\n assertTrue(new Car(p, 1).compareTo(new Car(p, 4)) < 0, \"size 1 should come before 4\");\n assertTrue(new Car(p, 4).compareTo(new Car(p, 1)) > 0, \"size 1 should come before 4\");\n assertTrue(new Car(p, 2).compareTo(new Car(p, 4)) < 0, \"size 2 should come before 4\");\n assertTrue(new Car(p, 4).compareTo(new Car(p, 2)) > 0, \"size 2 should come before 4\");\n }\n }\n\n @Test(timeOut = 1000)\n public void testCarCompareToSameParams() {\n for (Car.PriorityStatus p : Car.PriorityStatus.values()) {\n for (int size : new int[]{1, 2, 4}) {\n assertTrue(new Car(p, size).compareTo(new Car(p, size)) == 0, \"compareTo() for same priority and size should return 0.\");\n }\n }\n }\n\n @Test(timeOut = 1000)\n public void testParkingLotAddToQueueDoNotAllowAddingSameCarToQueue() {\n ParkingLot parkingLot = new SmallCarParkingLot(1, 4);\n Car c = p1();\n assertTrue(parkingLot.addToQueue(c));\n assertFalse(parkingLot.addToQueue(c));\n }\n\n @Test(timeOut = 1000)\n public void testParkingLotAddToQueueCarCanOnlyParkInOneLot() {\n Car c = p1();\n ParkingLot parkingLot1 = new SmallCarParkingLot(1, 4);\n ParkingLot parkingLot2 = new SmallCarParkingLot(1, 4);\n assertTrue(parkingLot1.addToQueue(c));\n assertFalse(parkingLot2.addToQueue(c));\n }\n\n @Test(timeOut = 1000)\n public void testSmallCarParkingLotAddToQueue() {\n ParkingLot smallCarParkingLot = new SmallCarParkingLot(1, 4);\n smallCarParkingLot.processQueue();\n assertEquals(smallCarParkingLot.getParkedCars().size(), 0);\n assertTrue(smallCarParkingLot.addToQueue(p1()));\n smallCarParkingLot.processQueue();\n assertEquals(smallCarParkingLot.getParkedCars().size(), 1);\n assertTrue(smallCarParkingLot.addToQueue(c1()));\n smallCarParkingLot.processQueue();\n assertEquals(smallCarParkingLot.getParkedCars().size(), 2);\n assertTrue(smallCarParkingLot.addToQueue(h1()));\n smallCarParkingLot.processQueue();\n assertEquals(smallCarParkingLot.getParkedCars().size(), 3);\n assertTrue(smallCarParkingLot.addToQueue(h1()));\n smallCarParkingLot.processQueue();\n assertEquals(smallCarParkingLot.getParkedCars().size(), 4);\n assertTrue(smallCarParkingLot.addToQueue(h1()));\n smallCarParkingLot.processQueue();\n assertEquals(smallCarParkingLot.getParkedCars().size(), 4);\n }\n\n @Test(timeOut = 1000)\n public void testSmallCarParkingLotGetTable() {\n ParkingLot smallCarParkingLot = new SmallCarParkingLot(1, 4);\n assertTrue(smallCarParkingLot.addToQueue(p1()));\n assertTrue(smallCarParkingLot.addToQueue(c1()));\n assertTrue(smallCarParkingLot.addToQueue(h1()));\n assertTrue(smallCarParkingLot.addToQueue(h1()));\n assertTrue(smallCarParkingLot.addToQueue(h1()));\n smallCarParkingLot.processQueue();\n assertEquals(smallCarParkingLot.getParkedCars().size(), 4);\n CarSetup setup = new CarSetup().add(\"H1\", 2).add(\"P1\").add(\"C1\");\n validateTable(smallCarParkingLot.getTable(), 1, 4, setup);\n }\n\n @Test(timeOut = 1000)\n public void testSmallCarParkingLotUnpark() {\n ParkingLot parkingLot = new SmallCarParkingLot(2, 2);\n Car c = p1();\n assertFalse(c.unpark());\n parkingLot.addToQueue(c);\n parkingLot.processQueue();\n assertEquals(parkingLot.getParkedCars().size(), 1);\n validateTable(parkingLot.getTable(), 2, 2, new CarSetup(\"P1\", 1));\n\n assertTrue(c.unpark(), \"Parked car should allow unpark()\");\n assertEquals(parkingLot.getParkedCars().size(), 0);\n validateTable(parkingLot.getTable(), 2, 2, new CarSetup());\n\n assertFalse(c.unpark(), \"After unparking, unpark() should return false\");\n assertTrue(parkingLot.addToQueue(c), \"After unparking, you can add it to queue again\");\n assertEquals(parkingLot.getParkedCars().size(), 1);\n validateTable(parkingLot.getTable(), 2, 2, new CarSetup(\"P1\", 1));\n }\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLotAddToQueue() {\n ParkingLot parkingLot = new PriorityParkingLot(4, 4);\n parkingLot.addToQueue(h4());\n parkingLot.addToQueue(h2());\n parkingLot.addToQueue(h1());\n parkingLot.addToQueue(p4());\n parkingLot.addToQueue(p2());\n parkingLot.addToQueue(p1());\n parkingLot.addToQueue(c4());\n parkingLot.addToQueue(c2());\n parkingLot.addToQueue(c1());\n parkingLot.processQueue();\n assertEquals(parkingLot.getParkedCars().size(), 9);\n }\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLotGetTable() {\n ParkingLot parkingLot = new PriorityParkingLot(4, 4);\n parkingLot.addToQueue(h4());\n parkingLot.addToQueue(h2());\n parkingLot.addToQueue(h1());\n parkingLot.addToQueue(p4());\n parkingLot.addToQueue(p2());\n parkingLot.addToQueue(p1());\n parkingLot.addToQueue(c4());\n parkingLot.addToQueue(c2());\n parkingLot.addToQueue(c1());\n parkingLot.processQueue();\n CarSetup setup = new CarSetup(1, 1, 1, 1, 1, 1, 1, 1, 1);\n var m = validateTable(parkingLot.getTable(), 4, 4, setup);\n validatePriorityParkingLotRules(m);\n }\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLot1x2AddCar4() {\n ParkingLot parkingLot = new PriorityParkingLot(1, 2);\n parkingLot.addToQueue(h4());\n parkingLot.processQueue();\n validateTable(parkingLot.getTable(), 1, 2, new CarSetup().add(\"H4\"));\n }\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLot2x1AddCar4() {\n ParkingLot parkingLot = new PriorityParkingLot(2, 1);\n parkingLot.addToQueue(h4());\n parkingLot.processQueue();\n validateTable(parkingLot.getTable(), 2, 1, new CarSetup().add(\"H4\"));\n }\n\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLotH1CanParkAlone() {\n ParkingLot parkingLot = new PriorityParkingLot(2, 2);\n parkingLot.addToQueue(h1());\n parkingLot.addToQueue(h1());\n parkingLot.addToQueue(h1());\n parkingLot.addToQueue(h1());\n parkingLot.addToQueue(h1());\n parkingLot.processQueue();\n assertEquals(parkingLot.getParkedCars().size(), 4);\n var m = validateTable(parkingLot.getTable(), 2, 2, new CarSetup(\"H1\", 4));\n validatePriorityParkingLotRules(m);\n }\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLot1SizedTogether() {\n ParkingLot parkingLot = new PriorityParkingLot(1, 1);\n parkingLot.addToQueue(p1());\n parkingLot.addToQueue(p1());\n parkingLot.addToQueue(p1());\n parkingLot.processQueue();\n assertEquals(parkingLot.getParkedCars().size(), 2);\n var m = validateTable(parkingLot.getTable(), 1, 1, new CarSetup(\"P1\", 2));\n validatePriorityParkingLotRules(m);\n }\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLotMoveCommonCarToQueueForHighestPriorityCar() {\n ParkingLot parkingLot = new PriorityParkingLot(1, 1);\n parkingLot.addToQueue(c2());\n parkingLot.processQueue();\n assertEquals(parkingLot.getParkedCars().size(), 1);\n validateTable(parkingLot.getTable(), 1, 1, new CarSetup(\"C2\", 1));\n // add highest priority car\n parkingLot.addToQueue(h2());\n parkingLot.processQueue();\n assertEquals(parkingLot.getParkedCars().size(), 1);\n validateTable(parkingLot.getTable(), 1, 1, new CarSetup(\"H2\", 1));\n }\n\n @Test(timeOut = 1000)\n public void testPriorityParkingLotUnpark() {\n ParkingLot parkingLot = new PriorityParkingLot(2, 2);\n Car c = p2();\n assertFalse(c.unpark());\n parkingLot.addToQueue(c);\n parkingLot.processQueue();\n assertEquals(parkingLot.getParkedCars().size(), 1);\n validateTable(parkingLot.getTable(), 2, 2, new CarSetup(\"P2\", 1));\n\n assertTrue(c.unpark(), \"Parked car should allow unpark()\");\n assertEquals(parkingLot.getParkedCars().size(), 0);\n validateTable(parkingLot.getTable(), 2, 2, new CarSetup());\n\n assertFalse(c.unpark(), \"After unparking, unpark() should return false\");\n assertTrue(parkingLot.addToQueue(c), \"After unparking, you can add it to queue again\");\n assertEquals(parkingLot.getParkedCars().size(), 1);\n validateTable(parkingLot.getTable(), 2, 2, new CarSetup(\"P2\", 1));\n }\n\n @Test(timeOut = 1000)\n public void testCityNoParkingSlots() {\n City city = new City(\"Tallinn\");\n assertEquals(city.parkCar(p1()), Optional.empty());\n }\n\n @Test(timeOut = 1000)\n public void testCityCannotAddSameParkingLotTwice() {\n City city = new City(\"A\");\n ParkingLot parkingLot = new SmallCarParkingLot(1, 1);\n assertTrue(city.addParkingLot(parkingLot));\n assertFalse(city.addParkingLot(parkingLot));\n }\n\n @Test(timeOut = 1000)\n public void testCityCannotHaveTheSameParkingLotTwice() {\n City city1 = new City(\"A\");\n City city2 = new City(\"B\");\n ParkingLot parkingLot = new SmallCarParkingLot(1, 1);\n assertTrue(city1.addParkingLot(parkingLot));\n assertFalse(city2.addParkingLot(parkingLot));\n }\n\n @Test(timeOut = 1000)\n public void testCityParkTheSameCarTwice() {\n City city = c();\n Car car = h1();\n SmallCarParkingLot parkingLot = new SmallCarParkingLot(1, 1);\n city.addParkingLot(parkingLot);\n assertEquals(city.parkCar(car).get(), parkingLot);\n assertEquals(city.parkCar(car), Optional.empty());\n\n }\n\n @Test(timeOut = 1000)\n public void testCityParkCarToSmallestQueue() {\n City c = c();\n ParkingLot p1 = new PriorityParkingLot(1, 1);\n ParkingLot p2 = new PriorityParkingLot(1, 1);\n ParkingLot p3 = new PriorityParkingLot(1, 1);\n SmallCarParkingLot p4 = new SmallCarParkingLot(2, 1);\n c.addParkingLot(p1);\n c.addParkingLot(p2);\n c.addParkingLot(p3);\n\n\n assertSame(c.parkCar(p1()).get(), p1);\n assertSame(c.parkCar(c2()).get(), p1);\n assertSame(c.parkCar(p1()).get(), p2);\n assertSame(c.parkCar(c2()).get(), p2);\n assertSame(c.parkCar(p1()).get(), p3);\n assertSame(c.parkCar(c2()).get(), p3);\n\n c.addParkingLot(p4);\n\n\n IntStream.range(0, 3).forEach(i -> assertSame(c.parkCar(c1()).get(), p4));\n IntStream.range(0, 2).forEach(i -> assertSame(c.parkCar(p1()).get(), p1));\n IntStream.range(0, 2).forEach(i -> assertSame(c.parkCar(p1()).get(), p2));\n IntStream.range(0, 2).forEach(i -> assertSame(c.parkCar(p1()).get(), p3));\n\n for (int i = 0; i < 3; i++) {\n assertSame(c.parkCar(c1()).get(), p4);\n assertSame(c.parkCar(c1()).get(), p1);\n assertSame(c.parkCar(c1()).get(), p2);\n assertSame(c.parkCar(c1()).get(), p3);\n }\n IntStream.range(0, 3).forEach(i -> assertSame(c.parkCar(c1()).get(), p4));\n }\n\n @Test(timeOut = 1000)\n public void testCityParkCarLargeCarForSmallCarParkingLot() {\n City c = c();\n ParkingLot parkingLot = new SmallCarParkingLot(2, 2);\n c.addParkingLot(parkingLot);\n assertEquals(c.parkCar(c2()), Optional.empty());\n assertEquals(c.parkCar(h4()), Optional.empty());\n assertEquals(c.parkCar(h2()), Optional.empty());\n }\n\n @Test(timeOut = 1000)\n public void testCityParkCarSmallCarParkingLotQueueNoLimit() {\n // no queue limit for small car parking lot\n City c = c();\n ParkingLot parkingLot = new SmallCarParkingLot(1, 1);\n c.addParkingLot(parkingLot);\n for (int i = 0; i < 100; i++) {\n assertSame(c.parkCar(h1()).get(), parkingLot);\n assertSame(c.parkCar(p1()).get(), parkingLot);\n assertSame(c.parkCar(c1()).get(), parkingLot);\n }\n }\n\n @Test(timeOut = 1000)\n public void testCityParkCarPriorityParkingLotQueueLimit() {\n City c = c();\n ParkingLot parkingLot = new PriorityParkingLot(1, 1);\n c.addParkingLot(parkingLot);\n for (int i = 0; i < 6; i++) {\n Optional<ParkingLot> pl = c.parkCar(h2());\n if (pl.isEmpty()) fail(\"parkCar returned empty result, but there should be a parking lot.\");\n assertSame(pl.get(), parkingLot);\n }\n assertEquals(c.parkCar(h2()), Optional.empty());\n }\n\n @Test(timeOut = 1000)\n public void testCityParkCarMultiLevelParkingLotQueueLimit() {\n City c = c();\n ParkingLot parkingLot = new MultiLevelParkingLot(1, 1, 1);\n c.addParkingLot(parkingLot);\n for (int i = 0; i < 11; i++) {\n Optional<ParkingLot> pl = c.parkCar(h2());\n if (pl.isEmpty()) fail(\"parkCar returned empty result, but there should be a parking lot.\");\n assertSame(pl.get(), parkingLot);\n }\n assertEquals(c.parkCar(h2()), Optional.empty());\n }\n\n @Test(timeOut = 1000)\n public void testMultiLevelParkingLotSize1Cars() {\n City c = c();\n ParkingLot parkingLot = new MultiLevelParkingLot(1, 1, 2);\n c.addParkingLot(parkingLot);\n IntStream.range(0, 5).forEach(i -> c.parkCar(i % 3 == 0 ? h1() : (i % 3 == 1 ? p1() : c1())));\n assertEquals(parkingLot.getParkedCars().size(), 4);\n\n }\n\n @Test(timeOut = 1000)\n public void testMultiLevelParkingLotNoRoomInFirstLevel() {\n City c = c();\n ParkingLot parkingLot = new MultiLevelParkingLot(2, 1, 2);\n c.addParkingLot(parkingLot);\n c.parkCar(h1());\n c.parkCar(p4());\n assertEquals(parkingLot.getParkedCars().size(), 2);\n c.parkCar(p4());\n assertEquals(parkingLot.getParkedCars().size(), 2);\n c.parkCar(h2());\n assertEquals(parkingLot.getParkedCars().size(), 3);\n }\n\n @Test(timeOut = 1000)\n public void testMultiLevelParkingLotGetTable() {\n City c = c();\n ParkingLot parkingLot = new MultiLevelParkingLot(2, 1, 2);\n c.addParkingLot(parkingLot);\n c.parkCar(h1());\n c.parkCar(p4());\n c.parkCar(h2());\n c.parkCar(p1());\n validateMultiLevelTable(parkingLot.getTable(), 2, 1, 2, new CarSetup(\"H1\", 1).add(\"P4\").add(\"H2\").add(\"P1\"));\n }\n\n @Test(timeOut = 1000)\n public void testMultiLevelParkingLotNoSpecialRules() {\n City c = c();\n ParkingLot parkingLot = new MultiLevelParkingLot(1, 1, 3);\n c.addParkingLot(parkingLot);\n // 2 h1 can be together\n c.parkCar(h1());\n c.parkCar(h1());\n c.parkCar(c2());\n c.parkCar(p1());\n c.parkCar(c1());\n c.parkCar(h1()); // should go to queue, not kicking c2() out\n assertEquals(parkingLot.getParkedCars().size(), 5);\n }\n\n @Test(timeOut = 1000)\n public void testMultiLevelParkingLotUnparkAndParkAgainAndGetTable() {\n City c = c();\n ParkingLot parkingLot = new MultiLevelParkingLot(2, 2, 2);\n c.addParkingLot(parkingLot);\n Car c1 = c1();\n c.parkCar(c1);\n c.parkCar(h4());\n String table = parkingLot.getTable();\n String[] lines = table.strip().split(\"\\n\");\n String topFloor = String.join(\"\\n\", lines[0], lines[1], lines[2], lines[3]);\n validateTable(topFloor, 2, 2, new CarSetup(\"C1\", 1).add(\"H4\"));\n c.parkCar(c4());\n c.parkCar(p4());\n validateMultiLevelTable(parkingLot.getTable(), 2, 2, 2, new CarSetup(\"C1\", 1).add(\"H4\").add(\"C4\").add(\"P4\"));\n c.parkCar(h4());\n assertEquals(parkingLot.getParkedCars().size(), 4);\n //System.out.println(parkingLot.getTable());\n c1.unpark();\n assertFalse(c1.unpark());\n //System.out.println(parkingLot.getTable());\n assertEquals(parkingLot.getParkedCars().size(), 4);\n validateMultiLevelTable(parkingLot.getTable(), 2, 2, 2, new CarSetup(\"H4\", 2).add(\"P4\").add(\"C4\"));\n\n\n }\n\n @Test(timeOut = 1000)\n public void testFitAllThenUnparkAllAndRepeat1000Times() {\n City city = c();\n PriorityParkingLot parkingLot = new PriorityParkingLot(2, 4);\n city.addParkingLot(parkingLot);\n List<Car> allCars = new ArrayList<>(List.of(c1(), c2(), h1(), h2(), c4(), p1(), p2()));\n\n for (int i = 0; i < 1000; i++) {\n Collections.shuffle(allCars);\n for (Car c : allCars) {\n city.parkCar(c);\n }\n parkingLot.processQueue();\n List<Car> parked = parkingLot.getParkedCars();\n parked.sort(null);\n allCars.sort(null);\n System.out.println(parkingLot.getTable());\n assertEquals(parked, allCars);\n for (Car c : allCars) {\n assertTrue(c.unpark());\n }\n }\n }\n\n @Test(timeOut = 4000)\n public void testHugeParkingLot() {\n City city = c();\n PriorityParkingLot parkingLot = new PriorityParkingLot(100, 100);\n city.addParkingLot(parkingLot);\n for (int i = 0; i < 5000; i++) {\n city.parkCar(c4()).get();\n }\n validateTable(parkingLot.getTable(), 100, 100, new CarSetup(\"C4\", 5000));\n }\n\n @Test(timeOut = 1000)\n public void testMultiLevelParkingLot1LevelEmpty() {\n City city = c();\n MultiLevelParkingLot parkingLot = new MultiLevelParkingLot(100, 100, 1);\n city.addParkingLot(parkingLot);\n validateTable(parkingLot.getTable(), 100, 100, new CarSetup());\n }\n\n @Test(timeOut = 1000)\n public void testMultiLevelParkingLotFull() {\n City city = c();\n MultiLevelParkingLot parkingLot = new MultiLevelParkingLot(1, 2, 100);\n city.addParkingLot(parkingLot);\n for (int i = 0; i < 210; i++) {\n assertTrue(city.parkCar(c2()).isPresent());\n }\n for (int i = 0; i < 10; i++) {\n assertFalse(city.parkCar(c2()).isPresent());\n }\n assertEquals(parkingLot.getParkedCars().size(), 200);\n for (int i = 0; i < 10; i++) {\n assertTrue(parkingLot.getParkedCars().get(0).unpark());\n }\n assertEquals(parkingLot.getParkedCars().size(), 200);\n assertTrue(parkingLot.getParkedCars().get(0).unpark());\n assertEquals(parkingLot.getParkedCars().size(), 199);\n }\n\n\n @Test(timeOut = 1000)\n public void testCityParkedCarCountMapWithOneParkingLot() {\n City city = c();\n PriorityParkingLot priorityParkingLot = new PriorityParkingLot(10, 10);\n city.addParkingLot(priorityParkingLot);\n Map<String, Integer> expected = Map.of(\"H1\", 5, \"P2\", 6, \"C4\", 4);\n List<Car> allCars = IntStream.range(0, 5).mapToObj(i -> h1()).collect(Collectors.toList());\n IntStream.range(0, 6).mapToObj(i -> p2()).forEach(allCars::add);\n IntStream.range(0, 4).mapToObj(i -> c4()).forEach(allCars::add);\n Collections.shuffle(allCars);\n allCars.forEach(city::parkCar);\n Map<String, Integer> actual = city.getParkedCarCountBySizeAndPriority();\n for (String key : expected.keySet()) {\n assertEquals(actual.get(key), expected.get(key));\n }\n }\n\n @Test(timeOut = 1000)\n public void testCityCarCountInQueueWithOneParkingLot() {\n City c = c();\n assertEquals(c.getCarCountInQueue(Car.PriorityStatus.PRIORITY, 1), 0);\n MultiLevelParkingLot multiLevelParkingLot = new MultiLevelParkingLot(1, 1, 1);\n c.addParkingLot(multiLevelParkingLot);\n IntStream.range(0, 12).mapToObj(i -> h4()).forEach(c::parkCar);\n assertEquals(c.getCarCountInQueue(Car.PriorityStatus.PRIORITY, 1), 0);\n assertEquals(c.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 4), 10);\n }\n\n @Test(timeOut = 1000)\n public void testCityCarCountInQueueWithSmallParkingLot() {\n City city = c();\n SmallCarParkingLot parkingLot = new SmallCarParkingLot(1, 1);\n city.addParkingLot(parkingLot);\n IntStream.range(0, 1000).mapToObj(i -> h1()).forEach(city::parkCar);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 1), 999);\n }\n\n @Test(timeOut = 1000)\n public void testCityCarCountInQueueWhenQueuesAreFull() {\n City c = c();\n PriorityParkingLot priorityParkingLot = new PriorityParkingLot(1, 1);\n MultiLevelParkingLot multiLevelParkingLot = new MultiLevelParkingLot(1, 1, 1);\n c.addParkingLot(priorityParkingLot);\n c.addParkingLot(multiLevelParkingLot);\n IntStream.range(0, 16).mapToObj(i -> h2()).forEach(c::parkCar);\n assertEquals(c.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 2), 14);\n c.parkCar(h2());\n assertEquals(c.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 2), 15);\n c.parkCar(h2());\n assertEquals(c.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 2), 15);\n priorityParkingLot.getParkedCars().get(0).unpark();\n assertEquals(c.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 2), 14);\n }\n\n @Test(timeOut = 1000)\n public void testCityCarCountInQueueWithSeveralParkingLots() {\n City city = c();\n SmallCarParkingLot smallCarParkingLot = new SmallCarParkingLot(1, 1);\n PriorityParkingLot priorityParkingLot = new PriorityParkingLot(1, 1);\n MultiLevelParkingLot multiLevelParkingLot = new MultiLevelParkingLot(1, 1, 1);\n city.addParkingLot(smallCarParkingLot);\n city.addParkingLot(priorityParkingLot);\n city.addParkingLot(multiLevelParkingLot);\n // small\n city.parkCar(h1());\n city.parkCar(h1());\n // priority\n city.parkCar(h2());\n city.parkCar(h1());\n // multi\n city.parkCar(h2());\n city.parkCar(h1());\n\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 1), 3);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 2), 0);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 4), 0);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.PRIORITY, 1), 0);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.PRIORITY, 2), 0);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.PRIORITY, 4), 0);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.COMMON, 1), 0);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.COMMON, 2), 0);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.COMMON, 4), 0);\n IntStream.range(0, 5).mapToObj(i -> h1()).forEach(city::parkCar);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 1), 8);\n SmallCarParkingLot smallCarParkingLot1 = new SmallCarParkingLot(1, 1);\n city.addParkingLot(smallCarParkingLot1);\n city.parkCar(h2());\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 1), 8);\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 2), 1);\n city.parkCar(h1());\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 1), 8);\n city.parkCar(h1());\n assertEquals(city.getCarCountInQueue(Car.PriorityStatus.HIGHEST, 1), 9);\n\n\n\n }\n\n @Test(timeOut = 1000)\n public void testCityParkedCarCountMapWithSeveralParkingLots() {\n City city = c();\n SmallCarParkingLot smallCarParkingLot = new SmallCarParkingLot(10, 10);\n PriorityParkingLot priorityParkingLot = new PriorityParkingLot(10, 10);\n MultiLevelParkingLot multiLevelParkingLot = new MultiLevelParkingLot(10, 10, 5);\n city.addParkingLot(smallCarParkingLot);\n city.addParkingLot(priorityParkingLot);\n city.addParkingLot(multiLevelParkingLot);\n Map<String, Integer> expected = Map.of(\n \"H1\", 15,\n \"H2\", 11,\n \"H4\", 7,\n \"P1\", 9,\n \"P2\", 8,\n \"P4\", 7,\n \"C1\", 8,\n \"C2\", 10,\n \"C4\", 5\n );\n List<String> keys = expected.keySet().stream()\n .flatMap(key -> Collections.nCopies(expected.get(key), key).stream())\n .collect(Collectors.toList());\n Collections.shuffle(keys);\n for (String key : keys) {\n int size = key.charAt(1) - '0';\n if (key.charAt(0) == 'H') city.parkCar(new Car(Car.PriorityStatus.HIGHEST, size));\n if (key.charAt(0) == 'P') city.parkCar(new Car(Car.PriorityStatus.PRIORITY, size));\n if (key.charAt(0) == 'C') city.parkCar(new Car(Car.PriorityStatus.COMMON, size));\n }\n assertEquals(city.getParkedCarCountBySizeAndPriority(), expected);\n for (String key : expected.keySet()) {\n Car.PriorityStatus status = Car.PriorityStatus.HIGHEST;\n if (key.charAt(0) == 'P') status = Car.PriorityStatus.PRIORITY;\n if (key.charAt(0) == 'C') status = Car.PriorityStatus.COMMON;\n int size = key.charAt(1) - '0';\n assertEquals(city.getParkedCarCount(status, size), expected.get(key).intValue());\n }\n\n }\n\n private String[][][][] validateMultiLevelTable(String table, int height, int width, int levels, CarSetup setup) {\n //System.out.println(table);\n Map<String, Integer> counts = setup.getMapWithDotCounts();\n String[] levelTables = table.split(\"---\");\n assertEquals(levelTables.length, levels, \"getTable() result doesn't have correct number of levels\");\n String [][][][] m = new String[levels][height][width][2];\n table = table.replace(\"---\\n\", \"\");\n String[] lines = table.strip().split(\"\\n\");\n assertEquals(lines.length, levels * height * 2);\n for (int e = 0; e < levels; e++) {\n for (int y = 0; y < height; y++) {\n for (int i = 0; i < 2; i++) {\n String line = lines[e * 2 * height + 2 * y + i].strip();\n assertEquals(line.length(), width * 2);\n for (int x = 0; x < width; x++) {\n String key = line.substring(2 * x, 2 * x + 2);\n if (key.equals(\"..\")) continue;\n m[e][y][x][i] = key;\n counts.put(key, counts.get(key) - 1);\n }\n }\n }\n }\n //System.out.println(table);\n //System.out.println(counts);\n assertTrue(counts.values().stream().allMatch(c -> c == 0));\n for (int e = 0; e < levels; e++) {\n validateSize2And4Cars(m[e]);\n }\n return m;\n }\n\n private String[][][] validateTable(String table, int height, int width, CarSetup setup) {\n Map<String, Integer> counts = setup.getMapWithDotCounts();\n\n String[] lines = table.strip().split(\"\\n\");\n assertEquals(lines.length, height * 2);\n String[][][] m = new String[height][width][2];\n for (int y = 0; y < height; y++) {\n for (int i = 0; i < 2; i++) {\n String line = lines[2 * y + i].strip();\n assertEquals(line.length(), width * 2);\n for (int x = 0; x < width; x++) {\n String key = line.substring(2 * x, 2 * x + 2);\n if (key.equals(\"..\")) continue;\n m[y][x][i] = key;\n counts.put(key, counts.get(key) - 1);\n }\n }\n }\n //System.out.println(table);\n //System.out.println(counts);\n assertTrue(counts.values().stream().allMatch(c -> c == 0));\n // let's validate 2 and 4 cars - so they fill the slots correctly\n validateSize2And4Cars(m);\n return m;\n }\n\n private void validateSize2And4Cars(String[][][] m) {\n // let's validate 2 and 4 cars - so they fill the slots correctly\n int height = m.length;\n int width = m[0].length;\n for (int y = 0; y < height; y++) {\n for (int x = 0; x < width; x++) {\n if (m[y][x][0] != null && m[y][x][0].charAt(1) == '2'\n || m[y][x][1] != null && m[y][x][1].charAt(1) == '2') {\n assertEquals(m[y][x][0], m[y][x][1]);\n }\n if (m[y][x][0] != null && m[y][x][0].charAt(1) == '4'\n || m[y][x][1] != null && m[y][x][1].charAt(1) == '4') {\n assertEquals(m[y][x][0], m[y][x][1]);\n String cc = m[y][x][0];\n boolean found = false;\n if (y > 0) {\n // up\n if (m[y - 1][x][0] != null && m[y - 1][x][0].equals(cc)\n && m[y - 1][x][1] != null && m[y - 1][x][1].equals(cc)) {\n found = true;\n }\n }\n if (!found && y < height - 1) {\n // down\n if (m[y + 1][x][0] != null && m[y + 1][x][0].equals(cc)\n && m[y + 1][x][1] != null && m[y + 1][x][1].equals(cc)) {\n found = true;\n }\n }\n if (!found && x > 0) {\n // left\n if (m[y][x - 1][0] != null && m[y][x - 1][0].equals(cc)\n && m[y][x - 1][1] != null && m[y][x - 1][1].equals(cc)) {\n found = true;\n }\n }\n if (!found && x < width - 1) {\n // left\n if (m[y][x + 1][0] != null && m[y][x + 1][0].equals(cc)\n && m[y][x + 1][1] != null && m[y][x + 1][1].equals(cc)) {\n found = true;\n }\n }\n assertTrue(found, \"car size 4 is not parked correctly\");\n }\n }\n }\n }\n\n private void validatePriorityParkingLotRules(String[][][] m) {\n // extra check for small cars in priority parking lot\n for (int y = 0; y < m.length; y++) {\n for (int x = 0; x < m[0].length; x++) {\n if (\"H1\".equals(m[y][x][0])) {\n assertNull(m[y][x][1]);\n continue;\n }\n if (\"H1\".equals(m[y][x][1])) {\n assertNull(m[y][x][0]);\n continue;\n }\n if (m[y][x][0] != null && m[y][x][0].charAt(1) == '1') {\n if (m[y][x][1] != null) {\n assertEquals(m[y][x][0], m[y][x][1]);\n }\n continue;\n }\n if (m[y][x][1] != null && m[y][x][1].charAt(1) == '1') {\n if (m[y][x][0] != null) {\n assertEquals(m[y][x][0], m[y][x][1]);\n }\n }\n\n }\n }\n }\n\n\n /* helpers for car creation */\n private Car p1() {\n return new Car(Car.PriorityStatus.PRIORITY, 1);\n }\n private Car p2() {\n return new Car(Car.PriorityStatus.PRIORITY, 2);\n }\n private Car p4() {\n return new Car(Car.PriorityStatus.PRIORITY, 4);\n }\n\n private Car c1() {\n return new Car(Car.PriorityStatus.COMMON, 1);\n }\n private Car c2() {\n return new Car(Car.PriorityStatus.COMMON, 2);\n }\n private Car c4() {\n return new Car(Car.PriorityStatus.COMMON, 4);\n }\n\n private Car h1() {\n return new Car(Car.PriorityStatus.HIGHEST, 1);\n }\n private Car h2() {\n return new Car(Car.PriorityStatus.HIGHEST, 2);\n }\n private Car h4() {\n return new Car(Car.PriorityStatus.HIGHEST, 4);\n }\n private City c() {\n return new City(\"tln\");\n }\n}\n"}],"testSuites":[{"unitTests":[{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":1,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLotGetTable","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":2,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLotMoveCommonCarToQueueForHighestPriorityCar","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":34,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testSmallCarParkingLotGetTable","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":93,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityCannotHaveTheSameParkingLotTwice","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":80,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkCarToSmallestQueue","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":35,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testParkingLotAddToQueueDoNotAllowAddingSameCarToQueue","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":31,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testSmallCarParkingLotAddToQueue","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":1,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLot1SizedTogether","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":2,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCarCompareToPriorities","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":64,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkCarLargeCarForSmallCarParkingLot","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":0,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLot2x1AddCar4","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":79,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkTheSameCarTwice","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":133,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityCarCountInQueueWithSeveralParkingLots","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":78,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkedCarCountMapWithSeveralParkingLots","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":84,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkCarSmallCarParkingLotQueueNoLimit","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":34,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testMultiLevelParkingLotNoSpecialRules","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":68,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testParkingLotAddToQueueCarCanOnlyParkInOneLot","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":0,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLotAddToQueue","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":1,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCarCompareToSameParams","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":50,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityCarCountInQueueWithOneParkingLot","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":1175,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testHugeParkingLot","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":2,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCarCompareToSizes","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":35,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testMultiLevelParkingLotNoRoomInFirstLevel","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":48,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkedCarCountMapWithOneParkingLot","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":41,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testMultiLevelParkingLot1LevelEmpty","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":40,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkCarPriorityParkingLotQueueLimit","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":182,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testFitAllThenUnparkAllAndRepeat1000Times","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[{"thread":"TestNG-method=testFitAllThenUnparkAllAndRepeat1000Times-1","truncated":true,"content":"H1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......C4\nH2P2C2C4\nH2P2C2C4\n\nH1P1C1C4\n......"}],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":76,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityCarCountInQueueWhenQueuesAreFull","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":83,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityCannotAddSameParkingLotTwice","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":43,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testSmallCarParkingLotUnpark","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":30,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCar","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":35,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testMultiLevelParkingLotSize1Cars","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":1,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLotH1CanParkAlone","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":38,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testMultiLevelParkingLotFull","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":48,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityParkCarMultiLevelParkingLotQueueLimit","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":36,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testMultiLevelParkingLotGetTable","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":34,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testMultiLevelParkingLotUnparkAndParkAgainAndGetTable","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":1,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLot1x2AddCar4","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":188,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityCarCountInQueueWithSmallParkingLot","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":32,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testCityNoParkingSlots","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]},{"status":"PASSED","weight":1,"description":"","printExceptionMessage":false,"printStackTrace":false,"timeElapsed":1,"groupsDependedUpon":[],"methodsDependedUpon":[],"name":"testPriorityParkingLotUnpark","stackTrace":null,"exceptionClass":null,"exceptionMessage":null,"stdout":[],"stderr":[]}],"name":"ee.taltech.iti0202.parking.ParkingLotTest (TestNG)","file":"ee.taltech.iti0202.parking.ParkingLotTest","startDate":1576067806013,"endDate":1576067810696,"weight":41,"passedCount":41,"grade":100}],"consoleOutputs":[{"content":null}],"output":"TEST RESULTS\n\n* Checkstyle report *\n\nFound errors: 0\n\n\n\n\n* Compiler report *\n\nCompilation succeeded.\n\n* Unit tests *\n\n\nee.taltech.iti0202.parking.ParkingLotTest (TestNG)\nWed Dec 11 12:36:50 UTC 2019\n ---\nSUCCESS: testPriorityParkingLotGetTable\n\t1 msec, weight: 1 unit\nSUCCESS: testPriorityParkingLotMoveCommonCarToQueueForHighestPriorityCar\n\t2 msecs, weight: 1 unit\nSUCCESS: testSmallCarParkingLotGetTable\n\t34 msecs, weight: 1 unit\nSUCCESS: testCityCannotHaveTheSameParkingLotTwice\n\t93 msecs, weight: 1 unit\nSUCCESS: testCityParkCarToSmallestQueue\n\t80 msecs, weight: 1 unit\nSUCCESS: testParkingLotAddToQueueDoNotAllowAddingSameCarToQueue\n\t35 msecs, weight: 1 unit\nSUCCESS: testSmallCarParkingLotAddToQueue\n\t31 msecs, weight: 1 unit\nSUCCESS: testPriorityParkingLot1SizedTogether\n\t1 msec, weight: 1 unit\nSUCCESS: testCarCompareToPriorities\n\t2 msecs, weight: 1 unit\nSUCCESS: testCityParkCarLargeCarForSmallCarParkingLot\n\t64 msecs, weight: 1 unit\nSUCCESS: testPriorityParkingLot2x1AddCar4\n\t0 msecs, weight: 1 unit\nSUCCESS: testCityParkTheSameCarTwice\n\t79 msecs, weight: 1 unit\nSUCCESS: testCityCarCountInQueueWithSeveralParkingLots\n\t133 msecs, weight: 1 unit\nSUCCESS: testCityParkedCarCountMapWithSeveralParkingLots\n\t78 msecs, weight: 1 unit\nSUCCESS: testCityParkCarSmallCarParkingLotQueueNoLimit\n\t84 msecs, weight: 1 unit\nSUCCESS: testMultiLevelParkingLotNoSpecialRules\n\t34 msecs, weight: 1 unit\nSUCCESS: testParkingLotAddToQueueCarCanOnlyParkInOneLot\n\t68 msecs, weight: 1 unit\nSUCCESS: testPriorityParkingLotAddToQueue\n\t0 msecs, weight: 1 unit\nSUCCESS: testCarCompareToSameParams\n\t1 msec, weight: 1 unit\nSUCCESS: testCityCarCountInQueueWithOneParkingLot\n\t50 msecs, weight: 1 unit\nSUCCESS: testHugeParkingLot\n\t1175 msecs, weight: 1 unit\nSUCCESS: testCarCompareToSizes\n\t2 msecs, weight: 1 unit\nSUCCESS: testMultiLevelParkingLotNoRoomInFirstLevel\n\t35 msecs, weight: 1 unit\nSUCCESS: testCityParkedCarCountMapWithOneParkingLot\n\t48 msecs, weight: 1 unit\nSUCCESS: testMultiLevelParkingLot1LevelEmpty\n\t41 msecs, weight: 1 unit\nSUCCESS: testCityParkCarPriorityParkingLotQueueLimit\n\t40 msecs, weight: 1 unit\nSUCCESS: testFitAllThenUnparkAllAndRepeat1000Times\n\t182 msecs, weight: 1 unit\nSUCCESS: testCityCarCountInQueueWhenQueuesAreFull\n\t76 msecs, weight: 1 unit\nSUCCESS: testCityCannotAddSameParkingLotTwice\n\t83 msecs, weight: 1 unit\nSUCCESS: testSmallCarParkingLotUnpark\n\t43 msecs, weight: 1 unit\nSUCCESS: testCar\n\t30 msecs, weight: 1 unit\nSUCCESS: testMultiLevelParkingLotSize1Cars\n\t35 msecs, weight: 1 unit\nSUCCESS: testPriorityParkingLotH1CanParkAlone\n\t1 msec, weight: 1 unit\nSUCCESS: testMultiLevelParkingLotFull\n\t38 msecs, weight: 1 unit\nSUCCESS: testCityParkCarMultiLevelParkingLotQueueLimit\n\t48 msecs, weight: 1 unit\nSUCCESS: testMultiLevelParkingLotGetTable\n\t36 msecs, weight: 1 unit\nSUCCESS: testMultiLevelParkingLotUnparkAndParkAgainAndGetTable\n\t34 msecs, weight: 1 unit\nSUCCESS: testPriorityParkingLot1x2AddCar4\n\t1 msec, weight: 1 unit\nSUCCESS: testCityCarCountInQueueWithSmallParkingLot\n\t188 msecs, weight: 1 unit\nSUCCESS: testCityNoParkingSlots\n\t32 msecs, weight: 1 unit\nSUCCESS: testPriorityParkingLotUnpark\n\t1 msec, weight: 1 unit\n\nPassed unit tests: 41/41\nFailed unit tests: 0\nSkipped unit tests: 0\nGrade: 100.0%\n\nOverall grade: 100.0%\n","totalCount":41,"totalGrade":"100.0","totalPassedCount":41,"style":100}