Marwan N
Marwan N

Reputation: 531

Empty diamond shape with numbers

So I have been asked this question and I could only solve the top part of the code, I am stuck on the bottom part.

Write a Java program called EmptyDiamond.java that contains a method that takes an integer n and prints a empty rhombus on 2n − 1 lines as shown below. Sample output where n = 3:

  1
 2 2
3   3
 2 2
  1

Here's my code so far:

public static void shape(int n) {
    //TOP PART
    for (int i = 1; i <= (n - 1); i++) {
        System.out.print(" ");
    }
    System.out.println(1);
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= (n - i); j++) {
            System.out.print(" ");
        }
        System.out.print(i);
        for (int j = 1; j <= 2 * i - n + 1; j++) {
            System.out.print(" ");
        }
        System.out.println(i);
    }

    //BOTTOM PART (The messed up part)
    for (int i = n + 1; i <= 2 * n - 2; i++) {
        for (int j = 1; j <= n - i; j++) {
            System.out.print(" ");
        }
        System.out.print(i);
        for (int j = 1; j <= n; j++) {
            System.out.print(" ");
        }
        System.out.print(i);
    }
    for (int i = 1; i <= (n - 1); i++) {
        System.out.print(" ");
    }
    System.out.println(1);
}
public static void main(String[] args) {
    shape(4);
}

Upvotes: 5

Views: 1654

Answers (8)

CharlieWhisky
CharlieWhisky

Reputation: 17

I did it for fun, here's the code :

import java.util.Scanner;

public class Diamond {
    public static void main(String[] args) {
        Scanner read = new Scanner(System.in);
        int num = read.nextInt();
        read.nextLine();
        //TOP
        for(int i = 1;i<=num;i++) {
            //LEFT
            for(int k = i; k<num;k++) {
                if ( k % 2 == 0 ) {
                    System.out.print(" ");
                }
            else {
                System.out.print(" ");
            }
        }
        if(i>1) {
            for(int j =1;j<=i;j++) {
                if (j==1 || j== i) {
                    for(int u=0;u<j;u++) {
                        System.out.print(" ");
                    }
                    System.out.print(i);
                    
                }
                else {
                    System.out.print(" ");
                }
            }
            System.out.println("");
        }
        else {
            System.out.println("  "+i);
        }
    }
    //BOTTOM
    for(int i = num-1;i>0;i--) {
        for(int k = i; k<num;k++) {
            if ( k % 2 == 0 ) {
                System.out.print(" ");
            }
            else {
                System.out.print(" ");
            }
        }
        if(i>1) {
            for(int j =1;j<=i;j++) {
                if (j==1 || j== i) {
                    for(int u=0;u<j;u++) {
                        System.out.print(" ");
                    }
                    System.out.print(i);
                }
                else {
                    System.out.print(" ");
                }
            }
            System.out.println("");
        }
        else {
            System.out.println(" "+i);
        }
    }
}
}

And the output :

    7
        1
      2  2
     3    3
    4      4
   5        5
  6          6
 7            7
  6          6
   5        5
    4      4
     3    3
      2  2
       1

Having seen the other answers, there's a whole load of loops I could've skipped. Just decided to wing it at the end and do it as quick as possible.

Upvotes: 0

Peter Walser
Peter Walser

Reputation: 15706

Stream-only function:

public static void printEmptyDiamond(int n) {
   IntStream.range(1, 2*n)
        .map(i-> i > n ? 2*n-i : i)
        .mapToObj(i -> " ".repeat(n-i) + i + (i>1 ? " ".repeat(2*(i-1)-1)+i : ""))
        .forEach(System.out::println);
}

Example output (printEmptyDiamond(7)):

      1
     2 2
    3   3
   4     4
  5       5
 6         6
7           7
 6         6
  5       5
   4     4
    3   3
     2 2
      1

With explainations:

