# Make a scalable Christmas Tree [closed]

Your challenge: Make a Christmas tree. The size must be choosable by some input method, but doesn't have to be directly related to any part of the tree; however, larger inputs should produce a larger tree.

How can you make it? You can make the tree any way you like, other than by printing the unicode character for the tree, such as ouputting an image, ascii art, with other aspects, etc. Whatever you do, remember that this is a , so be creative.

The answer with the most upvotes by the end of December wins, but I'll accept another if it gets higher

• Nice question ;) Commented Dec 12, 2013 at 22:34
• A pity decorations weren't mandatory!
– o0'.
Commented Dec 13, 2013 at 17:10
• @Lohoris I think it is good that they aren't mandatory. This way, people can do what they want, and those brilliant fractal trees are legitimate answers. Commented Dec 13, 2013 at 17:12
• @Quincunx you could add decorations even to fractal trees...
– o0'.
Commented Dec 13, 2013 at 17:13
• @Lohoris yes, but they are plenty as is. The author of those trees could add decorations if they'd like to, but I'd rather not require it. Commented Dec 13, 2013 at 17:14

## Python

A fractal Christmas tree using the turtle package:

n = input()*1.

from turtle import *
speed("fastest")
left(90)
forward(3*n)
color("orange", "yellow")
begin_fill()
left(126)
for i in range(5):
forward(n/5)
right(144)
forward(n/5)
left(72)
end_fill()
right(126)

color("dark green")
backward(n*4.8)
def tree(d, s):
if d <= 0: return
forward(s)
tree(d-1, s*.8)
right(120)
tree(d-3, s*.5)
right(120)
tree(d-3, s*.5)
right(120)
backward(s)
tree(15, n)
backward(n/2)

import time
time.sleep(60)


n is the size parameter, the shown tree is for n=50. Takes a minute or two to draw.

• This looks lovely :) Commented Dec 18, 2013 at 12:00

### JavaScript

Show the animated tree online.

var size = 400;

var canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
document.body.appendChild(canvas);

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

var p3d = [];

var p = [Math.random(), Math.random(), Math.random(), 0];

for (var i = 0; i < 100000; i++) {
p3d.push([p[0],p[1],p[2],p[3]]);
var t = Math.random();
if (t<0.4) {
_y = 0.4 * p[1];
_x = 0.1 * p[0];
_z = 0.6 * p[2];
var r = Math.floor(3*t/0.4)/3.0;
var rc = Math.cos(Math.PI*2.0*r);
var rs = Math.sin(Math.PI*2.0*r);
p[1] = _x+0.1*r+0.5*_y*_y;
p[0] = _y*rc+_z*rs;
p[2] = _z*rc-_y*rs;
p[3] = 0.2*t + 0.8*p[3];
} else {
p[1] = 0.2 + 0.8*p[1];
p[0] = 0.8 * p[0];
p[2] = 0.8 * p[2];
p[3] = 0.2 + 0.8*p[3];
}
}

var rot = 0.0;

function render() {
rot = rot + 0.1;
var rc = Math.cos(rot);
var rs = Math.sin(rot);

ctx.strokeStyle='#FF7F00';
ctx.lineWidth=2;
ctx.beginPath();
ctx.moveTo(size/2,size/8);
ctx.lineTo(size/2,size*15/16);
ctx.stroke();

var img = ctx.getImageData(0, 0, size, size);
for (var j = 0; j < size*size; j++) {
img.data[4*j+0] = 0.5*img.data[4*j+0];
img.data[4*j+1] = 0.5*img.data[4*j+1];
img.data[4*j+2] = 0.5*img.data[4*j+2];
img.data[4*j+3] = 255;
}

for (var i = 0; i < p3d.length; i++) {
var px = p3d[i][0];
var py = 0.5 - p3d[i][1];
var pz = p3d[i][2];
var col = Math.floor(128.0*p3d[i][3]);

var _x = rc*px + rs*pz;
var _z = rc*pz - rs*px;

var z = 3.0 * size / (_z + 4.0);
var x = size / 2 + Math.round(_x * z);
var y = size / 2 + Math.round(py * z);

if(x>=0&&y>=0&&x<size&&y<size) {
img.data[4 * (y * size + x) + 0] = col;
img.data[4 * (y * size + x) + 1] = 128+col;
img.data[4 * (y * size + x) + 2] = col;
img.data[4 * (y * size + x) + 3] = 255;
}
}

ctx.putImageData(img, 0, 0);
}

setInterval(render, 1000 / 30);

• I like it, but you should add a trunk.
– Fels
Commented Dec 13, 2013 at 9:42
• @Fels added trunk Commented Dec 13, 2013 at 10:16
• This is very impressive, but what's up with those green pixels circling the tree? I didn't realize that Santa had little green elves who can fly. (they do not detract from the beauty of your answer, but I wonder where they came from) Commented Dec 15, 2013 at 6:24
• @Quincunx: They seem to be initial sample points from before the iteration converges. Skipping the first 100 points gets rid of them. Commented Dec 15, 2013 at 14:25
• Really cool, but it doesn't quite look like a Christmas tree. It looks more like a stick with a few fern leaves attached to it. Also, could you make the view slowly scroll along the y axis, so the 3D-ness is more apparent? Commented Dec 20, 2013 at 17:04

Yet another Mathematica / Wolfram Language tree based on Vitaliy's answer:

PD = .5;
s[t_, f_] := t^.6 - f
dt[cl_, ps_, sg_, hf_, dp_, f_, flag_] :=
Module[{sv, basePt},
{PointSize[ps],
sv = s[t, f];
Hue[cl (1 + Sin[.02 t])/2, 1, .3 + sg .3 Sin[hf sv]],
basePt = {-sg s[t, f] Sin[sv], -sg s[t, f] Cos[sv], dp + sv};
Point[basePt],
If[flag,
{Hue[cl (1 + Sin[.1 t])/2, 1, .6 + sg .4 Sin[hf sv]], PointSize[RandomReal[.01]],
Point[basePt + 1/2 RotationTransform[20 sv, {-Cos[sv], Sin[sv], 0}][{Sin[sv], Cos[sv], 0}]]},
{}]
}]

frames = ParallelTable[
Graphics3D[Table[{
dt[1, .01, -1, 1, 0, f, True], dt[.45, .01, 1, 1, 0, f, True],
dt[1, .005, -1, 4, .2, f, False], dt[.45, .005, 1, 4, .2, f, False]},
{t, 0, 200, PD}],
ViewPoint -> Left, BoxRatios -> {1, 1, 1.3},
ViewVertical -> {0, 0, -1},
ViewCenter -> {{0.5, 0.5, 0.5}, {0.5, 0.55}}, Boxed -> False,
PlotRange -> {{-20, 20}, {-20, 20}, {0, 20}}, Background -> Black],
{f, 0, 1, .01}];

Export["tree.gif", frames]


• This is the best one!! Commented Dec 28, 2013 at 16:53

## Javascript

This is my first code golf!

var a=40,b=8,c=13,o="<div style='font-family:monospace;text-align:center;color:#094'>",w=1,x=0,y="|#|<br>";for(i=1;i<a;i++){for(j=0;j<w;j++){x%c==0?o+="<span style='color:#D00'>O</span>":o+="+";x++;}i%b==0?w-=4:w+=2;o+="<br>";}document.write(o+"<span style='color:#640'>"+y+y+y+"</span></div>");


