Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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 , so be creative.

share|improve this question
    
Sorry for not remembering to ask this when it was in the sandbox, but is ASCII-art ok? –  Victor Mar 2 at 2:08
    
@Victor Of course. (as long as you orient vertically) –  Quincunx Mar 2 at 2:08
1  
What is etc? That rule needs clarification. What about getInternetBellCurve+0? What does "hard-coding" imply? This rule is currently highly opinion based. –  Doorknob 冰 Mar 2 at 2:22
2  
@Doorknob The "etc" means "any other cheating method to avoid actually generating the curve by getting it already done from somewhere else". –  Victor Mar 2 at 3:06
1  

15 Answers 15

up vote 11 down vote accepted

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<Thread> threads = new Stack();

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

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

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

        for (int x = 0; x < Dust.data.length; x++) {
            for (int y = 0; y < output.getHeight(); y++) {
                output.setRGB(x, y, (y >= output.getHeight() - (Dust.data[x] * output.getHeight() / maxy)) ? 6591981 : 16777215);
            }
        }
        try {
            ImageIO.write(output, "png", new File("Filepath"));
        } 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 < LOOP_LIMIT; i++) {
                d = new Dust(r);
                while (!d.end) {
                    d.step();
                }
                if ((i & 1024) == 0) {
                    r = new Random();
                }
            }
        }

    }

    private static class Dust {

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

        static {
            for (int i = 0; i < 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] >= 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):

enter image description here

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.

share|improve this answer
1  
+1 for real world simulation. –  Milo Mar 2 at 8:12

Haskell, 9 LoC

Everyone's code is so ... huge, and their approximations are ... less than deterministic. Just to remind everyone of the simplicity of the actual task, here's a nine-liner in Haskell:

import Data.List; import Data.Ratio
main = do
  putStrLn "please choose the width and the maximum height:"
  [w, mh] <- (map read.words) `fmap` getLine
  let dist = map length $ group $ sort $ map length $ subsequences [2..w]
      scale = ceiling $ maximum dist % mh
      maxD = scale * ceiling (maximum dist % scale) 
  putStrLn $ unlines $ map (row dist) [maxD, maxD - scale .. 0]
      where row dist y = map (\x -> if x >= y then '*' else ' ') dist

OK... that wasn't exactly fast. Here's another go. Does it still count as not hard-coded?

import Data.List; import Data.Ratio

main = do
  putStrLn "please choose the width and the maximum height:"
  [w, mh] <- (map read.words) `fmap` getLine
  let dist = map ((w-1) `choose`) [0..(w-1)]
      scale = ceiling $ maximum dist % mh
      maxD = scale * ceiling (maximum dist % scale) 
  putStrLn $ unlines $ map (row dist) [maxD, maxD - scale .. 0]
      where row dist y = map (\x -> if x >= y then '*' else ' ') dist

factorial x = product [1..x]
n `choose` k = factorial n `div` factorial k `div` factorial (n-k)

bell curve

share|improve this answer
2  
You mean, "Them Java users' code is so huge." The other people's codes are rather small. Also, is there anything wrong with long code? I personally enjoy popularity-contests because I am free to make my code as long as I want to. –  Quincunx Mar 2 at 8:39
    
@Quincunx Hmm... true. But I'm still shorter than the non-Java solutions :-) as for whether long code or short code should be preferred in this challenge, that's up to voters. I offer consciseness. –  Jan Dvorak Mar 2 at 8:45
    
Yours is huge compared to mine. :P –  Tim Seguine Mar 6 at 22:26

Ruby

Simulates the classic example of bell curves, dropping a ball down a grid full of pole thingies.

a = [0]*30
1000.times do
  x = 15
  49.times do
    x += (rand(3) - 1)
  end
  a[[[x.to_i, 29].min, 0].max] += 1
end
until a.all?{|x| x == 0}
  a.each_with_index{|x,i|
    if x == 0
      print ' '
    else
      print 'x'
      a[i] -= 1
    end
  }
  puts
end

Sample output:

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxxxxxxxxxxxxx
  x xxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxxx
     xxxxxxxxxxxxxxxxxxx
      xxxxxxxxxxxxxxxxxx
      xxxxxxxxxxxxxxxxxx
      xxxxxxxxxxxxxxxxxx
      xxxxxxxxxxxxxxxxxx
       xxxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxx
        xxxxxxxxxxxxxx
        xxxxxxxxxxxxxx
         xxxxxxxxxxxxx
         xxxxxxxxxxxxx
         xxxxxxxxxxxxx
         xxxxxxxxxxxxx
         xxxxxxxxxxxxx
         xxxxxxxxxxxxx
         xxxxxxxxxxxx
          xxxxxxxxxxx
          xxxxxxxxxxx
          xxxxxxxxxxx
          xxxxxxxxxxx
           xxxxxxxxxx
           xxxxxxxxxx
           xxxxxxxxxx
           xxxxxxx xx
           xxxxxxx xx
           xxxxxxx xx
            xxxxxx xx
            xxxxxx xx
            xxxxxx x
            xxxxx  x
            xxxxx  x
              xxx  x
              xxx  x
              xxx  x
              xxx  x
              xxx  x
              xxx
              xxx
              xxx
              xxx
              xxx
              xxx
              xxx
              xxx
              xxx
              x x
              x x
              x x
              x x
              x
              x
              x

Oh, did I forget to mention it's upside down?

share|improve this answer
2  
+1 for hiding the most abnormal part of the curve below the fold. Genius! :) –  Jonathan Van Matre Mar 3 at 15:39

