text:
Animated drawing of a Bézier curve
Your job is to draw a Bézier curve given it's control points. The only criteria is that you actually have to show how to draw the curve from the initial control point to the last one.
Criterias

The result has to be animated, e.g. it has to show the drawing process somehow. The way you do the animation is irrelevant, it can generate a .gif, it can draw to a window, or generate ASCII results (and possibly clearing the screen after each draw), etc.
It has to support at least 64 control points.
This is a popularity contest, so you might want to add some additional features to your program to get more upvotes. (My answer for example draws the control points, and some visual aid on how to generate the image as well)
The winner is the most upvoted valid answer 7 days after the last valid submission.
My submission doesn't count as valid.

How to draw a Bézier curve
Assume we want to draw 100 iterations. To get the nth point of the curve you can use the following algorithm:
1. Take each adjanced control point, and draw a line between them
2. Divide this line by the number of iterations, and get the nth point based on this division.
3. Put the points you've got into a separate list. Let's call them "secondary" control points.
4. Repeat the whole process, but use these new "secondary" control points. As these points have one less points at each iteration eventually only one point will remain, and you can end the loop.
5. This will be nth point of the Bézier curve

This might be a bit hard to understand when written down, so here are some images to help visualize it:
For two control points (shown in black dots) you only have one line initally (the black line). Dividing this line by the number of iterations and getting the nth point will result in the next point of the curve (shown in red):

For three control points, you first have to divide the line between the first and the second control point, then divide the line between the second and third control point. You will get the points marked with blue dots.
Then, as you still have two points, you have to draw a line between these two points (blue in the image), and divide them again to get the next point for the curve:

As you add more control points the algorithm stays the same, but there will be more and more iterations to do. Here is how it would look like with four points:

And five points:

You can also check my solution, which was used to generate these images, or read more about generating Bézier curves at Wikipedia

"It has to support at least 64 control points."  Isn't this excessive?  I would think that 6 control points would be enough.

@DavidCarraher: the algorithm isn't that hard to implement, and it runs in O(n^2) time and space (where n is the number of control points), so 64 shouldn't be that excessive (and the results can be really cool with lots of control points). Of course if there is an actual technical limitation with a chosen language that makes it impossible / very impractical to solve this with more than a few degrees, then I'm happy to decrease it.

A nice variation, instead of going backwards or endlessly repeating. At the end drop the first point and choose another random point. Keep extending the line.

