text:
Draw random black-and-white forest
Your task is to write program which will draw 800x600 black-and-white image with something resembling a forest.
Like this (it is dithered photo):

Rules

You are disallowed to use any existing images - you should generate image purely algorithmically
Use only 2 colors - black and white (no grayscale)
Each time program runs image should be new - random every time
One tree is not a forest (let say 5 trees minumum)
Special libraries for drawing trees/forests are disallowed
Answer with most votes wins

This question appears to be off-topic because it is more an art contest rather than a programming contest.

@ProgramFOX Isn't programming art? :)

The question is about generating art, and the answers will likely compete by output, not by code. Example of a similar contest, which was also an art contest rather than a programming contest: http://codegolf.stackexchange.com/questions/20598/make-the-day-we-fight-back-logo

@ProgramFOX I thought for this task various interesting algorithms can be used.

Those algorithms will generate beautiful art, and better output will attract more votes, I think. Anyway, we'll see what other people think about it.

I think this question is more similar to this one: http://codegolf.stackexchange.com/questions/16826/lets-simulate-a-random-snowflake?rq=1 just for the randomness factor, and that one was well received.

@BrunoJ You're right, the community is getting tougher about closing art-based challenges. Some of my first answers (at the beginning of this year) were to questions similar to this one. I may mention it on Meta.

I, for one, would like to see some entries for this challenge, and am disappointed that it was put on hold.

@BrunoJ, the question you reference a) is less broad than this one (although it could still be improved considerably); b) was posted in the middle of a peak of activity which was characterised by a lot of poor questions and the absence due to holiday of some regulars. To get only 10 upvotes right then was not to be well received, and many questions which should have been closed managed not to be.

I like this challenge. Answers that aren't in the spirit of it won't get upvoted as much, so what's the problem?

Special libraries for drawing trees/forests are disallowed Why would those even exist?

@cjfaure For different purposes, for example for generating models and images for games.

"The question is about generating art, and the answers will likely compete by output, not by code" - this is a crazy argument. Its the code that generates the output. A question that asks for code that produces numbers is not considered to be too much of a maths challenge.

There are already answers to this question, and they clearly required programming - both effort and skill. Personally I would like to see questions with more restrictions to stimulate creative ways around them - this is broader than my personal preference. However, this question does have a number of restrictions and is not sufficiently broad to justify closing it.

The dithering is optional, is it not?

@LarsEbert Dithering is not mentioned in question at all (except example) so you may not use it.

http://algorithmicbotany.org/TreeSketch/

I assume that "you may not use it" means you are not required to use dithering. I can't see how there can be a ban on dithering as it can be implemented algorithmically from an algorithmically generated image, which meets the requirements of the question.

@githubphagocyte I meant only 2 colors - black and white. You are confusing with grayscale.

@githubphagocyte If you didn't see I already have mentioned that in rules.

Yes, I saw that from the start, but since it is common for people to read "black and white" as meaning the same thing as "greyscale" I'm just suggesting you could avoid confusion by changing "only 2 colors - black and white" to "only 2 colors - black and white (not greyscale)". Your wording is already perfectly clear, but since there are already people mistaking the meaning, it is worth adding the extra clarification to avoid arguments later and having to delete answers that clutter up your question. I like this question and don't want to see it fill up with off topic answers.

I also think making that clear might help avoid the close votes since some of the close voters also may not have realised that this isn't just a grayscale question.

C: 3863 1144 1023 999 942 927
The original solution saves 2 pnm files per run (one with g appended, before dithering). Because the dithering wasn't beautiful for the first few lines, there is a hack in place to render more lines than needed, and crop during output.
The golfed solution has a simpler dithering and saves only the dithered image.
(no warnings with gcc -std=c11 -pedantic -Wall -Wextra)
Example images from 3 original program runs and one run of the golfed version (last image):

Golfed version
  #include <math.h>
  #include <time.h>
  #include <stdlib.h>
  #include <stdio.h>
  #define D float
  #define R rand()/RAND_MAX
  #define Z(a,b,c) if(10.*R>a)T(h,s,j+b+c*R,g);
  #define U a[y][x]
  #define V e[y+1][x
  #define F(x) for(i=0;i<x;++i)
  int i,x,y,W=800,H=600;unsigned char a[600][800],c;D e[601][802],r,b,k,l,m,n,f,w,
  d,q=.01;void T(D h,D s,D j,D g){r=b=0;do{j+=.04*R-.02;h+=sin(j)*q;s+=cos(j)*q;b
  +=q;g+=q;f=525/d;r=.25-g/44;m=w*f+s*f+W/2;n=2*f-h*f+H/2;f*=r;for(y=n-f-2;y<n+f+2
  ;++y)if(y>=0&&y<H)for(x=m-f-2;x<m+f+2;++x)if(x>=0&&x<W)if(k=m-x,l=n-y,f>sqrt(k*k
  +l*l))if(U>d*3)U=d*3;}while(b<10*r+12*r*R&&r>q);if(r>q){Z(2,.26,.35)Z(2,-.26,-
  .35)Z(7,-.05,.1)}}int main(){FILE* o=fopen("i","wb");srand(time(0));F(W*H){y=i/W
  ;a[y][i%W]=(y<313)?255:6e3/(2*y-H);}F(200)w=1e2*R-60,d=80.*R+5,T(0,0,1.58,0);F(W
  *H){x=i%W;y=i/W;k=U+e[y][x+1];U=-(k>0);l=(k-U)*.1;e[y][x+2]+=l*4;V]+=l*2;V+1]+=l
  *3;V+2]+=l;}fprintf(o,"P5 800 600 255 ");fwrite(a,1,W*H,o);}

Original version
  #include <math.h>
  #include <stdio.h>
  #include <stdlib.h>

  #define W 800
  #define H 600
  #define SPEED 0.01
  #define HEIGHT 11.0

  #define R(m) ((double)(m) * rand() / RAND_MAX)
  #define RAD(deg) ((deg) / 180.0 * M_PI)
  #define LIMIT(x, min, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x))

  void shade(void);
  void growTree(double dist, double side, double h, double s, double alpha, double grown);
  void plot(double dist, double side, double h, double s, double alpha, double diam);
  void dither(void);
  void writeImg(int dither);

  unsigned char img[H+10][W];
  double err[H+10+2][W+4];
  long tim;

  int main(void)
  {
     int i;
     tim = time(0);
     srand(tim);
     shade();
     for(i = 0; i < 200; ++i)
     {
        growTree(5 + R(75), -60 + R(120), 0.0, 0.0, RAD(90), 0.0);
     }
     writeImg(0);
     dither();
     writeImg(1);
  }

  void shade(void)
  {
     int y;
     for(y = -10; y < H; ++y)
     {
        double dist = H * 3.5 / (2 * y - H);
        unsigned char color = dist / 80 * 255;
        if(y <= H / 2 || dist > 80) color = 255;
        memset(img[y+10], color, W);
     }
  }

  void growTree(double dist, double side, double h, double s, double alpha, double grown)
  {
     double diam, branchLength = 0.0;

     do
     {
        alpha += R(RAD(3)) - RAD(1.5);
        h += sin(alpha) * SPEED;
        s += cos(alpha) * SPEED;
        branchLength += SPEED;
        grown += SPEED;
        diam = (1.0 - grown / HEIGHT) * 0.5;
        plot(dist, side, h, s, alpha, diam);
     } while(branchLength < 5 * diam + R(6 * diam) && diam > 0.02);

     if(diam > 0.02)
     {
        int br = 0;

        if(R(10) > 2) br++,growTree(dist, side, h, s, alpha + RAD(15) + R(RAD(20)), grown);
        if(R(10) > 2) br++,growTree(dist, side, h, s, alpha - RAD(15) - R(RAD(20)), grown);
        if(R(10) < 2 || br == 0) growTree(dist, side, h, s, alpha - RAD(2.5) + R(RAD(5)), grown);
     }
  }

  void plot(double dist, double side, double h, double s, double alpha, double diam)
  {
     int x, y;
     double scale = H / 4.0 * 3.5 / dist;
     double x0 = side * scale + s * scale + W / 2.0;
     double y0 = H / 2.0 + 2.0 * scale - h * scale;
     diam *= scale;
     h *= scale;
     s *= scale;
     for(y = y0 - diam / 2 - 2; y < y0 + diam / 2 + 2; ++y)
     {
        if(y < -10 || y >= H) continue;
        for(x = x0 - diam / 2 - 2; x < x0 + diam / 2 + 2; ++x)
        {
           double dx, dy, d;
           if(x < 0 || x >= W) continue;
           dx = x0 - x;
           dy = y0 - y;
           d = diam / 2 - sqrt(dx * dx + dy * dy) + 0.5;
           if(d > 0)
           {
              unsigned char color = dist / 80 * 255;
              if(img[y+10][x] > color) img[y+10][x] = color;
           }
        }
     }
  }

  void dither(void)
  {
     int x0, x, y;
     for(y = -10; y < H; ++y)
     {
        for(x0 = 0; x0 < W; ++x0)
        {
           double error, oldpixel;
           unsigned char newpixel;
           if(y%2) x = W - 1 - x0;
           else x = x0;
           oldpixel = img[y+10][x] + err[y+10][x+2];
           newpixel = oldpixel > 127 ? 255 : 0;
           img[y+10][x] = newpixel;
           error = oldpixel - newpixel;
           err[y+10  ][x+1+2*(1-y%2)] += error * 7 / 48;
           err[y+10  ][x+4*(1-y%2)] += error * 5 / 48;
           err[y+10+1][x  ] += error * 3 / 48;
           err[y+10+1][x+1] += error * 5 / 48;
           err[y+10+1][x+2] += error * 7 / 48;
           err[y+10+1][x+3] += error * 5 / 48;
           err[y+10+1][x+4] += error * 3 / 48;
           err[y+10+2][x  ] += error * 1 / 48;
           err[y+10+2][x+1] += error * 3 / 48;
           err[y+10+2][x+2] += error * 5 / 48;
           err[y+10+2][x+3] += error * 3 / 48;
           err[y+10+2][x+4] += error * 1 / 48;
        }
     }
  }

  void writeImg(int dither)
  {
     FILE* fp;
     char buffer[32];
     sprintf(buffer, "%ld%s.pnm", tim, dither ? "" : "g");
     fp = fopen(buffer, "wb");
     fprintf(fp, "P5\n%d %d\n255\n", W, H);
     fwrite(&img[10][0], 1, W * H, fp);
     fclose(fp);
  }

+1. Nice pics. Anyway, this is popularity-contest, not code-golf. So, no need to golf. :)

I like this very much, this uses algorithm which I thought will give best results.

Looks good, I had a similar idea but was too lazy=) I think you could try to randomize the recursion depth of the branches, I think that would even look more natural.

I know I don't NEED to golf it, but that's the most fun part for me!

This is gorgeous.

Great job!  The undithered versions look even better!

Also, I put an undithered version into sepia tone -- gorgeous!  See here: http://i.imgur.com/lCrJCp7.jpg

If you were looking to golf it a bit more, you could get rid of the return 0; at the end of main and the int before main().

@syb0rg I could also remove most includes and switch FILE* to int. But as it is now it compiles without warnings.

Ahh.  Well, removing the return 0; shouldn't give you a warning.  Also, I don't see you using your FILE* anywhere besides in main(), so you could declare o when it is first used.  Also, couldn't you use write() and open() to save a few characters?  Lastly, you could get rid of your headers and still have no warnings, see this answer of mine.

@syb0rg -ansi -pedantic -Wall -Wextra. GCC will warn for all those things. Implicit declaration. Main doesn't return int. Non void function doesn't  return something. Etc. Moving FILE* o down will save something, thank you :)

@ManuelKasten -ansi is the same as -std=c89, you should be using at least -std=c99 (or go the extra mile and use the latest standard, C11).  Then you will be able to utilize items declared in the more recent standards, specifically C99 & C11 §5.1.2.2(3).

Looking at the if statements in your code, I learned about the comma operator in C. Thanks!

Java Jungle
(954 golfed)
Full of deep, twisting undergrowth, this is a forest not easily traversed.

It's basically a fractal random walk with slowly shrinking, twisty vines. I draw 75 of them, gradually changing from white in the back to black up front. Then I dither the whole thing, shamelessly adapting Averroes' code here for that.
Golfed: (Just because others decided to)
import java.awt.*;import java.awt.image.*;import java.util.*;class P{static Random rand=new Random();public static void main(String[]a){float c=255;int i,j;Random rand=new Random();final BufferedImage m=new BufferedImage(800,600,BufferedImage.TYPE_INT_RGB);Graphics g=m.getGraphics();for(i=0;i++<75;g.setColor(new Color((int)c,(int)c,(int)c)),b(g,rand.nextInt(800),599,25+(rand.nextInt(21-10)),rand.nextInt(7)-3),c-=3.4);for(i=0;i<800;i++)for(j=0;j<600;j++)if(((m.getRGB(i,j)>>>16)&0xFF)/255d<rand.nextFloat()*.7+.05)m.setRGB(i,j,0);else m.setRGB(i,j,0xFFFFFF);new Frame(){public void paint(Graphics g){setSize(800,600);g.drawImage(m,0,0,null);}}.show();}static void b(Graphics g,float x,float y,float s,float a){if(s>1){g.fillOval((int)(x-s/2),(int)(y-s/2),(int)s,(int)s);s-=0.1;float n,t,u;for(int i=0,c=rand.nextInt(50)<1?2:1;i++<c;n=a+rand.nextFloat()-0.5f,n=n<-15?-15:n>15?15:n,t=x+s/2*(float)Math.cos(n),u=y-s/2*(float)Math.sin(n),b(g,t,u,s,n));}}}

Sane original code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;

public class Paint {

    static int minSize = 1;
    static int startSize = 25;
    static double shrink = 0.1;
    static int branch = 50;
    static int treeCount = 75;

    static Random rand = new Random();
    static BufferedImage img;

    public static void main(String[] args) {
        img = new BufferedImage(800,600,BufferedImage.TYPE_INT_ARGB);
        forest(img);
        dither(img);
        new JFrame() {
            public void paint(Graphics g) {
                setSize(800,600);
                g.drawImage(img,0,0,null);
            }
        }.show();
    }

    static void forest(BufferedImage img){
        Graphics g = img.getGraphics();
        for(int i=0;i<treeCount;i++){
            int c = 255-(int)((double)i/treeCount*256);
            g.setColor(new Color(c,c,c));
            tree(g,rand.nextInt(800), 599, startSize+(rand.nextInt(21-10)), rand.nextInt(7)-3);
        }
    }

