Wolfram's Rule 30 is proper interesting, isn't it?
Here is a Java implementation:
Wolfram.java
package org.adrianwalker.cellularautomation;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
public final class Wolfram {
private static final int MAX_TIME = 500;
private static final int MAX_SPACE = MAX_TIME * 2;
private static final int WHITE = Color.WHITE.getRGB();
private static final int BLACK = Color.BLACK.getRGB();
private static final String FORMAT = "png";
private static final String OUTPUT = "/var/tmp/output.png";
// cell to RGB lookup
private static final Map<Integer, Integer> CELL_RGB = new HashMap<>();
static {
CELL_RGB.put(0, WHITE);
CELL_RGB.put(1, BLACK);
}
// RGB to cell lookup
private static final Map<Integer, Integer> RGB_CELL = new HashMap<>();
static {
RGB_CELL.put(WHITE, 0);
RGB_CELL.put(BLACK, 1);
}
// http://en.wikipedia.org/wiki/Rule_30
//
// current pattern 111 110 101 100 011 010 001 000
// new state for center cell 0 0 0 1 1 1 1 0
private static final Map<Integer, Integer> RULE_30 = new HashMap<>();
static {
RULE_30.put(Arrays.hashCode(new int[]{1, 1, 1}), 0);
RULE_30.put(Arrays.hashCode(new int[]{1, 1, 0}), 0);
RULE_30.put(Arrays.hashCode(new int[]{1, 0, 1}), 0);
RULE_30.put(Arrays.hashCode(new int[]{1, 0, 0}), 1);
RULE_30.put(Arrays.hashCode(new int[]{0, 1, 1}), 1);
RULE_30.put(Arrays.hashCode(new int[]{0, 1, 0}), 1);
RULE_30.put(Arrays.hashCode(new int[]{0, 0, 1}), 1);
RULE_30.put(Arrays.hashCode(new int[]{0, 0, 0}), 0);
}
public static void main(final String[] args) throws Throwable {
BufferedImage image = new BufferedImage(MAX_SPACE, MAX_TIME, BufferedImage.TYPE_INT_RGB);
init(image);
execute(image, RULE_30);
ImageIO.write(image, FORMAT, new File(OUTPUT));
}
private static void init(final BufferedImage image) {
int time;
int space;
for (time = 0; time < MAX_TIME; time++) {
for (space = 0; space < MAX_SPACE; space++) {
image.setRGB(space, time, WHITE);
}
}
time = 0;
space = MAX_SPACE / 2;
image.setRGB(space, time, BLACK);
}
private static void execute(final BufferedImage image, final Map<Integer, Integer> rule) {
for (int time = 1; time < MAX_TIME; time++) {
for (int space = 1; space < MAX_SPACE - 1; space++) {
int[] pattern = {
RGB_CELL.get(image.getRGB(space - 1, time - 1)),
RGB_CELL.get(image.getRGB(space, time - 1)),
RGB_CELL.get(image.getRGB(space + 1, time - 1))
};
int cell = rule.get(Arrays.hashCode(pattern));
image.setRGB(space, time, CELL_RGB.get(cell));
}
}
}
}