3
\$\begingroup\$

Description of the problem:

Design a parking system for a parking lot. The parking lot has three kinds of parking spaces: big, medium, and small, with a fixed number of slots for each size.

Implement the ParkingSystem class:

ParkingSystem(int big, int medium, int small) Initializes object of the ParkingSystem class. The number of slots for each parking space are given as part of the constructor.

bool addCar(int carType) Checks whether there is a parking space of carType for the car that wants to get into the parking lot. carType can be of three kinds: big, medium, or small, which are represented by 1, 2, and 3 respectively. A car can only park in a parking space of its carType. If there is no space available, return false, else park the car in that size space and return true.

Below is my code, I would appreciate any suggestions on how to improve the code.

#include <iostream>

class ParkingSystem {
    
public:
    ParkingSystem(int big, int medium, int small) :
    m_big_max(big),
    m_medium_max(medium),
    m_small_max(small),
    m_big_curr(0),
    m_medium_curr(0),
    m_small_curr(0)
    {}
    
    bool addCar(int carType) {
        if (carType == 1) {
            // big car
            if (m_big_curr == m_big_max) {
                return false;
            } else {
                m_big_curr++;
            }
        } else if (carType == 2) {
            // medium car
            if (m_medium_curr == m_medium_max) {
                return false;
            } else {
                m_medium_curr++;
            }
        } else {
            // small car
            if (m_small_curr == m_small_max) {
                return false;
            } else {
                m_small_curr++;
            }
        }
        
        return true;
    }
    
private:
    int m_big_max;
    int m_medium_max;
    int m_small_max;
    
    int m_big_curr;
    int m_medium_curr;
    int m_small_curr;
    
};

int main() {
    
    ParkingSystem parking_system(1, 1, 0);
    
    std::cout << "parking_system.addCar(1) " << parking_system.addCar(1) << std::endl;
    std::cout << "parking_system.addCar(2) " << parking_system.addCar(2) << std::endl;
    std::cout << "parking_system.addCar(3) " << parking_system.addCar(3) << std::endl;
    std::cout << "parking_system.addCar(1) " << parking_system.addCar(1) << std::endl;

    
    return 0;
}
\$\endgroup\$
5
\$\begingroup\$

Observation

You can simplify this using arrays.

You don't need two numbers for each type (max and current). Simply track the number of open spots (per type) and count down.

if you are not using arrays consider a switch statement.

Code Review:

Prefer "\n" over std::endl.

If your main() does not return anything but 0 at the end.
Then leave out the return. It is auto added by the compiler.

Re-Design

template<std::size_t typeCount = 3>
class ParkingSystem
{
    int openSlots[typeCount];
    
    public:
        template<typename... Args>
        ParkingSystem(Args... args)
            : openSlots{args...}
        {}
    
        bool addCar(int type)
        {
            if (openSlots[type - 1] == 0) {
                return false;
            }
            --openSlots[type - 1];
            return true;
        }
};

int main() 
{
    
    ParkingSystem parking_system(1, 1, 0);
    
    std::cout
        << "parking_system.addCar(1) " << parking_system.addCar(1) << "\n"
        << "parking_system.addCar(2) " << parking_system.addCar(2) << "\n"
        << "parking_system.addCar(3) " << parking_system.addCar(3) << "\n"
        << "parking_system.addCar(1) " << parking_system.addCar(1) << "\n";
}
\$\endgroup\$
1
  • \$\begingroup\$ is there any advantage in using a template for the size, compared to a constexpr variable? \$\endgroup\$ – Parekh Oct 9 '20 at 10:12
2
\$\begingroup\$

General observations

If you notice your Parking class, you see that there are too many member variables. The first way to improve would be to try to reduce the extra variables. And that could be done by improving the code logic. But before I get into the logic part, I would like to point out.

Use enum for clarity

if (cartype == 1)
if (cartype == 2)

These are called Magic Numbers
It's not clear as to what 1 or 2 here. Unless you read the question thoroughly, it can get confusing.

The solution is to use an enum.
enums in C++

An enumeration is a user-defined type that consists of a set of named integral constants that are known as enumerators.

This way you can give a name to numeric constants, which in this case are 1, 2, and 3.

The syntax would look like

enum CarType{ BIG= 1, MEDIUM, SMALL};

This will set MEDIUM and SMALL to 2 and 3 respectively. Now your if statement will look like

if (cartype == BIG)
if (cartype == MEDIUM)

Sure you type a little more, but this way it is much clearer as to what the if statement checks for.

The Logic

The code asks us to keep track of 3 types of cars. Hence, all we really need is 3 variables. Even better, an array of car types.

  • Every time we add a car, we do --car_type
  • If it is already 0, that means that the parking space of that type is full.
enum CarType{BIG = 1, MEDIUM, SMALL};

constexpr int nb_car_type = 3;

class Parking{
    private:
        int m_Big;
        int m_Medium;
        int m_Small;

    public:
        Parking(int big,int medium,int small)
            : m_Big{big}, m_Medium{medium}, m_Small{small}
        {}

};

With an array

#include <iostream>
#include <array>

constexpr int nb_car_type = 3;

class Parking{
    private:
        std::array< int , nb_car_type > space;

    public:
        Parking(int big,int medium,int small)
            : space{big,medium,small}
        {}

};

Since we use an array, we will not need to use an enum since we won't be making any checks
The advantage you have when using an array is that your addcar() function will be slightly smaller.

Adding the car

  • Check whether space[car_type] is 0
  • If true, return false as parking space is 0
  • If false, return true and decrement. --space[car_type]

Implementation.

#include <iostream>
#include <array>


constexpr int nb_car_type = 3;

class Parking{
    private:
        std::array< int , nb_car_type > space;

    public:
        Parking(int big,int medium,int small)
            : space{big,medium,small}
        {}
        bool addcar(int type)
        {
            if (space[type-1] == 0) 
            {
                return false;
            }
            --space[type-1];
            return true;
        }

};

What's happening here?

Since we have an array, we can directly slice the array by type and get the correct value. The reason it is not type, but type-1 is because counting starts from 0. The 1st element of an array is array[0].

All we do is check whether that value is 0. If it isn't that means more space is left, and we can derement that value. If it is then just return false as parking is full.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.