    static void tree(Graphics g, double x, double y, double scale, double angle){
        if(scale < minSize)
            return;
        g.fillOval((int)(x-scale/2), (int)(y-scale/2), (int)scale, (int)scale);
        scale -= shrink;
        int count = rand.nextInt(branch)==0?2:1;
        for(int i=0;i<count;i++){
            double newAngle = angle + rand.nextDouble()-0.5;
            if(newAngle < -15) newAngle = -15;
            if(newAngle > 15) newAngle = 15;
            double nx = x + (scale/2)*Math.cos(newAngle);
            double ny = y - (scale/2)*Math.sin(newAngle);
            tree(g, nx, ny, scale, newAngle);
        }
    }

    static void dither(BufferedImage img) {
        for (int i=0;i<800;i++)
            for (int j=0;j<600;j++) {
                double lum = ((img.getRGB(i, j) >>> 16) & 0xFF) / 255d;
                if (lum <= threshold[rand.nextInt(threshold.length)]-0.2)
                    img.setRGB(i, j, 0xFF000000);
                else
                    img.setRGB(i, j, 0xFFFFFFFF);
            }
    }

    static double[] threshold = { 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31,
            0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42,
            0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53,
            0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64,
            0.65, 0.66, 0.67, 0.68, 0.69 };

}

One more? Okay! This one has the dithering tuned down a bit, so the blacks in front are much flatter.

Unfortunately, the dither doesn't show the fine details of the vine layers. Here's a greyscale version, just for comparison:

Nice. Glad my code was helpful ;)

I read nowhere in the rules that dithering is required. I think the undithered version looks more beautiful.

@Lars dithering is not needed, BUT: only black and white may be used, no gray values allowed....

Javascript + HTML - not golfed
A javascript porting of the algorithm of @Manuel Kansten - it's amazing how good these trees look.
Just to do something different, I draw the image in color, then dither to b/w at the last step.
I don't know why, but my forest is less dark and less frightening respect to Manuel's.
Test with JSfiddle or run the new Snippet below. That's NOT fast. Be patient and watch the forest grow.

W=800
H=600
canvas.width = W;
canvas.height = H;

var ctx = canvas.getContext("2d");

R=function(m) { return m * Math.random()};
RAD=function(deg) { return deg / 180 * Math.PI};
LIMIT=function(x, min, max) {return x < min ? min : x > max ? max : x};
var SPEED = 0.01, HEIGHT = 11.0;

// Ground
var grd = ctx.createLinearGradient(0,0,0,H);
grd.addColorStop(0,"#88ccff");
grd.addColorStop(0.45,"#ffffee");
grd.addColorStop(0.5,"#80cc80");
grd.addColorStop(1,"#001100");
ctx.fillStyle = grd;
ctx.fillRect(0,0, W,H);

Plot = function(dist, side, h, s, alpha, diam)
{
    var x, y, a1,a2,scale = H/4 * 3.5 / dist,
        x0 = side * scale + s * scale + W/2,
        y0 = H/2 + 2.5*scale - h*scale;

    k = dist
    if (diam > 0.05) {
        red = k*3|0;
        green = k|0;
        a1=alpha+1
        a2=alpha-1
    }
    else
    {
        green= 80+(1-diam)*k*2|0;
        red = k|0;
        a1=0;
        a2=2*Math.PI;
    }
    diam *= scale;
    h *= scale;
    s *= scale;
    ctx.beginPath();
    ctx.arc(x0,y0,diam/2, a1,a2);//lpha-1, alpha+1);//0,2*Math.PI);
    ctx.fillStyle = 'rgb('+red+','+green+',0)';
    ctx.fill();
}

Grow = function(dist, side, h, s, alpha, grown)
{
    var diam, branchLength = 0.0;
    diam = (1.0 - grown / HEIGHT) * 0.5;
    do
    {
        alpha += R(RAD(3)) - RAD(1.5);
        h += Math.sin(alpha) * SPEED;
        s += Math.cos(alpha) * SPEED;
        branchLength += SPEED;
        grown += SPEED;
        diam = (1.0 - grown / HEIGHT) * 0.5;
        Plot(dist, side, h, s, alpha, diam);
    } while(branchLength < 5 * diam + R(6 * diam) && diam > 0.02);

    if (diam > 0.02)
    {
        var br = 0;

        if(R(10) > 2) br++,Grow(dist, side, h, s, alpha + RAD(15) + R(RAD(20)), grown);
        if(R(10) > 2) br++,Grow(dist, side, h, s, alpha - RAD(15) - R(RAD(20)), grown);
        if(R(10) < 2 || br == 0) Grow(dist, side, h, s, alpha - RAD(2.5) + R(RAD(5)), grown);
    }
}

trees=[]
for(i = 0; i < 300; ++i) trees.push({ z: 1+R(70), s:R(120)-60 });
trees.sort( function (a,b) { return a.z - b.z} );

Draw = function()
{
    t = trees.pop();
    if (t)
    {
        Grow(t.z, t.s, 0, 0, RAD(90), 0);
        setTimeout(Draw, 100);
    }
    else
    {
        var e,c,d,p,i,l, img = ctx.getImageData(0,0,W,H);
        l = img.data.length;
        for (i = 0; i < l-W*4-4; i+=4)
        {
            c = (img.data[i]+img.data[i+1])/2|0
            c = img.data[i]
            d = c > 120 + R(16) ? 255 : 0
            e = c - d;
            img.data[i]=img.data[i+1]=img.data[i+2]=d
            c = (img.data[i+4]+img.data[i+5])/2|0

            c = LIMIT(c + ((e*7)>>4),0,255)
            img.data[i+4]=img.data[i+5]=img.data[i+6]=c
            p = i+W*4
            c = (img.data[p-4]+img.data[p-3])/2|0
            c = LIMIT(c + ((e*3)>>4),0,255)
            img.data[p-4]=img.data[p-3]=img.data[p-2]=c
            c = (img.data[p]+img.data[p+1])/2|0
            c = LIMIT(c+ ((e*5)>>4),0,255)
            img.data[p]=img.data[p+1]=img.data[p+2]=c
            c = (img.data[p+4]+img.data[p+5]*2)/3|0
            c = LIMIT(c + (e>>4),0,255)
            img.data[p+4]=img.data[p+5]=img.data[p+6]=c

        }
        bwcanvas.width = W;
        bwcanvas.height = H;
        var bwx = bwcanvas.getContext("2d");
        bwx.putImageData(img,0,0);
    }
}

setTimeout(Draw, 10);
<canvas id='bwcanvas'  width="2" height="2"></canvas>
<canvas id='canvas'  width="2" height="2"></canvas>

It's the ground, I think. Manuel's trees blend into the ground, creating a hazy, murky appearance. Your ground plane is lighter, giving a more airy appearance with higher contrast. Also, the solid-color sky and the distance fade in Manuel's pictures help create the appearance of an obscuring fog or haze. (Mind you, I rather like the different look your pictures have.)

Yup, this is an orchard to Manuel's deep woods.

Context Free Art 3 (1133)
CF is a vector graphics rendering language, so I cannot avoid anti-alising. I worked that around by drawing square at the same place several (variable N) times. Fog is done by drawing small squares on random places.
startshape main

W = 80*0.6
H = 60*0.6

N = 3

CF::Background = [ b -1 ]
CF::Size = [ x 0 y -20 s W H ]
CF::Color = 0
CF::ColorDepth = 16
CF::MinimumSize = 0.6

shape main {
  transform [ z 0 y (H/2) b 1 ]
  loop 30 [ z -1 y -2 ] {
    loop 200000 []
      SQUARE1 [ s (0.1/3) x -W..W y -H..H z -0.5..0.5 ]
  }

  transform [ b -1 z 3 ]
  loop 14 [[ s 1.1 y -0.8..-1 s 0.6 z -3 ]] {
    loop 14 [] tree [ x (-30..-20) z (-3..3) ]
    loop 14 [] tree [ x (20..30) z (-3..3) ]
  }
}

shape tree {
  branch [ ]
}

shape branch
rule 7 {
  transform [ s (1..2) 1]
  SQUARE1 [ ]

  branch [ y (0.2..0.3) x (-0.05..0.05) s 0.994 r (-6..6) z (-0.3..0.3)  ]
  branch1 [ b 0.001 z -2 r -20..20 ]
}
rule 0.001 { }
rule 0.3 { branch [ r 4..20 ] }
rule 0.3 { branch [ r -4..-20 ] }

shape branch1
rule 90 { }
rule { branch [ r -22..22 s 0.8..1 ] }

path SQUARE1 {
  MOVETO( 0.5,  0.5)
  LINETO(-0.5,  0.5)
  LINETO(-0.5, -0.5)
  LINETO( 0.5, -0.5)
  CLOSEPOLY()
  loop N [] FILL()[]
}

shape S {
  SQUARE [ a -1 ]
  loop 1000 [ ] SQUARE [ x (-0.5..0.5) y (-0.5..0.5) s 0.01..0.001 ]
}

More renders using different numbers

I get that there's no dithering option, but the output should still be black/white only.

Can't you find a way to dither? As it is, it's not valid answer.

You don't have to dither, but you do have to use only 2 colours - black and white. Use of greyscale does not match the rules. The question has been edited to remove the ambiguity. I'd recommend using some method to achieve this, whether dithering or not, so that you can edit your answer before too many more downvotes arrive.

Just as a suggestion in case it helps: You can use your current approach of transparent rectangles to achieve the black and white image, just instead of partial transparency, use full transparency in a grid pattern of some sort, so that only every other grid cell is transparent.

Vector graphic rendering has anti-alising, but I can find a way to bypass it by drawing single-pixel rectangles and stacking same shapes 10 times. I'm going to try that later.

This is now much closer to being in the spirit of the question.

IFS with JAVA
This solution uses an Iterated Function System (IFS) to describe one (proto) tree. The IFS is applied 100 times (=forest).
Before each tree is painted (planted into the forest) the IFS is altered slightly in place (random walk style). So each tree looks slightly different.
Pictures are from random seeds:

-824737443
-1220897877
-644492215
1133984583

No dithering is needed.
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.*;

public class IFS {
    static Random random=new Random();
    static int BLACK = 0xff000000;
    static int treeCount = 100;
    static Random rand = new Random();
    static int Height = 600;
    static int Width = 800;
    static BufferedImage img = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_ARGB);

    static double[][] ifs=new double[][] {//Tree 3 {; Paul Bourke  http://ecademy.agnesscott.edu/~lriddle/ifskit/gallery/bourke/bourke.ifs
       {0.050000,  0.000000,  0.000000,  0.600000,  0.000000,  0.000000,  0.028000},
       {0.050000,  0.000000,  0.000000, -0.500000,  0.000000,  1.000000,  0.023256},
       {0.459627, -0.321394,  0.385673,  0.383022,  0.000000,  0.600000,  0.279070},
       {0.469846, -0.153909,  0.171010,  0.422862,  0.000000,  1.100000,  0.209302},
       {0.433013,  0.275000, -0.250000,  0.476314,  0.000000,  1.000000,  0.555814 /*Paul Bourke has: 0.255814*/},
       {0.421325,  0.257115, -0.353533,  0.306418,  0.000000,  0.700000,  0.304651 /*Paul Bourke has: 0.204651*/},
    };

    public static void main(String[] args) {
        int seed=random.nextInt();
        //seed=-1220897877;
        random=new Random(seed);
        for (int t = 0; t < treeCount; t++) {
            for (int i = 0; i < ifs.length; i++) {
                for (int j = 0; j < ifs[0].length; j++) {
                    ifs[i][j]=R(ifs[i][j]);
                }
            }
            tree(random.nextDouble(), 0.1*random.nextDouble());
        }
        JFrame frame = new JFrame(""+seed) {
            public void paint(Graphics g) {
                setSize(800,600);
                g.drawImage(img,0,0,null);
            }
        };
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static void tree(double x0, double dist) {
        double y0=Math.atan(dist+0.01);
        double scale=Math.atan(0.01)/y0;
        double x=0;
        double y=0;
        for (int n = 0; n < 200000/Math.pow(20*dist+1, 8); n++) {
            int k = select(ifs);
            double newx=ifs[k][0]*x + ifs[k][1]*y + ifs[k][2];
            double newy=ifs[k][3]*x + ifs[k][4]*y + ifs[k][5];
            x=newx;
            y=newy;
            newx= Width*(0.5*scale*newx+x0);
            newy= Height*((1-0.5*scale*newy)-y0-0.1);
            if (0<=newx && newx<Width && 0<=newy && newy<Height) {
                img.setRGB((int)newx, (int)newy, BLACK);
            }
        }
    }

    private static double R(double x) {
        return (1+ 0.01*random.nextGaussian())*x;
    }

    private static int select(double[][] ifs) {
        int k;
        double sum=0;
        for(k=0; k<ifs.length; k++) {
            sum+=ifs[k][6];
        }
        double r=sum*random.nextDouble();
        sum=ifs[0][6];
        for(k=0; k<ifs.length-1 && r>sum; k++) {
            sum+=ifs[k+1][6];
        }
        return k;
    }
}

Last images look best. However I think you should try fewer trees, because now there is always black unrecognizable area, but on edges it looks better.

"Beauty is in the eye of the beholder." I tested a lot of variations. At the end, I came up with treeCount=100. Everybody else is welcome to copy and change my solution.

C: 301
This program creates a simple, abstract image in the PGM format. You can open it with GIMP.
int x,y,i,d,w;srand(time(NULL));unsigned char p[480000];FILE *f=fopen("a.pgm","w");fprintf(f,"P5\n800 600\n1\n");i=480000;while(i--)p[i]=i>240000|(i%800+i/800&3)!=0;i=100;while(i--){d=(11000-i*i)/99;y=300+1100/d;x=rand()%800;while(y--){w=300/d;while(w--)p[y*800+w+x]=0;}}fwrite(p, 1, 480000, f);fclose(f);

Here is an example run:

This looks more like a barcode than a forest :)

bartree forest upside down

When scrolling down I thought my browser failed to render the image correctly. I'd give you a ton of bonus points if your bartrees scanned with a barcode scanner yield the URL to this challange. Except that it wouldn't be a random forest.

I scanned it and my barcode scanner cursed at me. thank you.

@nwp You could grab a random code from a UPC database, though. Scannable yet random :)

I noticed a distinct lack of conifers here, so I hacked something together in Python.
from PIL import Image
import random

#Generates the seed for a tree
def makeSeed(y):
    random.seed()
    seed_x = random.randint(10, 590)
    seed_y = y
    width = random.randint(5, 10)
    height = random.randint(width*5, width*30)

    return (seed_x, seed_y, width, height)

