Code Golf Christmas Edition: Como imprimir uma árvore de Natal de altura N

89

Dado um número N, como posso imprimir uma árvore de Natal de altura Nusando o menor número de caracteres de código? Né assumido restrito a um valor mínimo de 3e um valor máximo de 30(limites e verificação de erros não são necessários). Né fornecido como o único argumento de linha de comando para seu programa ou script.

Todos os idiomas são apreciados, se você vir um idioma já implementado e poderá reduzi-lo, edite-o se possível - comente de outra forma e espere que alguém limpe a bagunça. Inclua novas linhas e Espaços em branco para maior clareza, mas não as inclua na contagem de caracteres.

Uma árvore de Natal é gerada como tal, com seu "tronco" consistindo apenas de um "*" centralizado

N = 3:

   *
  ***
 *****
   *

N = 4:

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

N = 5:

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

N define a altura dos galhos, sem incluir o tronco de uma linha.

Feliz Natal PPCG!

TheSoftwareJedi
fonte

Respostas:

46

J , 24 caracteres

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

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

Explicação:

'*'$~5
*****

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

Em seguida, }:@|."1inverte cada linha e retira a última coluna e ,.grampeia-a para ].

Em seguida, ,{.cola a primeira coluna na parte inferior.

Entradas anteriores :

29 caracteres, sem espaços.

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

   NB. conte de 1 a n , depois 1 novamente
   >: 0, ~ i.3
1 2 3 1
   NB. replicar '*' x vezes cada
   $ & '*' "0>: 0, ~ i.3
*
**
***
*
   NB. inverta cada linha
   (\: i. @ #) "1 $ & '*'" 0>: 0, ~ i.3
  *
 **
***
  *
   NB. tira a coluna principal
   }. "1 $ & '*'" 0>: 0, ~ i.3

*
**

   NB. colar juntos
   ((\: i. @ #),}.) "1 $ & '*'" 0>: 0, ~ i.3
  *
 ***
*****
  *
efémero
fonte
Com apenas mais 9 caracteres, você pode dar um nome a esta função:c=:[:((\:i.@#),}.)"1[:$&'*'"0[:>:0,~i.
ephemient
11
Vocês usam algum tipo de biblioteca de documentação J para entender o código? :)
92

Brainfuck, 240 caracteres

              ,
             >++
            +++++
           +[-<---
          --->],[>+
         +++++++[-<-
        ----->]<<[->+
       +++++++++<]>>]<
      [->+>+>>>>>>>+<<<
     <<<<<<]>>>>++++++++
    [-<++++>]>++++++[-<++
   +++++>]+>>>++[-<+++++>]
  <<<<<<[-[>.<-]<[-<+>>+<]<
 [->+<]>>>>>[-<.>>+<]>[-<+>]
>.<<++<<<-<->]>>>>>>>-[-<<<<<
           <.>>>
           >>>]<
           <<<<.

Ainda não está pronto. Funciona, mas apenas com números de um dígito.

EDIT: Feito! Funciona para intérpretes usando 0 como EOF. Veja NOTEs na fonte comentada para aqueles com -1.

EDITAR novamente: devo observar que, como o Brainfuck não possui um método padrão para ler argumentos de linha de comando, usei stdin (entrada padrão). ASCII, é claro.

EDITE uma terceira vez: Oh, querida, parece que eu retirei .os caracteres (de saída) ao condensar o código. Fixo...

Aqui está o gerenciamento básico de memória do loop principal. Tenho certeza de que pode ser altamente otimizado para reduzir a contagem de caracteres em 30 ou mais.

  1. Temporário
  2. Cópia do contador
  3. Contador (conta até 0)
  4. Caractere de espaço (decimal 32)
  5. Caractere asterisco (decimal 42)
  6. Número de asteriscos na linha atual (1 + 2 * contador)
  7. Temporário
  8. Caractere de nova linha
  9. Temporário?
  10. Número total de linhas (ou seja, valor de entrada; armazenado até o final, ao imprimir o tronco)

Versão condensada:

,>++++++++[-<------>],[>++++++++[-<------>]<<[->++++++++++<]>>]<[->+>+>>>>>>>+<<<<<<<<<]>>>>++++++++[-<++++>]>++++++[-<+++++++>]+>>>++[-<+++++>]<<<<<<[-[>.<-]<[-<+>>+<]<[->+<]>>>>>[-<.>>+<]>[-<+>]>.<<++<<<-<->]>>>>>>>-[-<<<<<<.>>>>>>]<<<<<.

E a versão bonita:

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 =)
jrtapsell
fonte
1
meu cérebro está doente
3
Meu Deus.
Covarde anônimo 07/07/2009
63

Perl, 50 caracteres

(1 espaços relevantes)

perl: versão de uma linha:

print$"x($a-$_),'*'x($_*2+1),$/for 0..($a=pop)-1,0

e agora com mais espaço em branco:

print $"  x ( $a - $_ ),             #"# Syntax Highlight Hacking Comment
      '*' x ( $_ * 2  + 1),
      $/
for 0 .. ( $a = pop ) - 1, 0;

$ perl tree.pl 3
   *
  ***
 *****
   *
$ perl tree.pl 11
           *
          ***
         *****
        *******
       *********
      ***********
     *************
    ***************
   *****************
  *******************
 *********************
           *
$ 

Explicação expandida para usuários não-Perl.

# 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
fonte
25
Caramba ... Perl realmente é ilegível.
8
@zenazn, também, deve-se notar que a maioria dos jogos de golfe é um código MAU em qualquer idioma. Se fosse uma competição pelo código mais limpo, também poderíamos vencer.
Kent Fredric
5
@zenazn: prova, você pode ver-nos a colaborar e melhorar cada código de outros acima, isso prova WE pode ler uns dos outros código perfeitamente bem.
Kent Fredric
1
PS: Obrigado pela explicação para programadores não Perl. Ainda é bastante ilegível, mas pelo menos faz sentido. Acho que você se acostuma depois de um tempo.
2
@ RobH: J é filho da APL. Em alguns sentidos, é mais ilegível porque não usa o conjunto de caracteres da APL com um símbolo especial para todas as operações - em vez disso, sobrecarrega caracteres ASCII com vários significados. stackoverflow.com/questions/392788/1088931#1088931
ephemient
26

Idioma: Python (através do shell), Contagem de caracteres: 64 (2 espaços significativos)

python -c "
n=w=$1
s=1
while w:
    print' '*w+'*'*s
    s+=2
    w-=1
print' '*n+'*'"

$ sh ax6 11
           *
          ***
         *****
        *******
       *********
      ***********
     *************
    ***************
   *****************
  *******************
 *********************
           *
tzot
fonte
8
o que eu gosto mais sobre esta solução é que python torna realmente difícil escrever código obscuro, é uma das soluções mais legíveis
Você está usando o shell para processar o argumento, que não está no espírito do código golf IMO. Usando "import sys" e "n = w = int (sys.argv [1])" e um recuo de 1 caractere para o corpo do loop, criei 89 caracteres para esta versão.
4
Foi assim que eu fiz antes. O espírito desta pergunta é se divertir e, além disso, não havia especificação de usar apenas um idioma :) Veja a resposta do cérebro, por exemplo; sem argumentos.
26

x86 asm de 16 bits, 50 bytes

Ainda não há uma versão de montagem? :)

    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

(Nota: N está limitado a 1 - 9 nesta versão)

G:\>tree 9
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
         *

Baixe aqui

Jonas Gulle
fonte
24

Idioma: Script em lote do Windows ( chocante! )

@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!*

fonte
masoquista! Eu gosto disso
Muito bom ... você recebe +1
2
A expansão variável atrasada pode ser ativada usando o setlocal enabledelayedexpansioncomando
Helen
cara. a sério?
Não pode fazê-lo funcionar. Primeira vez que eu tento embora.
Fabinout
21

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

Feliz Natal a todos!

Edit: Melhorias adicionadas como sugerido por Joshua Swink

jrtapsell
fonte
Dang, eu esperava que ninguém tivesse experimentado em Ruby ainda. bom trabalho.
Esta é uma linha muito boa de Ruby.
Eu pareci muito abrubt? Desculpe, não é minha intenção! Feliz Natal! :)
Também não queria ser mau, e é claro que você estava certo! Feliz Natal!
1
No 1.9, você pode economizar mais alguns caracteres: n=$*[0].to_i;puts [*1..n,1].map{|i|" "*(n-i)+"*"*(2*i-1)}traz-lo para 58.
14

Idioma: C #, Contagem de caracteres: 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));
    }
}

