Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I need to print this in Java. I have written code for this, but I feel that my code is too big.

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

My Code:

public static void main(String[] args) {

    for(int i=0; i<=3; i++) {
        for(int j=0; j<=i; j++) {
            System.out.print("*");
        }
        System.out.println();
    }

    for(int j=1; j<=3; j++) {
        for(int i=3; i>=j; i--) {
            System.out.print("*");
        }
        System.out.println();
    }
}
share|improve this question

4 Answers 4

up vote 22 down vote accepted

Here is a lovely way to do it using only one nested for-loop:

for (int i = 0; i < 7; i++) {
    for (int numStars = 0; numStars < 4 - Math.abs(3 - i); numStars++) {
        System.out.print("*");
    }
    System.out.println();
}

This uses the Math.abs function to perform the calculation of how many stars to print.

If we take a look at a plot of the classic Math.abs we can see that it looks useful. We need to flip it upside-down though, this is done by taking 4 - abs(x) which would look like this. Finally, we need to switch it to the right a bit, so we modify the input to the function call and end up with this: 4 - abs(3 - x)

Images courtesy of wolframalpha.com

4-abs(x)

enter image description here

4-abs(3 - x)

enter image description here

Finally, here is a very flexible solution, which also works with even numbers:

int rows = 20;
double maximumValue = Math.ceil(rows / 2.0);
double shifted = maximumValue - 1;
for (int i = 0; i < rows; i++) {
    int count = (int) (maximumValue - Math.abs(shifted - i));
    if (i >= rows / 2 && rows % 2 == 0) // slight fix for even number of rows
        count++;

    for (int numStars = 0; numStars < count; numStars++) {
        System.out.print("*");
    }
    System.out.println();
}

This will output:

*
**
***
****
*****
******
*******
********
*********
**********
**********
*********
********
*******
******
*****
****
***
**
*
share|improve this answer
    
Thanks for the code. –  user3272408 Feb 4 '14 at 21:06
17  
This is an excellent answer. I am disappointed that @user3272408 was apparently only interested in the code. –  MirroredFate Feb 5 '14 at 1:58
7  
+5 for charts and graphs! Letterman would be proud. –  David Harkness Feb 5 '14 at 4:09

You've hard-coded 3 in three places. Yet, the output contains a row with four stars. That's underhanded programming. The culprit is this line:

for(int j=0; j<=i; j++)

Idiomatic Java would be either

for (int j = 0; j < somelimit; j++)

or

for (int j = 1; j <= somelimit; j++)

I also find the way that you interchanged i and j between the first and second halves of the program disconcerting.


Surely you should define a function that accepts a parameter. What varies? The fill character? The size? Otherwise, the simplest solution would be

public static void main(String[] args) {
    System.out.println("*\n**\n***\n****\n***\n**\n*");
}

I am in favour of keeping two for-loops, one increasing and one decreasing. Combining those into one loop would likely make it difficult to see the intent at a glance. As for how you generate each line of n stars, though, it's not particularly interesting how you accomplish it. I've chosen a one-line hack for the solution below, but you may wish to pick a more traditional approach.

private static String repeat(String s, int n) {
    // A bit of a hack, and not very efficient.  Feel free to reimplement.
    return String.format("%" + n + "s", "").replaceAll(" ", s);
}

public static void printArrow(String fill, int width, PrintStream out) {
    for (int i = 1; i < width; i++) {
        out.println(repeat(fill, i));
    }
    for (int i = width; i >= 1; i--) {
        out.println(repeat(fill, i));
    }
}

public static void main(String[] args) {
    printArrow("*", 4, System.out);
}
share|improve this answer

You don't need a loop for this.

public static void main(String[] args) {
        String ln = System.getProperty("line.separator");
        System.out.println("*" + ln
                        +  "**" + ln
                        +  "***" + ln
                        +  "****" + ln
                        +  "***" + ln
                        +  "**" + ln
                        +  "*");
}
share|improve this answer
2  
That is overkill: System.out.println("*\n**\n***\n****\n***\n**\n*"); Seriously, what were you thinking? ;-) ! –  rolfl Feb 5 '14 at 0:54
3  
@rolfl: But it looks like the output itself! ;-) –  Jamal Feb 5 '14 at 0:57

We can use StringBuffer as well:

StringBuffer buffer = new StringBuffer();
for (int i = 0; i < (n+n-1); i++) {
    if(i<n){
        System.out.println(buffer.append("*")); 
    }else{
        System.out.println(buffer.deleteCharAt(i-(i-1)));
    }
}
share|improve this answer

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

1  
Should at least be StringBuilder, not StringBuffer. In addition, the delete part is really complicated to understand, and it should just be deleteCharAt(1), and why would you do that, anyway? –  rolfl Aug 27 at 4:53

protected by Jamal Aug 27 at 3:31

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.