Approximate a Bell Curve Create a program to display some approximation of a bell curve. You are free to use whatever method you wish for generating the data, but the data must be displayed vertically, as in oriented like so:



Other restrictions:


Your code must create the approximation, that is, don't hardcode or take data from the internet.
The shape must actually look like a bell.


This is a popularity-contest, so be creative.
Java
The method of generation is based off of the game Sugar, Sugar. In that game, sugar particles fall, traveling randomly left and right. In my program, Dust objects fall until they hit the ground. I collect data based on where they land; this is the bell curve:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.Stack;
import javax.imageio.ImageIO;

/**
 *
 * @author Quincunx
 */
public class ApproxBellCurve {

    public static final int NUM_DUST = 10_000_000;
    public static final int NUM_THREADS = Runtime.getRuntime().availableProcessors() - 1;
    public static final int LOOP_LIMIT = NUM_DUST / (NUM_THREADS + 1);

    public static void main(String[] args) {
        BufferedImage output = new BufferedImage(2049, 2049, BufferedImage.TYPE_INT_RGB);

        Stack&lt;Thread&gt; threads = new Stack();

        for (int i = 0; i &lt; NUM_THREADS; i++) {
            threads.push(new Thread(new Duster()));
            threads.peek().start();
        }

        Dust d;
        Random r = new Random();
        for (int i = 0; i &lt; LOOP_LIMIT + NUM_DUST - (LOOP_LIMIT * (NUM_THREADS + 1)); i++) {
            d = new Dust(r);
            while (!d.end) {
                d.step();
            }
            if ((i &amp; 1024) == 0) {
                r = new Random();
            }
        }
        while (threads.size() &gt; 0) {
            try {
                threads.pop().join();
            } catch (InterruptedException ex) {

            }
        }
        int maxy = 0;
        for (int x = 0; x &lt; Dust.data.length; x++) {
            maxy = Dust.data[x] &gt; maxy ? Dust.data[x] : maxy;
        }

        for (int x = 0; x &lt; Dust.data.length; x++) {
            for (int y = 0; y &lt; output.getHeight(); y++) {
                output.setRGB(x, y, (y &gt;= output.getHeight() - (Dust.data[x] * output.getHeight() / maxy)) ? 6591981 : 16777215);
            }
        }
        try {
            ImageIO.write(output, &quot;png&quot;, new File(&quot;Filepath&quot;));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private static class Duster implements Runnable {

        @Override
        public void run() {
            Dust d;
            Random r = new Random();
            for (int i = 0; i &lt; LOOP_LIMIT; i++) {
                d = new Dust(r);
                while (!d.end) {
                    d.step();
                }
                if ((i &amp; 1024) == 0) {
                    r = new Random();
                }
            }
        }

    }

    private static class Dust {

        public static int[] data = new int[2049];

        static {
            for (int i = 0; i &lt; data.length; i++) {
                data[i] = 0;
            }
        }

        private int[] location;
        private Random r;
        public boolean end;

        public Dust(Random rand) {
            location = new int[]{1024, 0};
            r = rand;
            end = false;
        }

        public void step() {
            if (end) {
                return;
            }
            if (location[1] &gt;= 1024) {
                end = true;
                synchronized (data) {
                    data[location[0]] += 1;
                }
                return;
            }
            location[1] += 1;
            location[0] += r.nextInt(21) - 10;
        }
    }
}

Sample output (took 1 minute to create):

Because of the nature of the random number generation, it is possible to get an ArrayIndexOutOfBoundsException.
I used multithreading to speed up the process. The program determines the number of processors available and creates that many threads to run the simulations.
To obtain a finer image, NUM_DUST can be increased, but that would also lead to an increased risk of an ArrayIndexOutOfBoundsException.
Each thread creates a new Random after every 1024 Dust objects are simulated. When that code was removed, the image was more coarse.
rand.nextInt(21) - 10 is to widen the distribution. A change to rand.nextInt(3) - 1 would remove all chance of an ArrayIndexOutOfBoundsException.