Apenas o código, sem formatação (120 caracteres):

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

Versão com 109 caracteres (apenas o código):

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

Resultado da altura = 10:

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

fonte
13

Idioma: dc (através do shell) Contagem de caracteres: 83

Uma versão dc um pouco mais curta:

dc -e '?d1rdsv[d32r[[rdPr1-d0<a]dsaxszsz]dsbx1-rd42rlbx2+r10Plv1-dsv0<c]dscxszsz32rlbx[*]p' <<<$1

EDIT: mudou a constante 10 para $ 1

Hynek -Pichi- Vychodil
fonte
11
Bom Deus, que diabos é isso?
1
Basta ler página man ;-)
12

python, truque "-c" ... @ 61 caracteres (e uma linha)

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

fonte
Na verdade, são 57 caracteres, apenas o espaço '' é significativo conforme as especificações da pergunta.
10

Aqui está uma versão Haskell razoavelmente eficiente em termos de espaço, com 107 caracteres:

main=interact$(\g->unlines$map(\a->replicate(g-a)' '++replicate(a*2-1)'*')$[1..g]++[1]).(read::[Char]->Int)

executando:

$ echo 6 | runhaskell tree.hs
     *
    ***
   *****
  *******
 *********
***********
     *

Feliz Natal, todos :)


