KDjava
KDjava

Reputation: 2455

printing nested squares using for loops in Java

The pattern of stars that need to be printed The problem is to create concentric and nested squares,starting with the largest square's side given as N.Its just like drawing one square inside another ON PAPER,until no more squares are possible to be drawn, by decrementing the length of the side by 4 after each square(2 from startPos of side and 2 from endPos); And N is the size of the square to start with. You have to draw the sides by using multiplication symbol('*').

The proportion(looks more like rectangles than squares) of the above image might not be exact, but it would give u idea about what needs to be done .. The below code is what I have tried...This the exact pattern that needs to be printed..

public static void main(String[] args)
{
    int N=9;
    int iLo=0;
    int iHi=N-1;
    int jLo=0;
    int jHi=N-1;

    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(i==0 || (i==N-1) || (j==0) || (j==N-1))
                System.out.print('*');
            else
            {
                if(i<=N/2)
                {
                    if((i%2==0) && (i>=iLo) && (i<=iHi) && (j>=jLo) && (j<=jHi))
                        System.out.print('*');
                    else
                        if(i==iLo || i==iHi )
                            System.out.print('*');
                        else
                            System.out.print(' ');  
                }
                else
                {
                    if((i%2==0) && (i>=iLo) && (i<=iHi) && (j>=jLo) && (j<=jHi))
                            System.out.print('*');
                        else
                            System.out.print(' ');  
                }

            }

        }
        System.out.print("  i-->"+i+"   iLo-->"+iLo+" iHi-->"+iHi+" jLo-->"+jLo+" jHi-->"+jHi);
        if(i%2>0)
        {
            if(i<=N/2)
            {
                jLo=jLo+2;
                jHi=jHi-2;
                iLo=iLo+1;
                iHi=iHi-1;
            }
            else
            {
                jLo=jLo-2;
                jHi=jHi+2;
                iLo=iLo-1;
                iHi=iHi+1;
            }
        }
        else
        {

        }

        System.out.println();
    }

}

Upvotes: 3

Views: 5278

Answers (3)

KDjava
KDjava

Reputation: 2455

The following code offers the simplest recursive solution possible---

public class SquaresInSquare {

private static char[][] arr;


public static void populate(int start,int N)
{
    //System.out.println(start+" "+N);
    if(N < 0 || start > N)
        return;

    for (int i = start; i < N; i++)
    {
        for (int j = start; j < N; j++)
        {
            if(i==start || i==N-1 || j==start || j==N-1)
                arr[i][j]='*';
            else
                arr[i][j]=' ';
        }
    }

    populate(start+2,N-2);
}

public static void print()
{
    for (int i = 0; i < arr.length; i++)
    {
        for (int j = 0; j < arr.length; j++)
        {
            System.out.print(arr[i][j]);
        }
        System.out.println();
    }
}

/**
 * @Method :main is Personal Method Of Class-->SquaresInSquare
 * @returns : void
 * @param args
 */
public static void main(String[] args)
{
    int N=21;
    arr=new char[N][N];
    populate(0,N);
    print();

}

}

Upvotes: 0

cheeken
cheeken

Reputation: 34685

Overview

This question is appropriate for Adobe because it's essentially a rendering algorithm: given a pixel and a set of rules, calculate the appearance of that pixel.

The most efficient way to do this is to come up with a test that answers "given the position (x,y) in a square of size n, should it be marked with *?", and then answer that question for each position.

We can answer this question by first making a couple of observations.

  • Note the symmetry of the output of this algorithm. If we cut the square along its diagnols, we are left with four triangular quadrants. Within each quadrant, notice that the triangle is simply striped.
  • Vertical or horizontal stripes are simple to draw; just check if the row/column is an even distance from the nearest edge and shade it if so.

So we'll do two computations per position: (1) which quandrant is this position in and (2) given this quadrant, should this position's row/column be shaded?

Example implementation (python)

def getQuadrant(i,j,n):
    # 1 means top quadrant; 2 right; 3 bottom; 4 left
    half_n = float(n-1)/2
    x = float(i) - half_n
    y = float(j) - half_n
    if x > 0:
        if y > 0:
            if x > y:
                return 3
            else:
                return 2
        else:
            if x > -1*y:
                return 3
            else:
                return 4
    else:
        if y > 0:
            if -1*x > y:
                return 1
            else:
                return 2
        else:
            if x < y:
                return 1
            else:
                return 4

def isPixelShaded(x,y,n):
    q = getQuadrant(x,y,n)
    if q == 1:
        return (x % 2) == 0
    elif q == 2:
        return ((n-y-1) % 2) == 0
    elif q == 3:
        return ((n-x-1) % 2) == 0
    else:
        return (y % 2) == 0

def getPixelShade(x,y,n):
    if isPixelShaded(x,y,n):
        return ' * '
    else: 
        return '   '

def printSquare(n):
    for i in range(n):
        print ''.join(map(lambda x: str(getPixelShade(i,x,n)),range(n)))

printSquare(3)
printSquare(6)
printSquare(9)

Output

 *  *  * 
 *     * 
 *  *  * 
 *  *  *  *  *  * 
 *              * 
 *     *  *     * 
 *     *  *     * 
 *              * 
 *  *  *  *  *  * 
 *  *  *  *  *  *  *  *  * 
 *                       * 
 *     *  *  *  *  *     * 
 *     *           *     * 
 *     *     *     *     * 
 *     *           *     * 
 *     *  *  *  *  *     * 
 *                       * 
 *  *  *  *  *  *  *  *  * 

Other thoughts

Instead of a the rendering approach taken here, we could also take an iterative approach by "walking out squares" a in pre-allocated matrix. That approach is simpler to think about but it requires more memory. Additionally, the approach described in this answer has the benefit that to determine wither a given position is shaded, we don't need to know about its neighboring positions (which an iterative approach does). This means we could render small swatches of the final rendering at once. In other words, this approach supports parallelism, which is always a nice bonus.

Upvotes: 0

BlackVegetable
BlackVegetable

Reputation: 13064

This could be solved either by using a for-loop that decrements by 2 each time (i -= 2) Or recursively where the base case prints a single * to the screen, or none at all. As others have posted, unless you have some space between each square, you will only have a solid square.

EDIT: It seems you might not be printing one square on top of another, but rather in place of another. The same strategy applies, however.

EDIT2: You shouldn't need to use a nested for loop with i and j. A single for loop with the length of each side as the variable i should suffice. You will need to adjust for double counting of vertices, however.

Why not try something like:

// Assumes a cartesian coordinate system, origin at bottom left.
int startingX = 0;
int startingY = 0;
while( length > 0 ){
  printHorizontally(length, startingX, startingY);
  printVertically(length, startingX, startingY);
  startingX += 2;
  startingY += 2;
  length -= 4; 
}

private void printHorizontally(int length, int startingX, int startingY){
  // Prints length *s to the screen in a horizontal line starting at the
  // given points.  Define printVertically similarly.    
}

Upvotes: 1

Related Questions