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

Attempt at method to draw diamond (recursive or not ?)

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

Problem

I'm not so good with recursion, so I've decided to tackle an exercise consisting of drawing this pattern using characters:

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


Here is my code so far. What could be improved? Furthermore, is recursion suitable for a task like this or not?

class Main
{
    public static void main (String[] args)
    {
        Main.drawDiamond("*", 0, 5 );
    }

    public static void drawDiamond( String seed, int turn, int centerLevel ){

        if( seed.length() = 3 ) {
                 seed = seed.substring(1,seed.length()-1); 
            } else {
                seed = "";
            }
        }

        turn++;

        drawDiamond( seed, turn, centerLevel );
    }
}

Solution

You can make this a recursion exercise with two parts:

1) Write a recursive method to repeat a char n times.

Signature:

public static String getCharRepeatedTimes(final char c, final int times)


(Read at end to see a solution)

2) Write a recursive method to create a diamond pattern.

Signature for recursive start method:

public static String getDiamondWithSize(final int size)


Signature for recursive "work" method:

private static String getDiamondWithSize(final int size, final int currentSize)


Hint 1: You can use the method from 1)

Hint 2: Think about a pattern in the diamon and how to exploit it.

(Read at end to see a solution)

Let us start with 1):

public static String getCharRepeatedTimes(final char c, final int times) {
    if (times == 0)
        return "";
    return String.valueOf(c) + getCharRepeatedTimes(c, times - 1);
}


And continue with 2):

public static String getDiamondWithSize(final int size) {
    return getDiamondWithSize(size, 2 - (size & 1));
}


The start method can be done in two ways. Starting from the outer area to the inner area or vice-versa. I have done the out->in way. If you allow even and odd diamonds, then we have to manage the start or end size in the correct way. There the 2 - (size & 1) part, which is 2 for even size and 1 for odd size.

The idea is now to create the outer lines first and append it to the next inner part then. Until the inner part is the full part.

private static String getDiamondWithSize(final int size, final int currentSize) {
    if (currentSize == size)
        return getCharRepeatedTimes('*', size) + "\n";
    final int nonDiamondSpace = (size - currentSize) / 2;
    final String currentLine = getCharRepeatedTimes(' ', nonDiamondSpace) + getCharRepeatedTimes('*', currentSize) + "\n";
    return currentLine + getDiamondWithSize(size, currentSize + 2) + currentLine;
}


The + concatenation could be replaced by StringBuilder , insert and append. For clarity and the exercise purpose, it is not done here.

Suggestions for your code:

public static void drawDiamond(String seed, int turn, final int centerLevel) {
    ...
    if (turn <= centerLevel)


Noone would expect this if the method is called. At least for me, it is unclear how the argument centerLevel is related to the size of the diamond. You should add at least some JavaDoc, I would prefer to change the behavior.

turn++;
    drawDiamond(seed, turn, centerLevel);


In general, you should avoid to change arguments, if possible. In this case, we can go with this:

drawDiamond(seed, turn + 1, centerLevel);


This looks a bit complex:

if( turn = 3 ) {
             seed = seed.substring(1,seed.length()-1); 
        } else {
            seed = "";
        }
    }


You should add at least some comments. And you can decrease the branch depth by one:

if (turn = 3) //until the end is reached, reduce by 2 chars
        seed = seed.substring(1, seed.length() - 1);
    else //finished
        seed = "";


Rest is more a subjective view. I would rather introduce a method to generate a char/String repeated n times than doing it inside the diamond method. And I would avoid the seed argument as shown above.

Code Snippets

public static String getCharRepeatedTimes(final char c, final int times)
public static String getDiamondWithSize(final int size)
private static String getDiamondWithSize(final int size, final int currentSize)
public static String getCharRepeatedTimes(final char c, final int times) {
    if (times == 0)
        return "";
    return String.valueOf(c) + getCharRepeatedTimes(c, times - 1);
}
public static String getDiamondWithSize(final int size) {
    return getDiamondWithSize(size, 2 - (size & 1));
}

Context

StackExchange Code Review Q#29523, answer score: 3

Revisions (0)

No revisions yet.