fonte
10

Idioma: dc (através do shell), Contagem de caracteres: 119 (1 espaço significativo)

Apenas pela obscuridade :)

dc -e "$1dsnsm"'
[[ ]n]ss
[[*]n]st
[[
]n]sl
[s2s1[l2xl11-ds10<T]dsTx]sR
[lndlslRxlcdltlRxllx2+sc1-dsn0<M]sM
1sclMxlmlslRxltxllx
'

$ sh ax3 10
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
          *
tzot
fonte
Sério, wtf? Eu não entendo uma única linha disso: P
dc é uma calculadora de polimento reverso. 'homem dc' é o caminho óbvio para ir :)
6

Melhor C ++, cerca de 210 caracteres:

#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;
}

Minimizado para 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;}

fonte
usando std; qualquer um?
strager - quando comecei, havia apenas alguns std :: 's e' using namespace std; ' era muito texto. Suponho que agora haveria menos caracteres.
Sua versão é mais ineficiente que a minha, porque precisa criar strings, minha versão apenas imprime os caracteres necessários. :)
pyon 26/12/08
6

Idioma: python, sem truques, 78 caracteres

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

fonte
6

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

fonte
5

Melhorando a resposta de ΤΖΩΤΖΙΟΥ. Não posso comentar, então aqui está um novo post. 72 caracteres.

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

Usando o truque "python -c", 61 caracteres.

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

Aprendi a função central e que "python -c" pode aceitar mais de um código de linha. Obrigado ΤΖΩΤΖΙΟΥ.


fonte
5

C # usando 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));

fonte
5

AWK, 86 caracteres em uma linha.

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

fonte
5

Idioma: Java, Número de caracteres: 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");}}

Para referência, consegui depilar a solução Java anterior, usando recursão, até 231 caracteres, do mínimo anterior de 269. Embora um pouco mais, eu gosto dessa solução porque Té realmente orientada a objetos. Você pode criar uma pequena floresta de Tinstâncias de tamanho aleatório . Aqui está a evolução mais recente dessa abordagem:

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
fonte
Seu novo número de caracteres é 251 (1 espaço relevante)
se livrar de "public static void main", use um bloco estático e compilar com Java 6;)
Fabinout
Eu sei que tem sido quase 9 anos (lol ..) mas você pode golfe algumas coisas: class T{public static void main(String[]v){long n=new Long(v[0]),r=1,s;String o="";for(;r<=n;r++){for(s=n-r;s-->0;)o+=' ';for(;++s<2*r;)o+='*';o+="\n";}while(n-->1)o+=' ';System.out.println(o+"*");}}(199 caracteres / bytes)
Kevin Cruijssen
5

