# 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!

# J, 24 characters

(,{.)(}:@|."1,.])[\'*'$~  (,{.)(}:@|."1,.])[\'*'$~5
*
***
*****
*******
*********
*


Explanation:

'*'$~5 ***** [\'*'$~5
*
**
***
****
*****


Then }:@|."1 reverses each row and strips off the last column, and ,. staples it to ].

Then ,{. pastes the first column onto the bottom.

Previous entries:

29 characters, no spaces at all.

   ((\:i.@#),}.)"1$&'*'"0>:0,~i.3 * *** ***** * ((\:i.@#),}.)"1$&'*'"0>:0,~i.11
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************
*


   NB. count from 1 to n, then 1 again
>:0,~i.3
1 2 3 1
NB. replicate '*' x times each
$&'*'"0>:0,~i.3 * ** *** * NB. reverse each row (\:i.@#)"1$&'*'"0>:0,~i.3
*
**
***
*
}."1$&'*'"0>:0,~i.3 * ** NB. paste together ((\:i.@#),}.)"1$&'*'"0>:0,~i.3
*
***
*****
*

• With just 9 more characters you can give this function a name: c=:[:((\:i.@#),}.)"1[:$&'*'"0[:>:0,~i. – ephemient Jul 6 '09 at 20:45 • What, do you guys use some sort of J documentation library to understandable-ize the code? :) – RCIX Nov 20 '09 at 1:14 # Brainfuck, 240 characters  , >++ +++++ +[-<--- --->],[>+ +++++++[-<- ----->]<<[->+ +++++++++<]>>]< [->+>+>>>>>>>+<<< <<<<<<]>>>>++++++++ [-<++++>]>++++++[-<++ +++++>]+>>>++[-<+++++>] <<<<<<[-[>.<-]<[-<+>>+<]< [->+<]>>>>>[-<.>>+<]>[-<+>] >.<<++<<<-<->]>>>>>>>-[-<<<<< <.>>> >>>]< <<<<.  Not yet done. It works, but only with single-digit numbers. EDIT: Done! Works for interpreters using 0 as EOF. See NOTEs in commented source for those with -1. EDIT again: I should note that because Brainfuck lacks a standard method for reading command line arguments, I used stdin (standard input) instead. ASCII, of course. EDIT a third time: Oh dear, it seems I stripped . (output) characters when condensing the code. Fixed... Here's the basic memory management of the main loop. I'm sure it can be heavily optimized to reduce the character count by 30 or so. 1. Temporary 2. Copy of counter 3. Counter (counts to 0) 4. Space character (decimal 32) 5. Asterisk character (decimal 42) 6. Number of asterisks on current line (1 + 2*counter) 7. Temporary 8. New line character 9. Temporary? 10. Total number of lines (i.e. input value; stored until the very end, when printing the trunk) Condensed version: ,>++++++++[-<------>],[>++++++++[-<------>]<<[->++++++++++<]>>]<[->+>+>>>>>>>+<<<<<<<<<]>>>>++++++++[-<++++>]>++++++[-<+++++++>]+>>>++[-<+++++>]<<<<<<[-[>.<-]<[-<+>>+<]<[->+<]>>>>>[-<.>>+<]>[-<+>]>.<<++<<<-<->]>>>>>>>-[-<<<<<<.>>>>>>]<<<<<.  And the pretty version: ASCII to number ,> ++++++++[-<------>] = 48 ('0') Second digit (may be NULL) , NOTE: Add plus sign here if your interpreter uses negative one for EOF [ NOTE: Then add minus sign here >++++++++[-<------>] <<[->++++++++++<]>> Add first digit by tens ] Duplicate number <[->+>+>>>>>>>+<<<<<<<<<]>> Space char >>++++++++[-<++++>] Asterisk char >++++++[-<+++++++>] Star count + New line char >>>++[-<+++++>]<<< <<< Main loop [ Print leading spaces -[>.<-] Undo delete <[-<+>>+<] <[->+<] >> Print stars >>>[-<.>>+<] Add stars and print new line >[-<+>] >.< <++ <<< -<-> End main loop ] Print the trunk >>>>>>> -[-<<<<<<.>>>>>>] <<<<<. Merry Christmas =)  • my brain feels f.....sick – JoshBerke Jan 22 '09 at 0:14 • Oh my god. – anonymous coward Jul 7 '09 at 0:04 • I found this version online that's only 127 bytes when you delete unnecessary characters. – JosiahRyanW Nov 14 '19 at 0:15 # Perl, 50 chars (1 relevant spaces) perl: one line version: print$"x($a-$_),'*'x($_*2+1),$/for 0..($a=pop)-1,0  and now with more whitesapce: print$"  x ( $a -$_ ),             #"# Syntax Highlight Hacking Comment
'*' x ( $_ * 2 + 1),$/
for 0 .. ( $a = pop ) - 1, 0;$ perl tree.pl 3
*
***
*****
*
$perl tree.pl 11 * *** ***** ******* ********* *********** ************* *************** ***************** ******************* ********************* *$


### Expanded Explanation for Non-Perl Users.

# print $Default_List_Seperator ( a space ) # repeated ($a - $currentloopiterationvalue ) times, print$" x ( $a -$_ ),
#"# print '*' repeated( $currentloopiteration * 2 + 1 ) times. '*' x ($_ * 2  + 1),
# print $Default_input_record_seperator ( a newline )$/
# repeat the above code, in a loop,
#   iterating values 0 to ( n - 1) , and then doing 0 again
for 0 .. ( $a = pop ) - 1, 0; # prior to loop iteration, set n to the first item popped off the default list, # which in this context is the parameters passed on the command line.  • Holy crap... perl truly is unreadable. – zenazn Dec 25 '08 at 17:20 • @zenazn, also, it should be noticed that most golfing is BAD code in any language. If this were a competition for the cleanest code, we could win that too. – Kent Fredric Dec 25 '08 at 17:23 • @zenazn: proof, you can see us collaborating and improving each others code above, this proves WE can read EACH OTHERS code perfectly fine. – Kent Fredric Dec 25 '08 at 17:28 • PS: Thanks for the explanation for non-Perl programmers. It's still pretty unreadable, but at least it makes sense. I guess you get used to it after a while. – zenazn Dec 25 '08 at 18:11 • @RobH: J is the child of APL. In some senses, it's more unreadable because it doesn't use APL's character set with a special symbol for every operation -- it overloads ASCII characters with multiple meanings, instead. stackoverflow.com/questions/392788/1088931#1088931 – ephemient Jul 6 '09 at 20:01 ### Language: Python (through shell), Char count: 64 (2 significant spaces) python -c " n=w=$1
s=1
while w:
print' '*w+'*'*s
s+=2
w-=1
print' '*n+'*'"

$sh ax6 11 * *** ***** ******* ********* *********** ************* *************** ***************** ******************* ********************* *  • what I like most about this solution is that python makes it really hard to write obscure code, it's one of the most readable solutions – Georg Schölly Dec 26 '08 at 0:46 • You're using the shell to process the argument, which isn't in the spirit of code golf IMO. Using "import sys" and "n=w=int(sys.argv[1])" and an indent of 1 character for the loop body, I come up with 89 characters for this version. – Joshua Swink Dec 26 '08 at 19:19 • This is how I did it before. The spirit of this question is to have fun, and in addition there was no specification of using only one language :) See the brainfuck answer, for example; no arguments. – tzot Dec 26 '08 at 20:56 # x86 asm 16-bit, 50 bytes No assembly version yet? :)  bits 16 org 100h mov si, 82h lodsb aaa mov cx, ax mov dx, 1 push cx mov al, 20h int 29h loop$-2
push dx
mov al, 2ah
int 29h
dec dx
jnz $-3 pop dx mov al, 0ah int 29h inc dx inc dx pop cx loop$-23
shr dx, 1
xchg cx, dx
mov al, 20h
int 29h
loop $-2 mov al, 2ah int 29h ret  (Note: N is limited to 1 - 9 in this version) G:\>tree 9 * *** ***** ******* ********* *********** ************* *************** ***************** *  Download here Language: Windows Batch Script (shocking!) @echo off echo Enable delayed environment variable expansion with CMD.EXE /V rem Branches for /l %%k in (1,1,%1) do ( set /a A=%1 - %%k set /a B=2 * %%k - 1 set AA= for /l %%i in (1,1,!A!) do set "AA=!AA! " set BB= for /l %%i in (1,1,!B!) do set BB=*!BB! echo !AA!!BB! ) rem Trunk set /a A=%1 - 1 set AA= for /l %%i in (1,1,!A!) do set "AA=!AA! " echo !AA!*  • masochist! I like it – Colin Pickard Jan 8 '09 at 14:17 • Very nice... you get +1 – ojblass Apr 26 '09 at 4:49 • Delayed variable expansion can be enabled using the setlocal enabledelayedexpansion command. – Helen Jul 30 '09 at 17:49 • dude. seriously? – Earlz Dec 1 '09 at 2:34 • Can't make it work. First time I try though. – Fabinout Nov 15 '13 at 10:27 ### Ruby, 64 bytes n=ARGV[0].to_i ((1..n).to_a+[1]).each{|i|puts' '*(n-i)+'*'*(2*i-1)}  n=$*[0].to_i
((1..n).to_a<<1).each{|i|puts' '*(n-i)+'*'*(2*i-1)}


Merry Christmas all!

Edit: Improvements added as suggested by Joshua Swink

• dang I was hoping nobody tried it in ruby yet. nice job. – esabine Dec 25 '08 at 15:37
• This is a very nice line of Ruby. – zenazn Dec 25 '08 at 17:17
• Did I seem too abrubt? Sorry, not my intention! Merry XMas! :) – tzot Dec 25 '08 at 20:08
• Didn't mean to be mean either, and of course you were right! Merry Xmas! – user4812 Dec 25 '08 at 20:47
• On 1.9, you can save some more chars: n=$*[0].to_i;puts [*1..n,1].map{|i|" "*(n-i)+"*"*(2*i-1)} brings it down to 58. – manveru Sep 14 '10 at 10:05 ### Language: C#, Char count: 120 static void Main(string[] a) { int h = int.Parse(a[0]); for (int n = 1; n < h + 2; n++) Console.WriteLine(n <= h ? new String('*', n * 2 - 1).PadLeft(h + n) : "*".PadLeft(h + 1)); } }  Just the code, without formatting (120 characters): int h=int.Parse(a[0]);for(int n=1;n<h+2;n++)Console.WriteLine(n<=h?new String('*',n*2-1).PadLeft(h+n):"*".PadLeft(h+1));  Version with 109 characters (just the code): for(int i=1,n=int.Parse(a[0]);i<n+2;i++)Console.WriteLine(new String('*',(i*2-1)%(n*2)).PadLeft((n+(i-1)%n)));  Result for height = 10:  * *** ***** ******* ********* *********** ************* *************** ***************** ******************* *  ### Language: dc (through shell) Char count: 83 A little bit shorter dc version: dc -e '?d1rdsv[d32r[[rdPr1-d0<a]dsaxszsz]dsbx1-rd42rlbx2+r10Plv1-dsv0<c]dscxszsz32rlbx[*]p' <<<$1


EDIT: changed constant 10 into $1 • Good lord, what the hell is that? – amischiefr Aug 6 '09 at 18:34 • Just read man page ;-) – Hynek -Pichi- Vychodil Aug 8 '09 at 5:54 python, "-c" trick... @61 chars (and one line) python -c"for i in range($1)+[0]:print' '*($1-i)+'*'*(2*i+1)"  • Actually, it's 57 characters, only the ' ' space is significant as per the question specifications. – tzot Dec 27 '08 at 15:05 Here's a reasonably space-efficient Haskell version, at 107 characters: main=interact$(\g->unlines$map(\a->replicate(g-a)' '++replicate(a*2-1)'*')$[1..g]++[1]).(read::[Char]->Int)


running it:

$echo 6 | runhaskell tree.hs * *** ***** ******* ********* *********** *  Merry Christmas, all :) ### Language: dc (through shell), Char count: 119 (1 significant space) Just for the obscurity of it :) dc -e "$1dsnsm"'
[[ ]n]ss
[[*]n]st
[[
]n]sl
[s2s1[l2xl11-ds10<T]dsTx]sR
[lndlslRxlcdltlRxllx2+sc1-dsn0<M]sM
1sclMxlmlslRxltxllx
'

print ('*'*(2*i+1)).center(2*$1) "  I learned the center function and that "python -c" can accept more than one line code. Thanks, ΤΖΩΤΖΙΟΥ. ## C# using Linq:  using System; using System.Linq; class Program { static void Main(string[] args) { int n = int.Parse(args[0]); int i=0; Console.Write("{0}\n{1}", string.Join("\n", new int[n].Select(r => new string('*',i * 2 + 1) .PadLeft(n+i++)).ToArray()),"*".PadLeft(n)); } }  170 charcters. int n=int.Parse(a[0]);int i=0;Console.Write("{0}\n{1}",string.Join("\n",Enumerable.Repeat(0,n).Select(r=>new string('*',i*2+1).PadLeft(n+i++)).ToArray()),"*".PadLeft(n));  AWK, 86 characters on one line. awk '{s="#";for(i=0;i<$1;i++){printf"%"$1-i"s%s\n","",s;s=s"##"}printf"%"$1"s#\n",""}'

echo "8" | awk '{s="#";for(i=0;i<$1;i++){printf"%"$1-i"s%s\n","",s;s=s"##"}printf"%"$1"s#\n",""}' # ### ##### ####### ######### ########### ############# ############### # cat tree.txt 3 5 awk '{s="#";for(i=0;i<$1;i++){printf"%"$1-i"s%s\n","",s;s=s"##"}printf"%"$1"s#\n",""}' tree.txt
#
###
#####
#
#
###
#####
#######
#########
#


Language:PowerShell, Char count: 41 (including 1 space)

s="*"
for (( i=0; i<$n; i++ )); do printf "%$(($n+$i))s\n" "$s" s+="**" done printf "%$(($n))s\n" "*"  • – roblogic Aug 22 '19 at 14:34 ### Language: Python, Significant char count: 90 It's ugly but it works: import sys n=int(sys.argv[1]) print"\n".join(" "*(n-r-1)+"*"*(r*2+1)for r in range(n)+[0])  ... $ python tree.py 13
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************
***********************
*************************
*

• Your character count is 98 (2 significant spaces, those in quotes) – tzot Dec 25 '08 at 23:37

Since this is a CW: I don't like that code golfs are always organized in terms of "number of characters" or somesuch. Couldn't they be organized in terms of number of instructions for the compiler/interpreter (or some similar criterion)? Here is the Ruby solution again, and it's basically the same, but now for human consumption too:

SPACE = " "
ASTERISK = "*"
height_of_tree=ARGV[0].to_i
tree_lines = (1..height_of_tree).to_a
tree_lines.push 1 # trunk
tree_lines.each do | line |
spaces_before = SPACE*(height_of_tree-line)
asterisks = ASTERISK*(2*line-1)
puts spaces_before + asterisks
end

• I agree with the first statement. In such terms, languages like perl have a starting advantage. Should be something like number of statemetns or the like. – ldigas Jul 8 '09 at 5:35
• thanks... I asked a question about golf yesterday and the way to do it might be with "tokens"... that way name-length and so forth is not penalized. – Yar Jul 8 '09 at 9:22

# Charcoal, 9 bytes (noncompeting)

Ｇ↗↘←Ｎ*Ｍ↓*


Try it online!

## Verbose

Polygon(:UpRight, :DownRight, :Left, InputNumber(), "*")
Move(:Down)
Print("*")


Try it online!

# 05AB1E, 9 bytes

LĆ'*×j€û»


€û» can alternatively be ».º for the same byte-count.

Explanation:

L            # Create a list in the range [1, (implicit) input]
#  i.e. 3 → [1,2,3]
Ć           # Enclose; adding the first item (the 1) also add the end of the list
#  i.e. [1,2,3] → [1,2,3,1]
'*×       '# For each, repeat the string "*" that many times
#  i.e. [1,2,3,1] → ["*","**","***","*"]
j       # Prepend spaces to make all items of a length equal to the (implicit) input
#  i.e. ["*","**","***","*"] and 3 → ["  *"," **","***","  *"]
€û     # Palindromize each string
#  i.e. ["  *"," **","***","  *"] → ["  *  "," *** ","*****","  *  "]
»    # Join the list by newlines (and output implicitly)
#  i.e. ["  *  "," *** ","*****","  *  "] → "  *  \n *** \n*****\n  *  "