So I recently attempted the following exercise:

Write a program that reads in the size of the side of a square and then prints a hollow squareof that size out of asterisks and blanks. Your program should work for squares of all side sizes be-tween 1 and 20 .
My solution?
Code:
#include <iostream>


int main()
{
    int size;
    int row = 1;
    int col = 1;
    
    std::cout << "Enter size of square: ";
    std::cin >> size;
    
    while ( row <= size)
    {
        while (col <= size)
        {
            if (row == 1)
                std::cout << "*";
            else if (row != size)
            {
                if (col == 1)
                    std::cout << "*";
                else if (col!= size)
                    std::cout << " ";
                else if (col == size)
                    std::cout << "*";
            }
            else if (row == size)
                std::cout << "*";
            col++;
        }
        std::cout << "\n";
        col = 1;
        row++;
    }
}
I'm not too happy with it, it feels like a kludged solution. In the real world how important is it to make an elegant and concise algorithms vs one that simply works?

Working out the algorithm was the hardest part for me that involved a lot of trial and error. How would you organize your thinking to solve a problem like this?