It comes in at 295 Characters.

The size and decoration of the tree is set by the a,b,c variables:

• a sets the amount of rows in the tree
• b sets the amount of rows between decreases in width (set low for a skinny tree, high for a fat tree). Must be greater than or equal to 3.
• c sets the amount of baubles (set zero for none, 1 for only baubles, higher numbers for less dense placement of baubles)

It looks best when a is a multiple of b, as in the example.

Paste into the console to create a tree. Looks better from far away!

• reduced to 264 a=40,b=8,c=13,o="<p style='font:monospace;color:#094' align='center'>",w=1,x=0,y="|#|<br>";for(i=1;i<a;i++){for(j=0;j<w;j++){x%c==0?o+="<b style='color:red'>O</b>":o+="+";x++;}i%b==0?w-=4:w+=2;o+="<br>";}document.write(o+"<b style='color:#640'>"+y+y+y+"</b></p>"); Commented Dec 13, 2013 at 16:45
• You are really golfing on a popularity contest? Wow, I would have written nice readable code (easier to code in). +1 Commented Dec 13, 2013 at 17:06
• ungh. You're using doc.write? No +1 from me. Commented Dec 13, 2013 at 20:14
• @JanDvorak, Why not? I'd thought this is golfing..... Commented Apr 30, 2015 at 18:33

# Javascript

Quasirealistic fully 3D procedural fir tree generator.

Featuring: extensive configuration with even more configuration options present in code; a zigzagy trunk; branching branches; growth animation; rotation of a fully grown tree.

Not featuring: jQuery, Underscore.js or any other library; hardware dependency - only canvas support is required; messy code (at least that was the intention)

Edit page: http://jsfiddle.net/honnza/NMva7/

screenshot:

HTML:

<canvas id=c width=200 height=300 style="display:none"></canvas>
<div id=config></div>


Javascript:

var TAU = 2*Math.PI,
deg = TAU/360,

TRUNK_VIEW      = {lineWidth:3, strokeStyle: "brown", zIndex: 1},
BRANCH_VIEW     = {lineWidth:1, strokeStyle: "green", zIndex: 2},
TRUNK_SPACING   = 1.5,
TRUNK_BIAS_STR  = -0.5,
TRUNK_SLOPE     = 0.25,
BRANCH_LEN      = 1,
BRANCH_P        = 0.01,
MIN_SLOPE       = -5*deg,
MAX_SLOPE       = 20*deg,
INIT_SLOPE      = 10*deg,
MAX_D_SLOPE     =  5*deg,
DIR_KEEP_BIAS   = 10,
GROWTH_MSPF     = 10, //ms per frame
GROWTH_TPF      = 10, //ticks per frame
ROTATE_MSPF     = 10,
ROTATE_RPF      = 1*deg; //radians per frame

var configurables = [
//    {key: "TRUNK_SPACING", name: "Branch spacing", widget: "number",
//     description: "Distance between main branches on the trunk, in pixels"},
{key: "TRUNK_BIAS_STR", name: "Branch distribution", widget: "number",
description: "Angular distribution between nearby branches. High values tend towards one-sided trees, highly negative values tend towards planar trees. Zero means that branches grow in independent directions."},
{key: "TRUNK_SLOPE", name: "Trunk slope", widget: "number",
description: "Amount of horizontal movement of the trunk while growing"},
{key: "BRANCH_P", name: "Branch frequency", widget: "number",
description: "Branch frequency - if =1/100, a single twig will branch off approximately once per 100 px"},
{key: "MIN_SLOPE", name: "Minimum slope", widget: "number", scale: deg,
description: "Minimum slope of a branch, in degrees"},
{key: "MAX_SLOPE", name: "Maximum slope", widget: "number", scale: deg,
description: "Maximum slope of a branch, in degrees"},
{key: "INIT_SLOPE", name: "Initial slope", widget: "number", scale: deg,
description: "Angle at which branches leave the trunk"},
{key: "DIR_KEEP_BIAS", name: "Directional inertia", widget: "number",
description: "Tendency of twigs to keep their horizontal direction"},
{get: function(){return maxY}, set: setCanvasSize, name: "Tree height",
widget:"number"}
];

var config = document.getElementById("config"),
canvas = document.getElementById("c"),
maxX   = canvas.width/2,
maxY   = canvas.height,
canvasRatio = canvas.width / canvas.height,
c;

function setCanvasSize(height){
if(height === 'undefined') return maxY;
maxY = canvas.height = height;
canvas.width = height * canvasRatio;
maxX = canvas.width/2;
x}

var nodes = [{x:0, y:0, z:0, dir:'up', isEnd:true}], buds = [nodes[0]],
branches = [],
branch,
trunkDirBias = {x:0, z:0};

////////////////////////////////////////////////////////////////////////////////

configurables.forEach(function(el){
var widget;
switch(el.widget){
case 'number':
widget = document.createElement("input");
if(el.key){
widget.value = window[el.key] / (el.scale||1);
el.set = function(value){window[el.key]=value * (el.scale||1)};
}else{
widget.value = el.get();
}
widget.onblur = function(){
el.set(+widget.value);
};
break;
default: throw "unknown widget type";
}
var p = document.createElement("p");
p.textContent = el.name + ": ";
p.appendChild(widget);
p.title = el.description;
config.appendChild(p);
});
var button = document.createElement("input");
button.type = "button";
button.value = "grow";
button.onclick = function(){
button.value = "stop";
button.onclick = function(){clearInterval(interval)};
config.style.display="none";
canvas.style.display="";
c=canvas.getContext("2d");
c.translate(maxX, maxY);
c.scale(1, -1);
interval = setInterval(grow, GROWTH_MSPF);
}
document.body.appendChild(button);
function grow(){
for(var tick=0; tick<GROWTH_TPF; tick++){
var budId = 0 | Math.random() * buds.length,
nodeFrom = buds[budId], nodeTo, branch,
dir, slope, bias

if(nodeFrom.dir === 'up' && nodeFrom.isEnd){
nodeFrom.isEnd = false;
rndArg = Math.random()*TAU;
nodeTo = {
x:nodeFrom.x + TRUNK_SPACING * TRUNK_SLOPE * Math.sin(rndArg),
y:nodeFrom.y + TRUNK_SPACING,
z:nodeFrom.z + TRUNK_SPACING * TRUNK_SLOPE * Math.cos(rndArg),
dir:'up', isEnd:true}
if(nodeTo.y > maxY){
console.log("end");
clearInterval(interval);
rotateInit();
return;
}
nodes.push(nodeTo);
buds.push(nodeTo);
branch = {from: nodeFrom, to: nodeTo, view: TRUNK_VIEW};
branches.push(branch);
renderBranch(branch);
}else{ //bud is not a trunk top
if(!(nodeFrom.dir !== 'up' && Math.random() < BRANCH_P)){
buds.splice(buds.indexOf(nodeFrom), 1)
}
nodeFrom.isEnd = false;
if(nodeFrom.dir === 'up'){
bias = {x:trunkDirBias.x * TRUNK_BIAS_STR,
z:trunkDirBias.z * TRUNK_BIAS_STR};
slope = INIT_SLOPE;
}else{
bias = {x:nodeFrom.dir.x * DIR_KEEP_BIAS,
z:nodeFrom.dir.z * DIR_KEEP_BIAS};
slope = nodeFrom.slope;
}
var rndLen = Math.random(),
rndArg = Math.random()*TAU;
dir = {x: rndLen * Math.sin(rndArg) + bias.x,
z: rndLen * Math.cos(rndArg) + bias.z};
var uvFix = 1/Math.sqrt(dir.x*dir.x + dir.z*dir.z);
dir = {x:dir.x*uvFix, z:dir.z*uvFix};
if(nodeFrom.dir === "up") trunkDirBias = dir;
slope += MAX_D_SLOPE * (2*Math.random() - 1);
if(slope > MAX_SLOPE) slope = MAX_SLOPE;
if(slope < MIN_SLOPE) slope = MIN_SLOPE;
var length = BRANCH_LEN * Math.random();
nodeTo = {
x: nodeFrom.x + length * Math.cos(slope) * dir.x,
y: nodeFrom.y + length * Math.sin(slope),
z: nodeFrom.z + length * Math.cos(slope) * dir.z,
dir: dir, slope: slope, isEnd: true
}
//if(Math.abs(nodeTo.x)/maxX + nodeTo.y/maxY > 1) return;
nodes.push(nodeTo);
buds.push(nodeTo);
branch = {from: nodeFrom, to: nodeTo, view: BRANCH_VIEW};
branches.push(branch);
renderBranch(branch);
}// end if-is-trunk
}// end for-tick
}//end func-grow

