Hollow square

Hey everyone i hope your doing all fine.

The query that i have is that it is pretty easy to print a hollow square using loop but is thee a way to do the same with out using any loops or functions.

I need a reply as soon as possible.
Last edited on
Here's a reply. What is your question?

To clarify, we're glad to help, but you have to show what you've tried so far.
Last edited on
the answer is yes.

I mean, you can hard code it, if nothing else:

cout <<"*****\n* *\n* *\n* *\n*****\n";

to do a variable sized one is a bit trickier, but doable depending on how you define 'loop'. Can you define "loop" for us?
You know, I didn't actually closely read Agrito's post. It is quite a more unique request than I originally gave it credit for.

One could probably do something with std::string length-based constructor and concatenation to avoid writing a loop. It's an odd request.

Does goto count as a loop ;)
Last edited on
Technically main() is a function, so it cannot be done without functions.

As far as variable-size squares, I don't know how you would add the middle rows without using loops. Somehow you have to count the middle rows to make sure the correct number are added to the square, and I don't see how that can be done without loops (assuming goto is considered a loop per @Ganado's question). A string could be allocated with the correct size, but still the characters in the string will need to be manipulated to transform into rows forming the square, and a loop of some type will be needed to do so.

So, I don't know of a way to do this without loops.
I think figured out how to do it with std::strings + stringstream + <algorithm>, using the length-based constructor (2) @ https://en.cppreference.com/w/cpp/string/basic_string/basic_string

First, constructor the outer 2x rows using the constructor (2).
Then, you need to make one inner row using constructor (2).
Then, you need to repeat the constructed inner row height-2 times. This can be done with std::fill_n, I believe?

Obviously it's still looping under the hood.
Wait but fill_n is a function. Darn it!
But + operator is a "function" as well. I hate ill-defined questions.
Last edited on
If you set a maximum allowed size, you can unroll the loop uncleanly, with conditions and a counter...

counter++
if(counter < dimension)
spew out another line
... over and over until max allowed dimension,
then write the final bottom line...

if you get really keyed up about how loop is defined, the string allocations we are suggesting may contain a hidden loop. Again, it depends on the rules you want to play by.

it may be possible to make the string via macro expansions or something too. There are lots of hackery things c++ allows that we generally don't even consider doing until painted into a corner by some challenge.
Last edited on
I'm imagining that "no functions" must be "no user-defined functions", and "no loops" must mean "no user-defined (raw) loops".

All types of repetitions except your max-size approach would have to have a loop at some point. I do like your unrolled approach though, pretty funny.
Last edited on
sorry for the late reply but this is what i have done so far but i wana do this without using for and while loops

Write a program that reads in the size of the side of a square then prints a hollow square of that size out of asterisksand blanks.Your program should work for squares of all side sizes between 1 and 20. For example, if your program reads a size of 5, it should print
*****
* *
* *
* *
*****

#include<iostream>

using namespace std;

int main()
{
cout << "Enter the size between 1 and 20 for the sides of a square : ";
int size, i, j;
cin >> size;
if (size >= 1 && size <= 20)
{
cout << "The size of the sides of your square is: "<<size<<endl;
cout << "This is your square : \n";
for (i = 0;i < size;i++)
{
for (j = 0;j < size;j++)
{
if (i == 0 || i == (size - 1))
{
cout << "*";
}

else if (j == 0)
{
cout << "*";
}
else if (j == size - 1)
{
cout << "*";
}
else
{
cout << " ";
}

}
cout << "\n";
}
}
else
{
cout << "\nInvaid size.!\n";
}
system("pause");
return 0;

}
If you want it to be done as an iterative process, with each line being calculated as the program runs rather than hardcoded, and you can't use loops, then you should consider using recursion instead. That's the obvious alternative to loops, for an iterative process.

EDIT: Ignore that - recursion would involve writing a function, which you apparently are forbidden to do.

Has your teacher given you any other hints on what techniques to use?

While I would never, ever, recommend using goto, is it possible this is what your teacher is expecting you to use?
Last edited on
No (explicit) loops, but it does use a function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
using namespace std;

void line( int row, int num )
{
   if ( row < 0 ) return;
   char c = row * ( num - row - 1 ) ? ' ' : '*';
   cout << '*' << string( num - 2, c ) << "*\n";
   line( row - 1, num );
}

int main()
{
   int n;
   cout << "Input side (n > 2): ";   cin >> n;
   line( n - 1, n );
}


Input side (n > 2): 5
*****
*   *
*   *
*   *
*****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <string>
#include <sstream> // std::ostringstream
#include <iterator> // std::ostream_iterator
#include <algorithm> // std::fill_n

int main()
{
    int width = 6;
    int height = 4;
    
    std::string output;
    
    // first row
    output += std::string(width, '*');
    output += '\n';

    std::string inner_row;
    inner_row += "*";
    inner_row += std::string(width-2, ' ');
    inner_row += "*";
    inner_row += '\n';
    
    // inner rows repeated
    std::ostringstream oss; // https://stackoverflow.com/a/49613515/8690169
    std::fill_n(std::ostream_iterator<std::string>(oss), height - 2, inner_row);
    output += oss.str();

    // last row
    output += std::string(width, '*');
    output += '\n';

    // print
    std::cout << output;
}
Last edited on
square.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <valarray>
using namespace std;

int main()
{
   int n;
   cout << "Input side (n > 2): ";   cin >> n;
   valarray<char> square( '*', n * ( n + 1 ) );
   square[ slice( n, n, n + 1 ) ] = '\n';
   square[ gslice( n + 2, { n - 2, n - 2 }, { n + 1, 1 } ) ] = ' ';
   cout << string( begin( square ), end( square ) );
}




square.f90
1
2
3
4
5
6
7
8
program square
   integer n
   character(len=:), allocatable :: top, mid
   print *, "Input side (n > 2): ";   read *, n
   top = repeat( '*', n ) // new_line( 'a' )
   mid = '*' // repeat( ' ', n - 2 ) // '*' // new_line( 'a' )
   write( *, "(a)" ) top // repeat( mid, n - 2 ) // top
end program square




square.py
1
2
n = int( input( "Input side (n > 2): " ) )
print( n * '*' + '\n' + ( n - 2 ) * ( '*' + ( n - 2 ) * ' ' + "*\n"  ) + n * '*' )
Last edited on
i know how to use loops and functions and we didnt went past if else the loops (for and while) will be covered in the next lecture but i have to solve this before that but i cant think of a way to keep it simple and not use anything complex. Thanks for haring ur input guys this is helping me learn but im going to move forward and go with what i know best
If you posted the exact prompt that you're following, it might shed some light on the situation.
sorry agrito, you have sent us off into toyland ... your question has us playing with how to do it without the tools we are used to using and that yields exotic, humorous but unhelpful responses.

Let me see if I can do something less weird. Post what you come up with too.
Last edited on
lets try this. it does use something you likely havent seen, the ostringstream, but otherwise, its dead simple..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


int main()
{  
  int dim = 5; //example square dimension
  string s(dim,'*'); //the top and bottom lines will be solid, the * letter dim times. 
  string h(dim,' '); //dim spaces. 
  h[0] = h[h.length()-1] = '*'; //fill in the first and last letter to * to make 'walls' 
  h+= '\n';  //add end of lines, not necessary, but handy. 
  s+= '\n';
  ostringstream os;
  fill_n(std::ostream_iterator<std::string>(os), dim-2, h); //fill dim-2 copies of the wall string complete with end of lines.  
  cout << s << os.str() << s << endl;  //print the square.  the top, the middle, and the bottom.  the middle is, again, just dim-2 copies of the wall string, which is, again, first and last char * and dim-2 in the middle spaces. 
}


I just realized this is virutally the same as Ganado's. A little shorter, but not much, and same idea. I think this is about as good as you are going to get if you want simple. And, fill_n is just hiding a function that contains a loop -- its exploiting built in tools to hide the things you said not to do.
Last edited on
Topic archived. No new replies allowed.