views:

3937

answers:

59

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 min val of 3, and a max val 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 whitespace 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 SO!

+10  A: 

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:

          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
          *
CMS
+2  A: 

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
            *
           ***
          *****
         *******
        *********
       ***********
      *************
     ***************
    *****************
   *******************
  *********************
 ***********************
*************************
            *
Aaron Maenpaa
Your character count is 98 (2 significant spaces, those in quotes)
ΤΖΩΤΖΙΟΥ
+1  A: 

Language: Erlang, Char count: 183 (2 relevant spaces)

Here is an Erlang version, ~181chars:

-module (x).
-export ([t/1]).

t(N) ->
 t(N,0).
t(0,N) ->
 io:format("~s~s~n",[string:copies(" ",N),"*"]);
t(H,S) ->
 io:format("~s~s~n",[string:copies(" ",H),string:copies("*",(S*2)+1)]),
 t(H-1,S+1).

(btw, happy Christmas to everyone!)

cheng81
+1  A: 

Language: C, Char count: 433 (1 relevant space)

C version. Not short, not pretty, but it works.

#include <stdio.h>

void printLevel(int level, int width)
{
    int i;
    int count = level + (level - 1);
    int spaces = width - count;
    int lowerBound = spaces / 2;
    int upperBound = width - lowerBound;
    for (i = 0; i < width; i++) {
        if (i >= lowerBound && i < upperBound) {
            printf("*");
        } else {
            printf(" ");
        }
    }
    printf("\n");
}

void makeTree(int level)
{
    int i;
    int width = level * 2 - 1;
    for (i = 1; i <= level; i++) {
        printLevel(i, width);
    }
    printLevel(1, width);
}

int main(int argc, char **argv)
{
    int level = atoi(argv[1]);
    makeTree(level);
}
Jonas Oberschweiber
+5  A: 

Language: Java, Char count: 219

class T{ /* 219 characters */
  public static void main(String[] v){
    int n=new Integer(v[0]);
    String o="";
    for(int r=1;r<=n;++r){
      for(int s=n-r;s-->0;)o+=' ';
      for(int s=1;s<2*r;++s)o+='*';
      o+="%n";}
    while(n-->1)o+=' ';
    System.out.printf(o+"*%n");}}

For reference, I was able to shave the previous Java solution, using recursion, down to 231 chars, from the previous minimum of 269. Though a little longer, I do like this solution because T is truly object-oriented. You could create a little forest of randomly-sized T instances. Here is the latest evolution on that tack:

class T{ /* 231 characters */
  public static void main(String[] v){new T(new Integer(v[0]));}}
  String o="";
  T(int n){
    for(int r=1;r<=n;++r){
      x(' ',n-r);x('*',2*r-1);o+="%n";}
    x(' ',n-1);
    System.out.printf(o+"*%n");
  }
  void x(char c,int x){if(x>0){o+=c;x(c,x-1);}
 }
joel.neely
Your new character count is 251 (1 relevant space)
ΤΖΩΤΖΙΟΥ
A: 

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
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
*********************
          *
ΤΖΩΤΖΙΟΥ
A: 

Language: Nemerle+Nextem, Char count: 129 (1 relevant space)

Nemerle with Nextem:

type s=string;
module t {
    public Main(a : array[s]) : void {
     def t = int.Parse(a[0]);
     def x(i) { print s(' ',t-i) + s('*',i*2+1) }
     $[0..t].Iter(x);
     x(0)
    }
}

Char count: 128

Edit: Made it take an arg Edit2: Imperative now

Cody Brocious
+17  A: 
dang I was hoping nobody tried it in ruby yet. nice job.
esabine
This is a very nice line of Ruby.
zenazn
Did I seem too abrubt? Sorry, not my intention! Merry XMas! :)
ΤΖΩΤΖΙΟΥ
Didn't mean to be mean either, and of course you were right! Merry Xmas!
I recently found the "Try Ruby" webpage, it looks like such a lovely programming language! :)
Aistina
You can replace +[1] with <<1 and ARGV with $* (-3 characters)
Joshua Swink
Nice solution. I've translated it to code here http://stackoverflow.com/questions/392788/1089859#1089859
Yar
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
+3  A: 

