92
\$\begingroup\$

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!

\$\endgroup\$

105 Answers 105

0
\$\begingroup\$

C++

#include<iostream>

using namespace std;

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

golfed to 188 char

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

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
\$\endgroup\$
0
\$\begingroup\$

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)

"  *   
 ***  
***** 
  *   "
\$\endgroup\$
0
\$\begingroup\$

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)
*        *         *
*       ***       ***
         *       *****
                *******
                   *
\$\endgroup\$
  • \$\begingroup\$ We have posted similar R solutions in three minutes ;) \$\endgroup\$ – djhurio Jan 8 '14 at 14:37
  • \$\begingroup\$ becomes obsolete, see @djhurio solution \$\endgroup\$ – popojan Jan 8 '14 at 14:38
  • \$\begingroup\$ 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 ;) \$\endgroup\$ – popojan Jan 8 '14 at 14:51
  • \$\begingroup\$ Would be nice to see your 20 char solution for the "2014" ;) \$\endgroup\$ – djhurio Jan 8 '14 at 15:24
  • 1
    \$\begingroup\$ sum(T+T:exp(T+pi))-T \$\endgroup\$ – popojan Jan 8 '14 at 15:30
0
\$\begingroup\$

Python 2, 119 116

This one generates the tree on one line:

import sys
h=int(sys.argv[1])
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.

\$\endgroup\$
0
\$\begingroup\$

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
   a        load the variable A
    k       remove the first characters
       *    push "*"
        ¹   wrap in an array
         ╚  center horizontally
\$\endgroup\$
0
\$\begingroup\$

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])"*"
\$\endgroup\$
0
\$\begingroup\$

Python 3, 83 bytes

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

Lua, 113 significant chars

s=string.rep;n=tonumber(arg[1]);r=print;for i=0,n do l=s(" ", n-i)..s("*",(n-(n-i))*2+1);r(l)end r(s(" ",n).."*")
\$\endgroup\$
  • \$\begingroup\$ The two ns in s("*",(n-(n-i))*2+1) can be canceled out, yielding s("*",i*2+1). \$\endgroup\$ – cyclaminist Dec 23 '18 at 0:47
0
\$\begingroup\$

Dart, 174 characters

main(p){var x=-1,r='',a=int.parse(p[0]),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,' ','*')}');}
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 90 89 bytes

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

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!

\$\endgroup\$
0
\$\begingroup\$

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)

\$\endgroup\$
0
\$\begingroup\$

Python3,81 bytes

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

try it online

\$\endgroup\$
0
\$\begingroup\$

Wren, 91 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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
    aad

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.