8
\$\begingroup\$

I tried to draw a Sierpinski triangle by shading the even number entries of the Pascal triangle. Could you please suggest improvements?

public class Sierpinski {
    public static void main(String[] args) {
        int no_of_row = 50;
        int[][] tri = new int[no_of_row][no_of_row];

        for (int i = 0; i < no_of_row; i++) {
            for (int j = 0; j <= i; j++) {
                if (j == 0 || j == i) {
                    tri[i][j] = 1;
                }

                if (i > 0 && j > 0 ) {
                    tri[i][j] = tri[i - 1][j - 1] + tri[i - 1][j];
                }
            }
        }

        for (int i = 0; i < no_of_row; i++) {
            printSpace(no_of_row, i);
            for (int j = 0; j <= i; j++) {
                System.out.print(isEven(tri[i][j]));
                System.out.print(" ");
            }
            System.out.println();
        }
    }

    private static void printSpace(int no_of_row, int current_row) {
        for (int i = 0; i < no_of_row - current_row; i++) {
            System.out.print(" ");
        }
    }

    private static String isEven(int n) {
        return n % 2 == 0 ? "x" : " ";
    }
}

Sample output:

                                              x   

                                            x x x   
                                             x x     
                                          x   x   x   

                                        x x x x x x x   
                                         x x x x x x     
                                      x   x x x x x   x   
                                           x x x x         
                                    x x x   x x x   x x x   
                                     x x     x x     x x     
                                  x   x   x   x   x   x   x   

                                x x x x x x x x x x x x x x x   
                                 x x x x x x x x x x x x x x     
                              x   x x x x x x x x x x x x x   x   
                                   x x x x x x x x x x x x         
                            x x x   x x x x x x x x x x x   x x x   
                             x x     x x x x x x x x x x     x x     
                          x   x   x   x x x x x x x x x   x   x   x   
                                       x x x x x x x x                 
                        x x x x x x x   x x x x x x x   x x x x x x x   
                         x x x x x x     x x x x x x     x x x x x x     
                      x   x x x x x   x   x x x x x   x   x x x x x   x   
                           x x x x         x x x x         x x x x         
                    x x x   x x x   x x x   x x x   x x x   x x x   x x x   
                     x x     x x     x x     x x     x x     x x     x x     
                  x   x   x   x   x   x   x   x   x   x   x   x   x   x   x   

                x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x   
                 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x     
              x   x x x x x x x x x x x x x x x x x x x x x x x x x x x x x   x   
                   x x x x x x x x x x x x x x x x x x x x x x x x x x x x         
            x x x   x x x x x x x x x x x x x x x x x x x x x x x x x x x   x x x   
             x x     x x x x x x x x x x x x x x x x x x x x x x x x x x     x x     
          x   x   x   x x x x x x x x x x x x x x x x x x x x x x x x x   x   x   x   
                       x x x x x x x x x x x x x x x x x x x x x x x x                 
        x x x x x x x   x x x x x x x x x x x x x x x x x x x x x x x   x x x x x x x   
         x x x x x x     x x x x x x x x x x x x x x x x x x x x x x     x x x x x x     
      x   x x x x x   x   x x x x x x x x x x x x x x x x x x x x x   x   x x x x x   x   
           x x x x         x x x x x x x x x x x x x x x x x x x x         x x x x         
    x x x   x x x   x x x   x x x x x x x x x x x x x x x x x x x   x x x   x x x   x x x   
     x x     x x     x x     x x x x x x x x x x x x x x x x x x     x x     x x     x x     
  x   x   x   x   x   x   x   x x x x x x x x x x x x x x x x x   x   x   x   x   x   x   x   
                               x x x x x x x x x x x x x x x x                                 
x x x x x x x x x x x x x x x   x x x x x x x x x x x x x x x   x x x x x x x x x x x x x x x   
 x x x x x x x x x x x x x x     x x x x x x x x x x x x x x     x x x x x x x x x x x x x x