function rotateInit(){
branches.sort(function(a,b){
return (a.view.zIndex-b.view.zIndex);
});
interval = setInterval(rotate, ROTATE_MSPF);
}

var time = 0;
var view = {x:1, z:0}
function rotate(){
time++;
view = {x: Math.cos(time * ROTATE_RPF),
z: Math.sin(time * ROTATE_RPF)};
c.fillStyle = "white"
c.fillRect(-maxX, 0, 2*maxX, maxY);
branches.forEach(renderBranch);
c.stroke();
c.beginPath();
}

var prevView = null;
function renderBranch(branch){
if(branch.view !== prevView){
c.stroke();
for(k in branch.view) c[k] = branch.view[k];
c.beginPath();
prevView = branch.view;
}
c.moveTo(view.x * branch.from.x + view.z * branch.from.z,
branch.from.y);
c.lineTo(view.x * branch.to.x + view.z * branch.to.z,
branch.to.y);
}

• I know because this answer has only one comment: because it leaves people speechless. Commented Dec 2, 2014 at 20:48

# C++

Let's make it in the spirit of IOCCC and have the code in the shape of a tree as well! :D

#include <iostream>
using namespace std;

int
main(){
int a
;
cin
>>a;int
w=a*2+5;for
(int x=
0;x<a;++x){
for(int y=2;y>=
0;--y){for(int z=0;
z<a+y-x;++z
){cout<<" ";}for(
int z=0;z<x*2-y*2+5;++z
){cout<<".";}cout
<<endl;}}for(int x=0;
x<w/5+1;++x){for(int z=0;
z<w/3+1;++z){cout<<" ";}for(
int z=0;z<w-(w/3+1)*2;z+=1){cout
<<"#";}cout
<<endl;;;}}


Takes an integer as input, and returns a Christmas tree with that many "stack levels". For example, an input of

5


Returns:

       .
...
.....
...
.....
.......
.....
.......
.........
.......
.........
...........
.........
...........
.............
###
###
###
###

• output example? Commented Dec 14, 2013 at 9:48
• The code looks more like a chrismas tree than the output... Commented Dec 16, 2013 at 8:57
• @dystroy for the record, the instructions do not say it's the output that must containt the tree. Commented Dec 16, 2013 at 9:20
• @ArlaudPierre: But, the size must be adjustable, which is impossible with just the source code. I could make a program that outputs program code in the shape of a Christmas tree that outputs an actual Christmas tree, but I imagine that would be terribly difficult without resorting to just inserting stray semicolons everywhere. Commented Dec 16, 2013 at 11:02
• If you put a * at the top of the tree (source code), you will have my +1. Commented Dec 15, 2014 at 22:16

# Bash

Sample output:

The tree size (i.e. number of lines) is passed on the command line, and is limited to values of 5 or greater. The image above was produced from the command ./xmastree.sh 12. Here's the source code:

#!/bin/bash
declare -a a=('.' '~' "'" 'O' "'" '~' '.' '*')
[[ $# = 0 ]] && s=9 || s=$1
[[ $s -gt 5 ]] || s=5 for (( w=1, r=7, n=1; n<=$s; n++ )) ; do
for (( i=$s-n; i>0; i-- )) ; do echo -n " " done for (( i=1; i<=w; i++ )) ; do echo -n "${a[r]}"
[[ $r -gt 5 ]] && r=0 || r=$r+1
done
w=$w+2 echo " " done; echo " "  • That is very pretty. Commented Dec 28, 2013 at 7:29 Disclaimer: this is based on my LaTeX christmas tree, first posted here: https://tex.stackexchange.com/a/87921/8463 The following code will generate a chrismtas tree, with random decorations. You can change both the size of the tree, and the random seed to generate a different tree. To change the seed modify the value inside \pgfmathsetseed{\year * 6} to any other numerical value (the default one will generate a new tree every year) To change the size of the tree modify the order=10 to be either larger, or smaller depending on the size of the tree you want. Examples. order=11: order=8 \documentclass{article} \usepackage{tikz} \usetikzlibrary{calc, lindenmayersystems,shapes,decorations,decorations.shapes} \begin{document} \def\pointlistleft{} \def\pointlistright{} \pgfmathsetseed{\year * 6} \makeatletter \pgfdeclarelindenmayersystem{Christmas tree}{ \symbol{C}{\pgfgettransform{\t} \expandafter\g@addto@macro\expandafter\pointlistleft\expandafter{\expandafter{\t}}} \symbol{c}{\pgfgettransform{\t} \expandafter\g@addto@macro\expandafter\pointlistright\expandafter{\expandafter{\t}}} \rule{S -> [+++G][---g]TS} \rule{G -> +H[-G]CL} \rule{H -> -G[+H]CL} \rule{g -> +h[-g]cL} \rule{h -> -g[+h]cL} \rule{T -> TL} \rule{L -> [-FFF][+FFF]F} } \makeatother \begin{tikzpicture}[rotate=90] \draw [color=green!50!black,l-system={Christmas tree,step=4pt,angle=16,axiom=LLLLLLSLFFF,order=10,randomize angle percent=20}] lindenmayer system -- cycle; \pgfmathdeclarerandomlist{pointsleft}{\pointlistleft} \pgfmathdeclarerandomlist{pointsright}{\pointlistright} \pgfmathdeclarerandomlist{colors}{{red}{blue}{yellow}} \foreach \i in {0,1,...,5} { \pgfmathrandomitem{\c}{pointsleft} \pgfsettransform{\c} \pgfgettransformentries{\a}{\b}{\c}{\d}{\xx}{\yy} \pgfmathrandomitem{\c}{pointsright} \pgfsettransform{\c} \pgfgettransformentries{\a}{\b}{\c}{\d}{\XX}{\YY} \pgftransformreset \pgfmathsetmacro\calcy{min(\yy,\YY)-max((abs(\yy-\YY))/3,25pt)} \draw[draw=orange!50!black, fill=orange!50, decorate, decoration={shape backgrounds, shape=star, shape sep=3pt, shape size=4pt}, star points=5] (\xx,\yy) .. controls (\xx,\calcy pt) and (\XX,\calcy pt) .. (\XX,\YY); } \foreach \i in {0,1,...,15} { \pgfmathrandomitem{\c}{pointsleft} \pgfsettransform{\c} \pgftransformresetnontranslations \draw[color=black] (0,0) -- (0,-4pt); \pgfmathrandomitem{\c}{colors} \shadedraw[ball color=\c] (0,-8pt) circle [radius=4pt]; } \foreach \i in {0,1,...,15} { \pgfmathrandomitem{\c}{pointsright} \pgfsettransform{\c} \pgftransformresetnontranslations \draw[color=black] (0,0) -- (0,-4pt); \pgfmathrandomitem{\c}{colors} \shadedraw[ball color=\c] (0,-8pt) circle [radius=4pt]; } \end{tikzpicture} \end{document}  • I would say that this is based on Stefan Kottwitz's tree, first posted here. Saying that it is based on your tree makes it seem like you wrote all the code for it, which isn't true. Someone else wrote most the code for the actual tree. Commented Dec 21, 2013 at 13:37 • @RyanCarlson the idea to use the lindenmayer system as a basis for putting on decorations was my idea, and if you check carefully both of the code you can see, that the lindenmayer part of the code was redesigned to also have additional parts (like a root for the tree, which the original lacks). Besides that I didn't forget to reference the original, where anyone can check for the references (including the one to Peitgen and Saupe, who might've been the first to draft the equation of the tree) Commented Dec 21, 2013 at 20:29 # Befunge 93 This is an undecorated tree: &::00p20pv vp010 < v p00< >:0!#v_" ",1- v,"/"$<
>10g:2+v
vp01   <
>:0!#v_" ",1-
v,"\"$< >91+,00g1-::0!#v_^ v *2+1g02< >:0!#v_"-",1- v g02$<
>91+,v
v    <
>:0!#v_" ",1-
"||"$<@,,  Sample output, input is 10:  /\ / \ / \ / \ / \ / \ / \ / \ / \ / \ ---------------------- ||  Let's add some decorations: &::00p20pv vp010 < v p00< >:0!#v_" ",1- v,"/"$<
>10g:2+v             >"O" v
vp01   <            >?v
>:0!#v_           >?>>" ">,1-
v,"\"$< >?< >91+,00g1-::0!#v_^ >"*" ^ v *2+1g02< >:0!#v_"-",1- v g02$<
>91+,v
v    <
>:0!#v_" ",1-
"||"<@,,  Sample output:  /\ /O \ / \ / ** \ / * \ / ** O\ /* O* * * \ / O O \ / * ** O* \ / *OO * OOO * \ ---------------------- ||  # HTML and CSS <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Scalable christmas tree</title> <style> body { background-color: skyblue; background-size: 11px 11px, 21px 21px, 31px 31px; background-image: radial-gradient(circle at 5px 5px,white,rgba(255,255,255,0) 1px), radial-gradient(circle at 5px 5px,white,rgba(255,255,255,0) 2px), radial-gradient(circle at 5px 5px,white 1px,skyblue 1px); } div { float: left; border-style: solid; border-color: transparent; border-bottom-color: green; border-width: 20px; border-top-width: 0; border-bottom-width: 30px; border-bottom-left-radius: 35%; border-bottom-right-radius: 35%; box-shadow: red 0 15px 5px -13px; animation-name: light; animation-duration: 1s; animation-direction: alternate; animation-iteration-count: infinite; -webkit-animation-name: light; -webkit-animation-duration: 1s; -webkit-animation-direction: alternate; -webkit-animation-iteration-count: infinite; } section { float: left; } header { color: yellow; font-size: 30px; text-align: center; text-shadow: red 0 0 10px; line-height: .5; margin-top: 10px; animation-name: star; animation-duration: 1.5s; animation-direction: alternate; animation-iteration-count: infinite; -webkit-animation-name: star; -webkit-animation-duration: 1.5s; -webkit-animation-direction: alternate; -webkit-animation-iteration-count: infinite; } footer { float: left; width: 100%; height: 20px; background-image: linear-gradient(to right, transparent 45%, brown 45%, #600 48%, #600 52%, brown 55%, transparent 55%); } :target { display: none; } @keyframes star { from { text-shadow: red 0 0 3px; } to { text-shadow: red 0 0 30px; } } @-webkit-keyframes star { from { text-shadow: red 0 0 3px; } to { text-shadow: red 0 0 30px; } } @keyframes light { from { box-shadow: red 0 15px 5px -13px; } to { box-shadow: blue 0 15px 5px -13px; } } @-webkit-keyframes light { from { box-shadow: red 0 15px 5px -13px; } to { box-shadow: blue 0 15px 5px -13px; } } </style> </head> <body> <section> <header>&#x2605;</header> <div id="0"><div id="1"><div id="2"><div id="3"><div id="4"><div id="5"><div id="6"><div id="7"><div id="8"><div id="9"><div id="10"><div id="11"><div id="12"><div id="13"><div id="14"><div id="15"><div id="16"><div id="17"><div id="18"><div id="19"><div id="20"><div id="21"><div id="22"><div id="23"><div id="24"> </div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div> <footer></footer> </section> </body> </html>  Sizes between 1 and 25 are supported – just add the size to the URL as fragment identifier. Works in Chrome, Explorer and Firefox. In Opera is ugly, but the scaling part works. Sample access: http://localhost/xmas.html#5  Sample access: http://localhost/xmas.html#15  Live view: http://dabblet.com/gist/8026898 (The live view contains no vendor prefixed CSS and includes links to change the size.) • +1 I like the idea of using :target to scale the output :-) Commented Dec 14, 2013 at 23:03 # Java import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Toolkit; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; /** * * @author Quincunx */ public class ChristmasTree { public static double scale = 1.2; public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new ChristmasTree(); } }); } public ChristmasTree() { try { URL url = new URL("http://imgs.xkcd.com/comics/tree.png"); BufferedImage img = ImageIO.read(url); JFrame frame = new JFrame(); frame.setUndecorated(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); BufferedImage result = new BufferedImage((int)(img.getWidth() * scale), (int) (img.getHeight() * scale), BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) result.getGraphics(); g.drawRenderedImage(img, AffineTransform.getScaleInstance(scale, scale)); JImage image = new JImage(result); image.setToolTipText("Not only is that terrible in general, but you " + "just KNOW Billy's going to open the root present first, " + "and then everyone will have to wait while the heap is " + "rebuilt."); frame.add(image); frame.pack(); frame.setVisible(true); } catch (IOException ex) { } } class JImage extends JPanel implements MouseListener { BufferedImage img; public JImage(){ this(null); } public JImage(BufferedImage image){ img = image; setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); addMouseListener(this); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(img, WIDTH, WIDTH, this); } public void setImage(BufferedImage image) { img = image; repaint(); } @Override public void mouseClicked(MouseEvent me) { System.exit(0); } @Override public void mousePressed(MouseEvent me) { } @Override public void mouseReleased(MouseEvent me) { } @Override public void mouseEntered(MouseEvent me) { } @Override public void mouseExited(MouseEvent me) { } } }  To alter the size, change scale to some other double value (keep it around 1 if you want to see anything). Sample output (for 1.0 as scale, too lazy to take a screenshot, so just posted what it does): The program takes this image from the internet, resizes it according to scale, then puts it in an undecorated window where it is displayed. Clicking on the window closes the program. Also, the tool tip text is there, but the link is not. • This isn't "drawing" anything. Commented Dec 17, 2013 at 18:28 • @Mrchief The challenge isn't to draw something; it is to make a tree. This is making a tree, by taking the image Commented Dec 17, 2013 at 18:35 • Did you generate the image yourself? No. You're just downloading it from somewhere. The question isn't to download an image and resize it. Check other answers and you'll understand what the OP actually asked for. Commented Dec 18, 2013 at 5:23 • @Mrchief Did you notice who wrote the OP? This is one of the many possible solutions I was looking for when I asked this question. Commented Dec 18, 2013 at 5:44 • Ha! Smack on the head! Since its your own post, I don't see much reason to argue, other than expressing my opinion that this is not same as your code "making" something (like rest of the answers do). Just like downloading a movie is not the same as making a movie. Commented Dec 18, 2013 at 19:24 # TI-89 Basic Just because I wanted to see a Christmas Tree on my calculator. I shall type it here as it appears on my calculator. :tree() :Prgm : :Local size :Prompt size : :Local d,x,y,str,orn :size→x :0→y :{" "," "," "," "," "," "," "," ","°","∫","θ","O","©"}→orn :size→d : :While d≥0 : d-1→d : ""→str : : While x≥0 : str&" "→str : x-1→x : EndWhile : : str&"/"→str : 2*y→x : : While x>0 : str&elementAt(orn,rand(colDim(list▶mat(orn))))→str : x-1→x : EndWhile : : str&"\"→str : Disp str : y+1→y : d→x :EndWhile : :""→str : :For x,1,2*(size+2) : str&"-"→str :EndFor :Disp str : :""→str :For x,1,size+1 : str&" "→str :EndFor :str&"||"→str :Disp str : :EndPrgm :elementAt(l,i) :Func :Local m :list▶mat(l)→m : :Local cd :colDim(m)→cd : :If i>cd or i≤0 Then : 1/0 :Else : If i=cd Then : Return sum(mat▶list(subMat(m,1,i))) - sum(mat▶list(subMat(m,1,i+1))) : Else : Return sum(mat▶list(subMat(m,1,i))) - sum(mat▶list(subMat(m,1,i+1))) : EndIf :EndIf :EndFunc  This works the same way as my Befunge answer, but I use different ornaments. Yes, my elementAt function's repeated uses slows the program down because of many conversions between lists and matrices, but as I wrote it before, I decided against editing it. Also, I learned while typing this answer that © makes a comment (I thought it looked like @, but that is another character). Never knew what it was before now. Sample output: size? 7 /\ / O\ /∫ \ / © ∫°\ / θ ∫ ∫\ /° ° © ©\ /O ∫ O ° \ / θ °© ∫ O θ\ ------------------ ||  I love those ∫'s; they look like candy canes. • What version is this? Commented Jun 6, 2015 at 1:25 • @SuperJedi224 I added it to the answer Commented Jun 6, 2015 at 6:15 # Wolfram Language ( Mathematica ) As discussed at famed Reddit thread: t*sin (t) ≈ Christmas tree PD = .5; s[t_, f_] := t^.6 - f; dt[cl_, ps_, sg_, hf_, dp_, f_] := {PointSize[ps], Hue[cl, 1, .6 + sg .4 Sin[hf s[t, f]]], Point[{-sg s[t, f] Sin[s[t, f]], -sg s[t, f] Cos[s[t, f]], dp + s[t, f]}]}; frames = ParallelTable[ Graphics3D[Table[{dt[1, .01, -1, 1, 0, f], dt[.45, .01, 1, 1, 0, f], dt[1, .005, -1, 4, .2, f], dt[.45, .005, 1, 4, .2, f]}, {t, 0, 200, PD}], ViewPoint -> Left, BoxRatios -> {1, 1, 1.3}, ViewVertical -> {0, 0, -1}, ViewCenter -> {{0.5, 0.5, 0.5}, {0.5, 0.55}}, Boxed -> False, Lighting -> "Neutral", PlotRange -> {{-20, 20}, {-20, 20}, {0, 20}}, Background -> Black], {f, 0, 1, .01}]; Export["tree.gif", frames]  • Where you set the size and how it affects the generated tree? Commented Dec 28, 2013 at 15:24 • @manatwork this is basically graph t*sin(t) as i said in the post. So plotting for larger t's will just make a bigger tree: Table[..., {t, 0, 200, PD}] Commented Dec 28, 2013 at 19:41 # Bash with Bc and ImageMagick #!/bin/bash size="{1:-10}"

