public class Cellular {
    
    public static final int RULE = 0;
    public static final int X = 1;
    public static final int Y = 2;
    public static final int RANDOM = 3;
    
    public static int[] readData() {
	int[] data = new int[4];
	data[RULE] = StdIn.readInt();
	data[X] = StdIn.readInt();
	data[Y] = StdIn.readInt();
	data[RANDOM] = StdIn.readInt();
	return data;
    }

    public static int[] initializeCurrent(int r, int x) {
	int[] current = new int[x];
	if (r == 1) {   // make random current
	    for (int i = 0; i < x; i++) {
		if (Math.random() < 0.5) {
		    current[i] = 1;
		}
	    }
	} else {  // put dot in middle
	    current[x/2] = 1;
	}
	return current;
    }
    
    public static void drawCells(int[] current, int y) {
	for (int x = 0; x < current.length; x++) {
	    if (current[x] == 1) {
		StdDraw.filledSquare(x, y, 0.5);
	    } else {
		StdDraw.square(x, y, 0.5);
	    }
	}
    }

    public static int[] nextLine(int[] current, int rule) {
	int[] next = new int[current.length];

	for (int i = 0; i < current.length; i++) {
	    int which = current[(i + current.length - 1) % current.length] * 4 +
		current[i] * 2 + 
		current[(i + 1) % current.length];
	    
	    int bit = 0;
	    int j = -1;
	    int rulecopy = rule;
	    while (j < which) {
		bit = rulecopy % 2;
		rulecopy /= 2;
		j++;
	    }
	    next[i] = bit;
	}

	return next;
    }

    public static void main(String[] args) {
	
	// Get Data from the user (rule, x, y, random?)
	int[] data = readData();
	
	// Set up StdDraw
	StdDraw.setXscale(0, Math.max(data[X], data[Y]));
	StdDraw.setYscale(Math.max(data[X], data[Y]), 0);

	// set up initial row based on random?
	int[] current = initializeCurrent(data[RANDOM], data[X]);

	// loop to make the rest (as long as y)
	for (int i = 0; i < data[Y]; i++) {

	    //    print off the current row (based on x)
	    drawCells(current, i);

	    //    find the next row
	    current = nextLine(current, data[RULE]);
	}
    }
    
}

