patternjavaMinor
Sierpinski triangle from Pascal triangle
Viewed 0 times
pascaltrianglefromsierpinski
Problem
I tried to draw a Sierpinski triangle by shading the even number entries of the Pascal triangle. Could you please suggest improvements?
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
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 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
Solution
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.
As for the printing, calling
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
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 {
private class RowIterator implements Iterator {
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 iterator() {
return new RowIterator();
}
public static void main(String[] args) {
for (String line : new Sierpinski(50, 'x')) {
System.out.println(line);
}
}
}Code Snippets
// 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];
}
}// 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));
}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);
}
}
}Context
StackExchange Code Review Q#110386, answer score: 3
Revisions (0)
No revisions yet.