width=$(( size*25 )) height=$(( size*size+size*10 ))

cos=( $( bc -l <<< "for (i=0;i<3.14*2;i+=.05) c(i)*100" ) ) sin=($( bc -l <<< "for (i=0;i<3.14*2;i+=.05) s(i)*100" ) )
cos=( "${cos[@]%.*}" ) sin=( "${sin[@]%.*}" )

cos=( "${cos[@]/%-/0}" ) sin=( "${sin[@]/%-/0}" )

snow=()
needle=()
decor=()
for ((i=2;i<size+2;i++)); do
for ((j=3;j<=31;j++)); do
(( x=width/2+i*10+cos[62-j]*i*10/100 ))
(( y=i*i+sin[j]*i*5/100 ))

for ((e=0;e<i;e++)); do
needle+=(
-draw "line $x,$y $(( x+RANDOM%i-i/2 )),$(( y+RANDOM%i-i/2 ))"
-draw "line $(( width-x )),$y $(( width-x+RANDOM%i-i/2 )),$(( y+RANDOM%i-i/2 ))"
)
done

(( RANDOM%2 )) && (( x=width-x ))
snow+=(
-draw "circle $x,$(( y-i/2 )) $(( x+i/3 )),$(( y-i/2+i/3 ))"
)

(( RANDOM%10 )) || decor+=(
-fill "rgb($(( RANDOM%5*20+50 )),$(( RANDOM%5*20+50 )),$(( RANDOM%5*20+50 )))" -draw "circle$x,$(( y+i ))$(( x+i/2 )),$(( y+i+i/2 ))" ) done done flake=() for ((i=0;i<width*height/100;i++)); do flake+=( -draw "point$(( RANDOM%width )),$(( RANDOM%height ))" ) done convert \ -size "${width}x$height" \ xc:skyblue \ -stroke white \ -fill white \ "${snow[@]}" \
-blur 5x5 \
"${flake[@]}" \ -stroke brown \ -fill brown \ -draw "polygon$(( width/2 )),0 $(( width/2-size )),$height, $(( width/2+size )),$height" \
-stroke green \
-fill none \
"${needle[@]}" \ -stroke none \ -fill red \ "${decor[@]}" \
x:


Sample run:

bash-4.1$./xmas.sh 5  Sample output: Sample run: bash-4.1$ ./xmas.sh 15


Sample output:

C

Sample output for depth=4, zoom=2.0