Language: C, Char count: 133

Improvement of the C-version.

char s[61];

l(a,b){printf("% *.*s\n",a,b,s);}

main(int i,char**a){
  int n=atoi(a[1]);memset(s,42,61);
  for(i=0;i<n;i++)l(i+n,i*2+1);l(n,1);
}

Works and even takes the tree height as an argument. Needs a compiler that tolerates K&R-style code.

I feel so dirty now.. This is code is ugly.

Nils Pipenbrinck
This has the same problem as my first cut in Java; it isn't a complete program with use of a command-line argument!
joel.neely
Oh? Is this required? No problem. I'll fix that.
Nils Pipenbrinck
It's 138 characters when all unnecessary newlines are removed.
Can Berk Güder
I count 133 (just removed all whitespace and checked the filesize)
Nils Pipenbrinck
+50  A: 

Language: Perl, Char count: 50 (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.
MkV
Smaller perl implementation of same, only 81 chars $,="\n";$a=pop;print map{$"x($a-$_).'*'x($_*2+1)}(0...$a-1);print$,.$"x$a."*\n";
Hasturkun
Adding $n=$ARGV[0]; at the beginning (cost = 12 chars), then replacing all subsequent occurrences of $ARGV[0] with $n (savings = 6 chars each, times 3 occurrences) will get you a net 6 character reduction in total length.
joel.neely
now 79 chars$,="\n";$a=pop;print map{$"x($a-$_).'*'x($_*2+1)}0...$a-1;print$,.$"x$a."*\n";
Hasturkun
64: $,="\n";$a=pop;print map{$"x($a-$_).'*'x($_*2+1)}0...$a-1,0,-1;
Kent Fredric
62 $,=$/;$a=pop;print map{$"x($a-$_).'*'x($_*2+1)}0...$a-1,0,-1;
Hasturkun
56: $a=pop;print map{$"x($a-$_).'*'x($_*2+1).$/}0...$a-1,0;
Hasturkun
50, but you need to assume perl -E ( 5.10 ) : $a=pop;say $"x($a-$_).'*'x($_*2+1) for 0...$a-1,0;
Kent Fredric
55, $a=pop;print map{$"x($a-$_).'*'x($_*2+1).$/}0...$a-1,0;
Hasturkun
52: print $"x($a-$_),'*'x($_*2+1),$/for 0...($a=pop)-1,0
Kent Fredric
50! print$"x($a-$_),'*'x($_*2+1),$/for 0..($a=pop)-1,0
Hasturkun
Holy crap... perl truly is unreadable.
zenazn
@zenazn, it seems like that initially, but I would say the same thing about chinese. Once you learn it, it makes perfect sense.
Kent Fredric
@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
@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
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
someone tipped me off on this one(outputs to stderr, though)49: warn$"x($a-$_),'*'x($_*2+1),$/for 0..($a=pop)-1,0
Hasturkun
If you are using Perl 5.10, you could replace print, with say.
Brad Gilbert
Your character count is 49. The space is not significant.
ΤΖΩΤΖΙΟΥ
@Kent. Yes, the same way you can get used to count in binary. 10 + 10 - 11 = ( 100 - 11 ) = 1 ... :-/
OscarRyz
Perl...Is there nothing he can't do
benPearce
@zenazn: You haven't seen unreadable until you've seen APL. :-)
RobH
@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. http://stackoverflow.com/questions/392788/1088931#1088931
ephemient
@RobH: You haven't seen unreadable until you've seen Whitespace ( http://en.wikipedia.org/wiki/Whitespace_(programming_language) )
JasCav
I point out that the J solution is around half this length...
RCIX
Why did this win when J has smaller char count?
Claudiu
@Claudiu: Look at the dates. This was accepted *long* before the J solution was written.
ephemient
+1  A: 

Language: Scala, Char count: 128 (1 relevant space)

My Scala version. I'm glad I have found the * operator for strings (String implicitly promoted to RichString).

  def tree(n:Int) {
    def vals(n:Int,k:Int) = ((1 to n) map { i => (k - i, (i * 2) - 1) }).toList
    for(j <- vals(n,n) ::: vals(1,n)) 
      println(" " * j._1 + "*" * j._2)
  }
Germán
+1  A: 

Here's how I would do it in Python, very straightforward, only 103 characters:

import sys
n=int(sys.argv[1])
for i in range(n): print ('*'*(2*i+1)).center(2*n)
print '*'.center(2*n)
Can Berk Güder
A: 

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

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)
ΤΖΩΤΖΙΟΥ
+2  A: 

Groovy 62B

n=args[0]as Long;[*n..1,n].any{println' '*it+'*'*(n-~n-it*2)}

_

n = args[0] as Long
[*n..1, n].any{ println ' '*it + '*'*(n - ~n - it*2) }
matyr
+2  A: 

Language: C, Char count: 176 (2 relevant spaces)

#include <stdio.h>
#define P(x,y,z) for(x=0;x++<y-1;)printf(z);
main(int c,char **v){int i,j,n=atoi(v[1]);for(i=0;i<n;i++){P(j,n-i," ")P(j,2*i+2,"*")printf("\n");}P(i,n," ")printf("*\n");}
Can Berk Güder
A: 

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) + "*")
ePharaoh
+2  A: 

Ridiculously long C++ one:

#include <iostream>
#include <conio.h>

using namespace std;

class CTree
{
// Members
private:
    unsigned short m_Lvl;
    unsigned short m_Spc;

// Construction
public:
    CTree(unsigned short lvl)
        : m_Lvl(lvl), m_Spc(0) {}
private:
    CTree(unsigned short lvl, unsigned short spc)
        : m_Lvl(lvl), m_Spc(spc) {}

// Operations
public:
    void Print()
    {
        // Print the leaves.
        if (m_Lvl)
        {
            CTree(m_Lvl-1 , m_Spc+1).Print();
            Line();
        }

        // Print the trunk.
        if (!m_Spc)
            CTree(1 , m_Lvl ? (m_Lvl - 1) : 0).Line();
    }
private:
    void Line()
    {
        // Indent the current line.
        for (unsigned short s = m_Spc; s--; )
            cout << ' ';

        // Print the leaves.
        for (unsigned short l = m_Lvl; --l; )
            cout << '*' << '*';
        cout << '*' << endl;
    }
};

int main(int argc, char** argv)
{
    // Validate the command line.
    if ((argc != 2) || !isdigit(argv[1][0]))
    {
        cout << "Command line: tree.exe number_of_lines";
        _getch();
        exit(1);
    }

    // Validate the number of lines.
    short lvl = (short)atoi(argv[1]);
    if (lvl < 0)
    {
        cout << "Do you really think " << lvl << " lines can be printed?";
        _getch();
        exit(1);
    }
    if (lvl > 40)
    {
        cout << "Sorry, but a " << lvl << "-line tree is too big to be printed.";
        _getch();
        exit(1);
    }

    // Print the tree.
    CTree((unsigned short)lvl).Print();

    // The user must press a key before the program finishes.
    _getch();
    return 0;
}


EDIT: I must add that this program doesn't follow the specifications exactly. When the input argument is N, it prints a (N+1)-line tree.

Merry X-Mas to the SO community


EDIT: Debugged the program and corrected some nasty errors.

Eduardo León
conio.h? nooo! :)
Nazgob
+4  A: 

Better C++, around 210 chars:

#include <iostream>
using namespace std;
ostream& ChristmasTree(ostream& os, int height) {
    for (int i = 1; i <= height; ++i) {
        os << string(height-i, ' ') << string(2*i-1, '*') << endl;
    }
    os << string(height-1, ' ') << '*' << endl;
    return os;
}

Minimized to 179:

#include <iostream>
using namespace std;ostream& xmas(ostream&o,int h){for(int i=1;i<=h;++i){o<<string(h-i,' ')<<string(2*i-1,'*')<<endl;}o<<string(h-1,' ')<<'*'<<endl;return o;}
jmucchiello
using std; anyone?
strager
strager - when I started there were only a couple std::'s and 'using namespace std;' was a lot of text. I suppose now that would be fewer characters.
jmucchiello
Your version is more inefficient than mine, because it has to create strings, my version just prints the characters it needs. :)
Eduardo León
A: 

Language: JavaScript, Char count: 110 (2 relevant spaces)

function p(l)
{
    o=''
    for(c=0; c<=n+l; c++)
      o += c < n - l ? ' ' : '*'
    print(o)
}

n = parseInt(arguments[0])

for(l = 0; l < n; l++)
  p(l)
p(0)

Ran using spidermonkey. $ smjs christmas_tree.js 4

Shane Tomlinson
A: 

PHP (133 relevant characters):

function xmastree($h) {
    for($i=0;$i<$h;++$i)
        echo str_repeat(' ',$h-$i-1).str_repeat('*',2*$i+1)."\n";
    echo str_repeat(' ',$h-1)."*\n";
}
jmucchiello
+18  A: 

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
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
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.
ΤΖΩΤΖΙΟΥ
A: 

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");
}
some
+8  A: 

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

Gracenotes
+6  A: 

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
'

$ sh ax3 10
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
          *
ΤΖΩΤΖΙΟΥ
Uhm seriously, wtf? I don't understand a single line of that :P
Aistina
dc is a reverse-polish calculator. 'man dc' is the obvious way to go :)
ΤΖΩΤΖΙΟΥ
A: 