#Grows the vertical components
def growStems(seed_data, pixel_field):
    seed_x = seed_data[0]
    seed_y = seed_data[1]
    width = seed_data[2]
    height = seed_data[3]
    for x in range(seed_x, seed_x+width):
        for y in range(seed_y-height, seed_y):
            pixel_field[x][y] = (0, 0, 0)
            #Dithering
            if seed_y > 300 and seed_y < 320:
                if (x+y)%2==0:
                    pixel_field[x][y] = (255, 255, 255)
            elif seed_y >= 320 and seed_y < 340:
                if (x+y)%4==0:
                    pixel_field[x][y] = (255, 255, 255)
            elif seed_y >= 340 and seed_y < 360:
                if (x+y)%8==0:
                    pixel_field[x][y] = (255, 255, 255)

    return pixel_field

#Grows the horizontal components
def growBranches(seed_data, pixel_field):
    seed_x = seed_data[0]
    seed_y = seed_data[1]
    width = seed_data[2]
    height = seed_data[3]
    branch_height = seed_y-height
    branch_width = width
    branch_length = 2
    max_prev = branch_length
    branches = []
    while(branch_height >= seed_y-height and branch_height < seed_y-(3*width) and branch_length < height/3):
        branches.append((branch_height, branch_width, branch_length))
        branch_height+= 4
        branch_length+=2
        #Gives the conifer unevenness to make it look more organic
        if random.randint(0,110) > 100 and branch_length > max_prev:
            max_prev = branch_length
            branch_length -= branch_length/4
    max_length = height/3

    for x in range(seed_x-max_length, seed_x+max_length):
        for y in range(seed_y-height, seed_y):
            for branch in branches:
                bh = branch[0]
                bw = branch[1]
                bl = branch[2]
                #Establishing whether a point is "in" a branch
                if x >= seed_x-bl+(width/2) and x <= seed_x+bl+(width/2):
                    if x > 1 and x < 599:
                        if y >= bh-(bw/2) and y <= bh+(bw/2):
                            if y < 400 and y > 0:
                                pixel_field[x][y] = (0, 0, 0)
                                #Dithering
                                if seed_y > 300 and seed_y < 320:
                                    if (x+y)%2==0:
                                        pixel_field[x][y] = (255, 255, 255)
                                elif seed_y >= 320 and seed_y < 340:
                                    if (x+y)%4==0:
                                        pixel_field[x][y] = (255, 255, 255)
                                elif seed_y >= 340 and seed_y < 360:
                                    if (x+y)%8==0:
                                        pixel_field[x][y] = (255, 255, 255)

    return pixel_field

def growTrees(n):
    pixel_field = [[(255, 255, 255) for y in range(400)] for x in range(600)]
    #Create the ground
    for i in range(600):
        for j in range(400):
            if pixel_field[i][j]==(255,255,255) and j > 300:
                if (i+j)%2 == 0:
                    pixel_field[i][j]=(0,0,0)
    seed_ys=[]
    #Generates seeds for the trees and orders them back to front to make the dithering work
    for t in range(n):
        seed_ys.append(random.randint(300,390))
    seed_ys.sort()

    for s in range(len(seed_ys)):
        seed= makeSeed(seed_ys[s])
        pixel_field = growStems(seed, pixel_field)
        pixel_field = growBranches(seed, pixel_field)
    return pixel_field

def makeForest():
    forest = growTrees(25)
    img = Image.new( 'RGB', (600,400), "white") # create a new black image
    pixels = img.load() # create the pixel map
    for i in range(img.size[0]):    # for every pixel:
        for j in range(img.size[1]):
            if pixels[i,j]==(255,255,255) and j > 300:
                if (i+j)%2 == 0:
                    pixels[i,j]=(0,0,0)
            pixels[i,j] = forest[i][j] # set the colour accordingly

    img.save("Forest25.jpg")

if __name__ == '__main__':
    makeForest()

This was my first Code Golf, it was a lot of fun!

Looks good! I like it.

When I scroll by this, the trees actually appear green :)

This answer isn't as pretty as I hoped, but it's a stepping stone to a more 3D idea I'm working on, and I really like the idea of actually simulating which trees get resources
package forest;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Forest extends Canvas{
    private int[] heights = new int[800];
    private BufferedImage buffered_image;
    File outputFile = new File("saved.png");
    Random r = new Random();
    public Forest() {
        buffered_image = new BufferedImage(800, 600,
                BufferedImage.TYPE_INT_RGB);
        for( int j = 0; j < 800; j++){
            heights[j] = -10000;
            for(int k = 0; k < 600; k++){
                buffered_image.setRGB(j, k, 0xFFFFFF);
            }
        }
        for(int i = 0; i < 7; i ++){
            heights[r.nextInt(800)] = 0;
        }

        this.setPreferredSize(new Dimension(800, 600));
        this.setSize(new Dimension(800, 600));
        for( int i = 0; i < 200000; i++){
            int x = r.nextInt(798) + 1;
            heights[x] =  Math.min(599, heights[x - 1] == heights[x + 1] ? heights[x] : Math.max(Math.max(heights[x - 1], heights[x]),heights[x + 1]) + 1);
            buffered_image.setRGB(x, Math.min(599, 600 - heights[x]), 0);
        }

        try {

            ImageIO.write(buffered_image, "png", outputFile);
        } catch (IOException e) {

        }
        update();
    }
    public void repaint(){
        if(this.getGraphics() != null)
        paint(this.getGraphics());
    }

    public void paint(Graphics g) {
        g.drawImage(buffered_image, 0, 0, this);
    }

    public void update() {
        repaint();
    }

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

        JPanel top_panel = new JPanel();
        top_panel.setLayout(new BorderLayout());
        Forest s = new Forest();
        top_panel.add(s, BorderLayout.CENTER);
        main_frame.setContentPane(top_panel);

        main_frame.pack();
        main_frame.setVisible(true);
    }

}

Maybe flip it vertically to make it similar to fir-trees?

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


text:
Make me an alphabet tree
Intro
In most fonts all of the uppercase alphabet characters besides BDO have single lines approximately touching some of the four corners of the character's bounding rectangle: ACEFGHIJKLMNPQRSTUVWXYZ.
For example, the two legs of an A "touch" the bottom left and bottom right corners of the character. Likewise, C touches its top and bottom right corners (it is a bit curved but it's close enough). L only touches it's top left and bottom right corners with single lines. The bottom left corner of L is a vertex, not the end of a single line.
Here is a table of what characters touch which corners according to the Stack Exchange font I (and hopefully you) see. 1 is for upper left, 2 is for upper right, 3 lower left, 4 lower right.
A: 3 4
C: 2 4
E: 2 4
F: 2 3
G: 2
H: 1 2 3 4
I: 1 2 3 4
J: 1 3
K: 1 2 3 4
L: 1 4
M: 3 4
N: 2 3
P: 3
Q: 4
R: 3 4
S: 2 3
T: 1 2
U: 1 2
V: 1 2
W: 1 2
X: 1 2 3 4
Y: 1 2
Z: 1 4

Setup
Pretend like these corner touching lines extend in the direction of the corner that they touch so that arrangements of these characters on a grid can be "connected".
For example, all the characters in
 A
C X

are connected because the bottom left of A and top right of C connect, and the bottom right of A and top left of X connect.
However,
CAX

has no connections because connections only occur diagonally from one character to the next.
Challenge
Write the shortest program possible (in bytes) that outputs all of the characters in ACEFGHIJKLMNPQRSTUVWXYZ in one big fully connected tree, according to the rules above. Each character must appear exactly once. Use spaces for empty space.
Example
Everything in this 23-letter tree can be reached from anything else via the diagonal connections defined above:
  Q
 A J   R
C U   S Y
 I M N
E H X
 F L T
G   Z K P
     V W

Notes

You may hardcode your solution.
Your output should only contain ACEFGHIJKLMNPQRSTUVWXYZ, spaces, and newlines. BDO will not be used.
Leading/trailing spaces are fine as long as all the connections are properly positioned.
The output grid should not be larger than 30 by 30 characters (including newlines and spaces).
Only corner connections are considered. The bottom of Y does not connect to anything. You must use the corner connections from the table above.
Not all connectable corners need to connect to something. Connectable and non-connectable corners may border each other.
Output to stdout. There is no input.
Including a connectivity graph made with slashes as Peter Taylor has done is a helpful touch but not required.

Update:
githubhagocyte has made an alphabet tree validity checker over on Github.

You may hardcode your solution?

@edc65 You may hardcode your solution.

Funny how those 2 phrases only have 1 different character :P

Wny not accept a graph as an output? That way, the connections are prominent.

@githubphagocyte I don't see why not.

@githubphagocyte, that would be better as an addendum to the question than as an answer, given that it's not an answer.

@githubphagocyte You could give me a link to the code and I'll edit it in with credit to you.

@githubphagocyte, if it's short, edit it in. If it's not, put it somewhere like gist.github.com and edit in a link.

B and D should both touch top and bottom left hand side shouldn't they? They look like it on my screen

@TomTanner Only the endpoints of single lines count, not vertices.

Nice golf, @Calvin'sHobbies. This one's a lot of fun to see the answers for.

xkcd 1442 makes me wonder if Randall Munroe reads your questions as inspiration.

Pyth, 32
jd"QAPMFRLZ\nUINKSHXJ\n\0GTCVEWY

Output:
Q A P M F R L Z
 U I N K S H X J
  G T C V E W Y

Connections, thanks to @githubphagocyte's checker:
Q   A   P   M   F   R   L   Z
 \ / \ /   / \ /   / \   \   \
  U   I   N   K   S   H   X   J
     / \ /   / \ /   / \ / \ /
    G   T   C   V   E   W   Y

Combines @grc's null byte trick and Pyth's extremely short syntax. Made my own grid for the hell of it.
Explanation:
j is python's string join. d is space. \0 is the escape sequence for the null byte. It is a NOP when printed, so the third line has exactly two spaces in front. Also, note that strings can be EOL-terminated in Pyth, as well as quote-terminated.

Python, 49
print' '.join('  MQRCNAF\n XZHLKSIP\n\0GJWVUYET')

Example:
>>> print' '.join('  MQRCNAF\n XZHLKSIP\n\0GJWVUYET')
    M Q R C N A F
   X Z H L K S I P
  G J W V U Y E T

I think it connects up properly now, but I may have missed something again.

F4 looks connected to G1, which is invalid

@Timmy But F2 is connected to A3. It all looks connected to me.

@Calvin'sHobbies I think I misunderstood the requirements. Is it allowed to have adjacent corners that aren't connected?

@Timmy Sure. Those pairs of corners just don't count as connected, but the two letters may be connected in another way.

GolfScript (41 chars)
'QZENRPMALHIFKSXJTUVWYGC'8/{' '*n' '+:n}/

Online demo
Connectivity graph:
Q   Z   E   N   R   P   M   A
 \   \   \ /   / \ /   / \ / \
  L   H   I   F   K   S   X   J
   \ / \ / \ /   / \ /   /   /
    T   U   V   W   Y   G   C

Marbelous 164 158 143
used bmarks' tree since it almost perfectly optimized for Marbelous.
Code in this case is just the ascci codes for all characters (including spaces and newlines) from left to right, delimited by spaces.
43 20 46 20 50 20 4D 20 51 20 52 20 45 20 41 14 20 58 20 48 20 4e 20 4C 20 4B 20 5A 20 49 20 53 14 47 20 59 20 56 20 20 20 55 20 4A 20 54 20 57

Output:
 C F P M Q R E A
  X H N L K Z I S
 G Y V   U J T W

A better Marbelous approach 135 129
This one outputs the same tree with one extra space before and after each line, it works by feeding the literals into a subroutine that prints a space before printing the literal. And just printing a space if the literal is a space (20 HEX)
57
54
4A
55
20
56
59
47
14
53
49
5A
4B
4C
4E
48
58
20
14
41
45
52
51
4D
50
46
43
Sp
Sp:
20 I0
.. =V

This answer will get down to 96 when spaces between cells are no longer required for Marbelous source code, which will be the case later today.

Using languages or language features which postdate the question is considered cheating.

@PeterTaylor For now this answer only uses features that were implemented when the question was asked.

BrainF*ck 669
Made this one for giggles. Outputs the exact same as the example.
Will provide another solution later.
Can't think of a clever way to do this in Lua so I'll just stick to this one :)
++++[->++++++++<]>..[-->+++++<]>+.>++++++++++.[->+++<]>++.[->++<]>+.-[-->+<]>.+++++[->++<]>.--[->++++<]>...>-[--->+<]>---.>++++++++++.+[->++++++<]>+.-[-->+<]>-.>-[--->+<]>.[----->++<]>--...>-[--->+<]>--.+[--->+<]>++++.--[->+++<]>-.[->+++<]>-.[->+++<]>++.++++[->++<]>+.-[->++++<]>.++++++[->++<]>+.-----[->++++<]>.[-->+++++<]>--.>++++++++++.[->+++++++<]>-.-[-->+<]>--.++++[->++<]>.[->++++<]>.[++++>---<]>.>++++++++++.[->+++<]>++.+++[->++<]>.[-->+<]>---.++++++[->++<]>.[-->+<]>------.>-[--->+<]>-.>++++++++++.[->+++++++<]>+.+[->++++<]>...--[->+++<]>.[--->+<]>++.--[-->+++++<]>.---[->++++<]>.[-->+++++<]>.>++++++++++.[->+++<]>++.....>+[--->++<]>.+[--->+<]>+++.---[->+++<]>.

Output
  Q
 A J   R
C U   S Y
 I M N
E H X
 F L T
G   Z K P
     V W

No matter how crazy the codegolf challenge, there's almost always a brainfuck answer. Gotta love it +1

@AndoDaan Nope it wouldn't. I didn't use that though. I made my own brainf*ck like I always do. I did use that a lot and learned most of the tricks I always use when writing BF so I wouldn't be surprised if it looks simular.

Not simular, identical. Both 669 bytes in length. Both using the same character by character method(no optimization at all), and also both identical with where all the plussy, miney and other thingy symbols go.

Must be a coincidence then. I participate for the fun of the challenge and I don't see the fun of generating a BF. The only way that even could be fun a little bit is when you wrote the generator yourself.

PHP 46
This was more like puzzle solving rather than programming, so my answer is more like puzzle solution rather than code. However it's a valid PHP program, so I'm submitting it.
C A Q S R P M J
 X Z I F K N H
G T U V W Y E L

Update the same in Perl. Length still remains 46:
print"CAQSRPMJ
 XZIFKNH
GTUVWYEL"=~s/\S/$& /rg

HTML, 55
code
<pre>C F P M Q R E A
 X H N L K Z I S
G Y V   U J T W

output:
C F P M Q R E A
 X H N L K Z I S
G Y V   U J T W

Bash+coreutils, 46
sed 's/\S/ &/g'<<<"CAQSRPMJ
 XZIFKNH