This answer employs an approach quite different from other answers. It generates a tree structure by recursively branching. Each branch is represented by a set of circles. And finally the main function samples the circles and fill with characters when circles are met. Since it is done by sampling a scene (like ray-tracing), it is intrinsically scalable. The downside is speed, since it traverse the whole tree structure for every "pixel"!

The first command-line argument controls the depth of branching. And the second controls scale (2 means 200%).

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

#define PI 3.14159265359

float sx, sy;

float sdCircle(float px, float py, float r) {
float dx = px - sx, dy = py - sy;
return sqrtf(dx * dx + dy * dy) - r;
}

float opUnion(float d1, float d2) {
return d1 < d2 ? d1 : d2;
}

#define T px + scale * r * cosf(theta), py + scale * r * sin(theta)

float f(float px, float py, float theta, float scale, int n) {
float d = 0.0f;
for (float r = 0.0f; r < 0.8f; r += 0.02f)
d = opUnion(d, sdCircle(T, 0.05f * scale * (0.95f - r)));

if (n > 0)
for (int t = -1; t <= 1; t += 2) {
float tt = theta + t * 1.8f;
float ss = scale * 0.9f;
for (float r = 0.2f; r < 0.8f; r += 0.1f) {
d = opUnion(d, f(T, tt, ss * 0.5f, n - 1));
ss *= 0.8f;
}
}

return d;
}

int ribbon() {
float x = (fmodf(sy, 0.1f) / 0.1f - 0.5f) * 0.5f;
return sx >= x - 0.05f && sx <= x + 0.05f;
}

int main(int argc, char* argv[]) {
int n = argc > 1 ? atoi(argv[1]) : 3;
float zoom = argc > 2 ? atof(argv[2]) : 1.0f;
for (sy = 0.8f; sy > 0.0f; sy -= 0.02f / zoom, putchar('\n'))
for (sx = -0.35f; sx < 0.35f; sx += 0.01f / zoom) {
if (f(0, 0, PI * 0.5f, 1.0f, n) < 0.0f) {
if (sy < 0.1f)
putchar('.');
else {
if (ribbon())
putchar('=');
else
putchar("............................#j&o"[rand() % 32]);
}
}
else
putchar(' ');
}
}

• I think it's safe to say this is the most technically impressive answer to this question so far. Commented Mar 7, 2015 at 2:38

# Mathematica ASCII

I really like ASCII art, so I add another very different answer - especially so it's so short in Mathematica:

Column[Table[Row[RandomChoice[{"+", ".", "*", "~", "^", "o"}, k]], {k, 1, 35, 2}],
Alignment -> Center]


And now with a bit more sophistication a scalable dynamic ASCII tree. Watch closely - the tree is also changing - snow sticks to branches then falls ;-)

DynamicModule[{atoms, tree, pos, snow, p = .8, sz = 15},

atoms = {
Style["+", White],
Style["*", White],
Style["o", White],
Style[".", Green],
Style["~", Green],
Style["^", Green],
Style["^", Green]
};

pos = Flatten[Table[{m, n}, {m, 18}, {n, 2 m - 1}], 1];

tree = Table[RandomChoice[atoms, k], {k, 1, 35, 2}];

snow = Table[
RotateLeft[ArrayPad[{RandomChoice[atoms[[1 ;; 2]]]}, {0, sz}, " "],
RandomInteger[sz]], {sz + 1}];

Dynamic[Refresh[

Overlay[{

tree[[Sequence @@ RandomChoice[pos]]] = RandomChoice[atoms];
Column[Row /@ tree, Alignment -> Center, Background -> Black],

Grid[
snow =
RotateRight[
RotateLeft[#,
RandomChoice[{(1 - p)/2, p, (1 - p)/2} -> {-1, 0, 1}]] & /@
snow
, {1, 0}]]

}, Alignment -> Center]

, UpdateInterval -> 0, TrackedSymbols -> {}]
]
]


• Nice one. Where you adjust the size? Is that 35 in Table's parameters? Commented Jan 7, 2014 at 9:29
• @manatwork yes the 35 in Table. Thanks ;) Commented Jan 7, 2014 at 11:16

I made this for a challenge on /r/dailyprogrammer, (not sure if reusing code is against the spirit/rules of this) but:

Brainfuck. Takes as input a number (length of bottom row of leaves) and two characters. One space between each.

Example input: 13 = +

Example output:

      +
+++
+++++
+++++++
+++++++++
+++++++++++
+++++++++++++
===


Code:

                   >
,--
-----
-------
---------
---------[+
+++++++++++++
+++++++++++++++
+++<[>>++++++++++
<<-]>--------------
---------------------
-------------[<+>-]>[<<
+>>-]<,------------------
--------------],>,,>>++++[<
++++++++>-]++++++++++>+<<<<<-
[>>>>>>+>+<<<<<<<--]>>>>>>>[<<<
<<<<++>>>>>>>-]<<<<<<<[>>>>>>[<<<
.>>>>+<-]>[<+>-]<<[<<<.>>>>>+<<-]>>
[<<+>>-]<<<.>>><-<++<<<<<--]>>...>>>-
--[>+<<<<..>>>--]<.>>[<<<.>>>>+<-]<<<<<
...>>>.


## Processing

The original fractal Christmas tree. Mouse Y position determines size, use up and down arrow keys to change the number of generations.

int size = 500;

int depth = 10;

void setup() {
frameRate(30);
size(size, size, P2D);
}

void draw() {
background(255);
}

void keyPressed() {
if(keyCode == UP) depth++;
if(keyCode == DOWN) depth--;
depth = max(depth, 1);
}

void tree(float posX, float posY, float angle, float forkRight, float forkLeft, float length, int generation) {
if (generation > 0) {
float nextX = posX + length * sin(angle);
float nextY = posY - length * cos(angle);

line(posX, posY, nextX, nextY);

tree(nextX, nextY, angle + forkRight, forkRight, forkLeft, length*0.6, generation - 1);
tree(nextX, nextY, angle - forkLeft,  forkRight, forkLeft, length*0.6, generation - 1);
}
}


Or, if you prefer a fuller tree:

int size = 500;

int depth = 10;

void setup() {
frameRate(30);
size(size, size, P2D);
}

void draw() {
background(255);
tree(size/2.0 - 5, size, 0.0, 0.0, (size - mouseY)/3, depth);
}

void keyPressed() {
if(keyCode == UP) depth++;
if(keyCode == DOWN) depth--;
depth = max(depth, 1);
}

void tree(float posX, float posY, float angle, float fork, float length, int generation) {
if (generation > 0) {
float nextX = posX + length * sin(angle);
float nextY = posY - length * cos(angle);

line(posX, posY, nextX, nextY);

tree(nextX, nextY, angle + fork + radians(108), fork, length*0.6, generation - 1);
tree(nextX, nextY, angle - fork,                fork, length*0.6, generation - 1);
tree(nextX, nextY, angle + fork - radians(108), fork, length*0.6, generation - 1);
}
}


# Ruby

((1..20).to_a+[6]*4).map{|i|puts ('*'*i*2).center(80)}


You can customize output by changing *.
For a green tree: ((1..20).to_a+[6]*4).map{|i|puts "\e[32m"+('*'*i*2).center(80)}