Idioma: PowerShell, Número de caracteres: 41 (incluindo 1 espaço)

1..$args[0]+1|%{" "*(30-$_)+"*"*($_*2-1)}
Jaykul
fonte
5

21 caracteres com APL dyalog.

m,⍨⌽0 1↓m←↑'*'\¨⍨1,⍨⍳

⍳ fornece um vetor de números inteiros começando com 1.

1, ⍨ adiciona um ao final do vetor. Este será o pé da árvore.

'*' \ ¨⍨ fornece um vetor de * -strings com comprimentos dados pelo vetor anterior.

↑ transforma o vetor em uma matriz e adiciona espaços à direita.

m ← armazena a matriz em m.

0 1 ↓ descarta zero linhas e a primeira coluna.

⌽ inverte a matriz.

m, ⍨ concatena com m no lado direito.

user10639
fonte
m,⍨⌽0 1↓m←->(⌽,0 1↓⊢)
ngn
4

Idioma: C, Char charter: 133

Melhoria da versão C.

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);
}

Funciona e até leva a altura da árvore como argumento. Precisa de um compilador que tolere código no estilo K&R.

Eu me sinto tão sujo agora .. Esse código é feio.


fonte
Isso tem o mesmo problema do meu primeiro corte em Java; não é um programa completo com o uso de um argumento de linha de comando!
Oh? Isso é necessário? Sem problemas. Eu vou consertar isso.
São 138 caracteres quando todas as novas linhas desnecessárias são removidas.
Can Berk Güder
Conto 133 (acabou de remover todos os espaços e verificou o tamanho do arquivo)
4

R (62 bytes)

Ainda não vi a solução R. Corrija-me se eu perdi.

for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")

Resultado:

> N <- 3
> for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")
  *
 ***
*****
  *
> 
> N <- 4
> for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")
   *
  ***
 *****
*******
   *
> 
> N <- 5
> for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")
    *
   ***
  *****
 *******
*********
    *
djhurio
fonte
3

Idioma: C, Número de caracteres: 176 (2 espaços relevantes)

#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
fonte
3

Versão do shell, 134 caracteres:

#!/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" "*"

fonte
golfed até 70 bytes :)
roblogic
3

Idioma: Python, Contagem significativa de caracteres: 90

É feio, mas funciona:

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
            *
           ***
          *****
         *******
        *********
       ***********
      *************
     ***************
    *****************
   *******************
  *********************
 ***********************
*************************
            *

fonte
Sua contagem de caracteres é de 98 (2 vagas significativas, aquelas entre aspas)
3

Como esta é uma CW: não gosto que o código de golfe seja sempre organizado em termos de "número de caracteres" ou algo assim. Eles não poderiam ser organizados em termos de número de instruções para o compilador / intérprete (ou algum critério semelhante)? Aqui está a solução Ruby novamente , e é basicamente a mesma, mas agora também para consumo humano:

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
Comunidade
fonte
Eu concordo com a primeira afirmação. Em tais termos, idiomas como perl têm uma vantagem inicial. Deve ser algo como o número de parâmetros estatísticos ou similares.
obrigado ... Fiz uma pergunta sobre golfe ontem e a maneira de fazê-lo pode ser com "tokens" ... dessa forma, o tamanho do nome e assim por diante não são penalizados.
2

PHP, 111 caracteres

(O último caractere deve ser uma nova linha.)

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

Versão legível:

<?php

$n = $argv[1];

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

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

?>

fonte
Você pode salvar vários caracteres construindo a sequência e ecoando-a. Eu acho que. Experimente isso.
Boa ideia, mas eu tentei e só faz mais tempo. '$ t. = (...)' é apenas um caractere mais curto que 'eco (...)' e, em seguida, você teria que 'ecoar $ t' no final.
Encurtado em 4 caracteres, removendo o '$ i = 0;' primeira parte da declaração for. O PHP assume que variáveis ​​inexistentes usadas em um contexto inteiro já são 0! : P
Salvei um char colocando $ r = .. dentro do for. Além disso, digo que os caracteres de nova linha devem ter um byte, não dois. =]
Sim, eu acabei de perceber que eu contei um errado porque contei usando o número da coluna no meu editor de texto. Eu uso o Linux, então o novo caractere é de um byte.