public static void printEmptyDiamond(int n) {
   IntStream.range(1, 2*n)
        .map(i-> i > n? 2*n-i : i) // numbers from 1 to n ascending, then descending to 1 again
        .mapToObj(i -> " ".repeat(n-i) // leading spaces
            + i // leading number
            + (i>1 ? // only when number is > 1
                " ".repeat(2*(i-1)-1) // middle spaces
                 + i // trailing number
            : ""))
        .forEach (System.out::println);
}

Upvotes: 0

TriS
TriS

Reputation: 4038

Solution: Java program called EmptyDiamond.java that contains a method that takes an integer n and prints a empty rhombus on 2n − 1 lines.

public class EmptyDiamond {
    public static void main(String[] args) {
        shape(3); // Change n to increase size of diamond
    }

    public static void shape(int n) {
        int max = 2 * n - 1; // length of the diamond - top to bottom
        int loop = 0; // with of each loop. initialized with 0
        for (int i = 1; i <= max; i++) {
            int val = 0;
            if (i <= n) {
                loop = n + i - 1;// e.g. when i = 2 and n = 3 loop 4 times
                val = i; // value to be printed in each loop ascending
            } else {
                loop = n + (max - i); //e.g. when i = 4 and n = 3 loop 4 times
                val = max - i + 1; // value to be printed in each loop descending
            }
            for (int j = 1; j <= loop; j++) {
                // (value end of loop)
                // || (value in the beginning  when i <= n)
                // || (value in the beginning  when i > n)
                if (j == loop
                        || j == (n - i + 1)
                        || j == (n - val + 1)) {
                    System.out.print(val); // Print values
                } else {
                    System.out.print(" "); // Print space
                }
            }
            System.out.println(); // Print next line
        }
    }
}

Output when n = 3:

  1
 2 2
3   3
 2 2
  1

Upvotes: 0

Sebphil
Sebphil

Reputation: 509

Maybe a little bit late, but because the bottom part of your message is just the first part mirrored you can use a Stack to print the message in reverse order:

public static void main(String[] args) {
    int maxNumber = 3;
    Stack<String> message = new Stack<>();
    // upper part
    for (int row = 0; row < maxNumber; row++) {
        int prefix = maxNumber - (row + 1);
        int spaces = row >= 2 ? row * 2 - 1 : row;

        String line = getLine(row, prefix, spaces);
        System.out.println(line);
        if (row != maxNumber - 1)
            message.add(line);
    }
    // bottom part
    while (!message.isEmpty())
        System.out.println(message.pop());
}

public static String getLine(int row, int prefix, int spaces) {
    StringBuilder line = new StringBuilder("_".repeat(prefix));
    line.append(row + 1);
    if (row != 0) {
        line.append("_".repeat(spaces));
        line.append(row + 1);
    }
    return line.toString();
}

Output:

__1
_2_2
3___3
_2_2
__1

You can of course use any method you want to fill the stack (i.e. to generate the upper part of your message) like with the method this question suggessted. This upper part I describe contains the first line (inclusive) up to the middle line (exclusive).

Upvotes: 5

user16275053
user16275053

Reputation:

Alternative solution:

public static void main(String[] args) {
  int n = 7;
  for (int i = -n; i <= n; i++) {
    for (int j = -n; j <= n; j++) {
      // edge of the diamond
      int edge = Math.abs(i) + Math.abs(j);
      // diamond shape with numbers
      if (edge == n) System.out.print(n - Math.abs(i) + 1);
      // beyond the edge && in chessboard order || vertical borders
      else if (edge > n && (i + j) % 2 != 0 || Math.abs(j) == n)
        System.out.print("*");
      // empty part
      else System.out.print(" ");
    }
    System.out.println();
  }
}

Output:

** * * 1 * * **
* * * 2 2 * * *
** * 3   3 * **
* * 4     4 * *
** 5       5 **
* 6         6 *
*7           7*
8             8
*7           7*
* 6         6 *
** 5       5 **
* * 4     4 * *
** * 3   3 * **
* * * 2 2 * * *
** * * 1 * * **

See also: How to print a given diamond pattern in Java?

Upvotes: 0

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79015

java-11

Using String#repeat introduced as part of Java-11, you can do it using a single loop.