Language: C, Char count: 116

I realized I could improve on my original design:

main(int c,char**v){char l[99],i=0;for(c=atoi(1[v]);i<c;printf("%*s%.*s\n",c,l,i++,l))l[i]=42;printf("%*c\n",c,42);}

Different approach (119 characters):

s[99],w,i=0;p(n){printf("%*.*s\n",w+n,n*2+1,s);}main(int c,char**v){w=atoi(v[1]);for(memset(s,42,99);i<w;p(i++));p(0);}

Old version (123 characters):

main(int c,char**v){char*l=calloc(c=atoi(v[1]),2),i=0;for(;i<c;printf("%*s%.*s\n",c,l,i++,l))l[i]=42;printf("%*c\n",c,42);}

(One byte can be saved by putting char *l=... in the for loop. That makes it non-standard, however (though gcc still accepts it).)

strager
+37  A: 

Language: Brainfuck, Char count: 240

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 =)
strager
+1 Excellent work!!
CMS
my brain feels f.....sick
JoshBerke
Oh my god.
Charlie Somerville
+2  A: 

PHP, 111 chars

(The very last char should be a newline.)

<?php $n=$argv[1];for($r='str_repeat';$i<$n;$i++)echo $r(' ',$n-$i).$r('*',$i*2+1)."\n";echo $r(' ',$n).'*' ?>

