HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMajor

Print 10 × 10 square of X and O characters, split diagonally

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
diagonallysplitcharactersprintsquareand

Problem

I'm going through a beginners exercise for writing a small program in Java. My task is to print out (i.e. find an algorithm) the following output:

XOOOOOOOOO
XXOOOOOOOO
XXXOOOOOOO
XXXXOOOOOO
XXXXXOOOOO
XXXXXXOOOO
XXXXXXXOOO
XXXXXXXXOO
XXXXXXXXXO
XXXXXXXXXX


I have figured out how to do it but the code I wrote seems repetitive and tedious. How can I shorten my code?

```
package helloWorld;

public class HelloWorld {

public static void main(String[] args)
{
// Output

// Algorithm 1

boolean ft = true;

String s = new String();
for(int i = 0; i < 10; i++)
{
s += "X";
for(int j = 0; j < 9; j++)
{
if(i == 0)
{

s += "O";
}

if(i == 1)
{

if(ft == true)
{
s+="X";
ft = false;
}
if(j == 8)
{
continue;
}
s += "O";
}

if(i == 2)
{

if(ft == true)
{
s+= "XX";
ft = false;

}

if(j == 7)
{

break;
}
s += "O";

}

if(i == 3)
{

if(ft == true)
{
s+= "XXX";
ft = false;

}

if(j == 6)
{

break;
}
s += "O";
}

if( i == 4)
{
if(ft == true)
{
s+= "XXXX";
ft = false;

}

if(j == 5)
{

break;
}
s += "O";
}

if( i == 5)
{

Solution

Lots of answers already, but most of them seem to be about alternative solutions. I'll review your code on the details and show you how to refactor your code step by step. (This is a long answer, link to bottom of answer)

String s = new String();


Creating a new String could be simplified to "". The only time you'll actually use the String constructor is for creating strings from arrays like char[] or byte[].

The first line of output

for(int i = 0; i < 10; i++)
{
    s  += "X";
    for(int j = 0; j < 9; j++)
    {
        if(i == 0)
        {

            s += "O";
        }


Seems simple enough. Add an X, then add 9 O's.

The second line of output

for(int i = 0; i < 10; i++)
{
    s  += "X";
    for(int j = 0; j < 9; j++)
    {

        if(i == 1)
        {

            if(ft == true)
            {
                s+="X";
                ft = false;
            }
            if(j == 8)
            {
                continue;
            }
            s += "O";
        }


ft starts off true. Like that, you'll print 1 X, then enter the j loop, add one more X, then an O, and you loop from there to add the remaining characters. This leads to the problem that you have one character extra... so you have to add the j == 8 check to stop the algorithm from printing a line with 10 characters.

You can check boolean conditions without an equality operator, like so:

if(ft)
{
    s+="X";
    ft = false;
}


This will work just as well as the ft == true check.

The third line of output

for(int i = 0; i < 10; i++)
{
    s  += "X";
    for(int j = 0; j < 9; j++)
    {

        if(i == 2)
        {

            if(ft == true)
            {
                s+= "XX";
                ft = false;

            }

            if(j == 7)
            {

                break;
            }
            s += "O";

        }


Same as the second line, except here you add two X on the first iteration, and to compensate, you break one iteration earlier. This is kind of problematic, since you now have to duplicate your code for each iteration. You're missing out on the power of the for-loop.

Did you know Strings come with a length() method? You can retrieve the current length with it.

We can use that method to change the for loop so that each iteration adds just one character.

if(i == 2)
        {

            if(ft == true)
            {
                s+= "XX";
                ft = false;

            }

            if(j == 7)
            {

                break;
            }
            s += "O";

        }


If we use the length() method here to determine ft...

if(i == 2)
        {
            if(ft == true)
            {
                s+= "XX";
                ft = s.length() < 3;
            }

            if(j == 7)
            {

                break;
            }
            s += "O";

        }


Then we can change the code so that it only adds one character at a time, removing the condition that was added to prevent going over 10 characters.

if(i == 2)
        {
            if(ft == true)
            {
                s+= "X";
                ft = s.length() < 3;
            } 
            else
            {
                s += "O";
            }
        }


We could copy this change for all cases...

if(i == 3)
        {
            if(ft == true)
            {
                s+= "X";
                ft = s.length() < 4;
            } 
            else
            {
                s += "O";
            }
        }


but that seems like we're still duplicating code.

Fortunately, it seems we can make use of the fact that... if i == n, then the check needs to be s.length() < n + 1.

So let's apply that change.

if(i == 3)
        {
            if(ft == true)
            {
                s+= "X";
                ft = s.length() < (i + 1);
            } 
            else
            {
                s += "O";
            }
        }


Now all the cases look like this:

if(i == 2)
        {
            if(ft == true)
            {
                s+= "X";
                ft = s.length() < (i + 1);
            } 
            else
            {
                s += "O";
            }
        }

        if(i == 3)
        {
            if(ft == true)
            {
                s+= "X";
                ft = s.length() < (i + 1);
            } 
            else
            {
                s += "O";
            }
        }


Seems like we can merge the cases i == 1 through i == 9 because they're all the same. And since i only goes to 9 because of the i < 10 condition, all we're interested in is checking that it's not the first iteration:

if(i != 0)
        {
            if(ft == true)
            {
                s+= "X";
                ft = s.length() < (i + 1);
            } 
            else
            {
                s += "O";
            }
        }


Here's where we're at now.

`

Code Snippets

String s = new String();
for(int i = 0; i < 10; i++)
{
    s  += "X";
    for(int j = 0; j < 9; j++)
    {
        if(i == 0)
        {

            s += "O";
        }
for(int i = 0; i < 10; i++)
{
    s  += "X";
    for(int j = 0; j < 9; j++)
    {

        if(i == 1)
        {

            if(ft == true)
            {
                s+="X";
                ft = false;
            }
            if(j == 8)
            {
                continue;
            }
            s += "O";
        }
if(ft)
{
    s+="X";
    ft = false;
}
for(int i = 0; i < 10; i++)
{
    s  += "X";
    for(int j = 0; j < 9; j++)
    {

        if(i == 2)
        {

            if(ft == true)
            {
                s+= "XX";
                ft = false;

            }

            if(j == 7)
            {

                break;
            }
            s += "O";

        }

Context

StackExchange Code Review Q#140268, answer score: 31

Revisions (0)

No revisions yet.