112
\$\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\$
0

116 Answers 116

2
\$\begingroup\$

Intel 4004 machine code, 59 bytes

This 4-bit chip was the first commercial microprocessor, introduced in 1971. Multiplication and division were performed in software, and the accumulator could not be copied to one of the 16 registers except by swapping values.

40 33 50 0F A0 F8 B0 A0 1C 02 A1 B0 50 0F C0 24
20 A0 F8 50 2B 24 2A A1 90 F5 50 2B 24 20 A0 F8
50 2B 24 0C 53 E0 24 0D 53 E0 C0 14 32 53 E0 F8
40 2B C0 53 F0 B3 B0 A0 B1 50 02

The assembly code requires this python emulator for meaningful output.

jun start

mainloop:
    jms printline
    ld r0
    dac
    xch r0
    ld r0
    jcn an mainloop
    ld r1
    xch r0
    jms printline
    bbl 0

printline:
    fim r2 32
    ld r0
    dac
    jms printx

    fim r2 42
    ld r1
    sub r0
    ral
    jms printx

    fim r2 32
    ld r0
    dac
    jms printx

    ;carriage return
    fim r2 12
    jms $3e0
    fim r2 13
    jms $3e0

    bbl 0

printx: 
    jcn az ditch
    jms $3e0
    dac
    jun printx
ditch:
    bbl 0

start:
    jms $3f0 ; input
    xch r3
    xch r0 ; running total
    ld r0
    xch r1 ; permanent total
    jms mainloop

Sample run:

$ python intel4004-emu/main.py tree.4004 
8
       *       
      ***      
     *****     
    *******    
   *********   
  ***********  
 ************* 
***************
       *       
\$\endgroup\$
2
\$\begingroup\$

Python-3x, 119 bytes

N = int(input())
print(' '*N+'\n','\n'.join(['\t'+' '*(N-i)+'*'*(i*2+1) for i in range(N)]) + '\n', ' '*(N+3)+'*'+'\n')

result:-

enter N value
3
   *
  ***
 *****
   *



 4
        *
       ***
      *****
     *******
        *

9
             *
            ***
           *****
          *******
         *********
        ***********
       *************
      ***************
     *****************
             *
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Welcome to PPCG! The point of challenges like this one is to provide a solution in as few bytes as possible, so you should include in the title how long it is. (I'd recommend pasting it into this byte counter.) Speaking of which, you could shave off 25 bytes by removing the print statement at the beginning and removing the spaces around the = sign. \$\endgroup\$
    – user39326
    Commented Jun 17, 2015 at 22:40
  • \$\begingroup\$ Ok, but this is not Python 2.7 anymore, but Python 3. ;) The remaining issue is that your code generates one size smaller tree than specified. \$\endgroup\$
    – manatwork
    Commented Jun 18, 2015 at 14:14
  • \$\begingroup\$ I mentioned it as python-2.7 because in my systems library I have python-2.7 and in my virtualenvironment I have python 3.4. When I execute python 2.7 in the editor I get errors for example if I try end=' ' in the print function if I want to print anything in single line. I import from future to enable print functions which are active in python 3.x versions. Also I have made minor change to represent correct size of tree. \$\endgroup\$
    – Praneeth
    Commented Jun 18, 2015 at 15:11
2
\$\begingroup\$

Batch, 132 129 bytes