Readable version:

<?php

$n = $argv[1];

for ($r = 'str_repeat'; $i < $n; $i++)
    echo $r(' ', $n - $i) . $r('*' , $i * 2 + 1) . "\n";

echo $r(' ', $n) . '*'

?>
yjerem
You can save several characters by building the string, then echoing it. I think. Try that out.
strager
Good idea, but I tried it and it only makes it longer. '$t.=(...)' is only one char shorter than 'echo (...)', and then you'd have to 'echo $t' at the end as well.
yjerem
Shortened it by 4 chars by removing the '$i = 0;' first part of the for statement. PHP assumes that nonexistent variables used in an integer context are 0 already! :P
yjerem
Saved a char by putting $r=.. inside the for. Also, I say newline characters should be one byte, not two. =]
strager
Yeah I just realized I miscounted by one because I counted using the column number in my text editor. I use linux so the newline char is one byte.
yjerem
+4  A: 

Improving ΤΖΩΤΖΙΟΥ's answer. I can't comment, so here is a new post. 72 characters.

import sys
n=int(sys.argv[1])
for i in range(n)+[0]:
   print ("*"*(2*i+1)).center(2*n)

Using the "python -c" trick, 61 characters.

python -c "
for i in range($1)+[0]:
   print ('*'*(2*i+1)).center(2*$1)
"

I learned the center function and that "python -c" can accept more than one line code. Thanks, ΤΖΩΤΖΙΟΥ.

A: 

Common Lisp, 117 essential characters:

(defun x (n)
  (dotimes (v n)
    (format t "~v:@<~v{*~}~>~%"
            (1- (* 2 n))
            (1+ (* 2 v))
            '(())))
  (format t "~v:@<*~>~%" (1-(* 2 n)))

Are there any format gurus out there who know a better way to get repeating arbitrary characters?

Svante
+2  A: 

Shell version, 134 characters:

#!/bin/sh
declare -i n=$1
s="*"
for (( i=0; i<$n; i++ )); do
    printf "%$(($n+$i))s\n" "$s"
    s+="**"
done
printf "%$(($n))s\n" "*"
Alastair
+15  A: 

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!*
Zach Scrivena
masochist! I like it
Colin Pickard
Very nice... you get +1
ojblass
Delayed variable expansion can be enabled using the `setlocal enabledelayedexpansion` command.
Helen
dude. seriously?
Earlz
A: 

Java version. 189 character

class P
{
 static String p(int n, String s) 
 {
  return --n < 1 ? s : p(n, s) + s;
 }

 public static void main(String[] a) 
 {
  for (int N = new Integer(a[0]), i = -1; i++ < N;) 
   System.out.println(p(N - i % N, " ") + p(i % N * 2 + 1, "*"));
 }
}
Kire Haglin
+9  A: 

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

Hynek -Pichi- Vychodil
Good lord, what the hell is that?
amischiefr
Just read man page ;-)
Hynek -Pichi- Vychodil
A: 

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
           *
          ***
         *****
        *******
       *********
      ***********
     *************
    ***************
   *****************
  *******************
 *********************
           *
Hynek -Pichi- Vychodil
+5  A: 

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));
Øyvind Skaar
+4  A: 

Language: python, no tricks, 78 chars

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

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
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
         *
Jason S
+9  A: 

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.
ΤΖΩΤΖΙΟΥ
A: 

Language: Php, Char count: 110 (3 relevant spaces)

<? function x($n,$a,$t){return $n?str_repeat(' ',$n).$a.x($n-1,"*$a"," $t"):$t;}echo x($argv[1],"\n","*\n");

A bit of php recursion to reduce the count of chars to 110.

Eineki
+2  A: 

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
   #
  ###
 #####
   #
     #
    ###
   #####
  #######
 #########
     #
LoranceStinson
A: 

FreePascal:

program xmastree;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this };

var x,y,h:integer;

{$IFDEF WINDOWS}{$R xmastree.rc}{$ENDIF}

procedure printRow(sp,st:integer);
var i:integer;
begin
    for i := 1 to sp do begin
    write(' ');
  end;
    for x := 1 to st do begin
    write('*');
  end;
    for x := 1 to sp do begin
    write(' ');
  end;
    writeln();
end;

begin
    val(ParamStr(1),h);
  for y := 1 to h do begin
    printRow(h-y,(y-1)*2+1);
  end;
  printRow(h-1,1);
end.

Output for xmastree.exe 9

        *
       ***
      *****
     *******
    *********
   ***********
  *************
 ***************
*****************
        *
feihtthief
A: 

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)+'*'
Leon Tayson
A: 

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)
Matt Lewis
A: 

Language C# in verbosity

using System;

namespace ChristmasTree
{
    class Program
    {
        static void Main( string[] args )
        {

            var buildATree = new BuildATree( int.Parse( args[0] ) );

            Console.WriteLine( buildATree.MakeTree() );

            Console.ReadLine();
        }
    }
}


using System.Text;

namespace ChristmasTree
{
    public class BuildATree
    {
        private int TreeHeight
        {
            get;
            set;
        }

        public BuildATree()
            : this( 3 )
        {}

        public BuildATree( int treeHeight )
        {
            this.TreeHeight = treeHeight;

            if( treeHeight > 30 )
                this.TreeHeight = 30;
        }

        public string MakeTree()
        {
            StringBuilder sb = new StringBuilder();

            for( int i = 0; i < this.TreeHeight; i++ )
            {
                sb.AppendLine( 
                    new string( ' ', this.TreeHeight - i - 1 ) 
                    + new string( '*', i * 2 + 1 ) );
            }

            sb.AppendLine( new string( ' ', this.TreeHeight-1 ) + "*" );

            return sb.ToString();
        }
    }
}
Metro Smurf
A: 

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

