# Code Golf Christmas Edition: How to print out a Christmas tree of height N

Given a number N, how can I print out a Christmas tree of height N using the least number of code characters? N is assumed constrained to a minimum value of 3, and a maximum value of 30 (bounds and error checking are not necessary). N is given as the one and only command line argument to your program or script.

All languages appreciated, if you see a language already implemented and you can make it shorter, edit if possible - comment otherwise and hope someone cleans up the mess. Include newlines and White Spaces for clarity, but don't include them in the character count.

A Christmas tree is generated as such, with its "trunk" consisting of only a centered "*"

N = 3:

   *
***
*****
*


N = 4:

    *
***
*****
*******
*


N = 5:

     *
***
*****
*******
*********
*


N defines the height of the branches not including the one line trunk.

Merry Christmas PPCG!

First try in LUA

f=string.rep p=print function t(N) for i=0,N do s=f(" ",N-i) p(s..f("+",2*i-1)..s) end p(f(" ",N-1).."+"..f(" ",N-1)) end t(arg)


After selecting all of it scite tells me these are 131 chars

For clarities sake without optimizing away the \n etc:

f=string.rep
p=print
function t(N)
for i=0,N do
s=f(" ",N-i)
p(s..f("+",2*i-1)..s)
end
p(f(" ",N-1).."+"..f(" ",N-1))
end
t(arg)


For the python version by ΤΖΩΤΖΙΟΥ I get shown 115 chars... Hrm, some more things to optimize

• Note: all insignificant/irrelevant whitespace should be ignored, as per the question specifications. So, any beautifying/syntax-needed whitespace doesn't count, but a " " literal does count. So your fully expanded version has 119 chars (3 significant spaces)
– tzot
Dec 25, 2008 at 20:06

## Scala, 97 chars

This one gets n from command line.

Thanks to ΤΖΩΤΖΙΟΥ for the * operator

val n=args(0).toInt*2
(1.until(n,2))foreach{i=>println(" "*(n-i)+"* "*i)}
println (" "*(n-1) + "*")


Language: Erlang, Char count: 151

A little bit shorter Erlang version:

-module(x).
-export([t/1]).
t(N)->[H|_]=T=t(N,1),io:format([T,H]).
t(0,_)->[];t(N,M)->[[d(N,32),d(M,42),10]|t(N-1,M+2)].
d(N,C)->lists:duplicate(N,C).


When should run with command line argument

-module(x).
-export([t/1]).
t([N])->[H|_]=T=t(list_to_integer(N),1),io:format([T,H]),init:stop().
t(0,_)->[];t(N,M)->[[d(N,32),d(M,42),10]|t(N-1,M+2)].
d(N,C)->lists:duplicate(N,C).


Invocation:

$erl -noshell -noinput -run x t 11 * *** ***** ******* ********* *********** ************* *************** ***************** ******************* ********************* *  Language: FoxPro 2.x for DOS (should work with Clipper too), Char count: 62 para n for h=1 to n ?spac(n-h)+repl('*',2*h-1) endf ?spac(n-1)+'*'  Language: Euphoria 147 chars (9 relevant spaces): include get.e object a = command_line(), t = 42 a = value( a ) a = a for i = 1 to a do puts(1, repeat( 32, a - i ) & t & 10) t &= "**" end for puts(1, repeat( 32, a - 1 ) & 42 & 10 )  With only relevant whitespace: include get.e object a=command_line(),t=42a=value(a)a=afor i=1to a do puts(1,repeat(32,a-i)&t&10)t&="**"end for puts(1,repeat(32,a-1)&42&10)  Excessively long version in J (97 chars) t=:3 :0 d=:0 k=:'' while.d<y do. k=:k,((d{((y-1)+>:i.y))$!.'*'((d{((|.i.y)))$,' ')),LF d=:d+1 end.k,y$k
)


Run it this way:

t N


where N is tree height.

And Merry Xmas (a bit late).

Here's a Ruby Newbie (ha! It rhymes!) with his first working solution:

Ruby 164 characters (of readable code)

n=gets.to_i-1
(0..n).each do |j|
(n-j).times do
print " "
end
(1+j*2).times do
print "*"
end
print "\n"
end
n.times do
print " "
end
print "*"


# GolfScript, 34 characters

Another GolfScript entry:

~:x,-1%[x(]+{." "*x@- 2*("*"*n.},;


Explanation:

~:x                   #read input, store into x
,                     #create array [0,1,2,...,x-1]
-1%                   #reverse it
[x(]+                 #append x-1 to the array
{." "*x@- 2*("*"*n.}, #map each element in array to this block, outputs each line
;                     #remove results of map from stack


The block does:

{.                    #duplicate value given by map (stack is now: i i)
" "*                  #push " ", times it by i (stack now: i "   ")
x                     #push x, stack is: (i "   " x), and bring i
@                     #bring i to the front (stack is: "   " x i)
- 2*(                 #pop x,i, push ((x-i)*2-1)
"*"*                  #print that many *'s
n.}                   #print newline, duplicate it so the map doesn't kill it


## JavaScript, 137 bytes

function k(a){var b="";for(i=0;i<a;i++){for(j=0;j<a*2;j++)b+=j>a-2-i
&&j<a+i?"*":" ";b+="\n"}for(i=0;i<a*2;i++)b+=i==a-1?"*":" ";return b}


Test case (formatting disorder is due to the first " marking a string):

k(3)

"  *
***
*****
*   "


# R, 94 chars

Christmas is over, but anyway:

t=function(N){
f=function(i)cat(rep(" ",N-i),rep("*",2*i-3),"\n",sep="")
lapply(2:N,FUN=f);f(2)
}


For trees of height 2 or more:

> t(2)  > t(3)  > t(5)
*        *         *
*       ***       ***
*       *****
*******
*

• We have posted similar R solutions in three minutes ;) Jan 8, 2014 at 14:37
• becomes obsolete, see @djhurio solution Jan 8, 2014 at 14:38
• btw, I have got attracted to this site by the "2014" problem. I have got a 20 chars solution in R, but cannot post it as the question is protected from newbies ;) Jan 8, 2014 at 14:51
• Would be nice to see your 20 char solution for the "2014" ;) Jan 8, 2014 at 15:24
• sum(T+T:exp(T+pi))-T Jan 8, 2014 at 15:30

# Python 2, 119 116

This one generates the tree on one line:

import sys
h=int(sys.argv)
print '\n'.join([" "*(h-i)+"*"*(i*2-1) for i in range(h,0,-1)][::-1]+[" "*(h-1)+"*"])


It's too bad you have to import the sys module in Python before being able to read argv.

Being used from Command Prompt:

C:\Users\User4\Desktop>treeprint.py 6
*
***
*****
*******
*********
***********
*


I have a Linux box but it can't connect to the Internet and only has Python 2.4, in case you're wondering why I'm using Windows.

# SOGL V0.12, 11 10 bytes

ƨ*αak} *¹╚


Try it Here!

Explanation:

     }      implicitly started loop, repeated input times
ƨ*          push "**"
α         append that to the variable A, here defaulted to an empty string
k       remove the first characters
*    push "*"
¹   wrap in an array
╚  center horizontally


# Excel VBA, 72 Bytes

Anonymous VBE immediate window function that takes input from range [A1] and outputs to the VBE immediate window

For i=1To[A1]:[B1]=i:?Spc([A1]-i)[Rept("*",2*B1-1)]:Next:?Spc([A1-1])"*"


# Python 3, 83 bytes

f=lambda n:'\n'.join([' '*(n-1-i)+'*'*(i*2+1)for i in range(n)])+'\n'+' '*(n-1)+'*'


# Dart, 174 characters

main(p){var x=-1,r='',a=int.parse(p),b=a,f=(x,y,[z='']){var s='';while(x-->0)s+=y;return s+z;};while(a-->0){x+=2;r+=f(a,' ')+f(x,'*','\n');}print('$r${f(b-1,' ','*')}');}


# JavaScript, 90 89 bytes

f=(l,n=1,s="")=>l+1?s+=f(l-1,n+2,l?*.repeat(n).padStart(l+n)+


Try it online!

Alternative:

f=(l,n=1)=>l+1&&f(l-1,n+2,console.log(l?"*".repeat(n).padStart(l+n):"*".padStart(n/2+1)))


Try it online!

• There's a padStart function in JavaScript?? And who says you never learn anything useful in CodeGolf... Apr 30, 2020 at 6:59

# APL(NARS), 37 chars, 74 bytes

{⊃⍵{(' '⍴⍨⍺-⍵),'*'⍴⍨1+⍵×2}¨0,⍨0,⍳⍵-1}


test:

  h←{⊃⍵{(' '⍴⍨⍺-⍵),'*'⍴⍨1+⍵×2}¨0,⍨0,⍳⍵-1}
h 5
*
***
*****
*******
*********
*
h 1
*
*
h 2
*
***
*
h 3
*
***
*****
*


Ot: It seems that your sys for know if i'am a human not work good in this chellphone (so I write this because possible this step is not taken)

# Python3,81 bytes

n=int(input());
for j in range(n):
print(' '*(n-j)+'*'*(2*j+1))
print(' '*n+'*')


try it online

• 79 bytes Sep 23, 2020 at 14:18

## Wren, 91 bytes

Fn.new{|n|
for(i in 0...n)System.print(" "*(n-i)+"*"*(2*i+1))
System.print(" "*n+"*")
}


Try it online!

# x86 machine code, 42 40 bytes

Same limitation as in previous x86 answer (N < 10) applies. It may be lifted by replacing the first four lines with the following six (+6 bytes):

start:
mov si, 82h
lodsw
xchg al, ah
and ax, 0F0Fh


Assembly source code:

start:
mov si, 82h
lodsb
aaa
xchg ax, cx
mov dx, 0A2Ah
mov di, dx
push cx
_loop:
push cx
rep stosb
xchg ax, dx
mov cx, bx
rep stosb
stosw
inc bx
inc bx
pop cx
xchg ax, dx
loop _loop
pop cx
rep stosb
xchg ax, dx
stosw
xchg ax, dx
mov ax, 0924h
stosb
int 21h
ret


SmileBASIC, 55 Bytes

Takes input from variable 'N'

FOR I=1TO N?" "*(N-I);"*"*(1+(I-1)*2)NEXT?" "*(N-1);"*"


I think it may be possible to shorten line 2 or 3 in the breakdown below

FOR I=1TO N                                                Iterate values of 'I' from 1 to N (One for each layer of branches)
?" "*(N-I)                                      Display spaces to offset asterisks, which begins at N-1 spaces long and end at 0 spaces long
;"*"*(1+(I-1)*2)                      Display Asterisks
NEXT                  End loop
?" "*(N-1);"*"    Display trunk


# C++, 188 bytes

#include<iostream>
using namespace std;
#define s string
int main(int a,char**c){int h=atoi(c);for(int i=0;i<h;i++){cout<<s(h-i,' ')<<s(i*2+1,'*')<<endl;}cout<<s(h,' ')<<'*'<<endl;}


Ungolfed:

#include<iostream>

using namespace std;

int main(int a,char**c)
{
int h = atoi(c);
for(int i=0; i<h; i++)
{
cout << string(h-i, ' ') << string(i*2+1, '*') << endl;
}
cout << string(h, ' ') << '*' << endl;
}


## C# 3.0, 158 bytes

int n=int.Parse(a);Console.WriteLine(Enumerable.Range(1,n).Concat(new int[]{1}).Select(x=>new string('*',x*2-1).PadLeft(x+n)).Aggregate((x,y)=>x+"\n"+y));


Ungolfed:

using System;
using System.Linq;
class Program
{
static void Main(string[] a)
{
int n = int.Parse(a);
Console.WriteLine(Enumerable.Range(1, n).Concat(new int[] { 1 })
.Select(x => new string('*', x * 2 - 1).PadLeft(x + n))
.Aggregate((x, y) => x + "\n" + y));
}
}


# Lua, 113 significant chars

s=string.rep;n=tonumber(arg);r=print;for i=0,n do l=s(" ", n-i)..s("*",(n-(n-i))*2+1);r(l)end r(s(" ",n).."*")

• The two ns in s("*",(n-(n-i))*2+1) can be canceled out, yielding s("*",i*2+1). Dec 23, 2018 at 0:47

## SAS, 70 87 bytes

87 bytes. With a pop window for N input.

data;
window _ n;
display _;
do i=1to n;
s=repeat('*',i*2-2);
put@(n-i+1)s;
end;
put@n'*';
run;


70 bytes. Imperfect, need to assign to N handly.

data;
n=9;
do i=1to n;
s=repeat('*',i*2-2);
put@(n-i+1)s;
end;
put@n'*';
run;


The result is

        *
***
*****
*******
*********
***********
*************
***************
*****************
*

• Do you have a link to this language? Is there really no way to take input?
– Jo King
Dec 7, 2022 at 6:51
• @JoKing It is relatively rarely used. SAS is a language to do statistical analysis. Dec 7, 2022 at 7:09

# Raku, 5048 46 bytes

(45 characters, but » is 2 bytes)

{(|^$^n,0)».&{printf "%{$n+$_}s ",\*x$_*2+1}}


Try it online!

Original 50-byte version:

-> \n{(|^n,0)».&{printf "%{n+$_}s ",'*'x 2*$_+1}}


48-byte version:

-> \n{(|^n,0)».&{printf "%{n+$_}s ",\*x$_*2+1}}

• '*' can be \*, instead of -> \n you can use a placeholder parameter ($^n) and you can rarrange the 2*$_+1 to have $_ first to save that space – Jo King Dec 7, 2022 at 7:38 • @jo Thanks! But I don't think I can use a placeholder, because I'm using it inside a nested block. Dec 7, 2022 at 17:05 • You can, just don't add the ^ to the second instance of $n, like {(|^$^n,0)».&{printf "%{$n+$_}s ",\*x$_*2+1}}
– Jo King
Dec 7, 2022 at 20:45
• Oh! Well, then. Thanks again! Dec 7, 2022 at 21:28