@!! 2>nul||cmd/q/v/c%0 %1&&exit/b
for /l %%X in (1 1 %1)do set[= ![!
set]=![!*
:*
echo%]%
set]=%]:~1%**
2>x goto:*%]:~1%&echo%[%*

I shamelessly copied Golfing Delayed Expansion Variables in Batch to my batch script.
Uses the bizarre ability of GOTO :NUL to

allow execution of concatenated commands in the context of the caller

Edit 2020/5/1: Abused token delimiters to shorten variable names

\$\endgroup\$
2
\$\begingroup\$

Vyxal C, 7 bytes

ʁd›×*×J

Try it Online!

Vyxal, 13 bytes

ɾ×*§↵vøm:⁋₴h,

Try it Online!

\$\endgroup\$
2
\$\begingroup\$

jq -r, 47 41 39 bytes

-2 bytes thanks to Michael Chatiskatzi

. as$n|range(.),0|" "*($n-.)+"**"*.+"*"

Try it online! Add 2 bytes if a leading space is not acceptable.

. as$n                                   Store the input number in $n
      |                                  With that number as .
       range(.)                           Numbers from 0 up to one less than .
               ,0                         and also another 0
                 |                       With each of those numbers as .
                     *($n-.)              $n minus . copies of
                  " "                     space
                            +             Concatenate
                                 *.       . copies of
                             "**"         that string
                                   +"*"   Concatenate one more asterisk

The -r flag outputs each of those strings on a separate line without wrapping it in quotes.

\$\endgroup\$
1
  • \$\begingroup\$ range(.),0 will save 2 bytes. \$\endgroup\$ Commented Sep 4, 2021 at 18:27
1
\$\begingroup\$

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[1])

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[1])

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

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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) \$\endgroup\$
    – tzot
    Commented Dec 25, 2008 at 20:06
1
\$\begingroup\$

Language: Python, Char count: 104

Another take at python. Note that the question requested for a script, not a function.

import sys
n= int(sys.argv[1])
c= lambda s: s.center(2*n)
print "\n".join(c("*"*(2*i+1)) for i in range(n)); print c("*")

$ py ax 11
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
*********************
          *
\$\endgroup\$
1
\$\begingroup\$

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) + "*")
\$\endgroup\$
1
\$\begingroup\$

Language: Pike

101 Relevant characters

int main (int c, array a) {
    int n=(int)a[1], i,l;
    for(;i<=n; l = ++i < n ? i : 0)
        write(" " *(n-l) + "*" * (l*2+1) +"\n");
}
\$\endgroup\$
1
\$\begingroup\$

Rhino Javascript shell: 117 chars minified

t=['*'];
for(i=1;i<arguments[0];++i)
{
  s='*'+t[i-1]+'*';
  for(j in t) 
    t[j]=' '+t[j];
  t[i]=s;
}
t[i]=t[0];print(t.join('\n'));

minified:

t=['*'];for(i=1;i<arguments[0];++i){s='*'+t[i-1]+'*';for(j in t) t[j]=' '+t[j];t[i]=s;}t[i]=t[0];print(t.join('\n'));

results:

c:\>java -jar C:\appl\Java\rhino1_7R1\js.jar c:/tmp/Xtree.js 10
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
         *
\$\endgroup\$
1
\$\begingroup\$

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)+'*'
\$\endgroup\$
1
\$\begingroup\$

Language: Euphoria 147 chars (9 relevant spaces):

include get.e
object
    a = command_line(), 
    t = 42
a = value( a[3] )
a = a[2]
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[3])a=a[2]for i=1to a do puts(1,repeat(32,a-i)&t&10)t&="**"end for puts(1,repeat(32,a-1)&42&10)
\$\endgroup\$
1
\$\begingroup\$

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).

\$\endgroup\$
1
1
\$\begingroup\$

VBScript, 106 characters

n = WScript.Arguments(0)
For i = 1 To n
  WScript.Echo Space(n-i+1) & String(2*i-1, "*")
Next
WScript.Echo Space(n) & "*"

Usage and output example:

> cscript christmastree.vbs 7 //nologo
       *
      ***
     *****
    *******
   *********
  ***********
 *************
       *
\$\endgroup\$
1
\$\begingroup\$

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 "*"
\$\endgroup\$
1
\$\begingroup\$

Golfscript - 27 chars

~:i,0+{.i\-(' '*\.)+'*'*n}%

~:i  # eval the command line arg, store in i  
,0+  # create a list [0..i-1] add 0 to the end  
{}%  # map this block over the list  
.    # make a copy of the list element 
i\-  # subtract the list element from i 
(    # decrease by one more  
' '* # multiply the result by ' '
\    # swap, so the list element is back on top of stack
.)+  # duplicate, add one, add the two numbers together
'*'* # multiply the result by '*'
n    # put a newline here
\$\endgroup\$
1
  • \$\begingroup\$ nice, i did mine before seeing yours, was about to refactor it to look like this \$\endgroup\$
    – Claudiu
    Commented Jun 10, 2010 at 6:29