Mathematica

I decided it should not only look like a bell curve, it should look like a bell. So hey, let's spin it around the Z-axis and make it 3D.

And hey, while we're at it, it should sound like a bell as well.

So, each time you evaluate the code, it makes a nice pleasing church-bell BWONNGGG!

Manipulate[
 RevolutionPlot3D[PDF[NormalDistribution[mu, sigma], x], {x, -4, 4}, 
  PlotRange -> {Automatic, Automatic, Automatic}, 
  BoxRatios -> {1, 1, 1}, PlotStyle -> {Orange, Yellow}, 
  ImageSize -> {500, 500}], {{mu, 0, "mean"}, -3, 3, 
  Appearance -> "Labeled"}, {{sigma, 1.47, "standard deviation"}, .5, 
  2, Appearance -> "Labeled"}]
EmitSound[Sound[SoundNote[0, 3, "TubularBells", SoundVolume -> 1]]]

Here's what it looks like: Yo quiero Mathematica Bell!

And here's a brief video of the bell ringing.

share|improve this answer

Python

from pygame import*
t,u=640,400;init();d=display;s=d.set_mode((t,u))
s.fill(0xFFFFFF)
for x in range(t):
  d.flip();event.get()
  draw.line(s,u,(x,int(u-2**(-((x-t*.5)/120)**2)*u)),(x,u))

while time.wait(50):
 for e in event.get():
  if e.type==QUIT:exit()

This is actually a normal distribution, using 2 as the base of the exponent instead of e, and not dividing by ⎷2π, because without axes, it doesn't really matter if the area under the curve isn't exactly 1.

The last 3 lines just keep the window open until the user closes it manually.

share|improve this answer

Mathematica

Generating the sums of 5 random integers, each between 0 and 100, 20000 times.

Histogram[Plus @@@ RandomInteger[100, {20000, 5}]]

table


Here's the result for sums of 1,2, 3 numbers. As the number of integers to be summed increases, the curve approaches the bell shape.