Done recursively in Mathematica with no hard limits on the number control points in just three lines:
ctrlPts = {{0, 0}, {1, 1}, {2, 0}, {1, -1}, {0, 0}};
getLines[x_List] := Partition[x, 2, 1];
partLine[{a_, b_}, t_] := t a + (1 - t) b;
f[pts_, t_] := NestList[partLine[#, t] & /@ getLines@# &, pts, Length@pts- 1]

Showing it is more involved than the calculations!:
color[x_] := ColorData[5, "ColorList"][[x[[1]]]]
Animate[Graphics[{PointSize[.03], ,
        MapIndexed[{color@#2, Point/@ #1,Line@#1} &, f[ctrlPts,t]],
        Red, Point@Last@f[ctrlPts, t],
        Line@Flatten[(Last@f[ctrlPts, #]) & /@ Range[0, t, 1/50], 1]}], {t, 0, 1}]

Code dissection (kind of) for the calc part:
getLines[x_List] := Partition[x, 2, 1]; (* Takes a list of points { pt1, pt2, pt...}
                                           as input and returns {{pt1,pt2}, {pt2,pt3} ...}
                                           which are the endpoints for the successive
                                           lines between the input points *)

partLine[{a_, b_}, t_] := t a + (1 - t) b;(* Takes two points and a "time" as input
                                             and calculates
                                             a linear interpolation between them*)

f[pts_, t_] := NestList[partLine[#, t] & /@ getLines@# &, pts, Length@pts- 1]
                                          (* This is where the meat is :)
     Takes a list of n points and a "time" as input.
     Operates recursively on the previous result n-1 times, preserving all the results
     Each time it does the following with the list {pt1, pt2, pt3 ...} received:
           1) Generates a list {{pt1, pt2}, {pt2, pt3}, {pt3, pt4} ...}
           2) For each of those sublists calculate the linear interpolation at time "t",
              thus effectively reducing the number of input points by 1 in each round.
     So the end result is a list of lists resembling:
     {{pt1, pt2, pt3 ...}, {t*pt1+(1-t)*pt2, t*pt2+(1-t)*pt3,..}, {t*pt12+(1-t)*pt23, ..},..}
                             --------------   ---------------
                                  pt12              pt23
     And all those are the points you see in the following image:

With a few more lines you can drag the control points interactively while the animation is running:
Manipulate[
 Animate[Graphics[{
    PointSize[.03], Point@pts,
    MapIndexed[{color@#2, Point /@ #1, Line@#1} &, f[pts, t]],
    Red, Point@Last@f[pts, t], Line@Flatten[(Last@f[pts, #]) & /@ Range[0, t, 1/50], 1]},
   PlotRange -> {{0, 2}, {-1, 1}}], {t, 0, 1}],
  {{pts, ctrlPts}, Locator}]

Here dragging the green point:

BTW, the same code runs in 3D without modifications (For the Mathematica geeks you only have to replace Graphics[] by Graphics3D[] and add a third coordinate to the control points list):

NB:
Of course this kludge isn't needed in Mathematica as there are several primitives for drawing Beziers:
Graphics[{BSplineCurve[ctrlPts], Green, Line[ctrlPts], Red,  Point[ctrlPts]}]

it's nice to see a mathematica solution that doesn't heavily rely on its huge library

Instructions for testing this answer without Mathematica installed: 1) Download http://pastebin.com/qU9rztdf and save it as *.CDF 2) Dowload the free CDF environment from Wolfram Research at https://www.wolfram.com/cdf-player/ (not a small file) 3) "Alt + Left-Click" on Windows or "CMD + Left-Click" on Mac for creating/deleting control points 4) Control points can also be dragged!

Python
Certainly not the most efficient or beautiful code but it was fun to write. Run as
$> python thisscript.py

The control points are randomly generated for now but it is trivial to extend it to allow for stdin or file input.

Shows the control points
Shows the iterations
Different color for each iteration

As a bonus there is an endless mode that is guaranteed to provide for entertainment for hours if not days!
Matplotlib is required and ImageMagick if you want to save the resulting GIF. Tested up to 64 control points (runs very slow with a large number of points!)

import matplotlib
matplotlib.use('GTkAgg')
import pylab as pl
from math import sin,cos,pi
from random import random
import os
import time

class Point:
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def __repr__(self):
        return "[{:.3f},{:.3f}]".format(self.x,self.y)
    def __str__(self):
        return self.__repr__()

class Path:
    def __init__(self,points):
        self.points=points
    def interpolate(self,u): # interpolate the path, resulting in another path with one point less in length
        pts = [None]*(len(self.points)-1)
        for i in range(1,len(self.points)):
            x = self.points[i-1].x + u*( self.points[i].x - self.points[i-1].x)
            if (self.points[i-1].x == self.points[i].x): # vertical line
                y = self.points[i-1].y + u*( self.points[i].y - self.points[i-1].y)
            else:
                y = self.points[i-1].y + (self.points[i].y - self.points[i-1].y)/(self.points[i].x - self.points[i-1].x)*( x - self.points[i-1].x)
            pts[i-1] = Point(x,y)
        return Path(pts)

    def interpolate_all(self,u): # interpolate all the paths
        paths = [None]*len(self.points)
        paths[0]=self
        for i in range(1,len(paths)):
            paths[i] = paths[i-1].interpolate(u)
        return paths

    def draw(self,ax,color,*args,**kwargs):
        x = [ p.x for p in self.points]
        y = [ p.y for p in self.points]
        ax.plot(x,y,*args,color=color,**kwargs)
        ax.scatter([p.x for p in self.points], [p.y for p in self.points],color=color)

    def __str__(self):
        return str(self.points)

def bezier(path,ustep,ax,makeGif):
    if makeGif:
        os.system("mkdir -p tempgif")
    u=0.
    x=[] # x coordinate list for the bezier path point
    y=[] # y coordinate list for the bezier path point
    pl.ion()
    pl.show()
    n=0
    while u < 1.+ustep: # and not u <= 1.0 to get rid of rounding errors
        ax.cla()
        paths = path.interpolate_all(u)
        x.append(paths[-1].points[0].x)
        y.append(paths[-1].points[0].y)
        u+=ustep
        for i in range(len(paths)):
            color = pl.cm.jet(1.*i/len(paths)) # <-- change colormap here for other colors, for a list of available maps go to http://wiki.scipy.org/Cookbook/Matplotlib/Show_colormaps
            paths[i].draw(ax,color=color,lw=2) # draw all the paths
        ax.plot(x,y,color='red',lw=5) # draw the bezier curve itself
        pl.draw()
        if makeGif:
            pl.savefig("tempgif/bezier_{:05d}.png".format(n))
            n+=1
    if makeGif:
        print("Creating your GIF, this can take a while...")
        os.system("convert -delay 5 -loop 0 tempgif/*.png "+makeGif)
        os.system("rm -r tempgif/")
        print("Done.")
    pl.ioff()

def getPtsOnCircle(R,n):
    x = [None]*(n+1)
    y = [None]*(n+1)
    for i in range(n+1):
        x[i] = R*cos(i*2.*pi/n)
        y[i] = R*sin(i*2.*pi/n)
    return x,y

def getRndPts(n):
    x = [ random() for i in range(n) ]
    y = [ random() for i in range(n) ]
    return x,y

def run(ax,x,y,makeGif=False):
    ctrlpoints = [ Point(px,py) for px,py in zip(x,y) ]
    path = Path(ctrlpoints)
    bezier(path,0.01,ax,makeGif) # 0.01 is the step size in the interval [0,1]

def endless_mode(ax):
    while True:
        x,y = getRndPts( int(5+random()*10) )
        run(ax,x,y)
        pl.draw()
        time.sleep(0.5) # pause for a moment to gaze upon the finished bezier curve
def main():
    fig = pl.figure(figsize=(6,6)) # <-- adjust here for figure size
    fig.subplots_adjust(0,0,1,1)
    ax = fig.add_subplot(111)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    opt = raw_input("[s]ingle run or [e]ndless mode? ")
    if opt=='s':
        gifname = raw_input("Name of output GIF (leave blank for no GIF): ")
        x,y = getRndPts(15)
        run(ax,x,y,gifname if gifname != "" else False)
        pl.show()
    elif opt=='e':
        endless_mode(ax)
    else:
        print("Invalid input: "+opt)

main()

That was impressive. A note for others: PyGTK is only available for 2.6 and 2.7. And although not stated anywhere, the installed version of GTK+ on your system most visible to your python interpreter must be 2.x.

Postscript
to generate a gif, make sure 'emitpages' is defined as true, and:
gs -sDEVICE=png16 -g500x500 -o bezan%03d.png bezanim.ps
convert bezan*.png bezan.gif

extra features:

configurable bounding box
2 generators: random points, randomly permuted random flattened Bezier
"overlay" animation (where it doesn't erase anything).
optional 'showpage' (use for generating gifs, omit for on-screen preview)

Using ghostscript and larger sets of points, the on-screen preview is very different from the generated images, as you can watch the lines "converge" upon each point.
simple set of points, scaled, using png48:

simple set with overlay:

lots of points, overlay animation:

non-overlay:

code:
%!
/iterations 100 def
%/Xdim 612 def
%/Ydim 792 def
/Xdim 400 def
/Ydim 400 def
/scalepage {
    100 100 translate
    %1 5 scale % "tron"?
    1 3 dup dup scale div currentlinewidth mul setlinewidth
} def scalepage
/gen 2 def  % 0:rand points  1:rand permuted bezier
            % 2:special list
/genN 6 def % number of generated points
/overlay true def
/emitpages false def
/emitpartials false def
/.setlanguagelevel where { pop 2 .setlanguagelevel } if

/pairs { % array-of-points  .  array-of-pairs-of-points
    [ exch 0 1 2 index length 2 sub { % A i
        2 copy 2 getinterval % A i A_[i..i+1]
        3 1 roll pop % A_[i..i+1] A
    } for pop ]
} def

/drawpairs {
    gsave
    dup 1 exch length B length div sub setgray
    {
        aload pop
        aload pop moveto
        aload pop lineto
        stroke
        %flushpage
    } forall
    %flushpage
    %emitpartials { copypage } if
    grestore
} def

/points { % array-of-pairs  .  array-of-points
    [ exch { % pair
        [ exch
        aload pop % p0 p1
        aload pop 3 2 roll aload pop % p1x p1y p0x p0y
        exch % p1x p1y p0y p0x
        4 3 roll % p1y p0y p0x p1x
        exch % p1y p0y p1x p0x
        2 copy sub n mul add exch pop % p1y p0y p0x+n(p1x-p0x)
        3 1 roll % p0x+n(p1x-p0x) p1y p0y
        2 copy sub n mul add exch pop % p0x+n(p1x-p0x) p0y+n(p1y-p0y)
        ]
    } forall ]
} def

/drawpoints {
    gsave
    dup length B length div setgray
    {
        newpath
        aload pop 2 copy moveto currentlinewidth 3 mul 0 360 arc fill
        %flushpage
    } forall
    %flushpage
    emitpartials { copypage } if
    grestore
} def

/anim {
    /B exch def
    /N exch def
    /Bp B pairs def
    Bp drawpairs
    1 0 0 setrgbcolor
    B 0 get aload pop moveto
    0 1 N div 1 { /n exch def
        B
        {
            dup length 1 eq { exit } if
            dup drawpoints
            pairs dup drawpairs
            points
        } loop
        aload pop
        aload pop
        2 copy
        gsave
            newpath
            2 copy moveto currentlinewidth 3 mul 0 360 arc fill
        grestore
        lineto currentpoint stroke 2 copy moveto
        gsave
            count dup 1 add copy
            3 1 roll moveto
            2 idiv 1 sub {
                lineto
            } repeat
            pop
            stroke
        grestore
        emitpages {
            currentpoint
            currentrgbcolor
            overlay { copypage }{ showpage scalepage } ifelse
            setrgbcolor
            moveto
        }{
            flushpage 10000 { 239587 23984 div pop } repeat
            flushpage 4000 { 239587 23984 div pop } repeat
            overlay not {
                erasepage Bp drawpairs
            } if
            %flushpage
        } ifelse
    } for
    moveto N { lineto } repeat stroke
} def

% "main":

iterations
[
    { [ genN { [ rand Xdim mod rand Ydim mod ] } repeat ] }
    {
        40 setflat
        rand Xdim mod rand Ydim mod moveto
        genN 1 sub 3 div ceiling cvi
            { 3 { rand Xdim mod rand Ydim mod } repeat curveto } repeat
        flattenpath
        [{2 array astore}dup{}{}pathforall]
        [exch dup 0 get exch 1 1 index length 1 sub getinterval {
            rand 2 mod 0 eq { exch } if
        } forall]
        0 genN getinterval
    }
    {
        [
            [10 10]
            [100 10]
            [100 100]
            [10 100]
            [10 40]
            [100 40]
            [130 10]
            [50 50]
            [80 50]
            [110 30]
            [20 50]
            [70 50]
            [60 50]
            [10 10]
            [40 50]
            [30 50]
            [10 30]
            [90 50]
            [10 50]
            [120 20]
            [10 20]
        ] 0 genN getinterval
    }
] gen get exec

newpath anim

stroke

The overlay animation looks like a modern art dragon

It is pretty wild! When previewing with ghostscript, the erases were very difficult to watch because of the stroboscopic effect, so I tried removing them. But even with the overlay, the ghostscript preview is still very "flashy". Perhaps not suitable for epileptics. :(

You should add a few images with less control points. It's fairly hard to see what's going on.

Yes. good idea.

Ruby + RMagick
Additional features:

Shows the control points
Shows each iteration
Uses different colours for each iteration

To use send the points from STDIN:
$ echo "300 400 400 300 300 100 100 100 200 400" | ./draw.rb

Result will be inside result.gif:

Here is another run, with 12+1 points:
$ echo "100 100 200 200 300 100 400 200 300 300 400 400 300 500 200 400 100 500 0   400 100 300 0   200 100 100" | ./draw.rb

Code
This is neither golfed, nor too readable, sorry for that.
draw.rb
#!/usr/bin/env ruby
require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)

ITERATIONS = 100

points = ARGF.read.split.map(&:to_i).each_slice(2).to_a
result = []

def draw_line(draw,points)
  points.each_cons(2) do |a,b|
    draw.line(*a, *b)
  end
end

def draw_dots(draw,points,r)
  points.each do |x,y|
    draw.ellipse(x,y,r,r,0,360)
  end
end

canvas = Magick::ImageList.new

0.upto(ITERATIONS) do |i|
  canvas.new_image(512, 512)

  draw = Magick::Draw.new

  draw.stroke('black')
  draw.stroke_width(points.length.to_f/2)
  draw_line(draw,points)
  draw_dots(draw,points,points.length)

  it = points.dup
  while it.length>1
    next_it = []
    it.each_cons(2) do |a,b|
      next_it << [b[0]+(a[0]-b[0]).to_f/ITERATIONS * i, b[1]+(a[1]-b[1]).to_f/ITERATIONS * i]
    end
    draw.stroke("hsl(#{360/points.length.to_f*next_it.length},100,100)")
    draw.fill("hsl(#{360/points.length.to_f*next_it.length},100,100)")
    draw.stroke_width(next_it.length.to_f/2)
    draw_line(draw,next_it)
    draw_dots(draw,next_it,next_it.length)
    it = next_it
  end

  result << it.first

  draw.stroke("hsl(0,100,100)")
  draw.fill("hsl(0,100,100)")
  draw.stroke_width(points.length)
  draw_line(draw,result)
  draw_dots(draw,[it.first],points.length*2)

  draw.draw(canvas)
end

canvas.write('result.gif')

Gemfile
source "https://rubygems.org"
gem 'rmagick', '2.13.2'

Java
Using the adaptive subdivision algorithm of Anti Grain Geometry.
Code is interactive and allows the user to drag the four nodes with the mouse.
public class SplineAnimation extends JPanel implements ActionListener, MouseInputListener {
    int     CANVAS_SIZE             = 512;
    double  m_distance_tolerance    = 1;
    double  m_angle_tolerance       = 1;
    int     curve_recursion_limit   = 1000;

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.setContentPane(new SplineAnimation());

        f.pack();
        f.setResizable(false);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    // Graphics.
    BufferedImage   im      = new BufferedImage(CANVAS_SIZE, CANVAS_SIZE, BufferedImage.TYPE_INT_ARGB);
    Graphics2D      imageG  = im.createGraphics();
    Graphics2D      g       = null;
    Ellipse2D       dot     = new Ellipse2D.Double();
    Line2D          line    = new Line2D.Double();
    Path2D          path    = new Path2D.Double();

    // State.
    Point2D[]       pts     = {new Point2D.Double(10, 10), new Point2D.Double(CANVAS_SIZE / 8, CANVAS_SIZE - 10), new Point2D.Double(CANVAS_SIZE - 10, CANVAS_SIZE - 10), new Point2D.Double(CANVAS_SIZE / 2, 10)};
    double          phase   = 0;
    private int     dragPt;
    private double  f;
    private int     n       = 0;

    public SplineAnimation() {
        super(null);
        setPreferredSize(new Dimension(CANVAS_SIZE, CANVAS_SIZE));
        setOpaque(false);

        // Prepare stuff.
        imageG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        imageG.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        imageG.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        imageG.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        imageG.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        imageG.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        imageG.translate(0.5, 0.5);
        addMouseListener(this);
        addMouseMotionListener(this);

        // Animate!
        new javax.swing.Timer(16, this).start();
    }

    @Override
    public void paintComponent(Graphics g) {
        this.g = (Graphics2D)getGraphics();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // Drawable yet?
        if (g == null)
            return;

        // Clear.
        imageG.setColor(Color.WHITE);
        imageG.fillRect(0, 0, CANVAS_SIZE + 1, CANVAS_SIZE + 1);

        // Update state.
        f = 0.5 - 0.495 * Math.cos(phase += Math.PI / 100);

        // Render.
        path.reset();
        path.moveTo(pts[0].getX(), pts[0].getY());
        recursive_bezier(0, pts[0].getX(), pts[0].getY(), pts[1].getX(), pts[1].getY(), pts[2].getX(), pts[2].getY(), pts[3].getX(), pts[3].getY());
        path.lineTo(pts[3].getX(), pts[3].getY());

        imageG.setPaint(Color.BLACK);
        imageG.draw(path);
        g.drawImage(im, 0, 0, null);

//      if (phase > Math.PI)
//          System.exit(0);
//      save("Bezier" + n++ + ".png");
    }

    private void save(String filename) {
        paint(im.getGraphics());
        try {
            ImageIO.write(im, "PNG", new File(filename));
        }
        catch (IOException e) {}
    }

    // Modified algorithm from Anti Grain Geometry.
    // http://www.antigrain.com/research/adaptive_bezier/index.html
    private void recursive_bezier(int level, double x1, double y1, double x2, double y2, double x3, double y3, double x4,
            double y4) {
        if (level > curve_recursion_limit)
            return;

        // Calculate all the mid-points of the line segments
        // ----------------------
        double x12 = x1 + (x2 - x1) * f;
        double y12 = y1 + (y2 - y1) * f;
        double x23 = x2 + (x3 - x2) * f;
        double y23 = y2 + (y3 - y2) * f;
        double x34 = x3 + (x4 - x3) * f;
        double y34 = y3 + (y4 - y3) * f;
        double x123 = x12 + (x23 - x12) * f;
        double y123 = y12 + (y23 - y12) * f;
        double x234 = x23 + (x34 - x23) * f;
        double y234 = y23 + (y34 - y23) * f;
        double x1234 = x123 + (x234 - x123) * f;
        double y1234 = y123 + (y234 - y123) * f;

        if (level > 0) // Enforce subdivision first time
        {
            // Try to approximate the full cubic curve by a single straight line
            // ------------------
            double dx = x4 - x1;
            double dy = y4 - y1;

            double d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx);
            double d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx);

            double da1, da2;

            if ((d2 + d3) * (d2 + d3) <= m_distance_tolerance * (dx * dx + dy * dy)) {
                // If the curvature doesn't exceed the distance_tolerance
                // value we tend to finish subdivisions.
                // ----------------------

                // Angle & Cusp Condition
                // ----------------------
                double a23 = Math.atan2(y3 - y2, x3 - x2);
                da1 = Math.abs(a23 - Math.atan2(y2 - y1, x2 - x1));
                da2 = Math.abs(Math.atan2(y4 - y3, x4 - x3) - a23);
                if (da1 >= Math.PI)
                    da1 = 2 * Math.PI - da1;
                if (da2 >= Math.PI)
                    da2 = 2 * Math.PI - da2;

                if (da1 + da2 < m_angle_tolerance) {
                    // Finally we can stop the recursion
                    // ----------------------
                    path.lineTo(x1234, y1234);
                    return;
                }
            }
        }

        // Continue subdivision
        // ----------------------
        recursive_bezier(level + 1, x1, y1, x12, y12, x123, y123, x1234, y1234);
        recursive_bezier(level + 1, x1234, y1234, x234, y234, x34, y34, x4, y4);

        // Draw the frame.
        float c = 1 - (float)Math.pow(1 - Math.sqrt(Math.min(f, 1 - f)), level * 0.2);
        imageG.setPaint(new Color(1, c, c));
        line.setLine(x1, y1, x2, y2);
        imageG.draw(line);
        line.setLine(x2, y2, x3, y3);
        imageG.draw(line);
        line.setLine(x3, y3, x4, y4);
        imageG.draw(line);
        line.setLine(x12, y12, x23, y23);
        imageG.draw(line);
        line.setLine(x23, y23, x34, y34);
        imageG.draw(line);
        node(level + 1, x1234, y1234, level == 0? Color.BLUE : Color.GRAY);
    }

    private void node(int level, double x, double y, Color color) {
        double r = 20 * Math.pow(0.8, level);
        double r2 = r / 2;
        dot.setFrame(x - r2, y - r2, r, r);
        imageG.setPaint(color);
        imageG.fill(dot);
    }

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {
        Point mouse = e.getPoint();

        // Find the closest point;
        double minDist = Double.MAX_VALUE;
        for (int i = 0; i < pts.length; i++) {
            double dist = mouse.distanceSq(pts[i]);
            if (minDist > dist) {
                minDist = dist;
                dragPt = i;
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseDragged(MouseEvent e) {
        pts[dragPt] = e.getPoint();
    }

    @Override
    public void mouseMoved(MouseEvent e) {}
}

HOLYSHIT! That's awesome. +1

HTML5 + Javascript + CSS
So I did it long time ago (the last modified date of the file was 9/21/2012). Glad that I kept it. Unfortunately it only supports 4 control points in its current state, but I'm working on it.
EDIT: Although the UI only supports 4 control points, the underlying function (animateConstruction) does support an arbitrary number of control points. Though I would not suggest doing it for more than 10 since the code is VERY inefficient. (I tried with 25 and had to kill the tab using Task Manager) If this counts as a valid submission I am not planning on revising the code.
NOTE: I was a naive hobbyist back then. The code is wrong on so many levels (including lack of semicolons and use of eval).
To Use
Save the code as a .html file and open it in Google Chrome or JSfiddle
If you need 4 or less control points, enter the parameters on the right, then choose "Construction mode" and press "Animate" in bottom left.
If you need more control points, call the animateConstruction function. It takes an array of coordinates (2-item arrays) as the argument. (e.g. animateConstruction([[0,0],[500,0],[0,500]]). Note that the draw area is 500x500, and the coordinate system follow the HTML canvas element (origin at top-left, x-axis pointing right, y-axis pointing down)
For the fiddle, I have added a text box bottom-left. Enter semicolon-separated coordinates (default value is an example) and press Go.
Differences in Fiddle version

The textbox
Default animation steps reduced to 100
Secondary curves are off by default

Code
<html>
<head>
<style>
span.h{
    display: inline-block;
    text-align: center;
    text-decoration: underline;
    font: bold 1em Arial;
}

input[type="color"]{
    -webkit-appearance: button-bevel;
    vertical-align: -7px;
    width: 21px;
    height: 27px;
}

input[type="color"][disabled]{background: #FFF}

td{position:relative; padding:1px; text-align:center}
table[class] td{text-align:left}
td.t{padding:1px 5px; width:46px;}
table input[type="checkbox"]{visibility:hidden}
tr:hover input[type="checkbox"]{visibility:visible}
</style>
<script type='text/javascript'>
function Bezier(c){
    if(c.length==2) return function(t){return [c[0][0]+t*(c[1][0]-c[0][0]),c[0][1]+t*(c[1][1]-c[0][1])]}
    else return function(t){return Bezier([Bezier(c.slice(0,-1))(t),Bezier(c.slice(1))(t)])(t)}
}

function Bezier2(f1,f2){
    return function(t){return Bezier([f1(t),f2(t)])(t)}
}

//============================================
var c = null
var settings = {'guide':{'show':[true,true,true,true], 'color':['#EEEEEE','#00FF00','#0000FF','#FF00FF'], 'width':[10,1,1,1]}, 'curve':{'show':[true,true,true,true], 'color':['#EEEEEE','#00FF00','#0000FF','#FF00FF'], 'width':[10,3,3,3]}, 'main':{'show':true, 'color':'#FF0000', 'width':10}, 'sample': 100, 'steps':200, 'stepTime':10, 'mode':'Bezier', 'coords':[[0,500],[125,450],[125,0],[500,0]]}
var itv = 0

window.addEventListener('load',function(){
    c = $('c').getContext('2d')
    c.lineCap = 'round'
    c.lineJoin = 'round'
    draw(settings.coords,1)
},true)

function get(k,i){
    var t = settings
    if(k.constructor == Array) k.forEach(function(e){t = t[e]})
    return t.length>i ? t[i] : t.slice(-1)[0]
}

function frame(coords){
    c.strokeStyle = settings.curve.color[0]
    c.lineWidth = settings.guide.width[0]
    c.beginPath()
    c.moveTo.apply(c,coords[0])
    coords.slice(1).forEach(function(e){c.lineTo.apply(c,e)})
    c.stroke()
}

function transf(c){
    var t = []
    c.forEach(function(e){t.push([e[0]+5,e[1]+5])})
    return t
}
//============================================
function drawBezier(coords,t){
    if(t===undefined) t = 1
    coords = transf(coords)
    c.clearRect(0,0,510,510)
    frame(coords)
    c.beginPath()
    c.strokeStyle = settings.main.color
    c.lineWidth = settings.main.width
    c.moveTo.apply(c,coords[0])
    for(var i=0;i<=t*settings.sample;i++) c.lineTo.apply(c,Bezier(coords)(i/settings.sample))
    c.stroke()
}

function animateBezier(coords){
    var s = settings.steps
    var cur = ($('t').value==1 ? ($('t').value=$('T').innerHTML=(0).toFixed(3))*1 : $('t').value*s)+1
    var b = drawBezier(coords,$('t').value*1)
    itv = setInterval(function(){
        $("T").innerHTML = ($("t").value = cur/s).toFixed(3)
        drawBezier(coords,cur++/s,b)
        if(cur>s) clearInterval(itv)
    },settings.stepTime)
}
//============================================
function drawBezier2(coords,t){
    if(t===undefined) t = 1
    c.beginPath()
    c.strokeStyle = get(['curve','color'],coords.length-1)
    c.lineWidth = get(['curve','width'],coords.length-1)
    c.moveTo.apply(c,coords[0])
    for(var i=0;i<=t*100;i++) c.lineTo.apply(c,Bezier(coords)(i/100))
    c.stroke()
}

function drawConstruction(coords,t,B){
    coords = transf(coords)
    if(t===undefined) t = 0.5
    var b = B===undefined ? [[]] : B
    coords.forEach(function(e){b[0].push(function(t){return e})})
    c.clearRect(0,0,510,510)
    frame(coords)
    for(var i=1;i<coords.length;i++){
        if(B===undefined) b.push([])
        with(c){
            for(var j=0;j<coords.length-i;j++){
                if(B===undefined) b[i].push(Bezier2(b[i-1][j],b[i-1][j+1]))
                if(i!=coords.length-1 && get(['curve','show'],i-1) || i==coords.length-1 && settings.main.show){
                    strokeStyle = i==coords.length-1?settings.main.color:get(['curve','color'],i-1)
                    lineWidth = i==coords.length-1?settings.main.width:get(['curve','width'],i-1)
                    beginPath()
                    moveTo.apply(c,b[i][j](0))
                    for(var k=0;k<=t*settings.sample;k++) lineTo.apply(c,b[i][j](k/settings.sample))
                    stroke()
                }
                if(i && i!=coords.length-1 && get(['guide','show'],i)){
                    strokeStyle = i==coords.length-1?settings.main.color:get(['guide','color'],i)
                    lineWidth = i==coords.length-1?settings.main.width:get(['guide','width'],i)
                    beginPath()
                    if(i!=coords.length-1) arc.apply(c,b[i][j](t).concat([settings.curve.width[0]/2,0,2*Math.PI]))
                    stroke()
                }
            }
            if(i && i!=coords.length-1 && get(['guide','show'],i)){
                beginPath()
                moveTo.apply(c,b[i][0](t))
                for(var j=1;j<coords.length-i;j++) lineTo.apply(c,b[i][j](t))
                stroke()
            }
        }
    }
    return b
}

function animateConstruction(coords){
    var s = settings.steps
    var cur = ($('t').value==1 ? ($('t').value=$('T').innerHTML=(0).toFixed(3))*1 : $('t').value*s)+1
    var b = drawConstruction(coords,$('t').value*1)
    itv = setInterval(function(){
        $("T").innerHTML = ($("t").value = cur/s).toFixed(3)
        drawConstruction(coords,cur++/s,b)
        if(cur>s) clearInterval(itv)
    },settings.stepTime)
}
//============================================
function draw(coords,t){clearInterval(itv); return window['draw'+settings.mode](coords,t)}
function animate(coords){clearInterval(itv); return window['animate'+settings.mode](coords);}
//============================================
function $(id){return document.getElementById(id)}
function v(o,p){
    for(var i in o){
        var k = (p||[]).concat([i]).join('-')
        var t
        if((t = o[i].constructor) == Object || t == Array) v(o[i],[k])
        else if(t = $(k)){
            if(t.type=='checkbox') t.checked = o[i]
            else if(t.type=='radio'){
                for(var j=0, t=document.getElementsByName(t.name); j<t.length; j++) if(t[j].value == o[i]){
                    t[j].checked = true
                    break
                }
            }else t.value = o[i]
        }else if(t = $((i==0?'x':'y') + p[0].slice(-1))) t.value = o[i]
    }
}

document.addEventListener('load',function(){
    v(settings)
    $('t').setAttribute('step',1/settings.steps)
    var t = document.getElementsByTagName('input')
    for(i=0;i<t.length;i++) t[i].addEventListener('change',function(){
        var t
        if((t=this.id.split('-')).length > 1){
            var t1 = function(T){
                var t = 'settings'
                T.forEach(function(e){t += '[' + (isNaN(e)?'"'+e+'"':e) +']'})
                eval(t + '=' + (this.type=='text'?this.value:(this.type=='checkbox'?this.checked:'"'+this.value+'"')))
                $(T.join('-')).value = this.value
            }
            t1.call(this,t)
            if(t[0]=='curve' && t[1]=='color' && $('u').checked==true) t1.call(this,['guide'].concat(t.slice(1)))
        }else if(this.id == 'u'){
            for(i=0;t=$('guide-color-'+i);i++){
                t.disabled = this.checked
                t.value = settings.guide.color[i] = this.checked?settings.curve.color[i]:t.value
            }
        }else if(this.id == 't'){
            $('T').innerHTML = (this.value*1).toFixed(3)
            draw(settings.coords,this.value*1)
        }else if(t = /([xy])(\d+)/.exec(this.id)) settings.coords[t[2]*1][t[1]=='x'?0:1] = this.value*1
        else settings[this.id] = this.value
        if(this.id == 'steps') $("t").setAttribute("step",1/settings.steps)
    },true)
},true)
</script>
</head>
<body>
<canvas style='float:left' width='510' height='510' id='c'>
</canvas>
<div style='padding-left:550px; font-family:Arial'>
<span class='h' style='width:123px'>Control Points</span><br />
(<input type='text' id='x0' size='3' maxlength='3' />,<input type='text' id='y0' size='3' maxlength='3' />)<br />
(<input type='text' id='x1' size='3' maxlength='3' />,<input type='text' id='y1' size='3' maxlength='3' />)<br />
(<input type='text' id='x2' size='3' maxlength='3' />,<input type='text' id='y2' size='3' maxlength='3' />)<br />
(<input type='text' id='x3' size='3' maxlength='3' />,<input type='text' id='y3' size='3' maxlength='3' />)<br /><br />
<span class='h' style='width:200px'>Appearance</span><br />
<span style='font-weight:bold'>Guide lines</span><br />
<input type='checkbox' checked='checked' id='u' onchange='' /> Use curve colors<br />
<table style='border-collapse:collapse'>
<tr><td><input type='checkbox' id='guide-show-0' /></td><td><input type='color' id='guide-color-0' disabled='disabled' /></td><td class='t'>Frame</td><td><input type='text' id='guide-width-0' size='2' maxlength='2' /></td></tr>
<tr><td><input type='checkbox' id='guide-show-1' /></td><td><input type='color' id='guide-color-1' disabled='disabled' /></td><td class='t'>1</td><td><input type='text' id='guide-width-1' size='2' maxlength='2' /></td></tr>
<tr><td><input type='checkbox' id='guide-show-2' /></td><td><input type='color' id='guide-color-2' disabled='disabled' /></td><td class='t'>2</td><td><input type='text' id='guide-width-2' size='2' maxlength='2' /></td></tr>
<tr><td><input type='checkbox' id='guide-show-3' /></td><td><input type='color' id='guide-color-3' disabled='disabled' /></td><td class='t'>3</td><td><input type='text' id='guide-width-3' size='2' maxlength='2' /></td></tr>
</table>
<span style='font-weight:bold'>Curves</span>
<table style='border-collapse:collapse'>
<tr><td><input type='checkbox' id='curve-show-0' /></td><td><input type='color' id='curve-color-0' /></td><td class='t'>1</td><td><input type='text' id='curve-width-0' size='2' maxlength='2' /></td></td></tr>
<tr><td><input type='checkbox' id='curve-show-1' /></td><td><input type='color' id='curve-color-1' /></td><td class='t'>2</td><td><input type='text' id='curve-width-1' size='2' maxlength='2' /></td></td></tr>
<tr><td><input type='checkbox' id='curve-show-2' /></td><td><input type='color' id='curve-color-2' /></td><td class='t'>3</td><td><input type='text' id='curve-width-2' size='2' maxlength='2' /></td></td></tr>
<tr><td><input type='checkbox' id='curve-show-3' /></td><td><input type='color' id='curve-color-3' /></td><td class='t'>4</td><td><input type='text' id='curve-width-3' size='2' maxlength='2' /></td></td></tr>
<tr><td><input type='checkbox' id='main-show' /></td><td><input type='color' id='main-color' /></td><td class='t'>Main</td><td><input type='text' id='main-width' size='2' maxlength='2' /></td></td></tr>
</table><br />
<span class='h' style='width:300px'>Graphing & Animation</span><br />
<table class>
<tr><td>Sample points:</td><td><input type='text' id='sample' /></td></tr>
<tr><td>Animation steps:</td><td><input type='text' id='steps' /></td></tr>
<tr><td>Step time:</td><td><input type='text' id='stepTime' />ms</td></tr>
</table>
<div style='position:absolute; top:526px; left:8px; width:510px; height:100px;'>
<input type='range' id='t' max='1' min='0' style='width:450px' value='1' />   <span id='T' style='vertical-align: 6px'>1.000</span><br />
<input type='button' onclick='draw(settings.coords,$("t").value*1)' value='Draw' /><input type='button' onclick='animate(settings.coords)' value='Animate' />
<input type='radio' id='mode' name='mode' value='Bezier' />Basic Mode <input type='radio' id='mode' name='mode' value='Construction' />Construction Mode
</div>
</body>
</html>

You should make this jsfiddle compatible so it could be tested easily. Good solution, although I couldn't set the control points in Chrome.

@SztupY Added the fiddle

Perl + PerlMagick
use strict;
use Image::Magick;

sub point
{
    my ($image, $f, $x, $y, $r) = @_;
    $image->Draw(fill => $f, primitive => 'circle', points => $x . ',' . $y . ',' . ($x + $r) . ',' . $y);
}

sub line
{
    my ($image, $f, $x1, $y1, $x2, $y2, $w) = @_;
    $image->Draw(fill => 'transparent', stroke => $f, primitive => 'line', strokewidth => $w, points => "$x1,$y1,$x2,$y2");
}

sub colorize
{
    my $i = shift;
    return ((sin($i * 6) + 0.5) * 255) . ',' . ((sin($i * 6 + 2) + 0.5) * 255) . ',' . ((sin($i * 6 + 4) + 0.5) * 255);
}

sub eval_bezier
{
    my $p = shift;
    my @x = @_;
    my @y;
    for my $i (0 .. $#x - 1)
    {
        $y[$i] = $x[$i] * (1 - $p) + $x[$i + 1] * $p;
    }
    return @y;
}

sub render_bezier
{
    my (%args) = @_;
    my $seq = $args{sequence};
    for my $q (0 .. $args{frames} - 1)
    {
        my $p = $q / ($args{frames} - 1);
        my @x = @{$args{xpoints}};
        my @y = @{$args{ypoints}};
        my $amt = @x;
        my $image = Image::Magick->new(size => $args{size});
        $image->ReadImage('xc:black');
        for my $i (0 .. $amt - 1)
        {
            for my $j (0 .. $#x - 1)
            {
                line($image, 'rgba(' . (colorize $i / $amt). ', 0.5)', $x[$j], $y[$j], $x[$j+1], $y[$j+1], 4 * 0.88 ** $i)
            }
            for my $j (0 .. $#x)
            {
                point($image, 'rgba(' . (colorize $i / $amt). ', 1.0)', $x[$j], $y[$j], 4 * 0.88 ** $i);
            }
            @x = eval_bezier $p, @x;
            @y = eval_bezier $p, @y;
        }
        my ($ox, $oy) = ($x[0], $y[0]);
        for my $q (0 .. $q)
        {
            my $p = $q / ($args{frames} - 1);
            my @x = @{$args{xpoints}};
            my @y = @{$args{ypoints}};
            for (0 .. $amt - 2)
            {
                @x = eval_bezier $p, @x;
                @y = eval_bezier $p, @y;
            }
            line($image, 'rgba(255, 255, 255, 1.0)', $x[0], $y[0], $ox, $oy, 2);
            ($ox, $oy) = ($x[0], $y[0]);
        }
        push @$seq, $image;
    }
}

my @x = (10,190,40,190);
my @y = (190,30,10,110);

my $gif = Image::Magick->new;
render_bezier(xpoints => \@x, ypoints => \@y, sequence => $gif, size => '200x200', frames => 70);
$gif->Write(filename => 'output.gif');

Example of output:

Other outputs can be seen in this imgur album

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Run the Monty Hall Problem
There’s already been a question about simulating the Monty Hall Problem. This one is different. The user will play the Monty Hall Problem. Your program will play the role of the host. Montybot, if you like.
Here are the steps:

Pick (randomly) which of the three doors hides the prize.
Output a visual display of three doors. A simple ABC will do. Or three squares. Or whatever.
Receive input choosing one of the doors. This could be a mouse click on the chosen door, or a single letter input (B) or whatever.
Open another door. You do not open the chosen door. You do not open the door hiding the main prize. That may mean you have no choice, or it may mean that you have a choice of two. If you have a choice of two, pick one at random. Visually indicate that the door has been opened and that no prize was hidden behind it. For a program text-based input/output, this could be as simple as outputting AB0, to show that door C has been opened. Feel free to be more inventive. If you’re doing a GUI program, your choice of display is up to you.
Accept input from the user. The user may input stick or switch (or, for a GUI program, click on buttons, or use a select input, or whatever). If the user enters anything other than stick or switch, the implementation is undefined. Do whatever you want.
Output the text You won! or You lost.
Terminate the progam.

Rules:

When you have to choose something at random, don’t worry about cryptographic randomness. Any rand() function will do.
The program must not cheat. The prize must be in place before the game starts. That is to say that the steps must be performed in the order given: First choose a door behind which to hide your prize, then ask the player to choose. The choice of which door to open in step 4 must happen in step 4: it is not selected in advance.
The output in step 6 must be honest.
This is code golf. Shortest code wins.

My first time posting on this site, but I lurk a lot, so I think I'm familiar with your norms.

On meta.codegolf.stackexchange.com there's a thread for proposing questions and letting people work out any problems with it before it gets officially posted. I don't know if there's anything specifically wrong here that could have been ironed out, but it might be good to know for next time.

I am previewing that the winner will be just another golfscript answer...

BTW, "being inventive" does not goes well with codegolfing, since being inventive consumes some bytes and the objective of codegolfing is the opposite of this.

Yeah, @Victor. Being inventive is not a requirement. I just (a) did not want to limit this to command line programs, and (b) had no idea how a non-command line program should implement user selection. So I left it up to the answerers. Being inventive is an option, but it's one that'll garner no extra points.

Perhaps that's something I should have brought to the sandbox on meta, but I don't foresee it being a major problem, @Victor.

APL, 77
p←?3⋄d[e[?⍴e←(⍳3)~p,c←⍞⍳⍨⎕←d←3↑⎕A]]←'_'⋄⎕←d⋄⎕←'You','lost' 'won!'[(c=p)=5=⍴⍞]

Needs ⎕IO←0. Tested on Dyalog.
Explanation
p←?3                       ⍝ p(rize) is a random number between 1 and 3
⎕←d←3↑⎕A                   ⍝ d(oors) is the string 'ABC'; output it
c←d⍳⍞                      ⍝ ask for one of the letters; c(hoice) is its position
o←e[?⍴e←(⍳3)~p,c]          ⍝ o(pen) is a random position except for p and c
d[o]←'_'                   ⍝ replace the o position in the d string with a '_'
⎕←d                        ⍝ output the modified d string
w←(c=p)=5=⍴⍞               ⍝ get choice, if it's stick (5 chars) and c=p, or neither, (w)in
⎕←'You','lost' 'won!'[w]   ⍝ print the result

Examples
      p←?3⋄d[e[?⍴e←(⍳3)~p,c←⍞⍳⍨⎕←d←3↑⎕A]]←'_'⋄⎕←d⋄⎕←'You','lost' 'won!'[(c=p)=5=⍴⍞]
ABC
A
AB_
stick
You lost
      p←?3⋄d[e[?⍴e←(⍳3)~p,c←⍞⍳⍨⎕←d←3↑⎕A]]←'_'⋄⎕←d⋄⎕←'You','lost' 'won!'[(c=p)=5=⍴⍞]
ABC
A
AB_
stick
You won!

Lovely! But I think there's a ≠ in the source which mutates into a = in the explanation.

Thanks, that was a typo, the last bug I fixed before posting.

Python, 157
from random import*
C=choice
I=raw_input
p='\n> '
a='ABC'
g=C(a)
i=I(a+p)
print'You '+'lwoosnt!'[(i==g)^('w'in I(a.replace(C(list(set(a)-{g,i})),'_')+p))::2]

Example:
$ python monty.py
ABC
> A
AB_
> switch
You won!

PowerShell: 192 174
Changes from original:

-8 Characters Since the visual display of doors can be "whatever" I realized that I could save some characters (particularly,
  the apostrophes required to define strings) by using numbers instead
  of letters.
-8 Characters By specifically choosing single-digit, prime numbers to represent the doors I could use the shorter modulo operator
  instead of an actual comparison operator when I needed to match doors
  to figure out the host's possible choices or the player's door swap.
  (Briefly explained
  here.)
-2 Characters Swapping the win/loss responses in the final if/else statement allowed me to use the modulo trick there also.

Golfed Code
$w=($d=3,5,7)|random;357;$p=read-host;-join$d-replace($h=$d|?{$_%$w-and$_%$p}|random),0;if((read-host)-match'w'){$p=$d|?{$_%$p-and$_%$h}}if($p%$w){'You lost'}else{'You won!'}

Un-Golfed Code With Comments
# Set up an array of doors ($d), and choose one to be the winner ($w).
$w=($d=3,5,7)|random;

# Show doors.
357;

# Get input and save player's choice ($p).
$p=read-host;

# Join the doors into one string, replacing the host's choice ($h) with a zero, and display them again.
-join$d-replace
(
    # Host will randomly choose a door from those which are not evenly divisible by $w or $p.
    $h=$d|?{$_%$w-and$_%$p}|random
 ),0;

# Get input from player. If it contains a 'w', switch doors.
# While this is generally a sloppy way to distinguish 'switch' from 'stick', it is allowed by the rules.
# "If the user enters anything other than stick or switch, the implementation is undefined. Do whatever you want."
if((read-host)-match'w')
{
    # Player will switch doors to one which is not evenly divisible by the $h or the original $p.
    $p=$d|?{$_%$p-and$_%$h}
}

# Announce the result.
# If $p is not evenly divisible by $w, player has lost. Otherwise, they have won.
if($p%$w){'You lost'}else{'You won!'}

# Variables cleanup - not included in golfed code.
rv w,d,p,h

I like the if it contains a 'w' trick.

Incidentally, I originally said that if the input was anything other than "stick" or "switch", the program should terminate, but I changed my mind before posting.

@TRiG Thanks for that. While it wouldn't have been hard to implement, it would have added a bit of bloat.

And the various tricks (your w detection, or counting characters) are more fun, anyway.

Javascript, 221 197
(function(q,r,s,t,u,v){f='ABC';d=[0,1,2];b=q()%3;a=r(f);d.splice(a,1);(a==b)?(r(f[d[q()%2]])==t)?s(u):s(v):(r(f[d[(d[0]==b)+0]])!=t)?s(u):s(v)})(Date.now,prompt,alert,'stick','You won!','You lost')

It uses two calls to Date.now() for randomness with a prompt in between to guarantee a delay. The user input is a 0-based index (the rule did say "whatever"). The following alert says which door was opened. Here's a slightly longer version that gives the answer before the user picks, to verify that it doesn't cheat:
(function(q,r,s,t,u,v){f='ABC';d=[0,1,2];b=q()%3;s('ans:'+b);a=r(f);d.splice(a,1);(a==b)?(r(f[d[q()%2]])==t)?s(u):s(v):(r(f[d[(d[0]==b)+0]])!=t)?s(u):s(v)})(Date.now,prompt,alert,'stick','You won!','You lost')

Fiddle: http://jsfiddle.net/acbabis/9J2kP/
EDIT: Thanks dave

You could shorten it to 197:
(function(q,r,s,t,u,v){f='ABC';d=[0,1,2];b=q%3;a=r(f);d.splice(a,1);(a==b)?((r(f[d[q%2]])==t)?s(u):s(v)):(r(f[d[(d[0]==b)+0]])!=t)?s(u):s(v)})(Date.now(),prompt,alert,'stick','You won!','You lost')

@dave That's helpful. I didn't think to use the ternary operator here. I can't pass Date.now(), though, because the random numbers need to be independent. I can, however, pass Date.now.

@acbabis "I can't pass Date.now() ... I can, however, pass Date.now" ???

@Timtech date.now passes the function, date.now() passes the result of the function

PHP >= 5.4, 195 192
$r=[0,1,2];unset($r[$p=rand(0,2)]);$d='012';echo"$d\n";fscanf(STDIN,"%d",$c);unset($r[$c]);$d[array_rand($r)]='_';echo"$d\n",!fscanf(STDIN,"%s",$s),'You '.($s=='switch'^$c==$p?'won!':'lost.');

Output:
012
1
01_
stick
You won!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Minimal code CPU stress-tester…
Introduction
There are lots of utilities out there capable of creating a high CPU load to stress-test your processor(s). On Microsoft Windows, you can even use the on-board calculator.exe, enter a large number like 999999999, and press n! several times to make your CPU(s) work overtime.
But what’s in a solution if you didn’t create it yourself?
The mission
Your mission – if you choose to accept it – is to create the smallest CPU stress-test tool on the planet.
Must…

must produce 100% CPU load until aborted
must take a numeric input, representing the number seconds the stress-test should run
must allow user interaction (keypress, closing terminal window, or something like that) which should enable a user to abort the stress-test and/or quit the program
must target Microsoft Windows, Mac OSx, and/or Linux.
(Even a hamster could stress a Comodore64… therefore, you must target a current operating system.)

Must not…

must not use 3rd-party programs or tools which replace expected functionality.
(Proposing shortcuts in the likes of system('cpuStressThing.exe') disqualifies your proposal.)

May…

may use any approach/algorithm/functionality to produce expected 100% CPU load
may use any programming or scripting language
(as long as it allows practical verification of its functionality by running it)

Winning Condition
Present the smallest sourcecode possible. The winner is the one presenting the most minimal (in size) sourcecode that complies to the above “must” and “must not” conditions. Now, make that baby burn…

EDIT
Since the question came up in the comment area… you only need to target 1 CPU core. I'm definitely not expecting you to produce a multi-core solution. After all, this should be fun – not work.

Is "100% of one core" enough, or do you mean "100% of a multi-core CPU"?

@Tobia Yep, 1 core is enough. I've edited my question to specifically include that information. Thanks for pointing me to the fact that that wasn't all too clear.

do cryptocurrency miners count/

@TheDoctor If you can make it fit the conditions I described… be my guest. It would surely be interesting to see a cryptocurrency miner that is able to beat (for example) a 36 byte bash script in filesize.

The problem is that most miners are several thousand lines of code.

@TheDoctor I know – that's why I said it would surely be interesting to see you pull it off. ;)

Given the popularity of yes, it would be nice to clarify whether the program is allowed to produce output.

@NateEldredge Just like it says: may use any approach/algorithm/functionality to produce expected 100% CPU load – so if you decide that producing output will do the job of producing a high CPU load, you are free to do that…

Bash and standard utilities, 36 31 22 29 28 26 bytes
yes :|sh&sleep $1;kill $!

That looks pretty gorgeous for a Bash code! That's really a nice answer!

You don't need the : in do :; done. I've found do;done does the job - that'll pull you in 2 bytes. Also +1 for being nearly half the length of my bash solution (I made it overly complicated for no good reason as I forgot about $!).

@ChrisJ - that doesn't work for me: bash: syntax error near unexpected token \;'.  I've tried these bash versions: 3.00.15(1)-release (x86_64-redhat-linux-gnu), 3.2.48(1)-release (x86_64-apple-darwin12), 4.2.25(1)-release (x86_64-pc-linux-gnu)`

Ah - my mistake, sorry. ksh allows that syntax, bash/sh doesn't (having jsut tested).

@ChrisJ - I guess you have yourself a 34-byte ksh answer then ;-)

I'd put $1 in place of 10 there, just to make it into a script that "takes numeric input".

@Tobia - fixed.

Also /d*/n* works just as well on my Linux box, as there's only one file with that pattern—/dev/null

@Tobia - I have /dev/net /dev/network_latency /dev/network_throughput /dev/null.  I guess /d*/nu* would do it.  Not sure if its worth introducing fragility for the sake of 2 bytes.  Of course it is - its code-golf!

I like that you suppress the output of yes.  I thought of a shorter way: yes :|sh&

@NateEldredge - very good - thanks!

@e-sushi - yes I guess there is some inefficiency of utilization when writing all those chars to the terminal window.  I've removed that part of the answer.

+1 for emoticon... :|

Bash/iputils (Linux), 14 bytes
ping6 -fw$1 ::

Flood-pings the IPv6 null address, until the -w deadline timer expires
caveat - only consumes 55-60% CPU on my test VM
Edit: - I retract my caveat.  While top reports the ping6 process only consumes 55-60% CPU, I see the total CPU idle percentage (2 core VM) approach zero.  This presumably is because a good deal of the processing is going on in the kernel as it handles the packets.
Note - must be run as root.  As @Tobia comments, this seems like a reasonable requirement for something that will hog the CPU.  And the OP approved it in the comments.

+1. I would remove sudo  and just state that the test must be run as root. It seems like a reasonable requirement for something that will hog the CPU.

@Tobia - thanks - I think you're onto something ;-)

ping -6 :: -t --> only if this on windows made my cpu go wild... It's just the linux equivalent on windows, which only gives errors and doesn't even load the cpu at 1%! I'm using windows 8 pro x64 on a core2quad 2.63GHz.

@IsmaelMiguel - yep - I don't have windows to hand to test this.  Thats why I stated "Linux" in the title ;-)

I know, I'm just "giving" away this answer as a non-working one, for those who are thinking about trying the same in windows, as I did and failed.

Elf32 standalone binary - 86 bytes
I bet this is the smallest correctly formed Elf format binary that can be made to perform this function.  This will execute without any additional support on any linux based platform, or potentially even without an operating system.
Binary download: http://ge.tt/3m6h2cK1/v/0?c
Hex dump:
0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 0300 0100 0000 5480 0408 3400 0000  ........T...4...
0000020: 0000 0000 0000 0000 3400 2000 0100 0000  ........4. .....
0000030: 0000 0000 0100 0000 0000 0000 0080 0408  ................
0000040: 0080 0408 5600 0000 5600 0000 0500 0000  ....V...V.......
0000050: 0010 0000 75fe                           ....u.

This is done by building an asm file with a minimal Elf header of its own, and skipping the use of ld altogether.
Assembly:
BITS 32

              org     0x08048000

ehdr:                                                 ; Elf32_Ehdr
              db      0x7F, "ELF", 1, 1, 1, 0         ;   e_ident
times 8       db      0
              dw      2                               ;   e_type
              dw      3                               ;   e_machine
              dd      1                               ;   e_version
              dd      _start                          ;   e_entry
              dd      phdr - $$                       ;   e_phoff
              dd      0                               ;   e_shoff
              dd      0                               ;   e_flags
              dw      ehdrsize                        ;   e_ehsize
              dw      phdrsize                        ;   e_phentsize
              dw      1                               ;   e_phnum
              dw      0                               ;   e_shentsize
              dw      0                               ;   e_shnum
              dw      0                               ;   e_shstrndx

ehdrsize      equ     $ - ehdr

phdr:                                                 ; Elf32_Phdr
              dd      1                               ;   p_type
              dd      0                               ;   p_offset
              dd      $$                              ;   p_vaddr
              dd      $$                              ;   p_paddr
              dd      filesize                        ;   p_filesz
              dd      filesize                        ;   p_memsz
              dd      5                               ;   p_flags
              dd      0x1000                          ;   p_align

phdrsize      equ     $ - phdr

section .text
global  _start
_start:       jnz     _start

filesize      equ     $ - $$

Built with nasm -f bin tiny_cpu_stresser_elf32.asm -o tiny_cpu_stresser_elf32

bash builtins only 20 bytes
ulimit -t $1;exec $0

@e-sushi try with a faster terminal, e.g. a text console or xterm or rxvt

C, 52
t;main(s){for(scanf("%d",&s),t=time();time()-t<s;);}

Press Ctrl+C to exit.

If you do that in php, you will win! Just remove the $i=<> part and add <? to the beginning and you are good to go!

Perl, 32
for($i=<>,$t=time;time-$t<$i;){}

Now the embarrassing part: I foolishly put $t=time in front of $i=<> and was furiously trying to figure out why it exits a few seconds early.
Again, Ctrl+C to exit.

Unix C, 47
main(int a,char**b){alarm(atoi(b[1]));for(;;);}

Pass the time on the command line.  Interrupt key (Ctrl-C) aborts.

if you use @ace's scanf trick, you can get this down to 39: main(a){for(scanf("%d",&a),alarm(a);;);}

PHP 43 40 bytes:
I hope this is an acceptable answer:
set_time_limit($_REQUEST['t']);while(!0);
<?for(set_time_limit($_REQUEST['t']);;);

I could do like this: <?for(set_time_limit($_POST['t']);;); but it would lose flexibility and 3 bytes.

And i could cheat and do like this: <?for(set_time_limit($_REQUEST[t]);;);. It shaves off 2 bytes, but it's not a "standard" solution. Lets keep the game fair.

As @fireeyedboy and @primo suggested, you can also use this solution (34 bytes):
<?for(set_time_limit($argv[1]);;);

This allows it's use from the console, calling it like this:
php <filename> <time in seconds>

As i told, I'm not targeting the console solution, but they have to get the credit for this one.
Another answer could be this "monster", which is just both answers combined:
<?for(set_time_limit($argv[1]|$_REQUEST['t']);;);

It's impossible to get key presses in php, without being on console, which I'm not targeting!
To stop it, you MUST abort the process (stopping the page from loading might stop the code)!
As a plus, it works in Android too! If you install a php server (free on Google Play).
To make it work, simply do like this:
You create a .php webpage and append ?t=<time in seconds> to the end of the url or submit a post (using a form or even ajax).

@e-sushi I fixed the answer and reduced 3 bytes. Not as small as the Bash solution, but close. And with flexibility!

Run from the command line: replace $_REQUEST['t'] with $argv[1] then call it with: php -f cpustresstest.php <timelimit> and abort with ^C.

Why not use $_GET instead of $_REQUEST? 4 bytes and you are using GET anyway

@KristofferSHansen Because the flexibility of my code will be severely hurt.

@fireeyedboy That sounds like a good idea, but as I said, I'm not targeting to the console.

@IsmaelMiguel you could also use $argv[1], and accept the input as a command line argument, for example: php stress.php 4.

@fireeyedboy and @primo, I added a new answer using the solutions you suggested. And @fireeyedboy, you don't need the -f argument. If you want, you can try like this: php -r 'for(set_time_limit($argv[1]);;);' <time in seconds>

Smalltalk (Smalltalk/X), 34
input: n; interrupt with CTRL-c or CMD-.
[[]loop]valueWithTimeout:n seconds

can golf better, if measured in days ;-) (just kidding):
[[]loop]valueWithTimeout:n days

or from a command line:

This is not a serious attempt at it, but...
Bash, 12 bytes
:(){ :|:&};:

As found on Wikipedia.
WARNING: harmful code, don't run it on your computer!

Technically:
- It produces 100% CPU load until system crashes;
- Allows user interaction to stop it (if you manage to kill all the forks, you can actually stop it...);
- You could give it a numeric input that represents the number of seconds it should run, but it won't use it.

Perl - 14 bytes
alarm<>;{redo}

Sets a SIGALRM to be sent in input seconds, which terminates the script. In the meantime, it spins in a busy-wait.
Sample usage:
$ echo 4 | perl stress.pl
Terminating on signal SIGALRM(14)

Perl - 12 (+1) bytes
If command line options are counted as one byte each, this could be reduced to 13 bytes using a -n:
alarm;{redo}

Sample usage:
$ echo 4 | perl -n stress.pl
Terminating on signal SIGALRM(14)

+1 for clever use of signals to concisely satisfy the exit requirement.

BrainFuck/Extended BrainFuck: 3
+[]

It will use 100% cpu on one core until aborted. All Brainfuck programs are valid  EBF programs.
Zozotez LISP: 7 15 19
When using the little driver.
(:'r s) ; redfine read in the read-eval-print-loop

As a standalone expression without a driver: 15
((:'L(\()(L))))     ; setq a loop function and execute it

Usage: echo '((\(L)(L))(\()(L)))' | jitbf zozotez.bf

Python, 58 55 51
Wow... longer than the C one. There's got to be a better way. Still a tad long, but at least it beats the C solution!
import time;t=time.time;u=t()+input()
while t()<u:1

Haha, I love your first sentence. Personally I consider a C answer as the par.

@ace (Barely) Fixed!

Now the other C solution beats yours!

@ace Ah, I give up, At least this one is portable! :P (I actually looked at sigalrm earlier, but it's just too expensive to set up and use signals... Python can be rather wordy when its libs are required :[)

x86_64 assembly on Linux - 146 (source), 42 (assembled code)
The NASM minified source (146 bytes):
xor rdi,rdi
mov rcx,[rsp+16]
mov rcx,[rcx]
l:
sub cl,'0'
jl k
imul rdi,10
movsx rdx,cl
add rdi,rdx
ror rcx,8
jmp l
k:
mov rax,37
syscall
s:
jmp s

Accepts a parameter on the command line specifying the number of seconds to run in the range (0, 9999999]; can be interrupted with the usual Ctrl-C.
You can assemble it with
nasm -f elf64 -o stress.o stress.asm && ld -o stress stress.o

In theory it would be necessary to add a global _start followed by a _start: label at the beginning, but ld manages to fix it by itself with little fuss.
The corresponding machine code (42 bytes):
00000000  48 31 ff 48 8b 4c 24 10  48 8b 09 80 e9 30 7c 11  |H1.H.L$.H....0|.|
00000010  48 6b ff 0a 48 0f be d1  48 01 d7 48 c1 c9 08 eb  |Hk..H...H..H....|
00000020  ea b8 25 00 00 00 0f 05  eb fe                    |..%.......|
0000002a

(generated with nasm adding the BITS 64 directive)
A somewhat more readable version:
global _start

_start:
    xor rdi,rdi
    mov rcx,[rsp+16]
    mov rcx,[rcx]
argparse:
    sub cl,'0'
    jl alarm
    imul rdi,10
    movsx rdx,cl
    add rdi,rdx
    ror rcx,8
    jmp argparse
alarm:
    mov rax,37
    syscall
loop:
    jmp loop

Batch, 2 characters
%0
In essence, the program constantly starts itself over and over.  Your results may vary, due to processor task allocation priority, but it works for me.

Java - 154 148 186
Weird error ate my Thread.sleep() part
public class Z{public static void main(String[]a) throws Exception{new Thread(){public void run(){for(;;);}.start();Thread.sleep(Byte.valueOf(a[0])*1000);System.exit(0);}}

and a more readable version:
public class Z {
    public static void main(String[] a) throws Exception {
        new Thread() {
            public void run() {
                for (;;)
                    ;
            }
        }.start();
        Thread.sleep(Byte.valueOf(a[0]) * 1000);
        System.exit(0);
    }
}

Spawns a new Thread with a nice endless loop (for(;;);) then on main thread a thread.sleep() and a System.exit(0) after timeout to exit; ctrl-c exits, too on cmdline
wasnt able to shorthand that exit(). crashing wont work;

Go, 215 212 193 bytes (full)
package main
import(."runtime"
f"flag"
."strconv"
."time")
func main(){f.Parse()
c:=NumCPU()*2
t,_:=Atoi(f.Arg(0))
GOMAXPROCS(c)
for;c>0;c--{go(func(){for{Now()}})()}
<-After(Duration(t)*1e9)}

Bonus, stresses all CPU's.
The Now() in the loop is there to kick in the scheduler, Now was the shortest function name I could find in my namespace
If I run go fmt the size increases to 286 277 254 bytes

C# - 178 characters
using A=System.DateTime;class P{static void Main(string[]a){var b=A.Now.AddSeconds(int.Parse(a[0]));System.Threading.Tasks.Parallel.For(0,1<<30,(i,l)=>{if(A.Now>b)l.Stop();});}}

And more readable:
using A = System.DateTime;
{
    class P
    {
        static void Main(string[] a)
        {
            var b = A.Now.AddSeconds(int.Parse(a[0]));
            System.Threading.Tasks.Parallel.For(0, 1 << 30, (i, l) =>
            {
                if (A.Now > b)l.Stop();
            });
        }
    }
}

Thats 178 chars in C# and uses all cores.
The only weakness that it is always ending because of the 1<<30 integer limit.

Powershell, 18 54 50 bytes
To produce 100% load for all CPU cores.
for($s=date;($s|% AddS* "$args")-ge(date)){sajb{}}

The script takes a time in seconds as argument.
| AddS* is the shortcut for .AddSeconds() method.
sajb is the alias for Start-Job cmdlet.

How does this satisfy requirement 2 (must take a numeric input, representing the number seconds the stress-test should run)?

C#, 118
using a=System.DateTime;class b{static void Main(string[]c){var d=a.Now.AddSeconds(int.Parse(c[0]));while(d>a.Now){}}}

Uncompressed
using a = System.DateTime;
class b
{
    static void Main(string[] c)
    {
        var d = a.Now.AddSeconds(int.Parse(c[0]));
        while (d > a.Now) { }
    }
}

This requires a number as an argument which is the number of seconds to run.  It will use 100% of one core for that much time or until crtl+c.  I'm pretty sure this is as small as C# will go with its verbosity.

Linux sh and standard utilities, 14
Recent gnu coreutils includes a timeout utility which is helpful:
 timeout $1 yes

Nowhere near 100% CPU for me; it's throttled way too much by having to print I think...is there another command?

timeout $1 yes :|sh - 19 is probably the best you can do and get 100% utilisation.  Tempted to steal this for my answer, but I'll be sportsman-like :)

Matlab - 19
tic;while toc<5;end
Replace 5 with desired execution time.

EcmaScript 6:
z=z=>{while(1)z()};_=i=>(i+=1,i-=1,i++,i--,--i,++i,i<<=2,i>>=2,i+=0|Math.round(1+Math.random())&1|0,z(x=>setInterval(x=>z(x=>new Worker('data:text/javascript,'+_.toSource()),5))));setInterval(x=>z(x=>_(...Array(i=9e3).map((x,z)=>z*3/2*2/4*4e2>>2<<2))),5)

This will use 100% of the CPU on a single-core machine, and with Firefox, it has the added bonus that Firefox keeps using up more and more memory; the whole interface locks up and the only way to stop it is to kill Firefox in the task manager.

Bash: 19 chars
function f(){ f;};f

Assembly: 16 bytes
_start:jg _start

Edit: Having not noticed the requirement to take a numeric input, i'm going to claim it does take one on the commandline, but ignores it =)

This takes a numeric input for the number of seconds the test runs? It looks to me like it simply loops infinitely. Whatever it is, remember to add an explanation in your answer.

Oh... totally read past that part of the question :/

DOS Batch - 5 bytes
%0|%0

DOS Batch - 8 bytes
%0|%0&%0

Second is a translation of the infamous sh forkbomb.
Ctrl+C breaks the program (unless you've tweaked the settings a little).

Java - 88 characters
class S{public static void main(String[]a){for(long i=0;i<Long.valueOf(a[0]);){i=i+1;}}}

This allows for 2⁶³-1 loops.
More Readable Version
class S {
    public static void main(String[] a) {
      for (long i = 0; i < Long.valueOf(a[0]);) { i = i + 1; }
}

C# - 87 characters
class S{public static void Main(string[]a){for(long i=0;i<long.Parse(a[0]);){i=i+1;}}}

More Readable Version
class S {
public static void Main(string[] a) {
    for(long i = 0;i < long.Parse(a[0]);i++) { i = i + 1; }
}
}

(This is on a 4 core system)

OP asked for 100%

The OP also specified that you only need to peg one core. It can go to 25% (which is 100% of 1 core).

Not to be picky but your image shows 24.89% not 25%

True. It depends on what's happening on that core. If nothing is happening on the core, it will use the full 25%.

perl, 23 bytes
I can't figure out how to paste a literal control-T here, so I've typed $^T instead, but either works (the literal is 1 char shorter at 23 bytes):
$e=$^T+<>;1 until$e<time

$^T is just the time the interpreter started, so you can basically read that as time() since it is the first thing we calculate.

Python, 30
I found this old puzzle interesting, I hope it's OK to post an answer to an old question.  I just couldn't let the C answers beat Python.  ;)
sum(range(int(input())*2**26))
This needs tuned for different CPUs, but I don't think that violates the OP... sum(range(2**27)) pegs one of my 2.8GHz i7 cores for about a second.  :)

Welcome to PPCG! Posting answers to old questions is perfectly acceptable here, however as far as I see this answer does not full fill the requirement must produce 100% CPU load until aborted.

Thanks!  :)  On my machine, this code produces 100% load on a single core, and I can abort it like any other script by pressing Ctrl-C or killing the parent process (e.g., by closing the terminal window) or etc.  Note also requirement 2: must take a numeric input, representing the number seconds the stress-test should run.  So that the code needs to take user input somehow and self-limit accordingly, as well as just peg a CPU.  This is the part I found most interesting about the puzzle...

You're right, thanks for the clarification.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/