1
\$\begingroup\$

Q, 54

{-1(-:)[((x+(!)x),x)]$(((&)((!)(2*x))mod 2),1)#\:"*";}

example:

q){-1(-:)[((x+(!)x),x)]$(((&)((!)(2*x))mod 2),1)#\:"*";} 10
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
         *
\$\endgroup\$
1
\$\begingroup\$

This is my first experience with code golf. So advices are welcome :)

C: 170 chars:

int main(){
    int n,m=1,x;
    scanf("%d",&n);x=2*n-1;
    for(;m<x*n+n+2;m++)
        printf("%c",m==x*n|m==x*n+n+1?42:m==x*n+1?10:m>x*n?32:!(m%(2*n-1))?10:!(m%x<n-m/x)&m%x<m/x+n+1?42:32);
}
\$\endgroup\$
1
\$\begingroup\$

I did not see a solution using R. The code below may not be efficient, but it seems to work (170 characters with spaces if all code placed on one line):

for(i in 1:4){ cat( paste( paste(rep(' ', (3-(i-1))), collapse=''), 
                           paste(rep('*', (2*i-1)),   collapse=''), collapse=''),  
               sep='\n'); if(i==4) cat('    *    ', sep='\n')}


    *
   ***
  *****
 *******
    *
\$\endgroup\$
1
\$\begingroup\$

Javascript, 89

i=4
c=t=""
while(i){o=c,j=(i--+1)*2-3
while(j--)o+="*"
t=o+"\n"+t
c+=" "}console.log(t+o)

Javascript 81

o=s=''
for(a=3;a--;){l=s+=' '
for(k=a*2+1;k--;)l+='*'
o=l+'\n'+o}console.log(o+l)
\$\endgroup\$
1
\$\begingroup\$

><>: 136 chars

This one's not going to win, but because Christmas is coming again, I thought fish needed a Christmas tree too! (pun intended)

1-:&1$>:> :1(?!v~$:> :1(?!vv
        ^-1o" "<   ^-1o"*"<>~2+$1-:0(?!v~~&ao>" "o1-v
      ^                              oa<;o"*"^!?(1: <

It can be run as follows with the standard interpreter:

./fish.py christmas.fish -v 5

... for N=5. (If the file is called christmas.fish :P) In this way, one prepopulates the stack with the value 5. This is the closest I could get to a command-line argument.

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

Scala, 73 chars

val n=args(0).toInt
(1 to n):+1 foreach(i=>println(" "*(n-i)+"*"*(2*i-1)))

run as

golf.scala 10
\$\endgroup\$
2
  • \$\begingroup\$ Wait, does that display the trunk? \$\endgroup\$ Commented Dec 12, 2013 at 19:56
  • \$\begingroup\$ yes, :+1 would do that \$\endgroup\$
    – prashanth
    Commented Dec 12, 2013 at 20:05
1
\$\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\$
1
\$\begingroup\$

Japt, 11 bytes

õ_ç* êÃp* û

Try it online!

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

Japt -R, 11 bytes

ÇÑÄ î*Ãp* û

Try it

Ç               :Map the range [0,input)
 Ñ              :  Multiply by 2
  Ä             :  Add 1
    î*          :  Repeat * that many times
      Ã         :End map
       p*       :Push a *
          û     :Centre pad each element with spaces to the length of the longest
                :Implicitly join with newlines
\$\endgroup\$
1
\$\begingroup\$

Lua, 100 99 bytes

p,r,n=io.write,('').rep,arg[1]for i=0,n do p(r(' ',n-i+1),r('*',i*2+1),'\n')end p(r(' ',n+1),'*\n')

Try it online!

Another Lua version, a little shorter.

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

PHP, 79 bytes

while($argn)echo$r[]=str_pad("
",1+$argn--).str_pad("",++$n*2-1,"*");echo$r[0];

Run as pipe with -nR or try it online.

\$\endgroup\$
1
  • \$\begingroup\$ Save 2 bytes using variable variables: Try it online! \$\endgroup\$
    – Night2
    Commented Oct 13, 2019 at 13:50
1
\$\begingroup\$

Python3,81 bytes

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

try it online

\$\endgroup\$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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