Approach 2 (Xmas tree that doesn't look like an arrow)

((1..6).to_a+(3..9).to_a+(6..12).to_a+[3]*4).map{|i|puts "\e[32m"+('*'*i*4).center(80)}


Approach 3

((1..20).to_a+[6]*4).map{|i|puts' '*(20-i)+'*'*(2*i-1)}

• This is more an arrow, then a christmas tree! Commented Dec 14, 2013 at 13:40
• @klingt.net *than. Commented Dec 14, 2013 at 16:43
• Time to light up the christmas tree. Commented Dec 14, 2013 at 17:08
• And where you specify the size? Commented Dec 14, 2013 at 17:31
• @manatwork in ranges. 1..20, 1..6, etc. Commented Dec 14, 2013 at 17:56

# Turtle Graphics

Based on properties of the Euler spiral.

Code:

The scale is determined by the step size (move forward by: 6). An interactive version is available here.

P.S. Inspired by this question.

• Where is this "scalable"? Other than that, this is great! Commented Jan 11, 2014 at 4:40
• @Quincunx You can change scale by changing move forward by 6. For example, 10 will produce a larger tree. Actually there is no input in this "language" (or the whole code can be treated as input ;) ). Commented Jan 11, 2014 at 18:14

## Processing

I made this tree generator using an L-System and a Turtle.

code:

//My code, made from scratch:
final int THE_ITERATIONS = 7;
final float SCALE = 1;
final int ANGLE = 130;
final int SIZE = 4;

final int ITERATIONS = THE_ITERATIONS - 1;

int lineLength;

String lSystem;
ArrayList<Turtle> turtles;

int turtleIndex;
int lSystemIndex;

void setup()
{
size(320, 420);
background(255);
translate(width / 2, height - 70);

lineLength = ITERATIONS * 2 + 2;

lSystem = "[-F][+F]F";

turtles = new ArrayList<Turtle>(ITERATIONS + 1);
lSystemIndex = 0;

calculateLSystem();
println(lSystem);

doTurtles();
save("Tree.png");
}

void doTurtles()
{
while(lSystemIndex < lSystem.length())
{
print("\"" + lSystem.charAt(lSystemIndex) + "\": ");
if(lSystem.charAt(lSystemIndex) == 'F')
{
turtleForward();
}
else if(lSystem.charAt(lSystemIndex) == '[')
{
lineLength -= 2;
println(turtles.size());
}
else if(lSystem.charAt(lSystemIndex) == ']')
{
lineLength += 2;
removeTurtle();
println(turtles.size());
}
else if(lSystem.charAt(lSystemIndex) == '+')
{
turtleRight();
}
else if(lSystem.charAt(lSystemIndex) == '-')
{
turtleLeft();
}
lSystemIndex++;
}
}

{
}

void removeTurtle()
{
turtles.remove(turtles.size() - 1);
}

void turtleLeft()
{
turtles.get(turtles.size() - 1).left(ANGLE + random(-5, 5));
}

void turtleRight()
{
turtles.get(turtles.size() - 1).right(ANGLE + random(-5, 5));
}

void turtleForward()
{
print(turtles.get(turtles.size() - 1) + ": ");
strokeWeight(min(lineLength / SIZE, 1));
stroke(5 + random(16), 90 + random(16), 15 + random(16));
if(turtles.size() == 1)
{
strokeWeight(lineLength / 2);
stroke(100, 75, 25);
}
turtles.get(turtles.size() - 1).right(random(-3, 3));
turtles.get(turtles.size() - 1).forward(lineLength);
}

void calculateLSystem()
{
for(int i = 0; i < ITERATIONS; i++)
{
lSystem = lSystem.replaceAll("F", "F[-F][+F][F]");
}
lSystem = "FF" + lSystem;
}

void draw()
{

}

//——————————————————————————————————————————————————————
// Turtle code, heavily based on code by Jamie Matthews
// http://j4mie.org/blog/simple-turtle-for-processing/
//——————————————————————————————————————————————————————

class Turtle {
float x, y; // Current position of the turtle
float angle = -90; // Current heading of the turtle
boolean penDown = true; // Is pen down?
int lineLength;

// Set up initial position
Turtle (float xin, float yin) {
x = xin;
y = yin;
//lineLength = lineLengthin;
}

Turtle (Turtle turtle) {
x = turtle.x;
y = turtle.y;
angle = turtle.angle;
//lineLength = turtle.lineLength - 1;
}

// Move forward by the specified distance
void forward (float distance) {
distance = distance * SIZE * random(0.9, 1.1);
// Calculate the new position
float xtarget = x+cos(radians(angle)) * distance;
float ytarget = y+sin(radians(angle)) * distance;

// If the pen is down, draw a line to the new position
if (penDown) line(x, y, xtarget, ytarget);
println(x + ", " + y + ", " + xtarget + ", " + ytarget);
// Update position
x = xtarget;
y = ytarget;
}

// Turn left by given angle
void left (float turnangle) {
angle -= turnangle;
println(angle);
}

// Turn right by given angle
void right (float turnangle) {
angle += turnangle;
println(angle);
}
}

• Yes! An L-System! Commented Dec 18, 2013 at 8:47
• I agree about it being the most realistic :) Commented Dec 20, 2013 at 22:31
• @Timtech I disagree. I think this is the second most realistic, after Jan Dvorak's Javascript answer. I mean, look at those needles (on this one)! They are all clustered together in patterns that I have not seen on an evergreen tree. However, Jan's tree looks a lot like a fir sapling to me. Commented Dec 21, 2013 at 0:20
• @Quincunx I must have missed that one. Still, this one looks pretty good. Commented Dec 21, 2013 at 0:38
• @Quincunx Jan's tree—and Howard's, too—is really cool, but not necessarily completely realistic. Jan even admits that the tree is only "quasirealistic". – RyanCarlson 10 secs ago Commented Dec 21, 2013 at 13:51

# JavaScript (run on any page in console)

I was golfing this but then decided not to, so as you can see there are TONS of magic numbers :P

// size
s = 300

document.write('<canvas id=c width=' + s + ' height=' + s + '>')
c = document.getElementById('c').getContext('2d')
c.fillStyle = '#0D0'
for (var i = s / 3; i <= s / 3 * 2; i += s / 6) {
c.moveTo(s / 2, s / 10)
c.lineTo(s / 3, i)
c.lineTo(s / 3 * 2, i)
c.fill()
}
c.fillStyle = '#DA0'
c.fillRect(s / 2 - s / 20, s / 3 * 2, s / 10, s / 6)


Result for s = 300:

s = 600:

• Are you going to decorate the tree? :-) Commented Dec 12, 2013 at 23:53
• @Quincunx Possibly, I may work on that later :) Commented Dec 12, 2013 at 23:54
• GAH! Where are the semicolons?! Commented Dec 17, 2013 at 0:46
• @AndrewLarsson: Semicolons are not required in JavaScript Commented Dec 18, 2013 at 14:08

## Game Maker Language

spr_tree

The tree's Create Event

image_speed=0
size=get_integer("How big do you want me to be?#Integer between 1 and 10, please!",10)
image_index=size-1


Room, 402 by 599

The tree is placed at (0,0)

Bonus! You can resize the Christmas tree after the initial input with the keys 0-9.

Actually picked this up by accident while editing an answer in this question. Go figure.

Use this by running the code, typing in your number that you want, swiping over to the SE post and clicking in the text field. This exploits the fact that quotes stack.

tell application "System Events"
set layers to (display dialog "" default answer "")'s text returned as number
delay 5
repeat layers times
keystroke ">"
end repeat
end tell

