Making an ASCII hourglass using asterisks

890 Views Asked by At

I know it's been asked but I'm having some hard time understanding other programs and nested loops, if someone has a trick to follow nested loops and making a shape with asterisks I would like to know because it really got me confused.

Here is the code I wrote after many many tries and experiments:

Scanner input = new Scanner(System.in);
System.out.print("Enter a number: ");
int userentry = input.nextInt();
for (int i = 0; i < userentry - 1; i++) {
    for (int k = 0; k < i; k++) {
        System.out.print(" ");
    }
    for (int j = userentry - 1; j >= i; j--) {
        System.out.print("*");
    }
    System.out.println();
}
for (int i = 0; i < userentry; i++) {
    for (int k = 0; k < i + 1; k++) {
        System.out.print(" ");
    }
    for (int j = 0; j <= i; j++) {
        System.out.print("*");
    }
    System.out.println();
}

The output for the number entry 3 for example goes like this, i'm having trouble with the spacing:

***
 **
 *
  **
   ***

I would really appreciate someone who can help me with my program and explain me the algorithm and how can I make more patterns.

5

There are 5 best solutions below

0
On

Because each character in the font used for input/output/code all have the same width, you have to decrease each iteration by 2, like:

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

or

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

instead of one. For spacing, use the following:

for (int i = userentry; i > 0; i -= 2) {
  for (int j = 0; j < (userentry - i) / 2; j++) System.out.print(" ");
  for (int j = 0; j < i; j++) System.out.print("*");
  for (int j = 0; j < (userentry - i) / 2; j++) System.out.print(" ");
  System.out.println();
}
for (int i = (userentry % 2 == 0 ? 2 : 3); i <= userentry; i += 2) {
  for (int j = 0; j < (userentry - i) / 2; j++) System.out.print(" ");
  for (int j = 0; j < i; j++) System.out.print("*");
  for (int j = 0; j < (userentry - i) / 2; j++) System.out.print(" ");
  System.out.println();
}
0
On

Imagine a coordinate plane in a range [-n, n] both vertically and horizontally. You can use two nested for loops and one if else statement to print it out:

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

Coordinate plane:

---*---
---*---
---*---
*******
---*---
---*---
---*---

To print the hourglass you only need to change the if else statement:

int n = 3;
for (int i = -n; i <= n; i++) {
    for (int j = -n; j <= n; j++)
        if (Math.abs(i) < Math.abs(j))
            System.out.print(" ");
        else
            System.out.print("*");
    System.out.println();
}

Hourglass:

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

See also: How to print ASCII patterns in C# but using Java syntax?

0
On

You can try the below code

class HelloWorld {
  static void pattern(int rows_no) {
    int i, j, k;
    for (i = 1; i <= rows_no; i++) {
      for (k = 1; k < i; k++)
        System.out.print(" ");
      for (j = i; j <= rows_no; j++)
        System.out.print("*" + " ");

      System.out.println();
    }
    for (i = rows_no - 1; i >= 1; i--) {
      for (k = 1; k < i; k++)
        System.out.print(" ");
      for (j = i; j <= rows_no; j++)
        System.out.print("*" + " ");
      System.out.println();
    }
  }

  public static void main(String[] args) {
    int rows_no = 3;
    pattern(rows_no);
  }
}

Which gives the output as:

* * * 
 * * 
  * 
 * * 
* * * 
0
On

If you want to print an hourglass, you have to print two triangles, one erect and the other inverted (note that the tips of both triangles is common asterisk).

This may be done using the code given below...

class HourGlass {
    public static void main(String args[]) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter a number: ");
        int userentry = input.nextInt();
        for (int i = 0; i < userentry; i++) {
            for (int k = 0; k < i; k++) {
                System.out.print(" ");
            }
            for (int j = userentry - 1; j >= i; j--) {
                System.out.print("*");
            }
            for (int k = userentry - i; k > 1; k--) {
                System.out.print("*");
            }
            System.out.println();
        }
        for (int i = 1; i < userentry; i++) {
            for (int k = 0; k < userentry - i - 1; k++) {
                System.out.print(" ");
            }
            for (int j = 0; j <= i; j++) {
                System.out.print("*");
            }
            for (int k = 0; k < i; k++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

This prints on entering 3...

*****
 ***
  *
 ***
*****
0
On

You can visualize a hourglass as a matrix of numbers in a range [-n, n] inclusive, where each point is:

m[i][j] = Math.abs(i) - Math.abs(j);

If n = 3, then this matrix looks like this:

  0  1  2  3  2  1  0
 -1  0  1  2  1  0 -1
 -2 -1  0  1  0 -1 -2
 -3 -2 -1  0 -1 -2 -3
 -2 -1  0  1  0 -1 -2
 -1  0  1  2  1  0 -1
  0  1  2  3  2  1  0

Try it online!

int n = 3;
IntStream.rangeClosed(-n, n)
        .map(Math::abs)
        .peek(i -> IntStream.rangeClosed(-n, n)
                .map(Math::abs)
                .mapToObj(j -> i < j ? "  " : "* ")
                .forEach(System.out::print))
        .forEach(i -> System.out.println());

Output:

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

See also: How to draw a staircase with Java?