When single random integers are generated, but not summed, the distribution should be fairly uniform, not favoring any value. The apparent anomaly for 100 may be the result of how Matheamtica bins data. (see http://mathematica.stackexchange.com/questions/43300/does-randominteger0-n-disfavor-n/43302#43302 )

Table[Histogram[Plus @@@ RandomInteger[100, {20000, k}]], {k, 1, 3}]

enter image description here

share|improve this answer

C#, WPF

Rough approximation with a hand-crafted Bézier curve. To make it more interesting: No use of Line, Path or similar, only Ellipse.

Bézier curve

public MainWindow()
{
    InitializeComponent();
    // Requires a Canvas named Canvas in XAML file
    DrawBellCurve(Canvas, 300, 300);
}

public static void DrawBellCurve(Canvas canvas, int width, int height)
{
    Point p1 = new Point(0, height);
    Point p2 = new Point(0.3 * width, 1 * height);
    Point p3 = new Point(0.4 * width, 0.1 * height);
    Point peak = new Point(width / 2, 0);
    Point p3r = new Point(width - p3.X, p3.Y);
    Point p2r = new Point(width - p2.X, p2.Y);
    Point p1r = new Point(width, height);
    List<Point> controlPoints = new List<Point> { p1, p2, p3, peak, p3r, p2r, p1r };

    DrawBezierCurve(canvas, controlPoints, Color.FromRgb(50, 200, 25));
    DrawPoints(canvas, controlPoints, 5, Color.FromRgb(80, 80, 220));
}

public static void DrawPoints(Canvas canvas, List<Point> points, double radius, Color color)
{
    foreach (var p in points)
    {
        Ellipse ellipse = new Ellipse();
        ellipse.Width = radius;
        ellipse.Height = radius;
        ellipse.SetValue(Canvas.LeftProperty, p.X - radius / 2);
        ellipse.SetValue(Canvas.TopProperty, p.Y - radius / 2);
        ellipse.Fill = new SolidColorBrush(color);
        canvas.Children.Add(ellipse);
    }
}

public static void DrawBezierCurve(Canvas canvas, List<Point> controlPoints, Color color)
{
    var curvePoints = new List<Point>();
    double tStep = 0.01;
    for (double t = 0; t <= 1; t += tStep)
    {
        curvePoints.Add(GetBezierPoint(controlPoints, t));
    }

    DrawPoints(canvas, curvePoints, 3, color);
}

public static Point GetBezierPoint(List<Point> controlPoints, double t)
{
    // De Casteljau's algorithm
    if (controlPoints.Count == 1)
    {
        return controlPoints[0];
    }

    var newControlPoints = new List<Point>();
    for (int i = 0; i < controlPoints.Count - 1; i++)
    {
        Point p1 = controlPoints[i];
        Point p2 = controlPoints[i + 1];
        Point p = new Point(
            t * p1.X + (1 - t) * p2.X,
            t * p1.Y + (1 - t) * p2.Y);
        newControlPoints.Add(p);
    }
    return GetBezierPoint(newControlPoints, t);
}
share|improve this answer

Java 8

It gets the height and the width from the user, chooses width random booleans and count how many are true, registering the counted frequency. Repeat this until some of the generated frequencies is enough to fill the height:

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class Bell {
    public static int[] bell(int width, int height) {
        // I could have used Random.nextGaussian() method, but this way is more fun.
        Random r = new Random();
        int max = 0;
        int[] freqs = new int[width];
        for (int j = 0; max < height - 1; j++) {
            int count = 0;
            for (int i = 0; i < width; i++) {
                if (r.nextBoolean()) count++;
            }
            freqs[count]++;
            if (freqs[count] > max) max++;
        }
        return freqs;
    }

    public static BufferedImage drawBell(int[] ps, int width, int height) {
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < ps[i]; j++) {
                bi.setRGB(i, height - j - 1, 0xFF00FFFF); // Cyan
            }
            for (int m = i - 1; m <= i + 1; m++) {
                if (m < 0 || m >= width) continue;
                for (int n = ps[i] - 1; n <= ps[i] + 1; n++) {
                    if (n < 0 || n >= height) continue;
                    bi.setRGB(m, height - n - 1, 0xFF0000FF); // Blue
                }
            }
            for (int j = ps[i] + 1; j < height; j++) {
                bi.setRGB(i, height - j - 1, 0xFFFFFFFF); // White
            }
        }
        return bi;
    }

    public static void main(String[] args) {
        String a = JOptionPane.showInputDialog("Give the width:");
        String b = JOptionPane.showInputDialog("Give the height:");

        int w, h;
        try {
            w = Integer.parseInt(a);
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null, "Invalid width.");
            return;
        }

        try {
            h = Integer.parseInt(b);
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null, "Invalid height.");
            return;
        }

        int[] freqs = bell(w, h);
        BufferedImage image = drawBell(freqs, w, h);

        EventQueue.invokeLater(() -> {
            JFrame j = new JFrame("Bell curve");
            j.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            j.add(new SimpleSprite(image));
            j.setResizable(false);
            j.pack();
            j.setVisible(true);
        });
    }

    public static class SimpleSprite extends JComponent {
        private final BufferedImage image;
        private final Dimension dim;

        public SimpleSprite(BufferedImage image) {
            this.image = image;
            this.dim = new Dimension(image.getWidth(), image.getHeight());
        }

        @Override
        public Dimension getMinimumSize() {
            return dim;
        }

        @Override
        public Dimension getMaximumSize() {
            return dim;
        }

        @Override
        public Dimension getPreferredSize() {
            return dim;
        }

        @Override
        public void paintComponent(Graphics g) {
            g.drawImage(image, 0, 0, null);
        }
    }
}