Output (input 50):

>

## Decorated FORTRAN tree

    character(len=36) :: f='/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\'
character(len=18) :: g = '                  '
character(len=14) :: p = ".x$.+oO+oO.#,~" character(len=10) :: q n = iargc() if (n /= 1) then k = len(g) else call getarg(1,q) read(q,*) k end if l = modulo(k,len(g))+1 do i=1,l j = mod(i,len(p)-1)+1 print *,g(1:l-i),p(j:j),f(1:2*i),p(j+1:J+1) end do print *,g(1:l-1),f(1:4) end  The tree has a limited range of sizes, but it believe it accurately reflects the life of most Christmas trees. From infant tree: $./tree
x/$/\/\  To adolescent tree: ./tree 6 x/$
$/\/\. ./\/\/\+ +/\/\/\/\o o/\/\/\/\/\O O/\/\/\/\/\/\+ +/\/\/\/\/\/\/\o /\/\  To adult: $./tree 17
x/$/\/\. ./\/\/\+ +/\/\/\/\o o/\/\/\/\/\O O/\/\/\/\/\/\+ +/\/\/\/\/\/\/\o o/\/\/\/\/\/\/\/\O O/\/\/\/\/\/\/\/\/\. ./\/\/\/\/\/\/\/\/\/\# #/\/\/\/\/\/\/\/\/\/\/\, ,/\/\/\/\/\/\/\/\/\/\/\/\~ ./\/\/\/\/\/\/\/\/\/\/\/\/\x x/\/\/\/\/\/\/\/\/\/\/\/\/\/$
\$/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\.
./\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\+
+/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\o
o/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\O
/\/\


# Java

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

import javax.imageio.ImageIO;

public class ChristmasTree {
static class Point{
Point(int a,int b){x=a;y=b;}
int x,y;
double distance(Point o){
int dx=x-o.x;
int dy=y-o.y;
return Math.sqrt(dx*dx+dy*dy);
}
}
static int siz;
static BufferedImage b;
static Random r=new Random();
public static void main(String[]args) throws IOException{

if(args.length==0){
siz=(new Scanner(System.in)).nextInt();
}else{
siz=Integer.parseInt(args[0]);
}
b=new BufferedImage(20*siz,30*siz,BufferedImage.TYPE_INT_RGB);
Graphics2D g=(Graphics2D)b.getGraphics();
g.setColor(new Color(140,70,20));
int h=b.getHeight();h*=0.4;
for(int i=(int)(0.4*b.getWidth());i<(int)(0.6*b.getWidth());i++){
if(r.nextDouble()<0.3){
g.drawLine(i,b.getHeight(),i+r.nextInt(2)-1,h);
}
}
for(int i=h;i<b.getHeight();i++){
if(r.nextDouble()<0.3){
g.drawLine((int)(0.4*b.getWidth()),i,(int)(0.6*b.getWidth()),i);
}
}
for(int i=0;i<siz;i++){
g.setColor(new Color(r.nextInt(4),150+r.nextInt(15),20+r.nextInt(7)));
g.drawLine(b.getWidth()/2-(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9)+r.nextInt(5)-2,b.getWidth()/2+(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9)+r.nextInt(5)-2);
g.setColor(new Color(r.nextInt(4),150+r.nextInt(15),20+r.nextInt(7)));
g.drawLine(b.getWidth()/2-(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9),b.getWidth()/2,(int)(b.getHeight()*(0.1+(.06*i)/siz)));
g.setColor(new Color(r.nextInt(4),150+r.nextInt(15),20+r.nextInt(7)));
g.drawLine(b.getWidth()/2+(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9),b.getWidth()/2,(int)(b.getHeight()*(0.1+(.06*i)/siz)));
}
g.setColor(new Color(150,120,40));
g.fillOval((b.getWidth()-siz-2)/2,b.getHeight()/10,siz+2,siz+2);
g.setColor(new Color(250,240,80));
g.fillOval((b.getWidth()-siz)/2,b.getHeight()/10,siz,siz);
List<Color>c=Arrays.asList(new Color(0,255,0),new Color(255,0,0),new Color(130,0,100),new Color(0,0,200),new Color(110,0,200),new Color(200,205,210),new Color(0,240,255),new Color(255,100,0));
List<Point>pts=new ArrayList<>();
loop:for(int i=0;i<8+siz/4;i++){
int y=r.nextInt((8*b.getHeight())/11);
int x=1+(int)(b.getWidth()*0.35*y/((8*b.getHeight())/11));
x=r.nextInt(2*x)-x+b.getWidth()/2;
y+=b.getHeight()/8;
g.setColor(c.get(r.nextInt(c.size())));
x-=siz/2;
Point p=new Point(x,y);
for(Point q:pts){
if(q.distance(p)<1+2*siz)continue loop;
}
g.fillOval(x,y,siz,siz);
}
ImageIO.write(b,"png",new File("tree.png"));
}
}


Sample results:

Size=3:

Size=4:

Size=5:

Size=12:

Size=20:

• I didn't notice this before. Super cool +1 Commented Dec 22, 2015 at 20:04

Rebol

With a dialect to display the symbols. To change the tree size, just change the parameter of make-tree.

make-tree: func [int /local tr] [
tr: copy []
length: (int * 2) + 3
repeat i int [
repeat j 3 [
ast: to-integer ((i * 2) - 1 + (j * 2) - 2)
sp: to-integer (length - ast) / 2
append/dup tr space sp
append/dup tr "*" ast
append tr lf
]
]
append/dup tr space (length - 1) / 2
append tr "|"
append tr lf
tr
]

print make-tree 3


• Where you set the size and how it affects the generated tree? Commented Dec 24, 2013 at 16:13
• @manatwork To change the tree block. You can resize it or change some of the symbols at your will. Commented Dec 24, 2013 at 16:19
• @WayneTsui this doesn't conform to the OP's requirements, "size must be choosable by some input method" and "larger inputs should produce a larger tree." Commented Dec 25, 2013 at 14:28
• a new make-tree function from @kealist Commented Dec 25, 2013 at 15:49

Python

import sys
w = sys.stdout.write
def t(n,s):
for i in range(n):
for a in range(n-i):
w(" ")
w("[")
for l in range(i<<1):
if i==n-1:
w("_")
else:
w("~")
w("]")
print("")
for o in range(s):
for i in range(n):
w(" ")
print("[]")

t(10, 2)


## Ti-Basic 84

              :
Input
S:Lbl 1
S-1→S
:
"||
"+""→
Str1:"
"→Str2
:Disp Str2+
"   **":Disp
Str2+"  "+"*"+
Str1+"*":Disp "
"+Str1+"*-"+"||-*
":Disp Str1+"*--||-
-*":Disp "   *---||--
-*":Disp "  *----||----
*":Disp Str1+"   "+Str2+"
":If S>0:Goto 2:Goto 1:Lbl
2


Output (size 1):

       **
*||*
*-||-*
*--||--*
*---||---*
*----||----*
||

• Where is the size choosable? This is a fixed-size tree Commented Dec 20, 2013 at 23:00
• @Quincunx Fixed. Commented Dec 20, 2013 at 23:33
• -1; you can't just insert arbitrary whitespace into a TI-Basic program. Commented Oct 6, 2015 at 4:32