friol
I got it in 29 characters: http://stackoverflow.com/questions/392788/1088931#1088931
ephemient
+12  A: 

Language: x86 asm 16-bit, Byte count: 50

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

Jonas Gulle
A: 

in c++, the shortest and the fastest way "i think" :)

void tree(int c, char* o)
{
#define _(p,x) t=p;while(t--)*o++=x
    if(o&&c>0)
    {
     int m=c+1,t;
     do
     {
      _(c,' ');
      _((m-c)*2-1,'*');
      _(c,' ');
      *o++='\n';
     }while(--c);
     _(m-1,' ');
     *o++= '*';
     *o++='\n';
     *o=0;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    char t[1024];
    tree(5, t);
    printf("%s", t);
}
Tolgahan Albayrak
A: 

C# 3.0

using System;
using System.Linq;
class Program
{
    static void Main(string[] a)
    {
        int n = int.Parse(a[0]);
        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));
    }
}

158 characters:

int n=int.Parse(a[0]);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));
Matajon
+19  A: 

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.

   ((\:[email protected]#),}.)"1$&'*'"0>:0,~i.3
  *
 ***
*****
  *
   ((\:[email protected]#),}.)"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
   (\:[email protected]#)"1$&'*'"0>:0,~i.3
  *
 **
***
  *
   NB. strip off leading column
   }."1$&'*'"0>:0,~i.3

*
**

   NB. paste together
   ((\:[email protected]#),}.)"1$&'*'"0>:0,~i.3
  *
 ***
*****
  *
ephemient
ephemient
What, do you guys use some sort of J documentation library to understandable-ize the code? :)
RCIX
+3  A: 

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
Yar
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
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
A: 

Fortran 90

A bit modified, so the tree trunk looks more proportional to the height of the tree.

    write(*,*) 'how high a tree? '; read(*,*)n
    write(*,'(a,a)') (repeat(' ',n-i),repeat('*',2*i-1),i=1,n)
    write(*,'(a,a)') (repeat(' ',n-1),repeat('*',1),i=1,n/5+1)
    end
ldigas
A: 

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
       *
      ***
     *****
    *******
   *********
  ***********
 *************
       *
Helen
A: 

Windows Batch File

Windows batch files have poor support for string operations: they can concatename, extract and replace strings, but generation of arbitrary-length strings according to a certain pattern AFAIK can only be done via loops. This is how Zach Scrivena's solution works.

However, one can notice that the N+1-th tree line can be generated from the N-th line by cutting one leading space off and adding two traling asterisks, which pretty much simplifies the task. Also, the tree truck repeats the tree top so we can re-use that string to get rid of a few extra loops. So, here's my batch file that uses these two tricks (165 characters):

@echo off
setlocal enableextensions enabledelayedexpansion
set s=
for /l %%i in (1,1,%1)do set s= !s!
set t=!s!*
for /l %%i in (1,1,%1)do echo !t!&set t=!t:~1!**
echo %s%*

Assuming that echo is already off and command extensions and delayed variable expansion are on, we can drop the first two lines and shorten the code down to 108 characters.

Usage:

> xmastree.bat 7 & pause
       * 
      *** 
     ***** 
    ******* 
   ********* 
  *********** 
 ************* 
       *
Helen
A: 

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 "*"
Alex Mcp
+2  A: 

C# - Recursion

using System;

class A
{
    static string f(int n, int r)
    {
        return "\n".PadLeft(2 * r, '*').PadLeft(n + r) 
            + (r < n ? f(n, ++r) : "*".PadLeft(n));
    }

    static void Main(string[] a)
    {
        Console.WriteLine(f(int.Parse(a[0]), 1));
    }
}

177 chars (not as short the other C# method posted, but a different way of doing it).

BenAlabaster
A: 

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).."*")
RCIX
A: 

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
gnibbler
nice, i did mine before seeing yours, was about to refactor it to look like this
Claudiu
A: 

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;}
Graphics Noob
A: 

GolfScript, 34 characters

Another GolfScript entry:

~:x,-1%[x(]+{." "*[email protected] 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
{." "*[email protected] 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
Claudiu