rss ss
rss ss

Reputation: 65

Printing pyramid pattern out of characters

I need to print an array of characters in a pyramid shape. What I have so far is this:

char[] chars = {'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N','I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O'};
    int length = chars.length;


  for (int i = 1; i < length; i += 2) {
  for (int j = 0; j < 9 - i / 2; j++)
    System.out.print(" ");

  for (int j = 0; j < i; j++)
    System.out.print(chars[j]);

  System.out.print("\n");
}
  for (int i = length; i > 0; i -= 2) {
  for (int j = 0; j < 9 - i / 2; j++)
    System.out.print(" ");

  for (int j = 0; j < i; j++)
    System.out.print(chars[j]);

  System.out.print("\n");

and it prints this:

           F
          FEL
         FELIZ
        FELIZ A
       FELIZ ANI
      FELIZ ANIVE
     FELIZ ANIVERS
    FELIZ ANIVERSAR
   FELIZ ANIVERSARIO
    FELIZ ANIVERSAR
     FELIZ ANIVERS
      FELIZ ANIVE
       FELIZ ANI
        FELIZ A
         FELIZ
          FEL
           F

But I need it to start printing from the character in the middle of the array. The end result gotta be like this:

                       I
                      NIV
                     ANIVE
                    ANIVER
                   Z ANIVERS
                  IZ ANIVERSA
                 LIZ ANIVERSAR
                ELIZ ANIVERSARI
               FELIZ ANIVERSARIO
                ELIZ ANIVERSARI
                 LIZ ANIVERSAR
                  IZ ANIVERSA
                   Z ANIVERS
                    ANIVER
                     ANIVE
                      NIV
                       I

Any help would be greatly appreciated.

Upvotes: 5

Views: 1331

Answers (4)

Coder
Coder

Reputation: 2044

You can do the same thing as show on below code. It will use lesser number of for loops. I have added inline comments in the code go through it.

    char[] chars = { 'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N', 'I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O' };
    int length = chars.length;


    for (int line=0;line<=length;line++) {
        //This will print upper part of pyramid
        if(line < length/2){
            String output="";
            int middelVal=length/2;
            for (int i = middelVal - line; i > 0; i--) {
                output=output+" ";
            }
            for (int i = middelVal - line; i <= middelVal + line; i++) {
                output=output+chars[i];
            }
            System.out.println(output);
        }else if(line > length/2){
            //This will print lower part of pyramid
            String output="";
            int middelVal=length/2;
            int nwNum = chars.length-line;
            for (int i = middelVal - nwNum; i > 0; i--) {
                output=output+" ";
            }
            for (int i = middelVal - nwNum; i <= middelVal + nwNum; i++) {
                output=output+chars[i];
            }
            System.out.println(output);
        }
    }

Upvotes: 5

raymelfrancisco
raymelfrancisco

Reputation: 871

Getting the middle index, storing it in two variables will mark where to start and end the character printing.

int mid = length / 2; // left end
int midLen = mid;     // right end

The loop will start printing spaces until the left end mid, then chars will be printed until the right end midLen + 1. Then increment midLen to go further right, and decrement mid to go further left.

for(int i = mid; mid > -1; mid--, midLen++) {
    for(int s = 0; s < mid; s++)
        System.out.print(" ");

    for (int j = mid; j < midLen + 1; j++) {
        System.out.print(chars[j]);
    }
    System.out.print("\n");
}

To print the lower pyramid, we'll start from 0 index to length. This time, we increment mid to go further right, and decrement midLen to go further left, truncating the string line per line until the middle character.

mid = 0;
midLen = length;

for(int i = mid; midLen != length / 2; mid++, midLen--) {

    for(int s = 0; s < mid; s++)
        System.out.print(" ");

    for(int j = mid; j < midLen; j++) {
        System.out.print(chars[j]);
    }
    System.out.print("\n");
}

Test here

BONUS: Harnessing Java 8's new features. Same mechanism, I'll leave the examining for you.

...
static int mid;
static int midLen;
static String line = "";

public static void main(String[] args) {
    char[] chars = {'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N','I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O'};

    mid = chars.length / 2;
    midLen = mid;

    List<String> tri = new ArrayList<String>();
    IntStream.rangeClosed(0, mid)
        .forEach(i -> {
            Stream.of(chars).forEach( j -> {
                IntStream.range(0, mid).forEach(x -> line += " ");
                IntStream.rangeClosed(mid, midLen)
                    .forEach(x -> line += String.valueOf(chars[x]));
                mid--;
                midLen++;
                tri.add(line);
                line = "";
            });
         });

    tri.forEach(System.out::println); // print upper pyramid
    Collections.reverse(tri);
    tri.forEach(System.out::println); // print lower pyramid
}
...

Upvotes: 3

mitim
mitim

Reputation: 3201

This is off the top of my head, but one method I'd try would be like this:

Find the index of my middle character in the array. Call this 'startIndex'

For every line, I would find the length, divide by 2 (round down) and this would be the starting offset from startIndex that determines what my first character would be.

Let's say I'm on line 5, which you have as "Z ANIVERS". That has a length of 9. Divide by 2 (and round down), you get 4.

In your chars array, the startIndex is calculated to be 8 (17 / 2, round down). Thus I should start printing from char 4 (which is startIndex - 4) in my char array up to however many characters needed.

You can also easily print the whole line without counting characters in a loop, since if you know the line length needed and the starting char index, you could just substring that line out in one go if you had your initial characters as one string.

Finally, you can also only do half the work since it looks like your top half is the same as the bottom half (build the result in strings then concatenate them together to print out the full result)

edit: Reading my answer over, you wouldn't need to actually 'find' the line length as it just starts from 1 and increases by 2 every time, but the original method would still be the same.

edit 2:

Since everyone is adding their coded version (and the answer has been accepted), I might as well add mine following what I said:

    String sourceString = "FELIZ ANIVERSARIO"; // source of characters
    String padding = "        "; // used to create the padding offset for each line

    int middle = sourceString.length() / 2;

    // top and bottom halves of the output
    String top = "";
    String bottom = "";

    for(int currentLength = 1; currentLength < sourceString.length(); currentLength += 2){
        String linePadding = padding.substring(currentLength / 2, padding.length());

        // speical case here, in the given example by the post, the 4th line the offset is one less as the I characters do not line up in the middle
        // 7 is used as the 4th line has a length of 7
        if(currentLength == 7){
            linePadding = linePadding.substring(1, linePadding.length());
        }

        top += linePadding + sourceString.substring(middle - (currentLength / 2), middle + (currentLength / 2) + 1) +"\n";
        bottom = linePadding + sourceString.substring(middle - (currentLength / 2), middle + (currentLength / 2) + 1) + "\n" + bottom;
    }

    System.out.println(top + sourceString +"\n"+ bottom);

Not sure if this was intentional, but I added a special expectation in the loop where I noticed in the user's example the 4th line is off by 1 (the I's don't line up there). If the I's are supposed to line up and it was a typo, can remove that if block entirely.

Upvotes: 2

Saravana
Saravana

Reputation: 12817

Here is another approach using 2d array

    char[] chars = { 'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N', 'I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O' };
    int size = chars.length;
    int mid = size / 2 + 1;
    char[][] matrix = new char[size][size];
    for (char[] cs : matrix) {
        Arrays.fill(cs, ' ');
    }
    for (int i = 0; i < size; i++) {
        int l = Math.abs(mid - 1 - i);
        int r = size - l;
        for (int m = l; m < r; m++) {
            matrix[i][m] = chars[m];
        }
    }
    for (char[] cs : matrix) {
        System.out.println(cs);
    }

output

        I        
       NIV       
      ANIVE      
      ANIVER     
    Z ANIVERS    
   IZ ANIVERSA   
  LIZ ANIVERSAR  
 ELIZ ANIVERSARI 
FELIZ ANIVERSARIO
 ELIZ ANIVERSARI 
  LIZ ANIVERSAR  
   IZ ANIVERSA   
    Z ANIVERS    
      ANIVER     
      ANIVE      
       NIV       
        I        

Upvotes: 3

Related Questions