\$\endgroup\$
3
\$\begingroup\$

Small rewrite

The code can be divided into two phases. It would be helpful to write a comment on each code block.

The Pascal's triangle loop can be tightened by getting rid of unnecessary conditional logic.

// Generate Pascal's triangle
int[][] tri = new int[SIZE][SIZE];
for (int i = 0; i < SIZE; i++) {
    tri[i][0] = tri[i][i] = 1;
    for (int j = 1; j < i; j++) {
        tri[i][j] = tri[i - 1][j - 1] + tri[i - 1][j];
    }
}

isEven() is poorly named: it looks like it should return true or false, because it follow Java's naming convention for predicates.

As for the printing, calling System.out.print() to output one character at a time is slow and, in my opinion, makes the code more cumbersome. I suggest this loop instead, which marks the places which have even entries, then prints a row at a time.

// Print 'x' where Pascal's Triangle has even entries
char[] buf = new char[2 * SIZE];
for (int i = 0; i < SIZE; i++) {
    Arrays.fill(buf, ' ');
    int leftPad = SIZE - i;
    for (int j = 0; j < i; j++) {
        if ((tri[i][j] & 1) == 0) {
            buf[leftPad + 2 * j] = 'x';
        }
    }
    System.out.println(new String(buf, 0, leftPad + 2 * i));
}

Window dressing

Note that you don't actually need to store the entire Pascal's triangle at once; you can build it a row at a time as you print each line. I suggest making an iterator to take care of that bookkeeping and reduce main() to being just a simple, pretty loop. The Sierpinski object also makes the size and fill character are parameterizable.

import java.util.Arrays;
import java.util.Iterator;

public class Sierpinski implements Iterable<String> {
    private class RowIterator implements Iterator<String> {
        private int row;
        private int[] thisPascalRow = new int[Sierpinski.this.size],
                      nextPascalRow = new int[Sierpinski.this.size];
        private char[] buf = new char[2 * Sierpinski.this.size];

        @Override
        public boolean hasNext() {
            return this.row < Sierpinski.this.size;
        }

        // For compatibility with Java < 8
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

        @Override
        public String next() {
            try {
                // Generate the next row of Pascal's Triangle
                nextPascalRow[0] = nextPascalRow[row] = 1;
                for (int i = 1; i < row; i++) {
                    nextPascalRow[i] = thisPascalRow[i - 1] + thisPascalRow[i];
                }

                // Format it as a line of text in Sierpinski's Triangle
                int leftPad = Sierpinski.this.size - this.row;
                int length = leftPad + 2 * this.row;
                Arrays.fill(this.buf, 0, length, ' ');
                for (int i = 0; i < this.row; i++) {
                    if ((nextPascalRow[i] & 1) == 0) {
                        this.buf[leftPad + 2 * i] = Sierpinski.this.fill;
                    }
                }

                return new String(this.buf, 0, length);
            } finally {
                // Prepare for next call.  Swap to avoid reallocating arrays.
                this.row++;
                int[] swap = this.thisPascalRow;
                this.thisPascalRow = nextPascalRow;
                this.nextPascalRow = swap;
            }
        }
    }

    private final int size;
    private final char fill;

    public Sierpinski(int size, char fill) {
        this.size = size;
        this.fill = fill;
    }

    @Override
    public Iterator<String> iterator() {
        return new RowIterator();
    }

    public static void main(String[] args) {
        for (String line : new Sierpinski(50, 'x')) {
            System.out.println(line);
        }
    }
}
\$\endgroup\$
1
\$\begingroup\$

Making main more high level

main should be very high level. It should look like a description of the task, like:

int[][] pascalTriangle = buildPascalTriangle(50);
printSierspinkyFromPascalTriangle(pascalTriangle);

You may then separate your code currently in main into the two methods, and you'll have code that reads as English!

Constants

50 should be a constant named TRIANGLE_SIZE, using names for important settings also improves readibility.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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