Screenshot:

Bell

share|improve this answer

Python and tkinter

I liked Doorknob's generation method and Victor's output (his generation is actually equivalent), so I decided to combine the two with tkinter!

from tkinter import *
import random

bins = [0]*201
for i in range(20000):
    x = 0
    for j in range(100):
        if random.randint(0, 1):
            x += 0.5
        else:
            x -= 0.5
    bins[int(x)+100] += 1

master = Tk()

w = Canvas(master, width = 201, height=200)
w.pack()

for i in range(201):
    w.create_line(i, 200, i, 200-bins[i]/10, fill="light blue")
    w.create_line(i-1, 200-bins[i-1]/10, i, 200-bins[i]/10, fill="blue")

enter image description here

share|improve this answer

GeoGebra

I don't know whether it is valid to use an application that is made to draw graphs, but if you enter this in the input, you get a Bell Curve:

f(x) = 3ℯ^(-(x - 1)²)

Or, if you want a customizable bell curve:

a = 0
b = 0
c = 0
d = 0
f(x) = a ℯ^((-(x - b)²) / 2 c²) + d

Then, make sure that you enable the sliders for the variables (if they are disabled, click on the circle next to the variable names). Then, you can set a value for them by sliding.

Image of the curve with the sliders (click to enlarge):

GeoGebra Bell Curve

share|improve this answer
    
Although the rules didn't technically require posting them, give us the visuals! We'd love to see the result. And is this program specifically designed to give accessibility options for disabled users? That is great! –  Jonathan Van Matre Mar 3 at 15:36
    
@JonathanVanMatre: Done. –  ProgramFOX Mar 3 at 15:42
    
Haha, I see now I made a parsing error when reading your text. Nice graph, though! –  Jonathan Van Matre Mar 3 at 16:30
    
It's a cool program, fun to mess around with. –  Tim Seguine Mar 6 at 22:21

Wolfram Alpha (tongue-in-cheek) 4 bytes:

Here is a practical application of the Central Limit Theorem. I even golfed it!

Type this into the input box on Wolfram Alpha:

3d20

Here is a link to the results. It interprets this input as 3 icosahedral dice, and decides you want a graph of the distribution function of the pip sums. It prints the following graph:

enter image description here

We can make the graph more and more bell shaped by adding more dice. I don't see this as taking my data from the internet since, if I could run the query engine for it on my home computer I would. Unfortunately, Wolfram Research doesn't provide it for download, though.

share|improve this answer
    
You can get a better looking curve with more dice and die-faces: wolframalpha.com/input/?i=10d50 –  Quincunx Mar 6 at 20:33
    
@Quincunx I wanted to keep it to 20 sided dice so that it could actually be done with physical dice that are fair. I think 20d20 looks pretty good though: wolframalpha.com/input/?i=20d20 –  Tim Seguine Mar 6 at 20:37
    
@Quincunx Oh, I didn't know you could hotlink images here... I learn something new all the time –  Tim Seguine Mar 6 at 20:39
    
@Quincunx I rolled back your edit, because the link went dead. –  Tim Seguine Mar 6 at 22:00

Java

Throwing 6 dice in every possible combination approaches a 'normal distribution', which happens to be a bell curve.

public class Temp {
    public static void main(String[] args) throws Exception {
        int[] hist = new int[31];
        for (int d1 = 0; d1 < 6; d1++)
            for (int d2 = 0; d2 < 6; d2++)
                for (int d3 = 0; d3 < 6; d3++)
                    for (int d4 = 0; d4 < 6; d4++)
                        for (int d5 = 0; d5 < 6; d5++)
                            for (int d6 = 0; d6 < 6; d6++)
                                hist[d1 + d2 + d3 + d4 + d5 + d6]++;
        for (int y = 4104; y >= 0; y -= 228)
            for (int x = 0; x < 32; x++)
                System.out.print(x == 31? '\n' : hist[x] <= y? '\u3000' : (char)('\u2580' + Math.min(Math.ceil((hist[x] - y) / 28.5), 8)));
    }
}

Some Unicode tricks make the output smoother:

              ▅█▅              
             ▂███▂             
             █████             
            ▁█████▁            
            ███████            
            ███████            
           ▅███████▅           
           █████████           
           █████████           
          ▇█████████▇          
          ███████████          
         ▃███████████▃         
         █████████████         
        ▁█████████████▁        
        ███████████████        
       ▃███████████████▃       
       █████████████████       
     ▁███████████████████▁     