public class Main {
    public static void main(String[] args) {
        int n = 3;
        for (int i = 1 - n; i < n; i++) {
            int x = Math.abs(i);
            System.out.println(" ".repeat(x) + (n - x)
                    + " ".repeat(Math.abs((n - x) * 2 - 3))
                    + ((i == 1 - n || i == n - 1) ? "" : (n - x)));
        }
    }
}

Output:

  1 
 2 2
3   3
 2 2
  1 

You can print a variant of the diamond simply by increasing the amount of space by one character:

public class Main {
    public static void main(String[] args) {
        int n = 3;
        for (int i = 1 - n; i < n; i++) {
            int x = Math.abs(i);
            System.out.println("  ".repeat(x) + (n - x)
                    + "  ".repeat(Math.abs((n - x) * 2 - 3))
                    + ((i == 1 - n || i == n - 1) ? "" : (n - x)));
        }
    }
}

Output:

    1  
  2  2
3      3
  2  2
    1  

Upvotes: 0

user14940971
user14940971

Reputation:

You can print an empty diamond shape with numbers using two nested for loops over rows and columns from -n to n. The diamond shape is obtained when iAbs + jAbs == n:

int n = 2;
for (int i = -n; i <= n; i++) {
    // absolute value of 'i'
    int iAbs = Math.abs(i);
    for (int j = -n; j <= n; j++) {
        // absolute value of 'j'
        int jAbs = Math.abs(j);
        // empty diamond shape
        System.out.print(iAbs + jAbs == n ? jAbs + 1 : " ");
        if (j < n) {
            System.out.print(" ");
        } else {
            System.out.println();
        }
    }
}

Output:

    1    
  2   2  
3       3
  2   2  
    1    

You can separately define width and height:

int m = 4;
int n = 2;
int max = Math.max(m, n);
for (int i = -m; i <= m; i++) {
    // absolute value of 'i'
    int iAbs = Math.abs(i);
    for (int j = -n; j <= n; j++) {
        // absolute value of 'j'
        int jAbs = Math.abs(j);
        // empty diamond shape
        System.out.print(iAbs + jAbs == max ? jAbs + 1 : " ");
        if (j < n) {
            System.out.print(" ");
        } else {
            System.out.println();
        }
    }
}

Output:

    1    
  2   2  
3       3
         
         
         
3       3
  2   2  
    1    

See also:
Filling a 2d array with numbers in a rhombus form
How to print a diamond of random numbers?

Upvotes: 1

Mohit Tyagi
Mohit Tyagi

Reputation: 2876

Here is the program for printing empty diamond:

int n = 3; //change the value of n to increase the size of diamond
int upperCount = 1;
for (int i = n; i >= 1; i--) {
    for (int j = i; j >= 1; j--) {
        System.out.print(" ");
    }
    System.out.print(upperCount);
    for (int j = 0; j <= upperCount - 2; j++) {
        System.out.print(" ");
    }
    for (int j = 0; j <= upperCount - 2; j++) {
        System.out.print(" ");
    }
    if (upperCount != 1) {
        System.out.print(upperCount);
    }
    upperCount++;
    System.out.print("\n");
}

int lowerCount = n - 1;
for (int i = 1; i <= n - 1; i++) {
    for (int j = 0; j <= i; j++) {
        System.out.print(" ");
    }
    System.out.print(lowerCount);
    for (int j = 0; j <= lowerCount - 2; j++) {
        System.out.print(" ");
    }
    for (int j = 0; j <= lowerCount - 2; j++) {
        System.out.print(" ");
    }
    if (lowerCount != 1) {
        System.out.print(lowerCount);
    }
    lowerCount--;
    System.out.print("\n");
}

Do following changes in the Bottom Part of your code:

int lowerCount = n - 1;
for (int i = n - 1; i >= 2; i--) {
    for (int j = 1; j <= (n - i); j++) {
        System.out.print(" ");
    }
    System.out.print(i);

    for (int j = 1; j <= lowerCount; j++) {
        System.out.print(" ");
    }
    System.out.print(i);
    lowerCount -= 2;
}

Upvotes: 2

Related Questions