GTUVWYEL"

Now shamelessly borrowing @core1024 optimal tree:
Output:
$ ./alphatree.sh
 C A Q S R P M J
  X Z I F K N H
 G T U V W Y E L
$

STATA 63
Edit: now my own solution. Should be all the letters.
di 'C F P M Q R E A' di ' X H N L K Z I S' di 'G Y V   U J T W'

 C F P M Q R E A
  X H N L K Z I S
 G Y V   U J T W

Javascript 83
I'll begin with hardcoding YOUR solution
console.log('  Q\n A J   R\nC U   S Y\n I M N\nE H X\n F L T\nG   Z K P\n     V W')

make it shorter with alert instead of console.log

@MarkGabriel I'd like to make it shorter in some smarter way. Alert has not the right font to display ascii art.

I see. Forgot about alert's formatting being different. :)

PHP, 69
<?php echo preg_replace("/(\w)/",'\1 ',"CAQSRPMJ
 XZIFKNH
GTUVWYEL");

gives
C A Q S R P M J
 X Z I F K N H
G T U V W Y E L

You have no diagonal connections at all in your output

@MartinBüttner - thank you, it cost me a byte to fix.

The problem with this (and many other) response is that the output is shorter than the code (see core1024 php)

You can shave two bytes by replacing your regex with "/\w/",'\0 '

Vyxal, 28 bytes
«⟑Eƈ↓Z↔⁺τ¾ꜝdB_ḣC«3/ƛṄ¥$꘍&›⇧,

Try it Online!
Yes, I stole @isaacg's grid.
«...«            # Compressed string 'qapmfrlzuinkshxjgtcvewy ' (Note trailing space)
     3/          # Into 3 pieces
       ƛ         # Map...
        Ṅ        # Join by spaces
         ¥$꘍     # Prepend (register) spaces
            &›   # Increment register
              ⇧, # Output as uppercase.

source: Stack Exchange

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

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

sort: votes


text:
Congratulations on getting 10,000 reputation!
After @MartinBüttner achieved exactly 10,000 reputation, we now have three full rows of 10k users on the users page! Now, since we're all programmers here, we like to automate things instead of doing them manually. Your challenge is to write a program to automatically congratulate new 10k users.
Specification
Input
The input will be n lines of space-separated numbers. (If you would like, you may also take a single comma-separated list of space-separated numbers, if that makes your code shorter.) For example:
10 20 30 40 50
15 25 35 45 55
20 30 40 50 60

Or:
10 20 30 40 50,15 25 35 45 55,20 30 40 50 60

Each list of numbers represents a list of users' reputation values on a single day.
Output
The output will be the same amount of n lines (or a comma-separated list of the same length). Each line / list item will be:

:D if there was a user whose reputation just became >= 10,000.

Multiple space-separated :Ds if there were multiple users who met or passed the 10,000 rep count. For example, :D :D :D for 3 new 10k users.

:( and then halt further output if the input is ambiguous or impossible (more on this in the next section).
nothing if neither of these conditions is true.

Ambiguity
It is possible that the input is ambiguous. For the purposes of this challenge, we assume that:

The reputation cap is 200 per day, ignoring accepts and bounties and the like for the sake of the challenge.
Users may not lose reputation (again for simplicity and for the challenge).

Input is considered ambiguous when it is impossible to determine which reputation values correspond to which user. For example, in the input 10 20,30 40, you can't tell whether the 10-rep user became the 30-rep user or the 40-rep user.
Input is considered impossible when the users from one day could not possibly have become the users from the next day. For example, in the input 10 20,310 320, this situation is clearly impossible because the users could not have gained 300 reputation in a day. Users losing reputation is also impossible.
Edge cases

The initial reputation values can start at anything (i.e. a user can start with 1337 reputation).
There is no output for the first line / list item.
The input will always be syntactically valid, meaning that the reputation values will always be positive integers, there will always be the same amount of reputation values per line / list item, etc.
The reputation values are not sorted; they may be in any order.

Test cases
Input: 9900,10000
Output: :D
Input: 9900 9950 9910,10100 9950 9910,10300 10150 10110
Output: :D,:D :D
Input: 10 20 30,42 10 20,10 242 20,442 42 10,0 0 0,442 42 10
Output: ,,,:(
Input: 10 20,15 25,15 25
Output: ,,
Input: 9999 9998 9997,10000 9998 9997,10000 10000 9997,10300 10000 10000
Output: :D,:D,:(
Input: 100,90,80,70
Output: :(
Input: 10000 10000 10000 9999,10000 10000 10000 10000,10010 10020 10030 10040
Output: :D,:(
Input: 9999 9998 9997 9996,10196 10197 10198 10199,10399 10199 10197 10196
Output: :D :D :D :D,

@MartinBüttner Ah, didn't notice that. Fixed

The first step in that example is also ambiguous.

Whereas example 4 is not ambiguous.

(i.e. a user can start with 1337 reputation). I liked this coz that was my rep... wel 5 min ago until someone upvoted one of my answers xD

Example 5, step 2 is also ambiguous (which 10k user is which?). Same goes for example 7 (unless you add some rule that discerning equal-rep users is irrelevant, but then how do you know which user was which on day one, if he tied with someone else later on?)

Are users always in the same order? in the chapter Ambiguity you seem to say they wont. Doenst that mean that example 2 is also ambiguous?

@TeunPronk Answer to that first question seems to be no. Example 2 isn't ambiguous because the user with 9910 rep can't gain 240 to be the 10150 user. They can gain 200 to be the 10110 user instead.

@fuandon it's the first step that's ambiguous.

@MartinBüttner How? I don't see it. All I see is the user with 9900 gaining 200 rep to get to 10100. The reputation values aren't sorted?

@fuandon e.g., the first user gets 10 rep, the second user gets 150 rep, the third user gets 40 rep. I think there are 4 valid combinations in total.

@MartinBüttner Oh, woah, I see it now. A lot more inputs are ambiguous than I initially expected...

Ruby, 209 bytes
Edit: I switched to Ruby which shortened this by about 30%. See the edit history for the original Mathematica version. I suppose the main savings come from Ruby's permutation not ignoring switched positions of identical elements (which I had to trick Mathematica into).
This uses the newline-separated format.
gets.split('
').map{|s|s.split.map &:to_i}.each_cons(2){|a,b|a.permutation.map{|q|q.zip(b).map{|x,y|y-x}}.reject{|d|d.any?{|x|x<0||x>200}}.size!=1?abort(':('):(puts':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))}

The gist is this:

Get all consecutive pairs of days.
Get all permutations of the former day, and subtract each of these from the current day.
Ditch all results which contain differences that are negative or greater 200.
If the number of remaining permutations isn't 1, output :(.
Otherwise, output as many :D as there are new 10k users.
At the end, drop all days after the first :(.

Less golf:
gets.split("\n").map{|s|
  s.split.map &:to_i
}.each_cons(2){|a,b|
  a.permutation.map{|q|
    q.zip(b).map{|x,y|
      y-x
    }
  }.reject{|d|
    d.any?{|x|
      x<0||x>200
    }
  }.size!=1 ? abort(':(') : (puts ':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))
}

I think that's one beautiful chain of enumerators. :)
PS: Is it weird that I was the first one to submit an answer to this?

I don't think it's weird. Something tells me you have the home field advantage ;)

So this will fail some of the examples in the question, right?

@Cruncher It will fail those which I think are wrong according to the spec (as I have mentioned in the comments). If Doorknob decides to change the spec instead of fixing the examples, I guess I'll have to rework this.

@MartinBüttner That's what I figured. Just confirming :)

Haskell, 254 249 244 232 228
import Data.List
t=m(9999<)
p(a:b:r)=(a,b,r)%(filter(all(`elem`[0..200]))$nub$m(zipWith(-)b)$permutations a)
p _=""
(a,b,r)%(_:[])=(concat$m(const":D ")$t b\\t a)++'\n':p(b:r)
_%_=":("
m=map
main=interact$p.m(m read.words).lines

A little explanation: The algorithm is very similar to that used by MartinBüttner, except the nub that I spent some thought on.  Note that a list difference is used for working out how many more reputation values are 10000 or larger on day n+1 compared to day n: t b\\t a.
I also agree with MartinBüttner on the interpretation of the specs and that some of the examples above are wrong, even to the point that example #2 is wrong (should be :().

Shouldn't you alias map?

That's right (saving 2 bytes), but another 10 bytes can be saved by making z infix and replacing replicate (length l) x with map (const x) l.  Isn't Haskell fantastic?

it sure is. Nice golfing! On that note, Because function application has the highest precedence, you should be able to shorten (t b)\\(t a) to t b\\t a, golfing out 4 more bytes.

It would be nice if there was some code to find these places where code can be shortened automatically... Seems a bit big of a project though.

You're right @proudhaskeller, those paretheses were unncessary.  Thanks.

I stared at your solution a bit more and saw you should be able to switch the pattern match on the fifth row to [x]. Also sometime i saw someone write import List. I have no idea why it worked. Or maybe it doesn't. I didn't check.

authors: ซ๋ะบั๋น ยู๋โซ๊ะ


text:
The distance between circles
Imagine you are given two lists of numbers which are to be interpreted as points on a circle of circumference 1000.  Let us say
circleA = [10, 24, 44, 175, 321, 579, 618, 841, 871, 979]
circleB = [270, 283, 389, 406, 435, 457, 612, 684, 692, 732]

To measure the distance between these two circles we do the following.
For the first point in circleA, starting from the left, we find the next biggest point in circleB.  So 10 finds 270 and is matched up with it.  Now, using 270, we skip to the next biggest point in circle A which is 321.  We then use 321 to find 389 and match up 321 and 389 and repeat until the end of circleA or we can't find a matching pair.
This gives us a list of pairs as follows.
[(10,270), (321, 389), (579,612), (618,684)]

We say the distance between circleA and circleB is just the average difference between pairs. That is (270-10 + 389-321+612-579+684-618)/4 = 106.75
Now comes the tricky part. As the point are on a circle, we can rotate circleB and recompute this distance.  The task is to compute the following value.

For arbitrary inputs circleA and circleB, the task is to compute the
  average distance between circleA and all rotations of circleB.

In order to make it interesting I am setting this as fastest-code challenge. I will test with increasing size circles created using (in python)
import random
circumference = 1024
numberpoints = circumference/64
circleA = sorted(random.sample(range(circumference),numberpoints))
circleB = sorted(random.sample(range(circumference),numberpoints))

I will just double the size of circumference until the code takes more than 1 minute to run on my computer.  You output should be accurate to machine precision.
Please provide full instructions for how to compile and run your code on a linux machine.

A rotation simply means adding an offset modulo circumference and then resorting.  In python
rotatedcircleB = sorted([(c+offset)%circumference for c in circleB])

You should add an example of what rotation does. Increment all points modulo 1000 and then resort?

Is rotation continuous or discrete?

@PeterTaylor I meant it to be continuous.  If this causes a problem then I will rethink of course.

@JanDvorak Yes you are right. I updated the question.

@QuadrExAtt The difference can't be negative. Note that in my example 979 just isn't paired up with anything.

This algorithm is basically the same as @fredtantini's. The main difference is I keep a rolling sum instead of creating a list to hold the differences. I also forgo the list slicing as it is an O(k) operation.
from __future__ import division
from bisect import bisect_left
import timeit

def circular_distance(circle_a, circle_b):
    total = 0
    count = 0
    value_on_a = circle_a[0]
    value_on_b = 0
    while 1:
        try:
            insertion_point = bisect_left(circle_b, value_on_a)
            value_on_b = circle_b[insertion_point]

            total += value_on_b - value_on_a
            count += 1

            value_on_a = circle_a[bisect_left(circle_a, value_on_b+1)]
        except IndexError:
            break
    return total/count

def rotate(circle, offset, circumference=1024):
    return sorted((point + offset) % circumference for point in circle)

def get_average_distance(circle_a, circle_b, circumference=1024):
    total = 0
    for iteration_num in xrange(circumference):
        total += circular_distance(circle_a, rotate(circle_b, iteration_num))
    return total/circumference

These changes resulted in about a 64% improvement for 10,000 iterations on my machine:
                     +------------------+-------------------------+
                     | List and slicing | Rolling sum and average |
+--------------------+------------------+-------------------------+
| Per Iteration (ms) |  0.0128661600274 |    0.00821646809725     |
+--------------------+------------------+-------------------------+
|          Total (s) |    128.661600274 |       82.1646809725     |
+--------------------+------------------+-------------------------+

My first try at a fatest-code question. Problem is, I didn't try any optimization…
If the rotation part isn't correct, please tell me.
Also, I don't know how to time test the code, so I tried to use timeit module to run 1000 times in order to have a correct timing. I am not sure if I have to do that, or if it is your part :þ
Anyway, here is my code:
import random
circumference = 1024
numberpoints = circumference/64
circleA = sorted(random.sample(range(circumference),numberpoints))
circleB = sorted(random.sample(range(circumference),numberpoints))

####
from  bisect import bisect_left

def find_next(a, x):
    i = bisect_left(a, x)
    if i != len(a):
        return i, a[i]
    raise ValueError

def dist1(cA, cB):
    l = []
    p = cA[0]
    cA = cA[1:]
    while True:
        try:
            (i, n) = find_next(cB, p)
            l.append(n-p)
            cB = cB[(i+1):]
            (i, p) = find_next(cA, n)
            cA = cA[(i+1):]
        except:
            break
    return (sum(l)/len(l))

def rotate(circleB,i):
    return sorted([(c+i)%circumference for c in circleB])

def distAll(circleA, circleB):
    l = [dist1(circleA, rotate(circleB,i)) for i in xrange(circumference)]
    return sum(l)/circumference

if __name__ == '__main__':
    import timeit
    print(timeit.timeit("distAll(circleA,circleB)", setup="from __main__ import *", number=1000))

C
The first argument is a filename which the program expects to read for input. The first line of the file contains the circumference and the number of points each of circle a and circle b. Then the values for circle a follow, one per line; then the values of circle b, one per line.
The time spent reading the input is a huge portion of the overall running time, but I wasn't sure how to get so much input into the program without resorting to file I/O. If anyone has a better solution to that (or any suggestions in general) please feel free to chime in.
Compile it with -O3 for extra speed!
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

static inline void rotateB(int_fast32_t* const, int_fast32_t, int_fast32_t, int_fast32_t);

static inline void getDistances(const int_fast32_t* const, const int_fast32_t* const, int_fast32_t, int_fast32_t, int_fast32_t* const, int_fast32_t* const);

static inline int comparePoints(const void*, const void*);

static inline int_fast32_t getNextIndex(const int_fast32_t* const, int_fast32_t, int_fast32_t, int_fast32_t);

int main(int argc, char* argv[]) {
    int_fast32_t counter;

    int_fast32_t *circleA;
    int_fast32_t *circleB;

    int_fast32_t CIRCUMFERENCE;
    int_fast32_t lengthOfA;
    int_fast32_t lengthOfB;

    FILE *fp = fopen(argv[1], "r");
    fscanf(fp, "%d %d %d\n", &CIRCUMFERENCE, &lengthOfA, &lengthOfB);

    circleA = malloc(sizeof(int_fast32_t)*lengthOfA);
    circleB = malloc(sizeof(int_fast32_t)*lengthOfB);

    for(counter = 0; counter < lengthOfA; counter++)
        fscanf(fp, "%d\n", &(circleA[counter]));
    for(counter = 0; counter < lengthOfB; counter++)
        fscanf(fp, "%d\n", &(circleB[counter]));

    fclose(fp);

    int_fast32_t totalDistance = 0;
    int_fast32_t numberOfPairs = 0;

    for(counter = 0; counter < CIRCUMFERENCE; counter++) {
        rotateB(circleB, counter, lengthOfB, CIRCUMFERENCE);
        getDistances(circleA, circleB, lengthOfA, lengthOfB, &totalDistance, &numberOfPairs);
    }

    printf("%f\n", ((double)totalDistance)/((double)numberOfPairs));

    free(circleA);
    free(circleB);

    return 0;
}

static inline void rotateB(int_fast32_t* const circleB, int_fast32_t offset, int_fast32_t length, int_fast32_t CIRCUMFERENCE) {
    int_fast32_t counter;
    for(counter = 0; counter < length; counter++)
        circleB[counter] = (circleB[counter] + offset) % CIRCUMFERENCE;
    qsort(circleB, length, sizeof(int_fast32_t), comparePoints);
}

static inline int comparePoints(const void* a, const void* b) {
    return (*((int_fast32_t*)a)) - (*((int_fast32_t*)b));
}

static inline void getDistances(const int_fast32_t* const circleA, const int_fast32_t* const circleB, int_fast32_t lengthOfA, int_fast32_t lengthOfB, int_fast32_t* const totalDistance, int_fast32_t* const numberOfPairs) {
    int_fast32_t currentAIndex = 0;
    int_fast32_t currentBIndex = getNextIndex(circleB, circleA[currentAIndex], 0, lengthOfB);
    while((currentAIndex < lengthOfA) && (currentBIndex < lengthOfB)) {
        *totalDistance += circleB[currentBIndex] - circleA[currentAIndex];
        *numberOfPairs += 1;
        currentAIndex = getNextIndex(circleA, circleB[currentBIndex], currentAIndex, lengthOfA);
        currentBIndex = getNextIndex(circleB, circleA[currentAIndex], currentBIndex, lengthOfB);
    }
}

static inline int_fast32_t getNextIndex(const int_fast32_t* const targetCircle, int_fast32_t otherValue, int_fast32_t currentIndex, int_fast32_t length) {
    int_fast32_t lowerBound = currentIndex;
    int_fast32_t upperBound = length-1;
    int_fast32_t guess;
    if(targetCircle[upperBound] <= otherValue)
        return length;
    while(1) {
        if(upperBound - lowerBound < 4) {
            while(targetCircle[lowerBound] <= otherValue)
                lowerBound++;
            return lowerBound;
        }
        guess = (lowerBound + upperBound) >> 1;
        if(targetCircle[guess] > otherValue)
            upperBound = guess;
        else
            lowerBound = guess;
    }
    return lowerBound;
}


text:
Golf String's format() inverse
Invert the Format method.
The Format method of the String class (or equivallent, such as sprintf) is available in most languages. It basically takes a "Format" string which may contain placeholders with some extra formatting, and zero or more values to be inserted instead of those placeholders.
Your task is to implement the inverse function in your language of choice.
API
Method name should be either format1 or deformat.
Input: 1st parameter will be the "Format" string, just like in the original format method. 2nd parameter will be the parsed string (see examples below). No other parameters are needed nor allowed.
Output: an array (or your language-of-choice's equivalent) of values that were extracted correspondingly with the placeholders in the format.
The placeholders are {0}, {1}, {2}, etc.
In case of bad format you may throw an error, or return whatever you like.
In case of invalid input, you may throw an error, or return whatever you like. Invalid input is such that cannot be generated by String.Format using same format string, for example: '{0}{0}', 'AAB'.
Examples
deformat('{0} {1}', 'hello world') => ['hello', 'world']
deformat('http{0}://', 'https://') => ['s']
deformat('http{0}://', 'http://') => [''] // array of one item which is an empty string
deformat('{0}{1}{0}', 'ABBA') => ['A', 'BB']

Ambiguity
In case of ambiguity you may return any suitable answer. For example:
deformat('{0} {1}', 'Edsger W. Dijkstra')
// both ['Edsger', 'W. Dijkstra'] and ['Edsger W.', 'Dijkstra'] are applicable.

Some More Rules

To make it easier, there's no need to actually support formatting. You can forget all about leading zeros, decimal point or rounding issues. Just generate the values as strings.
To make it non-trivial, Regular Expressions are not allowed.
You don't need to take care of curly braces in input (i.e. 2nd input parameter will not contain any {s or }s).

Winning
This is code-golf! (should be read as "This is Sparta!") the correct function having shortest length wins. Standard loopholes are forbidden.

In the example deformat('{0}{1}{0}', 'ABBA') => ['A', 'BB'], what if we were instead given deformat('{0}{1}{0}', 'AAAA')?

@xnor - than we have an ambiguity, and each of the following would be a valid output: ['', 'AAAA'], ['A', 'AA'], ['AA', '']

Could one have then outputted deformat('{0}{1}{0}', 'ABBA') => ['', 'ABBA']? If so, there's a cheap solution unless every string appears at least twice.

will your cheap solution also work for deformat('{0}_{1}_{0}', 'A_BB_A')?

Oh, I see, I had forgotten about actual characters in the results. I'm still trying to wrap my head around how algorithmically hard this is. Let me see if I can make up a really perverse instance.

What do you think about deformat('{0}{0}{0}{0}{0}{0}{1}{1}{1}{1}{1}{1}{1}{1}{1}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}')='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') (that's 6 zeroes, 9 ones, 20 twos, and 44 a's)?

This is a most as hard as matching regexes with positive backreferences. That doesn't say much, though.

At first glance I thoght you were kidding. But I see your point: it sums up to 43 while the as count is 44 - so there's no way to solve it. I will add an assumption to the question that no invalid inputs will be given. An invalid input is such that cannot be generated by the original String.Format with the given format string.

@Jacob my algorithm can handle that (by throwing an exception) just fine. Without too much backtracking, even.

Okay, maybe that huge example above is not an invalid input, but such inputs exist. Will your algorithm be able to solve deformat('{0}{0}', 'AAB')...? I belive it's an invalid input.

@Jacob There is no solution to that, indeed. Exception: Prelude.(!!): index too large means that it tried to access the first out of no solutions

@xnor That case is actually solvable: the solution is ['a', 'aa', 'a']. (6 + 18 + 20 = 44)

@Jacob That case is in fact solvable, see my other comment.

Alright. Thank you all. I will add relevant assumptions.

@AJMansfield I understand the 44 a's example is solvable, I just want to illustrate that there are instances that seems to take exponential time, at least with a naive algorithm. Can the solutions posted handle a huge instance of this form with many placeholders? Would succeeding at this be required for an answer?

Traditionally, in Code Golf we don't care about performance. You don't have to bother yourself testing such inputs. It should work however if one waits long enough...

Haskell, 220 characters
import Data.Map;f""""=[empty]
f('{':b)d=[insert k m b|(k,('}':a))<-lex b,(m,c)<-[splitAt n d|n<-[0..length d]],b<-f a c,notMember k b||b!k==m]
f(x:b)(y:d)|x==y=f b d;f _ _=[];format1 x y=elems$mapKeys((0+).read)$f x y!!0

Breaks if you use multiple representations for the same pattern ({1} vs {01}) - doesn't enforce their equality, discarding matches for all but one representation instead.
19 characters can be saved by omiting mapKeys((0+).read)$ if proper ordering of matches above 10 patterns doesn't matter, or if padding to the same length may be required, or if string ordering of patterns is acceptable. In any case, if a pattern is omitted from the first argument, it is omitted from the result as well.
Removing !!0 from the end makes format1 return the list of all solutions, rather than just the first one.
before golfing:
import Data.Map
import Control.Monad

cuts :: [a] -> [([a],[a])]
cuts a=[splitAt n a | n <- [0..length a]]

f :: String -> String -> [Map String String]
-- empty format + empty parsed = one interpretation with no binding
f "" "" = [empty]
-- template-start format + some matched = branch search
f ('{':xs) ys = do
    let [(key, '}':xr)] = lex xs
    (match, yr) <- cuts ys
    b <- f xr yr
    guard $ notMember key b || b!key == match
    return $ insert key match b
-- non-empty format + matching parsed = exact match
f (x:xs) (y:ys) | x == y = f xs ys
-- anything else = no interpretation
f _ _ = []

deformat :: String -> String -> [String]
deformat x y = elems $ mapKeys ((0+).read) $ head $ f x y

whi is there (0+)? isn't just writing read shorter?

@proudhaskeller just a read leaves you with an ambiguous type. Haskell doesn't know what orderable type to read the keys as. +0 forces a number, from which Haskell is already able to make an arbitrary choice and goes for integers.

Ruby, 312 characters
class String
def-@
self[0,1].tap{self[0,1]=''}end
end
def format1 f,s,r=[]
loop{if'{'==c=-f
n,f=f.split('}',2)
[*1..s.length,0].each{|i|next if'{'!=f[0]&&s[i]!=f[0]
if u=format1((g=f.gsub("{#{n}}",q=s[0,i])).dup,s[i..-1],r.dup)
r,s,f=u,s[i..-1],g
r[n.to_i]=q
break
end}else
c!=-s&&return
end
""==c&&break}
r
end

5 characters could be saved by preferring zero-length matches, making the ABBA solution ['', 'ABBA'], rather than the question's preferred solution. I chose to interpret the examples as an implied part of the specification.

Python, 208 chars, albeit incomplete.
def format1(i,o):
 i+=" ";o+=" ";x=y=0;s=[]
 while x<len(i):
  if i[x]=="{":
   try:y+=len(s[int(i[x+1])])
   except:
    s+=[""]
    while o[y]!=i[x+3]:s[int(i[x+1])]+=o[y];y+=1
   x+=3
  x+=1;y+=1
 return s

The function sweeps both strings simultaneously, until it finds a opening brace in the input string, signifying a placeholder.
Then, it assumes the placeholder has already been expanded, and tries to advance the index of the output string past it by looking in the list of values found so far.
If it hasn't been expanded, it adds a new entry to the list of values, and starts adding in characters from the output string until it reaches the character after the placeholder in the input string.
When it gets to the end of the input string, it returns the values found so far.

It works well for simple inputs, but it has a number of issues:

It requires a known delimiter after each placeholder in the input, so it doesn't work with placeholders right next to each other i.e. "{0}{1}". This is why I needed to append a space char to both strings.
It assumes the first instances of each placeholder are in order e.g. "{0}{1}{1}{0}{2}".
It only works for the first 10 placeholders as it assumes they are all 3 chars long.
It doesn't handle ambiguous cases at all :(

C++11 code, 386 characters
#include <string>
#include <map>
using namespace std;using _=map<int,string>;using X=const char;_ format1(X*p,X*s,_ k=_()){_ r;while(*p!='{'){if(!*p||!*s){return*p==*s?k:r;}if(*p++!=*s++)return r;}int v=0;while(*++p!='}'){v=v*10+(*p-48);}p++;if(k.find(v)!=k.end()){return format1((k[v]+p).c_str(),s,k);}while((r=format1(p,s,k)).empty()){k[v]+=*s++;if(!*s){return*p==*s?k:r;}}return r;}

The format1 function have 2 strings as input
    (const char*)
and returns an hashmap with keys integer (the pattern) and value is the identified string. If nothing is found or any error, an empty hashmap is returned.
Usage:
for (auto v : format1("{1} {2}", "one two")){
    cout << v.first << "=" << v.second << endl;
}

Output:
1=one
2=two

Example 2:
auto v = format1("{1} {2}", "one two");
cout << v[1] << " and " << v[2] << endl;

Output:
one and two

The patterns are in decimal representation, inputs bigger than MAXINT will overflow but it still works.
Even though there are smaller solutions in other programming languages, this is the smallest C++ - yet! :)
This is the code before golfing:
#include <string>
#include <map>
using namespace std;

using res = map<int,string>;

res format1(const char* p, const char* s, res k=res()){
    res r; // intermediate result, empty until the end
    // match until first '{'
    while (*p != '{'){
        if (!*p || !*s){
            // exit case
            return ((*p == *s) ? k : r); // == 0
        }
        if (*p++ != *s++)
               return r;
    }

    // *p == '{'
    int v = 0;
    while(*++p != '}'){
        v = v*10 + (*p - '0');
    }
    p++; // advance past '}'

    // match back-references
    if (k.find(v) != k.end()){
       return format1((k[v]+p).c_str(), s, k);
    }

    // recursive search
    while ( (r=format1(p, s, k)).empty() ){
        k[v] += *s++;
        if (!*s){
            return *p == *s ? k : r;
        }
    }
    return r;
}


text:
How many trees in the Alphabet Forest?
Inspired by the connection rules from Calvin's Hobbies' question Make me an alphabet tree take a number of lines of letters as input and output the number of distinct connected trees it represents.
Letters connect to diagonally adjacent letters (never horizontally or vertically) and only where such a connection is available. Available connections correspond to the end of a line in the shape of the letter. For example, X can potentially connect at all four corners as they are all the ends of lines. W can only connect at the top left and top right corners, as the bottom left and bottom right corners are not ends of lines.
Example 1
Input:
XXX
XXX
XXX

Output:
2

The two trees (which do not form part of the output):
X   X             X
 \ /             / \
  X             X   X
 / \             \ /
X   X             X

Example 2
Input:
AMF
QWK

Output:
3

The three trees (which do not form part of the output):
A   F                M
 \ /                  \
  W         Q          K

Rules

The only valid characters are spaces, newlines, and the 23 upper case letters listed in Calvin's Hobbies' question: ACEFGHIJKLMNPQRSTUVWXYZ.
The letters B, D and O are not valid.
The output is undefined if the input contains invalid characters.
A tree can be of any size, including just 1 letter and including over 23 letters.
The same letter can appear an arbitrary number of times in a single tree.
The input will not be more than 79 lines long.
Each line (excluding newlines) will not be more than 79 characters long.
The lines will not necessarily be the same length as each other.
A tree is defined to be a set of connected letters. Since the connections are all diagonal this excludes letters which are horizontally or vertically adjacent from being part of the same tree.
Input containing zero trees (for example, all spaces and newlines) gives output 0.
To clarify, input and output are as defined on meta (so there is not already a variable containing the input).

This is code golf. The shortest correct code wins. Code length is measured in bytes.
If you have python 3.4, the alphabet tree counter outputs the number of connected trees in its input, and can be used to test your golfed code gives the same results. The alphabet tree checker confirms whether its input is a valid output for Calvin's Hobbies' original question, and outputs a list of the distinct trees in the input. This may be useful for visualising the trees if there is any dispute over the number of trees in a given input (although using it on large forests will give a lot of output - a visualisation of every single tree separately).
If the either of these is incorrect please let me know so I can fix it.
Table of connections.
1 is for upper left, 2 is for upper right, 3 lower left, 4 lower right.
A: 3 4
C: 2 4
E: 2 4
F: 2 3
G: 2
H: 1 2 3 4
I: 1 2 3 4
J: 1 3
K: 1 2 3 4
L: 1 4
M: 3 4
N: 2 3
P: 3
Q: 4
R: 3 4
S: 2 3
T: 1 2
U: 1 2
V: 1 2
W: 1 2
X: 1 2 3 4
Y: 1 2
Z: 1 4

Sample forest
Here is an example of a forest to test your code with. It has the maximum size of 79 x 79 and no spaces. The alphabet tree counter gives an output of 714. I don't recommend running the alphabet tree checker on it as it will try to output a separate visualisation of every single one of the 714 trees.
CKZNXXJEHCNHICKFHNAFZTMNXZKXSXAFHEKKFJYUZPCHRSNAUPEZKIHZJSKKPHQJYHKMXSHCXKEHCXQ
YSRCHHQLXXKKXITAAHSKMXISHIGFXMVXTZZKLXIXVHJYKTAHSHYPCFLHSWIHHCXXRXXJNKXXVVRNSKM
CZWJKKNIXXUHKXCKRTXXSVHQZERHXIXNHXPKELNKHXRHFKHIEPKUWKXKUPHEKKIKLLSFWUSLYEEXLSI
KHGURVKSXXKAGXIWKCSHFNVWWHNHNIVYKKAKZKFSKHCVRHUENHFIIKNUNICHYRKYXXHTLKYHPQKWHKI
KGAFRXJMKMJJSXCUTFAKLHHFXTIXKNHKKRHIZHXWRRXJNHXQEMKKXCNVHWFMPERJKKZLHIKIUZRKWLM
YRXXXCXXHVISVIYTHNHKSXKRXYHXUFYYKXTHXRYIIKHEWHXVZAZHTQKJAKKHXKKVCKJHWHIIZXXZZYK
FQLXHIHJFKSKWMTHXISAXTVIKKHTIXUAGUAJHHHHRVHXHRNWKXKUKWHVUJLKIJCWTLCHTXSYTKLTFWX
AEKNFXUXHXHICSNCYWNEVVALHXUSACWKRNJAKLLXKVJCZHSAKYHXLHHTHFKSMCGXHFHPKTHXTRYYWXK
HHHKHXGKFUHKSKHKKHHRHIKYNQSXMKQKIXHTXXHHIXCZIWGXKAHRXKRYXPXXXVSYIXWXVMUFYWHKINZ
XXWWHXUTXGKXFKZUTHHZPJGMAEHZVGHLEXHKKPXHZIVKFETHKXTIVKSMHWYEKHIMIHWEHKHIIJXXJZS
XHHXHRHKKXHHVXYZMNHIYHKKXXKAVWKUKEXYGGCHMLHFJCKXXXHEXGCZUKMHIXKVXKHZHFLCKXIPZHH
TCHAXXKHHNKKMKPRFKKURCWLFXWIXUGTKKXHKRSYKZUXQXIEYWWWKKIXGXHALKAXXJHEXXLMNXJKHHL
INKRHXMMXZSTAZZKGLAPKLHSPGKUINHUMXXXLTNZWENCXLKRIXHZXHHKHCSXSHHXXKCTXXXHSFHJIHI
SHXKTXKXWPYZXKCNYSAVMICKJHKSMXKAWVNHZKGPFYPAEKEWXNKXXHKEYHAYWKIYHKXEHNJJRISLXXI
IHZLMKYUTHWHIXEKRJIHFVHCFKLMSKIKHMUHQLYXILMHKXXXCJHZXJKKHSHXMVCHIGSICHITKIGMYYT
USKJTKLQYXYKKRKELMXVMLKNNNXIHPHMXKNXXYFKRHXRNNJRCQKEFKXXSWHUECTMCWVCXHLALKMSIZM
VCKPXRCSYRVEKTCUHKVIKAXHMNMJMTKMGXEPJXYZVLKQFIIJRZHXHHSSRKHHYRHZXFHXXLUKXCAHNXX
CGHQIQXTHRLIKKQFHQCUKZXLMVLSWHJKGKYKJMKVFIHHKYHCKAFXHMEHKJKMKWIXAYEKYKCXIMKHRXJ
XYIJIIAHHEXKIYGKHKIALIXKRHRXYXRAVHGXTUKKKXHIIGNHXFVVHTFUKHNIKHFKRXHXXNIIXTSQHIH
XSNXRHIUXHTXWYRHXHSXZKKKXIKHEKSHHWINIGEIXNJYSXILYIKHVYAMFNKXYWEINHHXSVFVXQRHUHW
FRIRFCKFKIVHCKYXKXMTXELJXNCKWYHKXVTXIIHFVFZVHYSXEXZNWKWIXESHXFHKCKVPXUXCIMRHNXR
XELHXNMKVHRHHHVKTKKPCXEXZHKPHNAWVXJKWWHMSKFFRUJVSHGXFATZSSWYXKHIHKAHXIEJXSKXFLE
KFKECCCPWKXJTVKXHJRYVXUIFHKUHHHLMKSVJICQHKXZKNIXHKEHKNYTKKFKHUCHZFILHRHKHQKIIEJ
MGIKXXPZQXHRHHXKXJHAGJKHIXKILXNEVWHXWWLTFWHHUMKJPZTJXXTXVPTMHHMGEPHIXRHLGQTWJCV
UKHXXYXHAFXXSIJXHHXKLJQJIIKXIKYHSRKUNNKHTMXTCTKXGWFHSJKQSCHINSKLGSKUTXKKAWAEXAM
LFKXWWXXSKKXPUIKTFREKIXLXNXKHHVXJKVWEFKFMYFIHGHXSHTEUJRIEAMQSXQMRJIHRETXYMHKIUX
XFAAMXHXUFITLAWNMJYHTCWQFNXAIXKSZXIXXKRKAHWHYEAMVHNKLHKVUTAIZLVXGCHHAZTTHCELIGK
XPJRXIVVFTJKQFNSKMKFKIHMRCHWFYVIRVXFPTKIKUKQKKMVKWIYIKRXWEVXUIHFHXASHHXVFWEWHHK
KYELCKHLXXHXHTVMJHNFQUFJXKUHIZXFEXRZMEYZHSJXVZKMYHNCVEXKXKATRFLGHXTHXRPHXLHKSTY
IXUUFXHWMKRIWWIRSKSCQHXSIIKRHXZNFCXXHSLXHRNHZXNWHKMQRPTHTHXXSVKHXZXICYHSXXXKXHU
TXESLHCCEHHHHKHICSILWLHFEKVKSUECLAZHZXIKRUKWKFHXILWNSTMXXAGKWVLQNXESKXYIIXKXZRI
HHSSHXRXKHNUWLKPXLIXFUIHXNKIKJCHTGWXLJZSLHSMZMSZTKLFAVEKIMGXJVAIKXHWUUHKHURIYMG
IXMYFVXIWMZVNVYWKYFVXJKKEHKMNLYXNXFSRHHSANKTKTNVKNTRHPXKLRCMHLHUWKIMGWVFAPZXWXH
RHIKVZWLHJYUKCQSSCNZFRRMXTJXQMRXCZIVPRHJMHVVXHHHLHKNKRKNXLKKREIWSTINKKXFSMPILXK
KSFKKXGIAKXKRWHNHZMVFVFUHIKJWIHUJHHNKKSXMMUVNHEJIYCCWEHHHGJXWJJVXWIPXCKWHSXFYXI
RWVXEHJLHANHXIVHMMQHAHHRKTMHXXXLHPCQRSHTHVXXJSXQZRHKKLSFYXKTKLKXHKHRSXLKKXUJXKJ
TNKIMHEXKVYMVMRKTXIXJHTXYIXKMHXKKWQGFLGIFIKXKTMXSYYMTVQITPWHXHHKXEYKXHHJETJHXVK
KXEWWAHIHVHXAUTCHZLRXKMKHKNKREKKMKHIHPXXZNFHFYIXHJXXWKIKHQWWISXZHJZKHHZXTGIIXJN
YKZHRXXFQKHKXZHVEWSHREHKIYTFSTHLREKHFJIAVWKMKJMXHXKWKWYRTKMHIIXNCVKXRHKKEMYERRL
KREZXUHKRQKFYKWKHEZXKWWXEHXYKLAIKYNVXFRPUNFHVJHKWZXSXKIHKYHKXFHYXXXTXIXIXGIXKHK
ZHIKXXXRCSKVKYVHXKRJHHXWCNEXRQIKAIHHTFHWCSCZCHKXMUMKLVKXPKLIZIYKRKHIKZSHHAKCNKK
ZUHHHWKMNIXRGAVXHCXAQUKXHHEXLIRNNHLHCKRZSXHKMKWTKHKVJEUSKHXEFPHMPKHYKKUMHFLKSIJ
KKKZXHRRNSSKXWIUCXPJUFLJSVXHMRKHXWHYURHXNKCWKIXKKWHXZMRAHHXCKIHKXXTJRHTEHUHTPZK
HAKHLHCEGIXIIVAYWWKXCEXIHKWMKEHILYZEXKHKYVWJVKVYHFTSNIHGHCIJXKNSXXTXHSYEXNFKHSY
KWGUHKCXWGCXKFSIPZXIZKPLHIXXYPKYHHFKYMNTXHIVMNTRYJPUKUKYUMZFTYSIIXVAXINHCMXKTEH
GQYGHKHIKKKIKXYGCHKLAYSXPHHKFSICIKFFHSKHMAWVYKHJKNZZXYISGZMJWRRIJILHHKKHFFKARKH
RIKUACKKMVIGHXKKMHFSXJEKXFMKSHXZXHKMHHXXSXHHLXHHEKKAKMXXECVLHEIKGWACSNKKVKARERJ
CXMVNITXXMKCYUIHUHUXUIKYHNZYHXXLTHJATGKHKTIKKYTWXRJIXCJNHTYXIRLTKAMEHZMKRJXHAWV
HKIMIQKMRSJNHZZYKHWWKSFIRHKHFWKKYFITXWATKKXSECSHKXHPQCNIIIWFMKUHUMXWCXYJHVSVELR
NXUKLFAHVGGHYVTAWNIXHKXHXHXXAKKANKYIFXUTLKKTHHIKHKATJXKXETTWEKNIHQSKIXXJXXYLXXJ
RXPCUSXZLZXVKIRLSVXHHXXKMAIXCXXQVIKIUKIXIXXJHXFRRSXXQREIWHXFKWISXYHVEKHYYXKZLMN
XCHKWYHJRWXRLXLEAXXHKVRKLGUMWSCXINKHMNHHISNKLVKWXRWKEKPCRGZNIXSXTXHEKEEKHXTHJUH
XGVNFTHKHNVGXGSRIPGKFXZTUKEKYKIINRKUHIKLHXRIYXRIKXSCENMZLXXHAXXWTIGJXHHWXHMIFIK
HEVJQXTXKPFSTVKWGKXTKYRXJHVPKKNLQLPSXPIZVNIAKJJRHZHKFXIGRHKVCTVXINNHTGLIHMVYINA
HIQHXXVZAHIHRHIHFTUWFKGKQKTAUXJSIXWHUXNXJIJIIAWUKHRLIHKVSIFSNKKHNTYCTPNWIKHHIKX
MRLCMZXPALCTFXPHVHSVNXTJWFHKQZTZEYMALXXIXRJIKCFJYSPXKZXKUGKZLQHKUYINNUKKKLKMVLI
VQHFXEKRVSHKKKHGWZWTLXRFWMVXHKKXWXKEHAJIXJKHXFNNGHKKLXKKKLJYKJEEHCKXTGHHICISHMF
ZXPUAXPXKXXVYAHPIJHLRCIKXLCGZXLWFJPHXAHFKSLFEHGLKHFIIHHKHHCTVAKWPXWGIQKHNILHQJW
XHPIQLZHKVUKXCMLHSFHEKHEKREWXKYIXSZHTAHIIEUYVUHSMKTHFKMGKSLMHXKYACCXXKATLYXKXFL
WKHIKFVFKUVXXRVEYUTCRNCXPZCCLSKTHWQXXJMHFLKXHNXCVZXHGXYAVYEXVJCHKXIKMSVAXVHNEXV
IXIKYSSJQKKPTXFXFREKXJAKKXEJXNVXHEUJHIMHHPNRVZHXUKZPWTXCCIHXAKZUSHXRMSLIUWHIHKK
MXIHKCKKHSIHXCKCRKATFKFSJXLRXIJNFYQISMKHSAYKZXPXNIHWSKHXYZLAVXIEXVTYHGSRXXAGQRK
IMCXXHXSCXVXCKCTHNSHWEIRAELTJMFKCXQIIXVFSZXHXXIPCCFIZXEXPWHEGJUHWXGZJCISRJSCIPV
HIXHUIHJXXLXXXZLNZCTJKYHNHAVIHIITLHXGEXXKUIXGNKLHHUVFJAFKHHPCJSUKXHCSIHKCXZEIFI
UKUHWRKSJFKZNYJMSZYRTXZKWHVIXLXHRFXTZHTHHHUMYTXKRXMFAKLUMAPNGHKKJUKYIHUXQHMIUVI
XHCKNCKTSXTZMHETTLTMYXHJKUUVXHHSHIVSZKHHWXAWMFXVVHFUCXHMXWKXHXKVLLHXZSICSACKIHC
FXFNPHXHTHCLHKJTSLVTHKHHXHXHHKTKSUTIXKYQUHAQXXNSLKUMTKHSKKYTXHTVPGVHHMXVNLHXIRF
WJFVVXITNRCXKHTFARSIXASVCNXJQNXIJVUHYIVNIRZXMHHFKHKMMNCUXFTEXEKEHTIHSKAKXZVTSKY
ZJGHRTHUWMHHZXHPAIHWHUSXXKLHKYKHJSHHNKXXKRSHMKHSIHIUIXKZXSUZHKXIMMIXMXTXZZLXXIM
EQZKRLALIEVHXYKHXIFYKXMAINSNIASMGLLYHXHRIXVWUKZHFREJCAXKXWYHXNUKTQCUKIHLWKTEKMC
MHLXXHHYQWHTXVHCMKKHGIUFSEHNEVYSXQHHXXKHMXUXQKHZHHHSHRKWHMMEHZMIKKYYWIUNEIJUIKT
NCHKRNSJYLLIXKXAIERXKKXIQZVHXFVIIAXHIYUGZURXFHSXKLIWESKHEXQSCUHWKALZIVEZHAFKKWA
IKCJWNVRKMITKNYXJYKYXVXXUKWHXXJAKLXXXVKXGXKKZXMHCKKCGRLZQINVHRLNVWXTKVLTEPTXUXH
XVCICKXXXEVTIKIHHSHCKYIJXNCJKJSLSHVXJHTHSIKUXPHWRIKMFXXMMHKHCAQWITIEWEXPFHYXXKU
XXSHHIXHWWRKITSHSXHJKEWHXIZHSHZCHFARIXNPHYSNIKJXLQENKFCXYRWMXAPIYTZKNMXFHNIMCCS
PAACXJMNVZZHMXXSNVSXEIINNCHLSTIXHHKYXLEHQHKHPRWIXXHRKVCXFKLHSHKGXJGKLLLWSHIISKT
WUYXTJHXXMKJCYIXQJRNFKYHHUUKTIAYXVUUXFCYLHXWWZAUHWZIUAIGKHKIMKXXXKJZXCKKRCJAKQJ
EVAGXIHTINSXENKWVXWCLFUVHXFPFCIFVHWXRIFZRYZKUUEMXNGAJLIFHJJIGUXFKKRIMKGFKXJYXKV
KKRHHWKIYXWXWKLWXWKFHXLXRXRKKENMHHIQRHTTMFYTGRLSHRXIXKKUEHXXJKRIKSYLTKYJMNIUWVE

GolfScript, 150 characters
I thought a GolfScript implementation is missing in this competition. While it is not a particularly fitting challenge for GolfScript it can be done quite nicely.
n%{.,' '80*>+}%n*:^,,{.80+'AFJMNPRS'\'CEFGNSTUVWY'3$'ACELMQRZ'3$2+'JLTUVWYZ'}%4/{2/.{~'HIKX'+\^[=]&},=},{~@;;]}%.,{:A{A{1$&},{|}/$}%.&}*^'
 '-,\{,-)}/

Note that edc65`s testcase takes only a few seconds but the huge forests may run for several minutes, depending on your computer. Although the algorithm itself is not extremely slow it is only slightly optimised for speed instead of size. It copies huge lists of trees several times which is a costly operation in GolfScript.
I am still trying to find a shorter representation of the encodings for the letters' connections. Also you can save 16 characters if you can guarantee that all lines have the same length.

Ruby - 228
My very first Ruby golf. Still new to Ruby. Ruby is awesome language! Love learning it! =)
But I'm afraid will probably lose. =(
g=$<.each.map{|k|k.ljust 99}*''<<?@*1e5
p (0..1e4).map(&f=->k,a=!0{l=(0..3).map{|i|k+~0**i+99*~0**(i/2)if"xhv8gstx930ognx8puyr".to_i(36)>>(i+4*g[k].ord-260)&1>0};(g[k]=?@;l.map{|v|v&&f[v,k]})if(l&[a]!=[])|!a&l.any?}).count{|x|x}

To run, create a file with the forest as forest.txt
and run using ruby test.rb forest.txt
GoRuby Edition - 188
g=A.e.m{|k|k.lj 99}.j.lj 1e5
p 9999.mp(&f=->k,a=N{l=4.mp{|i|k+~0**i+99*~0**(i/2)if"xhv8gstx930ognx8puyr".toi(36)>>(i+4*g.g(k)-260)&1>0}.cp;(g[k]=?@;l.m{|v|f[v,k]})if(l.i a)|!a&l.an}).cp.sz

Ok... So my fear came true. @Howard (I'd actually expected him) actually made a GS solution.

Why the pessimism? This is the shortest one so far... +1.

I was eating peacefully and checking code golf on my handphone.. and then I saw bounty. I was like.. If there is a time to learn ruby, its now. XD

you're leading now.

It's a race byte by byte

Argh... GolfScript solution is here by @Howard, who can even use it for the most absurd of stuff (e.g. Wang tiles). I guess I shall just show all my cards. Nice race anyways!

JavaScript (E6) 235 238 240 276 284 291 294 319
A function with a string parameter (the forest), returning the tree count. This seems ok with the rules in meta about input/ouput (point 2).
This scans the forest numbering the branches (var u) and keeping a running count of joinined branches (var j now). Branches that have been joined are remembered in a set, so that two joined branches are recognizable even if they have different numbers.
Edit Slightly changed the algorithm, now it manages the forest string as a char array avoiding the split into lines. Simplified the branch joining - slower but shorter. Bonus: at the end the r array can be used as a map to extract any of the n trees from the forest. I'll elaborate.
Probably a little more golfable, but not so much as the answer in Ruby. I'll try.
Edit Ruby and goRuby passed. In the meantime @bitpwner has probably become a Ruby guru and he'll cut away half of his ruby code with his next edit ...
Here is a jsfiddle with less golfed code and the graphical output of tree connections.
C=t=>(r=['\n',...t]).map((e,i)=>
  e<' '?(a=b,p=i-h,b=[]):
   (k=(2&a[h=b.push(n='0x'+'30909a8ff6f53a0213accccfc5'[e.charCodeAt()-65]|0)]|1&a[h-2])&n/4,
   x=r[p-1],y=r[++p],k>2&&x-y?r=r.map(v=>v-x?v:y,++j):0,
   r[i]=k>1?y:k?x:n&&++u),j=u=h=b=0)|u-j

Test
C("AMF\nQWK")

Result: 3
A new testcase
CKZNXXJEHCNHICKFHNAFZTMNXZKXSXAFHEKKFJYU
YSRCHHQLXXKKXITAAHSKMXISHIGFXMVXTZZKLXIX
QZWJKKNIXXUHKXCKRTXXSVHQZERHXIXNHXPKELNW
 HGUR                              KZKF
 GAFR                              RZHX
 EXXXC                            THXRR
  LXHI                            UAJH
  KNFX                            NJAK
  TWWHXUTXGKXFKZUTHHZPJGMAEHZVGHLEXHKY
   XHRHKKXHHVXYZMNHIYHKKXXKAVWKUKEXYG
   AXXKHHNKKMKPRFKKURCWLFXWIXUGTKKXHK
   USHXK                        VNHZI
    LMKY                        MUHQ
    JTKL                        KNXX
    PVCKP                      XEPJA
     QIQX                      KYKJ
     IJIIHEXKIYGKHKIALIXKRHRXYXRAVH
     SXSNXRHIUXHTXWYRHXHSXZKKKXIKHF
      KIVHCKYXKXMTXELJXNCKWYHKXVHF
      HXNM                    WWHM
      GKFKE                  KSVJH
       KXXP                  WHXW
       UKHX                  RKUN
       JLFKX                EFKFK
        XFAAMXHXUFITLAWNMJYHTCWQ
        XPJRXIVVFTJKQFNSKMKFKIHM
        KYELCKHLXXHXHTVMJHNFQUFJ

C("CKZNXXJEHCNHICKFHNAFZTMNXZKXSXAFHEKKFJYU\nYSRCHHQLXXKKXITAAHSKMXISHIGFXMVXTZZKLXIX\nQZWJKKNIXXUHKXCKRTXXSVHQZERHXIXNHXPKELNW\n"
+" HGUR                              KZKF\n GAFR                              RZHX\n EXXXC                            THXRR\n"
+"  LXHI                            UAJH\n  KNFX                            NJAK\n  TWWHXUTXGKXFKZUTHHZPJGMAEHZVGHLEXHKY\n"
+"   XHRHKKXHHVXYZMNHIYHKKXXKAVWKUKEXYG\n   AXXKHHNKKMKPRFKKURCWLFXWIXUGTKKXHK\n   USHXK                        VNHZI\n"
+"    LMKY                        MUHQ\n    JTKL                        KNXX\n    PVCKP                      XEPJA\n"
+"     QIQX                      KYKJ\n     IJIIHEXKIYGKHKIALIXKRHRXYXRAVH\n     SXSNXRHIUXHTXWYRHXHSXZKKKXIKHF\n"
+"      KIVHCKYXKXMTXELJXNCKWYHKXVHF\n      HXNM                    WWHM\n      GKFKE                  KSVJH\n"
+"       KXXP                  WHXW\n       UKHX                  RKUN\n       JLFKX                EFKFK\n"
+"        XFAAMXHXUFITLAWNMJYHTCWQ\n        XPJRXIVVFTJKQFNSKMKFKIHM\n        KYELCKHLXXHXHTVMJHNFQUFJ")

Result: 149
The huge forest
C("CKZNXXJEHCNHICKFHNAFZTMNXZKXSXAFHEKKFJYUZPCHRSNAUPEZKIHZJSKKPHQJYHKMXSHCXKEHCXQ\nYSRCHHQLXXKKXITAAHSKMXISHIGFXMVXTZZKLXIXVHJYKTAHSHYPCFLHSWIHHCXXRXXJNKXXVVRNSKM\n"+
"CZWJKKNIXXUHKXCKRTXXSVHQZERHXIXNHXPKELNKHXRHFKHIEPKUWKXKUPHEKKIKLLSFWUSLYEEXLSI\nKHGURVKSXXKAGXIWKCSHFNVWWHNHNIVYKKAKZKFSKHCVRHUENHFIIKNUNICHYRKYXXHTLKYHPQKWHKI\n"+
"KGAFRXJMKMJJSXCUTFAKLHHFXTIXKNHKKRHIZHXWRRXJNHXQEMKKXCNVHWFMPERJKKZLHIKIUZRKWLM\nYRXXXCXXHVISVIYTHNHKSXKRXYHXUFYYKXTHXRYIIKHEWHXVZAZHTQKJAKKHXKKVCKJHWHIIZXXZZYK\n"+
"FQLXHIHJFKSKWMTHXISAXTVIKKHTIXUAGUAJHHHHRVHXHRNWKXKUKWHVUJLKIJCWTLCHTXSYTKLTFWX\nAEKNFXUXHXHICSNCYWNEVVALHXUSACWKRNJAKLLXKVJCZHSAKYHXLHHTHFKSMCGXHFHPKTHXTRYYWXK\n"+
"HHHKHXGKFUHKSKHKKHHRHIKYNQSXMKQKIXHTXXHHIXCZIWGXKAHRXKRYXPXXXVSYIXWXVMUFYWHKINZ\nXXWWHXUTXGKXFKZUTHHZPJGMAEHZVGHLEXHKKPXHZIVKFETHKXTIVKSMHWYEKHIMIHWEHKHIIJXXJZS\n"+
"XHHXHRHKKXHHVXYZMNHIYHKKXXKAVWKUKEXYGGCHMLHFJCKXXXHEXGCZUKMHIXKVXKHZHFLCKXIPZHH\nTCHAXXKHHNKKMKPRFKKURCWLFXWIXUGTKKXHKRSYKZUXQXIEYWWWKKIXGXHALKAXXJHEXXLMNXJKHHL\n"+
"INKRHXMMXZSTAZZKGLAPKLHSPGKUINHUMXXXLTNZWENCXLKRIXHZXHHKHCSXSHHXXKCTXXXHSFHJIHI\nSHXKTXKXWPYZXKCNYSAVMICKJHKSMXKAWVNHZKGPFYPAEKEWXNKXXHKEYHAYWKIYHKXEHNJJRISLXXI\n"+
"IHZLMKYUTHWHIXEKRJIHFVHCFKLMSKIKHMUHQLYXILMHKXXXCJHZXJKKHSHXMVCHIGSICHITKIGMYYT\nUSKJTKLQYXYKKRKELMXVMLKNNNXIHPHMXKNXXYFKRHXRNNJRCQKEFKXXSWHUECTMCWVCXHLALKMSIZM\n"+
"VCKPXRCSYRVEKTCUHKVIKAXHMNMJMTKMGXEPJXYZVLKQFIIJRZHXHHSSRKHHYRHZXFHXXLUKXCAHNXX\nCGHQIQXTHRLIKKQFHQCUKZXLMVLSWHJKGKYKJMKVFIHHKYHCKAFXHMEHKJKMKWIXAYEKYKCXIMKHRXJ\n"+
"XYIJIIAHHEXKIYGKHKIALIXKRHRXYXRAVHGXTUKKKXHIIGNHXFVVHTFUKHNIKHFKRXHXXNIIXTSQHIH\nXSNXRHIUXHTXWYRHXHSXZKKKXIKHEKSHHWINIGEIXNJYSXILYIKHVYAMFNKXYWEINHHXSVFVXQRHUHW\n"+
"FRIRFCKFKIVHCKYXKXMTXELJXNCKWYHKXVTXIIHFVFZVHYSXEXZNWKWIXESHXFHKCKVPXUXCIMRHNXR\nXELHXNMKVHRHHHVKTKKPCXEXZHKPHNAWVXJKWWHMSKFFRUJVSHGXFATZSSWYXKHIHKAHXIEJXSKXFLE\n"+
"KFKECCCPWKXJTVKXHJRYVXUIFHKUHHHLMKSVJICQHKXZKNIXHKEHKNYTKKFKHUCHZFILHRHKHQKIIEJ\nMGIKXXPZQXHRHHXKXJHAGJKHIXKILXNEVWHXWWLTFWHHUMKJPZTJXXTXVPTMHHMGEPHIXRHLGQTWJCV\n"+
"UKHXXYXHAFXXSIJXHHXKLJQJIIKXIKYHSRKUNNKHTMXTCTKXGWFHSJKQSCHINSKLGSKUTXKKAWAEXAM\nLFKXWWXXSKKXPUIKTFREKIXLXNXKHHVXJKVWEFKFMYFIHGHXSHTEUJRIEAMQSXQMRJIHRETXYMHKIUX\n"+
"XFAAMXHXUFITLAWNMJYHTCWQFNXAIXKSZXIXXKRKAHWHYEAMVHNKLHKVUTAIZLVXGCHHAZTTHCELIGK\nXPJRXIVVFTJKQFNSKMKFKIHMRCHWFYVIRVXFPTKIKUKQKKMVKWIYIKRXWEVXUIHFHXASHHXVFWEWHHK\n"+
"KYELCKHLXXHXHTVMJHNFQUFJXKUHIZXFEXRZMEYZHSJXVZKMYHNCVEXKXKATRFLGHXTHXRPHXLHKSTY\nIXUUFXHWMKRIWWIRSKSCQHXSIIKRHXZNFCXXHSLXHRNHZXNWHKMQRPTHTHXXSVKHXZXICYHSXXXKXHU\n"+
"TXESLHCCEHHHHKHICSILWLHFEKVKSUECLAZHZXIKRUKWKFHXILWNSTMXXAGKWVLQNXESKXYIIXKXZRI\nHHSSHXRXKHNUWLKPXLIXFUIHXNKIKJCHTGWXLJZSLHSMZMSZTKLFAVEKIMGXJVAIKXHWUUHKHURIYMG\n"+
"IXMYFVXIWMZVNVYWKYFVXJKKEHKMNLYXNXFSRHHSANKTKTNVKNTRHPXKLRCMHLHUWKIMGWVFAPZXWXH\nRHIKVZWLHJYUKCQSSCNZFRRMXTJXQMRXCZIVPRHJMHVVXHHHLHKNKRKNXLKKREIWSTINKKXFSMPILXK\n"+
"KSFKKXGIAKXKRWHNHZMVFVFUHIKJWIHUJHHNKKSXMMUVNHEJIYCCWEHHHGJXWJJVXWIPXCKWHSXFYXI\nRWVXEHJLHANHXIVHMMQHAHHRKTMHXXXLHPCQRSHTHVXXJSXQZRHKKLSFYXKTKLKXHKHRSXLKKXUJXKJ\n"+
"TNKIMHEXKVYMVMRKTXIXJHTXYIXKMHXKKWQGFLGIFIKXKTMXSYYMTVQITPWHXHHKXEYKXHHJETJHXVK\nKXEWWAHIHVHXAUTCHZLRXKMKHKNKREKKMKHIHPXXZNFHFYIXHJXXWKIKHQWWISXZHJZKHHZXTGIIXJN\n"+
"YKZHRXXFQKHKXZHVEWSHREHKIYTFSTHLREKHFJIAVWKMKJMXHXKWKWYRTKMHIIXNCVKXRHKKEMYERRL\nKREZXUHKRQKFYKWKHEZXKWWXEHXYKLAIKYNVXFRPUNFHVJHKWZXSXKIHKYHKXFHYXXXTXIXIXGIXKHK\n"+
"ZHIKXXXRCSKVKYVHXKRJHHXWCNEXRQIKAIHHTFHWCSCZCHKXMUMKLVKXPKLIZIYKRKHIKZSHHAKCNKK\nZUHHHWKMNIXRGAVXHCXAQUKXHHEXLIRNNHLHCKRZSXHKMKWTKHKVJEUSKHXEFPHMPKHYKKUMHFLKSIJ\n"+
"KKKZXHRRNSSKXWIUCXPJUFLJSVXHMRKHXWHYURHXNKCWKIXKKWHXZMRAHHXCKIHKXXTJRHTEHUHTPZK\nHAKHLHCEGIXIIVAYWWKXCEXIHKWMKEHILYZEXKHKYVWJVKVYHFTSNIHGHCIJXKNSXXTXHSYEXNFKHSY\n"+
"KWGUHKCXWGCXKFSIPZXIZKPLHIXXYPKYHHFKYMNTXHIVMNTRYJPUKUKYUMZFTYSIIXVAXINHCMXKTEH\nGQYGHKHIKKKIKXYGCHKLAYSXPHHKFSICIKFFHSKHMAWVYKHJKNZZXYISGZMJWRRIJILHHKKHFFKARKH\n"+
"RIKUACKKMVIGHXKKMHFSXJEKXFMKSHXZXHKMHHXXSXHHLXHHEKKAKMXXECVLHEIKGWACSNKKVKARERJ\nCXMVNITXXMKCYUIHUHUXUIKYHNZYHXXLTHJATGKHKTIKKYTWXRJIXCJNHTYXIRLTKAMEHZMKRJXHAWV\n"+
"HKIMIQKMRSJNHZZYKHWWKSFIRHKHFWKKYFITXWATKKXSECSHKXHPQCNIIIWFMKUHUMXWCXYJHVSVELR\nNXUKLFAHVGGHYVTAWNIXHKXHXHXXAKKANKYIFXUTLKKTHHIKHKATJXKXETTWEKNIHQSKIXXJXXYLXXJ\n"+
"RXPCUSXZLZXVKIRLSVXHHXXKMAIXCXXQVIKIUKIXIXXJHXFRRSXXQREIWHXFKWISXYHVEKHYYXKZLMN\nXCHKWYHJRWXRLXLEAXXHKVRKLGUMWSCXINKHMNHHISNKLVKWXRWKEKPCRGZNIXSXTXHEKEEKHXTHJUH\n"+
"XGVNFTHKHNVGXGSRIPGKFXZTUKEKYKIINRKUHIKLHXRIYXRIKXSCENMZLXXHAXXWTIGJXHHWXHMIFIK\nHEVJQXTXKPFSTVKWGKXTKYRXJHVPKKNLQLPSXPIZVNIAKJJRHZHKFXIGRHKVCTVXINNHTGLIHMVYINA\n"+
"HIQHXXVZAHIHRHIHFTUWFKGKQKTAUXJSIXWHUXNXJIJIIAWUKHRLIHKVSIFSNKKHNTYCTPNWIKHHIKX\nMRLCMZXPALCTFXPHVHSVNXTJWFHKQZTZEYMALXXIXRJIKCFJYSPXKZXKUGKZLQHKUYINNUKKKLKMVLI\n"+
"VQHFXEKRVSHKKKHGWZWTLXRFWMVXHKKXWXKEHAJIXJKHXFNNGHKKLXKKKLJYKJEEHCKXTGHHICISHMF\nZXPUAXPXKXXVYAHPIJHLRCIKXLCGZXLWFJPHXAHFKSLFEHGLKHFIIHHKHHCTVAKWPXWGIQKHNILHQJW\n"+
"XHPIQLZHKVUKXCMLHSFHEKHEKREWXKYIXSZHTAHIIEUYVUHSMKTHFKMGKSLMHXKYACCXXKATLYXKXFL\nWKHIKFVFKUVXXRVEYUTCRNCXPZCCLSKTHWQXXJMHFLKXHNXCVZXHGXYAVYEXVJCHKXIKMSVAXVHNEXV\n"+
"IXIKYSSJQKKPTXFXFREKXJAKKXEJXNVXHEUJHIMHHPNRVZHXUKZPWTXCCIHXAKZUSHXRMSLIUWHIHKK\nMXIHKCKKHSIHXCKCRKATFKFSJXLRXIJNFYQISMKHSAYKZXPXNIHWSKHXYZLAVXIEXVTYHGSRXXAGQRK\n"+
"IMCXXHXSCXVXCKCTHNSHWEIRAELTJMFKCXQIIXVFSZXHXXIPCCFIZXEXPWHEGJUHWXGZJCISRJSCIPV\nHIXHUIHJXXLXXXZLNZCTJKYHNHAVIHIITLHXGEXXKUIXGNKLHHUVFJAFKHHPCJSUKXHCSIHKCXZEIFI\n"+
"UKUHWRKSJFKZNYJMSZYRTXZKWHVIXLXHRFXTZHTHHHUMYTXKRXMFAKLUMAPNGHKKJUKYIHUXQHMIUVI\nXHCKNCKTSXTZMHETTLTMYXHJKUUVXHHSHIVSZKHHWXAWMFXVVHFUCXHMXWKXHXKVLLHXZSICSACKIHC\n"+
"FXFNPHXHTHCLHKJTSLVTHKHHXHXHHKTKSUTIXKYQUHAQXXNSLKUMTKHSKKYTXHTVPGVHHMXVNLHXIRF\nWJFVVXITNRCXKHTFARSIXASVCNXJQNXIJVUHYIVNIRZXMHHFKHKMMNCUXFTEXEKEHTIHSKAKXZVTSKY\n"+
"ZJGHRTHUWMHHZXHPAIHWHUSXXKLHKYKHJSHHNKXXKRSHMKHSIHIUIXKZXSUZHKXIMMIXMXTXZZLXXIM\nEQZKRLALIEVHXYKHXIFYKXMAINSNIASMGLLYHXHRIXVWUKZHFREJCAXKXWYHXNUKTQCUKIHLWKTEKMC\n"+
"MHLXXHHYQWHTXVHCMKKHGIUFSEHNEVYSXQHHXXKHMXUXQKHZHHHSHRKWHMMEHZMIKKYYWIUNEIJUIKT\nNCHKRNSJYLLIXKXAIERXKKXIQZVHXFVIIAXHIYUGZURXFHSXKLIWESKHEXQSCUHWKALZIVEZHAFKKWA\n"+
"IKCJWNVRKMITKNYXJYKYXVXXUKWHXXJAKLXXXVKXGXKKZXMHCKKCGRLZQINVHRLNVWXTKVLTEPTXUXH\nXVCICKXXXEVTIKIHHSHCKYIJXNCJKJSLSHVXJHTHSIKUXPHWRIKMFXXMMHKHCAQWITIEWEXPFHYXXKU\n"+
"XXSHHIXHWWRKITSHSXHJKEWHXIZHSHZCHFARIXNPHYSNIKJXLQENKFCXYRWMXAPIYTZKNMXFHNIMCCS\nPAACXJMNVZZHMXXSNVSXEIINNCHLSTIXHHKYXLEHQHKHPRWIXXHRKVCXFKLHSHKGXJGKLLLWSHIISKT\n"+
"WUYXTJHXXMKJCYIXQJRNFKYHHUUKTIAYXVUUXFCYLHXWWZAUHWZIUAIGKHKIMKXXXKJZXCKKRCJAKQJ\nEVAGXIHTINSXENKWVXWCLFUVHXFPFCIFVHWXRIFZRYZKUUEMXNGAJLIFHJJIGUXFKKRIMKGFKXJYXKV\n"+
"KKRHHWKIYXWXWKLWXWKFHXLXRXRKKENMHHIQRHTTMFYTGRLSHRXIXKKUEHXXJKRIKSYLTKYJMNIUWVE")

Result: 714

Taking input as a function argument is fine according to the meta post, as long as it's as part of a complete program.

@githubphagocyte that's not so clear to me, can you elaborate? Is mine a complete program - I don't think so - is it possible to make a "complete program" in JS? If not, what else? prompt + alert?

@edc65 as far as I'm concerned, if you can run it without it being part of a larger piece of source code, then it's complete.

Python - 437 429
Since forests contain newlines, I've set the input to come from a text file instead.
To run, specify the forest in a file called forest.txt,
save the code as forest_of_alphabets.py
and run from terminal/command line with python forest_of_alphabets.py forest.txt
Code:
import sys
N="@"
g=open(sys.argv[1]).read().replace(" ",N).split()
u=max(map(len,g))+1
g=[list(k)+[N]*(u-len(k))for k in g]+[[N]*u]
def f(y,x,a=0):
 c=g[y][x]
 if c>N:
    l=[zip([-1,-1,1,1],[1,-1]*2)[i]for i in 0,1,2,3if c in"CHAAEICFFJEHGKHIHLIJITKKKULMNVMNSWQPTXRRUYXSVZZXW___X___Y"[i::4]]
    if a<1 or a in l:g[y][x]=N;return[f(y+j,x+i,(-j,-i))for j,i in l]
 return 0
s=j=0
exec"i=0;exec's+=f(j,i)>0;i+=1;'*u;j+=1;"*len(g)
print s

Any suggestions are welcomed. Did this in a rush during my office break.
Tested with both test cases in this page and those in the alphabet tree question.
Update: Tested with the sample, which yields 714 too. Changed the while loops to the exec which is all the rage these days.

Thanks for mentioning test cases - I've added a large sample forest to the question.

For anyone wanting to run this code, it requires python 2.7, rather than python 3

C - 691 571 Bytes
Any suggestions for further golfing are welcome.
#include <cstdio>
#include <cstring>
#define L(i) strlen(t[i])
#define R(a,b,c) if(z&a&&T(b,c)&8/a){f(b,c);}
#define S !!strstr(
#define U return
#define V if(i<0||j<0||j>=L(i)
char t[80][80];int n=0,I=0,J,C=0;int T(int i,int j){V)U 0;char c[]="i";c[0]=t[i][j];U 1*S"HIJKLTUVWXYZ",c)+2*S"CEFGHIKNSTUVWXY",c)+4*S"AFHIJKMNPRSX",c)+8*S"ACEHIKLMQRXZ",c);}int f(int i,int j){V||t[i][j]<0)U 0;int z=T(i,j);t[i][j]=-1;R(1,i-1,j-1)R(2,i-1,j+1)R(4,i+1,j-1)R(8,i+1,j+1)U 1;}main(){while(scanf("%s\n",t[n++])>0){};n--;for(;I<n;I++){for(J=0;J<L(I);J++){C+=f(I,J);}}printf("%d\n",C);}

Ungolfed
#include <cstdio>
#include <cstring>
#define L(i) strlen(t[i])

char t[80][80];
int n=0;

int T(int i,int j){
   if(i<0||j<0||j>=L(i)){return 0;}
   char c[]="i";
   c[0]=t[i][j];
   return 1*!!strstr("HIJKLTUVWXYZ",c) +
          2*!!strstr("CEFGHIKNSTUVWXY",c) +
          4*!!strstr("AFHIJKMNPRSX",c) +
          8*!!strstr("ACEHIKLMQRXZ",c);
}

int f(int i,int j){
   if(i<0||j<0||j>=L(i)||t[i][j]<0){return 0;}
   int z=T(i,j);
   t[i][j]=-1;
   if(z&1&&T(i-1,j-1)&8){f(i-1,j-1);}
   if(z&2&&T(i-1,j+1)&4){f(i-1,j+1);}
   if(z&4&&T(i+1,j-1)&2){f(i+1,j-1);}
   if(z&8&&T(i+1,j+1)&1){f(i+1,j+1);}
   return 1;
}

int main(){
   while(scanf("%s\n",t[n++])>0){};
   n--;
   int c=0;
   for(int i=0;i<n;i++){
      for(int j=0;j<L(i);j++){
         c+=f(i,j);
      }
   }
   printf("%d\n",c);return 0;
}

Results
The result I get from the sample input provided in the question is 714.

I get 714 when I run my code on your sample.

suggestion: too many int declarations in your golfed code.

Some other thought (515) http://ideone.com/EcPdEn

@edc65 Thanks a lot for taking the time to go over this; I haven't fully digested your changes yet, but after I understand all of them, I'll update my entry.