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

Printing an hourglass pattern

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

Problem

In a recent interview I have been asked to write a program to generate the following output:

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


I had written the following code in java

public class Triangle
{
    public static void main( String[] args )
    {
        show( 5 );
    }

    public static void show( int n )
    {
        for ( int i = 0; i  0; k-- )
            {
                System.out.print( "* " );
            }
            System.out.println();
        }
        for ( int i = 0; i  1; j-- )
            {
                System.out.print( " " );
            }
            for ( int k = 0; k < i + 1; k++ )
            {
                System.out.print( "* " );
            }
            System.out.println();
        }
    }
}


But the interviewer was not happy. He asked me minimize the number variables I had used. I didn't found a way. Anyone could help? Also, could there be a possibility to optimize the iteration here?

Solution

The biggest performance boost you could make would be to issue fewer print() and println() calls. Each call involves a lot of overhead for locking, which you normally don't think about. Coalesce everything down to one single print() for optimal performance.

The number of variables isn't that bad. The problem is, rather, that i, j, k, and n are cryptic and headache-inducing. The headache remedy would be to introduce a helper function and rename the variables to be more meaningful. Note that in assigning meaning to the variables, you'll want to reverse one of the i loops to be a countdown, so that i serves the same role in both loops.

public class Triangle {
    public static void show(int maxWidth) {
        // Top
        for (int width = maxWidth; width > 1; width--) {
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }

        // Middle and bottom
        for (int width = 1; width  0) {
            sb.append(block);
        }
        return sb;
    }

    public static void main(String[] args) {
        show(5);
    }
}


You could try writing one loop to handle both the top and bottom triangles. Unfortunately, this clever solution is not as elegant as it could be, due to the need to skip 0.

public static void show(int maxWidth) {
        for (int i = -maxWidth + 1; i < maxWidth; i++) {
            int width = Math.abs(i) + 1;
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }
    }

Code Snippets

public class Triangle {
    public static void show(int maxWidth) {
        // Top
        for (int width = maxWidth; width > 1; width--) {
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }

        // Middle and bottom
        for (int width = 1; width <= maxWidth; width++) {
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }
    }

    private static StringBuilder repeat(CharSequence block, int n) {
        StringBuilder sb = new StringBuilder(block.length() * n);
        while (n --> 0) {
            sb.append(block);
        }
        return sb;
    }

    public static void main(String[] args) {
        show(5);
    }
}
public static void show(int maxWidth) {
        for (int i = -maxWidth + 1; i < maxWidth; i++) {
            int width = Math.abs(i) + 1;
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }
    }

Context

StackExchange Code Review Q#111461, answer score: 6

Revisions (0)

No revisions yet.