▁▁▁▂▅█████████████████████▅▂▁▁▁

enter image description here

share|improve this answer

Python (Box-Muller) - 6 lines

This short code uses the Box-Muller transform for simulating a normally distributed variable:

from math import cos, log, pi
from random import random

f = open("normDist.txt",'w')
for i in xrange(10**6):
    f.write(str(cos(2*pi*random())*(-2*log(random()))**.5)+'\n')
f.close()

You can plug the values on GNUPLOT or use this script

f=open("normDist.txt",'r')

v = [0 for i in xrange(51)]
for i in f:
    v[int(float(i)*10) if float(i)<5 and float(i)>-5 else 0]+=1

m=0
for i in v:
    if i>m:
        m=i
for i in v[3:]:
    for j in xrange(int(70.*i/m)):
        print '*',
    print

to produce something like this:

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * *
* * * * * * * * * * * *
* * * * * * * * * *
* * * * * * * *
* * * * * * *
* * * * * *
* * * * *
* * * *
* * *
* * *
* *
* *
* *
* *
* *
* *
* * *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * * *
* * * * * * * * * * * *
* * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
share|improve this answer
3  
Not properly oriented according to the question. Should be rotated 90 degrees. –  Tim Seguine Mar 6 at 22:17

C

Based on random walks

#include <stdio.h>
#include <stdlib.h>

#define X_SIZE 40
#define Y_SIZE 15
#define SMOOTH 100

int main(void)
{
int i,j;
int T[X_SIZE*2];
int w;

for (i=0; i<X_SIZE*2; i++) T[i]=0;

// random walks
do  {
    w=X_SIZE;
    for (i=0;i<X_SIZE;i++)
        w+=rand()%2?1:-1;
    T[w]++;
    }
while (T[w]<Y_SIZE*SMOOTH);

// display
for (j=Y_SIZE; j>=0; j--)
    {
    for (i=0; i<X_SIZE*2; i+=2)
        printf("%c", (T[i]>j*SMOOTH)?'#':' ');
    printf("\n");
    }

}

Output :

               ###
               ###
              #####
              #####
              #####
             #######
             #######
            #########
            #########
            #########
           ###########
           ###########
          #############
         ###############
     #######################
share|improve this answer

awk

#!/ust/bin/awk -f
BEGIN {
  #
  # do WALKS random walks with OOPS times left or right per walk
  #
  WALKS=100000
  OOPS=39
  #
  # output will be H lines
  # the line width will be 2*OOPS+1
  #
  H=23
  #
  # shake awk's pseudorandom generator
  #
  srand()
  #
  # do the walks
  #
  for(i=0;i<WALKS;i++) {
    x=0
    for(j=0;j<OOPS;j++) rand()<0.5?--x:++x
    X[x]++
  }
  #
  # scan for maximum height
  #
  M=0
  for(x=-OOPS;x<=OOPS;x++) {
    if(X[x]>M) M=X[x]
  }
  #
  # "draw" into S[x]: strings of H*X[x]/M "*"s
  #
  for(x=-OOPS;x<=OOPS;x++) {
    s=sprintf("%*s",H*X[x]/M," ")
    gsub(/./,"*",s)
    S[x]=s
  }
  #
  # print S[x] transposed
  #
  for(y=H;y>0;y--) {
    for(x=-OOPS;x<=OOPS;x++) {
      if(c=substr(S[x],y,1)) printf c
      else printf " "
    }
    print ""
  }
}

Output:

                                        *                                      
                                      * *                                      
                                      * *                                      
                                    * * * *                                    
                                    * * * *                                    
                                    * * * *                                    
                                    * * * *                                    
                                  * * * * * *                                  
                                  * * * * * *                                  
                                  * * * * * *                                  
                                  * * * * * *                                  
                                * * * * * * * *                                
                                * * * * * * * *                                
                                * * * * * * * *                                
                                * * * * * * * *                                
                              * * * * * * * * * *                              
                              * * * * * * * * * *                              
                              * * * * * * * * * *                              
                            * * * * * * * * * * *                              
                            * * * * * * * * * * * *                            
                            * * * * * * * * * * * *                            
                          * * * * * * * * * * * * * *                          
*******************************************************************************
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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