Desenhe um triângulo de Sierpinski


43

O Triângulo de Sierpinsky é um fractal criado usando um triângulo, diminuindo a altura e a largura em 1/2, criando 3 cópias do triângulo resultante e colocando-as de modo que cada triângulo toque as outras duas em um canto. Esse processo é repetido repetidamente com os triângulos resultantes para produzir o triângulo de Sierpinski, conforme ilustrado abaixo.

insira a descrição da imagem aqui

Escreva um programa para gerar um triângulo de Sierpinski. Você pode usar qualquer método que desejar para gerar o padrão, desenhando os triângulos reais ou usando um algoritmo aleatório para gerar a imagem. Você pode desenhar em pixels, arte ascii ou o que quiser, desde que a saída pareça com a última imagem mostrada acima. Menos personagens ganham.


1
Veja também a versão antiga do Stack Overflow: stackoverflow.com/questions/1726698/…
dmckee

3
Tive a ideia disso depois de ver a questão do triângulo de pascal e lembrar o programa de exemplo no meu manual da TI-86. Decidi convertê-lo para o QBasic e depois codificá-lo.
Kibbee

Não há problema em executar um desafio aqui que já foi executado no Stack Overflow, mas muitas pessoas não desejam apresentar o mesmo material novamente. Então, eu os vinculo para a edificação de visitantes posteriores.
dmckee

Para evitar duplicação, talvez você deva mudar para regras para permitir apenas implementações gráficas.
Primo

Muitas idéias de volfrâmio: wolframscience.com/nksonline/page-931
luser Droog

Respostas:


41

HTML + JavaScript, 150 caracteres (ver notas para 126 caracteres)

Espaço em branco inserido para facilitar a leitura e não contado.

<title></title><canvas></canvas><script>
for(x=k=128;x--;)for(y=k;y--;)
  x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1)
</script>

O núcleo disso é a aplicação da regra de colorir pixels, pela qual, x & y == 0pela condicional x&y||, produz um "triângulo retângulo de Sierpinski"; e x-~y/2,k-ysão uma transformação de coordenadas para produzir a exibição aproximadamente equilateral.

insira a descrição da imagem aqui

Uma versão menos correta (em HTML) tem 126 caracteres:

<canvas><script>
for(x=k=128;x--;)for(y=k;y--;)
  x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1)
</script>

(A maneira pela qual isso é menos correto é que ele omite o titleelemento e a tag final do canvaselemento, os quais são necessários para um documento correto, mesmo que sua omissão não mude a interpretação do documento.)

É possível salvar três caracteres, eliminando a kfavor da constante 64, ao custo de um resultado menor; Eu não contaria a 8opção, pois possui detalhes insuficientes.

Observe que um tamanho de 256 ou superior requer atributos <canvas>para aumentar o tamanho da tela do padrão.


22
Ninguém se importa se o seu HTML é validado no codegolf :-) Algumas melhorias: <canvas id=c>e então c.getContext. Encurtar loops:for(x=k=128;x--;)for(y=k;y--;)
copie

4
ids sendo transformados em variáveis ​​globais é uma característica horrível que eu me recuso a reconhecer e o WebKit não o implementa no modo de padrões. Obrigado pelo truque de loop.
Kevin Reid

1
Melhoria menor: x&y?0:pode ser substituída por x&y||uma solução agradável.
Primo

5
Bravo, isso é simplesmente maravilhoso.
Boothby

2
Como ele contém um script, eu recomendo que o intitule como HTML + Javascript . Isso tornará mais claro para alguém que procura que tipo de resposta é essa.

30

GolfScript ( 43 42 caracteres)

' /\ /__\ '4/){.+\.{[2$.]*}%\{.+}%+\}3*;n*

Resultado:

               /\               
              /__\              
             /\  /\             
            /__\/__\            
           /\      /\           
          /__\    /__\          
         /\  /\  /\  /\         
        /__\/__\/__\/__\        
       /\              /\       
      /__\            /__\      
     /\  /\          /\  /\     
    /__\/__\        /__\/__\    
   /\      /\      /\      /\   
  /__\    /__\    /__\    /__\  
 /\  /\  /\  /\  /\  /\  /\  /\ 
/__\/__\/__\/__\/__\/__\/__\/__\

Mude o "3" para um número maior para um triângulo maior.


27

Python (234)

Golfe máximo, imagem minúscula:

#!/usr/bin/env python3
from cairo import*
s=SVGSurface('_',97,84)
g=Context(s)
g.scale(97,84)
def f(w,x,y):
 v=w/2
 if w>.1:f(v,x,y);f(v,x+w/4,y-v);f(v,x+v,y)
 else:g.move_to(x,y);g.line_to(x+v,y-w);g.line_to(x+w,y);g.fill()
f(1,0,1)
s.write_to_png('s.png')

Requer python3-cairo.

Para obter uma boa imagem grande, eu precisava de 239 caracteres.

Triângulo de Sierpinski


1
import cairo as cwhould poupar alguns personagens
Quasimodo

1
esta resposta precisa de mais
votos positivos

26

Mathematica - 32 caracteres

Nest[Subsuperscript[#,#,#]&,0,5]

insira a descrição da imagem aqui

Mathematica - 37 caracteres

Grid@CellularAutomaton[90,{{1},0},31]

Isso produzirá uma tabela 2D de 0 e 1, onde 1s estão desenhando o triângulo de Sierpinski.

insira a descrição da imagem aqui


2
Ao custo de 5 caracteres adicionais, sua segunda solução será exibida melhor com ArrayPlot@CellularAutomaton[90, {{1}, 0}, 31]ou MatrixPlot@CellularAutomaton[90, {{1}, 0}, 31].
DavidC

1
... ou com ReliefPlot@...
DavidC 2/13

Eu entendo isso . Como você conseguiu a saída sem todos os colchetes?
Mr.Wizard

@ Mr.Wizard hmm ... de onde são os suportes do mundo? Até funciona aqui: mathics.net Tente e me avise.
Vitaliy Kaurov

1
@Vitaliy Kaurov A solução principal (32 caracteres) é surpreendente. Você pode fazer o desafio da "árvore fractal" (em outras partes do PCG) usando a mesma técnica?
Michael Stern

22

Python, 101 86

Usa o autômato da regra 90.

x=' '*31
x+='.'+x
exec"print x;x=''.join(' .'[x[i-1]!=x[i-62]]for i in range(63));"*32

Isso é mais longo, mas mais bonito.

x=' '*31
x+=u'Δ'+x
exec u"print x;x=''.join(u' Δ'[x[i-1]!=x[i-62]]for i in range(63));"*32

Edit: tocando diretamente com as cordas, se livrando de fatias desagradáveis, tornando a saída mais bonita.

Resultado:

                               Δ                               
                              Δ Δ                              
                             Δ   Δ                             
                            Δ Δ Δ Δ                            
                           Δ       Δ                           
                          Δ Δ     Δ Δ                          
                         Δ   Δ   Δ   Δ                         
                        Δ Δ Δ Δ Δ Δ Δ Δ                        
                       Δ               Δ                       
                      Δ Δ             Δ Δ                      
                     Δ   Δ           Δ   Δ                     
                    Δ Δ Δ Δ         Δ Δ Δ Δ                    
                   Δ       Δ       Δ       Δ                   
                  Δ Δ     Δ Δ     Δ Δ     Δ Δ                  
                 Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ                 
                Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ                
               Δ                               Δ               
              Δ Δ                             Δ Δ              
             Δ   Δ                           Δ   Δ             
            Δ Δ Δ Δ                         Δ Δ Δ Δ            
           Δ       Δ                       Δ       Δ           
          Δ Δ     Δ Δ                     Δ Δ     Δ Δ          
         Δ   Δ   Δ   Δ                   Δ   Δ   Δ   Δ         
        Δ Δ Δ Δ Δ Δ Δ Δ                 Δ Δ Δ Δ Δ Δ Δ Δ        
       Δ               Δ               Δ               Δ       
      Δ Δ             Δ Δ             Δ Δ             Δ Δ      
     Δ   Δ           Δ   Δ           Δ   Δ           Δ   Δ     
    Δ Δ Δ Δ         Δ Δ Δ Δ         Δ Δ Δ Δ         Δ Δ Δ Δ    
   Δ       Δ       Δ       Δ       Δ       Δ       Δ       Δ   
  Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ  
 Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ 
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ

Isso parece muito legal: D
beary605 11/11

Usar esse Delta do capital do U + 0394 é um toque realmente agradável.
David Conrad

16

J

,/.(,~,.~)^:6,'o'

Não é o ideal, já que o triângulo é torto e seguido por muito espaço em branco - mas interessante, no entanto, pensei.

Resultado:

o                                                               
oo                                                              
o o                                                             
oooo                                                            
o   o                                                           
oo  oo                                                          
o o o o                                                         
oooooooo                                                        
o       o                                                       
oo      oo                                                      
o o     o o                                                     
oooo    oooo                                                    
o   o   o   o                                                   
oo  oo  oo  oo                                                  
o o o o o o o o                                                 
oooooooooooooooo                                                
o               o                                               
oo              oo                                              
o o             o o                                             
oooo            oooo                                            
o   o           o   o                                           
oo  oo          oo  oo                                          
o o o o         o o o o                                         
oooooooo        oooooooo                                        
o       o       o       o                                       
oo      oo      oo      oo                                      
o o     o o     o o     o o                                     
oooo    oooo    oooo    oooo                                    
o   o   o   o   o   o   o   o                                   
oo  oo  oo  oo  oo  oo  oo  oo                                  
o o o o o o o o o o o o o o o o                                 
oooooooooooooooooooooooooooooooo                                
o                               o                               
oo                              oo                              
o o                             o o                             
oooo                            oooo                            
o   o                           o   o                           
oo  oo                          oo  oo                          
o o o o                         o o o o                         
oooooooo                        oooooooo                        
o       o                       o       o                       
oo      oo                      oo      oo                      
o o     o o                     o o     o o                     
oooo    oooo                    oooo    oooo                    
o   o   o   o                   o   o   o   o                   
oo  oo  oo  oo                  oo  oo  oo  oo                  
o o o o o o o o                 o o o o o o o o                 
oooooooooooooooo                oooooooooooooooo                
o               o               o               o               
oo              oo              oo              oo              
o o             o o             o o             o o             
oooo            oooo            oooo            oooo            
o   o           o   o           o   o           o   o           
oo  oo          oo  oo          oo  oo          oo  oo          
o o o o         o o o o         o o o o         o o o o         
oooooooo        oooooooo        oooooooo        oooooooo        
o       o       o       o       o       o       o       o       
oo      oo      oo      oo      oo      oo      oo      oo      
o o     o o     o o     o o     o o     o o     o o     o o     
oooo    oooo    oooo    oooo    oooo    oooo    oooo    oooo    
o   o   o   o   o   o   o   o   o   o   o   o   o   o   o   o   
oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o 
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

Uma explicação rápida:

O verbo (,~,.~)é o que está fazendo o trabalho aqui. É um gancho que primeiro une ,.o argumento ( o-> oo) e depois anexa o argumento original à saída:

oo

torna-se

oo
o

Esse verbo é repetido 6 vezes, ^:6com a saída de cada iteração se tornando a entrada da próxima iteração. assim

oo
o

torna-se

oooo
o o
oo
o

que por sua vez se torna

oooooooo
o o o o 
oo  oo
o   o
oooo
o o
oo
o

etc. Em seguida, usei o advérbio oblíquo no anexo ,/.para ler as linhas na diagonal para endireitar (ish) o triângulo. Eu não precisava fazer isso, como randomra aponta. Eu poderia ter revertido |.o lote para obter o mesmo resultado. Ainda melhor, eu poderia ter usado apenas (,,.~)^:6,'o'para salvar a etapa inversa completamente.

Ah, bem, você vive e aprende. :-)


1
Você poderia explicar brevemente como funciona? Eu não estou familiarizado com J
aditsu

1
|.(,~,.~)^:6,'o'é mais curto e sem espaços extras. E (,~,.~)^:6,1também oferece entrada decente em apenas 12 caracteres!
randomra

@aditsu Adicionei uma explicação.
Gareth

Então, se eu entendi, esse operador concatena duas matrizes 2D?
MaiaVictor

13

APL (51)

      A←67⍴0⋄A[34]←1⋄' ○'[1+32 67⍴{~⊃⍵:⍵,∇(1⌽⍵)≠¯1⌽⍵⋄⍬}A]

Explicação:

  • A←67⍴0: A é um vetor de 67 zeros
  • A[34]←1: o 34º elemento é 1
  • {...}A: começando com A, faça:
  • ~⊃⍵:: se o primeiro elemento da linha atual for zero
  • ⍵,∇: adicione a linha atual à resposta e recorra com:
  • (1⌽⍵)≠¯1⌽⍵: o vetor em que cada elemento é o XOR de seus vizinhos na geração anterior
  • ⋄⍬: caso contrário, terminamos
  • 32 67⍴: formate isso em uma matriz 67x32
  • 1+: adicione um para selecionar o valor correto da matriz de caracteres
  • ' ○'[... ]: gera um espaço (não faz parte do triângulo) ou um círculo (quando faz parte do triângulo)

Resultado:

                                 ○                                 
                                ○ ○                                
                               ○ ○                               
                              ○ ○ ○ ○                              
                             ○ ○                             
                            ○ ○ ○ ○                            
                           ○ ○ ○ ○                           
                          ○ ○ ○ ○ ○ ○ ○ ○                          
                         ○ ○                         
                        ○ ○ ○ ○                        
                       ○ ○ ○ ○                       
                      ○ ○ ○ ○ ○ ○ ○ ○                      
                     ○ ○ ○ ○                     
                    ○ ○ ○ ○ ○ ○ ○ ○                    
                   ○ ○ ○ ○ ○ ○ ○ ○                   
                  ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○                  
                 ○ ○                 
                ○ ○ ○ ○                
               ○ ○ ○ ○               
              ○ ○ ○ ○ ○ ○ ○ ○              
             ○ ○ ○ ○             
            ○ ○ ○ ○ ○ ○ ○ ○            
           ○ ○ ○ ○ ○ ○ ○ ○           
          ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○          
         ○ ○ ○ ○         
        ○ ○ ○ ○ ○ ○ ○ ○        
       ○ ○ ○ ○ ○ ○ ○ ○       
      ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○      
     ○ ○ ○ ○ ○ ○ ○ ○     
    ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○    
   ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○   
  ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○  

1
Caramba. Eu esperava que este seja 4 caracteres, utilizando binômios mod 2 ... (ok ... talvez um pouco mais do que isso)
Boothby

13

Haskell (292)

Eu não sou muito bom em códigos de haskell de golfe.

solve n = tri (putStrLn "") [2^n] n
tri m xs 1 =
  do putStrLn (l1 1 xs "/\\" 0)
     putStrLn (l1 1 xs "/__\\" 1)
     m
tri m xs n=tri m' xs (n-1)
  where m'=tri m (concat[[x-o,x+o]|x<-xs]) (n-1)
        o=2^(n-1)
l1 o [] s t=""
l1 o (x:xs) s t=replicate (x-o-t) ' '++s++l1 (x+2+t) xs s t

Saída de solve 4is:

               /\
              /__\
             /\  /\
            /__\/__\
           /\      /\
          /__\    /__\
         /\  /\  /\  /\
        /__\/__\/__\/__\
       /\              /\
      /__\            /__\
     /\  /\          /\  /\
    /__\/__\        /__\/__\
   /\      /\      /\      /\
  /__\    /__\    /__\    /__\
 /\  /\  /\  /\  /\  /\  /\  /\
/__\/__\/__\/__\/__\/__\/__\/__\

13

QBasic 151 caracteres

Como um exemplo, aqui está como isso pode ser feito no QBasic.

SCREEN 9
H=.5
P=300
FOR I=1 TO 9^6
    N=RND
    IF N > 2/3 THEN
        X=H+X*H:Y=Y*H
    ELSEIF N > 1/3 THEN
        X=H^2+X*H:Y=H+Y*H    
    ELSE
        X=X*H:Y=Y*H
    END IF
    PSET(P-X*P,P-Y*P)
NEXT

insira a descrição da imagem aqui


Você poderia descrever a medida sob a qual este programa tem 129 caracteres? Recebo 151 se retirar todo o espaço em branco provavelmente desnecessário. (Eu não estou familiarizado com o QBasic.)
Kevin Reid

Tirei todo o espaço em branco da minha conta. Eu acho que eu poderia contar apenas espaços em branco não essenciais. Não tenho certeza de qual é a regra "oficial" para o código de golfe.
Kibbee

4
Você deve contar o número real de caracteres, incluindo espaços em branco, em um programa que executa e produz a saída correta . Naturalmente, você não precisará de espaços em branco desnecessários.
Kevin Reid

1
Corrigido minha contagem de caracteres.
Kibbee

13

Python (42)

Originalmente, eu queria postar algumas sugestões sobre a solução boothbys (que realmente usa a regra 18 :), mas eu não tinha reputação suficiente para comentar, então fiz isso em outra resposta. Desde que ele mudou sua abordagem, adicionei algumas explicações. Minhas sugestões teriam sido:

  1. use '% d' * 64% de tupla (x) em vez de '' .join (map (str, x)
  2. mudança de zeros em vez de envolver a lista

o que levaria ao seguinte código (93 caracteres):

x=[0]*63
x[31]=1
exec"print'%d'*63%tuple(x);x=[a^b for a,b in zip(x[1:]+[0],[0]+x[:-1])];"*32

Mas eu otimizei ainda mais, primeiro usando um longint em vez de um array inteiro e apenas imprimindo a representação binária (75 caracteres):

x=2**31
exec"print'%d'*63%tuple(1&x>>i for i in range(63));x=x<<1^x>>1;"*32

E, finalmente, imprimindo a representação octal, que já é suportada pela interpolação printf (42 caracteres):

x=8**31
exec"print'%063o'%x;x=x*8^x/8;"*32

Todos eles imprimirão:

000000000000000000000000000000010000000000000000000000000000000
000000000000000000000000000000101000000000000000000000000000000
000000000000000000000000000001000100000000000000000000000000000
000000000000000000000000000010101010000000000000000000000000000
000000000000000000000000000100000001000000000000000000000000000
000000000000000000000000001010000010100000000000000000000000000
000000000000000000000000010001000100010000000000000000000000000
000000000000000000000000101010101010101000000000000000000000000
000000000000000000000001000000000000000100000000000000000000000
000000000000000000000010100000000000001010000000000000000000000
000000000000000000000100010000000000010001000000000000000000000
000000000000000000001010101000000000101010100000000000000000000
000000000000000000010000000100000001000000010000000000000000000
000000000000000000101000001010000010100000101000000000000000000
000000000000000001000100010001000100010001000100000000000000000
000000000000000010101010101010101010101010101010000000000000000
000000000000000100000000000000000000000000000001000000000000000
000000000000001010000000000000000000000000000010100000000000000
000000000000010001000000000000000000000000000100010000000000000
000000000000101010100000000000000000000000001010101000000000000
000000000001000000010000000000000000000000010000000100000000000
000000000010100000101000000000000000000000101000001010000000000
000000000100010001000100000000000000000001000100010001000000000
000000001010101010101010000000000000000010101010101010100000000
000000010000000000000001000000000000000100000000000000010000000
000000101000000000000010100000000000001010000000000000101000000
000001000100000000000100010000000000010001000000000001000100000
000010101010000000001010101000000000101010100000000010101010000
000100000001000000010000000100000001000000010000000100000001000
001010000010100000101000001010000010100000101000001010000010100
010001000100010001000100010001000100010001000100010001000100010
101010101010101010101010101010101010101010101010101010101010101

Claro que também existe uma solução gráfica (131 caracteres):

from PIL.Image import*
from struct import*
a=''
x=2**31
exec"a+=pack('>Q',x);x=x*2^x/2;"*32
fromstring('1',(64,32),a).save('s.png')

triângulo muito pequeno de sierpinsky : D


1
36:x=8**31;exec"print'%o'%x;x^=x/8;"*32
aditsu 27/02

13

8086 Código da máquina - 30 bytes.

NOTA: Este não é o meu código e não deve ser aceito como resposta . Encontrei isso enquanto trabalhava em um problema de CG diferente para emular uma CPU 8086 . O arquivo de texto incluído credita David Stafford , mas é o melhor que eu pude apresentar.

Estou postando isso porque é inteligente, curto e achei que você gostaria de vê-lo.

Ele utiliza opcodes sobrepostos para embalar mais instruções em um espaço menor. Surpreendentemente inteligente. Aqui está o código da máquina:

B0 13 CD 10 B3 03 BE A0 A0 8E DE B9 8B 0C 32 28 88 AC C2 FE 4E 75 F5 CD 16 87 C3 CD 10 C3

Uma decodificação direta é assim:

0100: B0 13              mov AL, 13h
0102: CD 10              int 10h
0104: B3 03              mov BL, 3h
0106: BE A0 A0           mov SI, A0A0h
0109: 8E DE              mov  DS, SI
010B: B9 8B 0C           mov CX, C8Bh
010E: 32 28              xor  CH, [BX+SI]
0110: 88 AC C2 FE        mov  [SI+FEC2h], CH
0114: 4E                 dec SI
0115: 75 F5              jne/jnz -11

Quando executado, quando o salto em 0x0115 acontece, observe que ele volta para 0x010C, bem no meio de uma instrução anterior:

0100: B0 13              mov AL, 13h
0102: CD 10              int 10h
0104: B3 03              mov BL, 3h
0106: BE A0 A0           mov SI, A0A0h
0109: 8E DE              mov  DS, SI
010B: B9 8B 0C           mov CX, C8Bh
010E: 32 28              xor  CH, [BX+SI]
0110: 88 AC C2 FE        mov  [SI+FEC2h], CH
0114: 4E                 dec SI
0115: 75 F5              jne/jnz -11
010C: 8B 0C              mov  CX, [SI]
010E: 32 28              xor  CH, [BX+SI]
0110: 88 AC C2 FE        mov  [SI+FEC2h], CH
0114: 4E                 dec SI
0115: 75 F5              jne/jnz -11
010C: 8B 0C              mov  CX, [SI]

Brilhante! Espero que vocês não se importem de eu compartilhar isso. Sei que não é uma resposta em si, mas é interessante para o desafio.

Aqui está em ação:

Corrida


11

C 127 119 116 108 65

Este usa o truque da resposta HTML para ^ i & jfazê-lo imprimir uma saída bonita levaria mais 1 caractere (você pode obter uma saída realmente feia sacrificando o a^).

a=32,j;main(i){for(;++i<a;)putchar(a^i&j);++j<a&&main(puts(""));}

Para torná-lo bonito, vire (32^i&j)para (32|!(i&j))e ++i<apara ++i<=a. No entanto, desperdiçar caracteres na aparência parece-me um absurdo.

Saída feia:

 ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
""  ""  ""  ""  ""  ""  ""  ""
"# !"# !"# !"# !"# !"# !"# !"#
  $$$$    $$$$    $$$$    $$$$
 !$%$% ! !$%$% ! !$%$% ! !$%$%
""$$&&  ""$$&&  ""$$&&  ""$$&&
"#$%&' !"#$%&' !"#$%&' !"#$%&'
      ((((((((        ((((((((
 ! ! !()()()() ! ! ! !()()()()
""  ""((**((**  ""  ""((**((**
"# !"#()*+()*+ !"# !"#()*+()*+
  $$$$((((,,,,    $$$$((((,,,,
 !$%$%()(),-,- ! !$%$%()(),-,-
""$$&&((**,,..  ""$$&&((**,,..
"#$%&'()*+,-./ !"#$%&'()*+,-./
              0000000000000000
 ! ! ! ! ! ! !0101010101010101
""  ""  ""  ""0022002200220022
"# !"# !"# !"#0123012301230123
  $$$$    $$$$0000444400004444
 !$%$% ! !$%$%0101454501014545
""$$&&  ""$$&&0022446600224466
"#$%&' !"#$%&'0123456701234567
      ((((((((0000000088888888
 ! ! !()()()()0101010189898989
""  ""((**((**0022002288::88::
"# !"#()*+()*+0123012389:;89:;
  $$$$((((,,,,000044448888<<<<
 !$%$%()(),-,-010145458989<=<=
""$$&&((**,,..0022446688::<<>>
"#$%&'()*+,-./0123456789:;<=>?

Na verdade, eu meio que gosto da aparência. Mas se você insistir em ser bonito, pode encaixar quatro caracteres. Saída bonita:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
  !!  !!  !!  !!  !!  !!  !!  !
  !   !   !   !   !   !   !   !
!!    !!!!    !!!!    !!!!    !
!     ! !     ! !     ! !     !
      !!      !!      !!      !
      !       !       !       !
!!!!!!        !!!!!!!!        !
! ! !         ! ! ! !         !
  !!          !!  !!          !
  !           !   !           !
!!            !!!!            !
!             ! !             !
              !!              !
              !               !
!!!!!!!!!!!!!!                !
! ! ! ! ! ! !                 !
  !!  !!  !!                  !
  !   !   !                   !
!!    !!!!                    !
!     ! !                     !
      !!                      !
      !                       !
!!!!!!                        !
! ! !                         !
  !!                          !
  !                           !
!!                            !
!                             !
                              !
                              !

Saindo da versão anterior de autômatos celulares de 108 caracteres.

j,d[99][99];main(i){d[0][31]=3;for(;i<64;)d[j+1][i]=putchar(32|d[j][i+2]^d[j][i++]);++j<32&&main(puts(""));}

Então, acho que não vou ficar muito mais curto que isso, então vou explicar o código. Deixarei essa explicação, pois alguns truques podem ser úteis.

j,d[99][99]; // these init as 0
main(i){ //starts at 1 (argc)
  d[0][48]=3; //seed the automata (3 gives us # instead of !)
  for(;i<98;) // print a row
    d[j+1][i]=putchar(32|d[j][i+2]]^d[j][i++]);
    //relies on undefined behavoir. Works on ubuntu with gcc ix864
    //does the automata rule. 32 + (bitwise or can serve as + if you know
    //that (a|b)==(a^b)), putchar returns the char it prints
  ++j<32&&main(puts(""));
  // repeat 32 times
  // puts("") prints a newline and returns 1, which is nice
}

Alguma saída

                             # #                               
                            #   #                              
                           # # # #                             
                          #       #                            
                         # #     # #                           
                        #   #   #   #                          
                       # # # # # # # #                         
                      #               #                        
                     # #             # #                       
                    #   #           #   #                      
                   # # # #         # # # #                     
                  #       #       #       #                    
                 # #     # #     # #     # #                   
                #   #   #   #   #   #   #   #                  
               # # # # # # # # # # # # # # # #                 
              #                               #                
             # #                             # #               
            #   #                           #   #              
           # # # #                         # # # #             
          #       #                       #       #            
         # #     # #                     # #     # #           
        #   #   #   #                   #   #   #   #          
       # # # # # # # #                 # # # # # # # #         
      #               #               #               #        
     # #             # #             # #             # #       
    #   #           #   #           #   #           #   #      
   # # # #         # # # #         # # # #         # # # #     
  #       #       #       #       #       #       #       #    
 # #     # #     # #     # #     # #     # #     # #     # #   
#   #   #   #   #   #   #   #   #   #   #   #   #   #   #   #  
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

1
Este não parece ser um triângulo de Sierpinski; divide-se em três sub-triângulos (procedendo para baixo) em vez de dois, e pode-se ver que isso não produz um grande triângulo vazio central.
Kevin Reid

1
Isso porque eu usei a regra errada: O. Corrigido e raspado alguns caracteres.
walpen

9

Código 80x86 / MsDos - 10 bytes

Como um codificador de tamanho especializado para introduções muito pequenas no MsDos, eu consegui criar um programa que ocupa apenas 10 bytes.

em hexadecimal:

04 13 CD 10 20 E9 B4 0C E2 F6

insira a descrição da imagem aqui

em asm:

X: add al,0x13
int 0x10
and cl,ch
mov ah,0x0C
loop X

A primeira versão que codifiquei foi "Colpinski", com 16 bytes de tamanho, e até interativa de uma maneira que você pode alterar a cor com o teclado e o mouse. Juntamente com o "Frag" - outro sizecoder - reduzimos esse para 13 bytes, permitindo um programa de 10 bytes que contém apenas a rotina principal.

Fica um pouco mais interessante quando as coisas são animadas, então vou mencionar outra versão, o Zoompinski 64 - tentando imitar o comportamento exato do "Zoompinski C64" em 512 bytes - também para MsDos, 64 bytes de tamanho, como o nome sugere.

É possível otimizar isso ainda mais até 31 bytes, enquanto perde a elegância, as cores e a simetria (fonte e executável disponíveis no link acima)

Faça o download do original e comente sobre "Pouet"


2
Você deve publicar um dump hexadecimal do seu código, para que possamos ver os bytes reais.
mbomb007

8

PostScript, 120 caracteres

-7 -4 moveto
14 0 rlineto
7{true upath dup
2{120 rotate uappend}repeat[2 0 0 2 7 4]concat}repeat
matrix setmatrix
stroke

Saída Ghostscript:

Saída renderizada do Ghostscript

Isso está desenhando a figura triplicando recursivamente o que já está desenhado.

O primeiro passo é desenhar uma linha. A linha é salva como um caminho do usuário e, em seguida, o caminho do usuário é adicionado mais duas vezes depois de girar 120 graus a cada vez. [2 0 0 2 7 4]concatmove o "ponto de rotação" para o centro do próximo grande "triângulo central" branco que deve ser delimitado pelas repetições do triângulo que já temos. Aqui, voltamos à etapa 1 (criando uma atualização triplicada pela rotação).

O número de iterações é controlado pelo primeiro número na linha 3.


+1 Muito bom. Eu não tinha ideia de que poderia ser usado assim.
Luser droog

Ei, você tem o representante para adicionar essa imagem agora!
Luser droog

@luserdroog: Está certo (mesmo em parte graças a você)!
Thomas W.

7

J (9 caracteres)

Facilmente o mais feio, você realmente precisa apertar os olhos para ver a saída;)

2|!/~i.32

produz a saída

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

é claro que você pode exibi-lo graficamente:

load 'viewmat'
viewmat 2|!/~i.32

Imagem


como o ... o que?
Acolito #

4
O código explora a propriedade do triângulo de Pascal que, se você colorir todos os números ímpares (pares) de preto (branco), você termina com o triângulo de Sierpinski. (veja esta imagem). i.32 gera a lista 0 1 2 ... 31. Então! / ~ calcula os coeficientes binomiais de cada elemento da lista em relação a si próprio, isto é, produz uma matriz 32 x 32 que possui o triângulo de Pascal embutido nela. Então 2 | é simplesmente cada elemento nesta matriz mod 2, produzindo o triângulo de Sierpinski.
Mark Allen

4

APL, 37 32 ( 28 23)

Triângulo vertical ( 37 32 caracteres)

({((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 2⍴'/\'

Explicação

  • 1 2⍴'/\': Crie uma matriz de caracteres 1 × 2 /\
  • {((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}: Uma função que preenche o argumento da direita em ambos os lados com espaços em branco para criar uma matriz com o dobro da largura e depois lamina o próprio argumento da direita dobrado na parte inferior.
    Por exemplo, /\se tornaria
 / \ 
/ \ / \
  • ⍣⎕: Repita os tempos da função (entrada do usuário).

Saída de exemplo

               /\               
              /\/\              
             /\  /\             
            /\/\/\/\            
           /\      /\           
          /\/\    /\/\          
         /\  /\  /\  /\         
        /\/\/\/\/\/\/\/\        
       /\              /\       
      /\/\            /\/\      
     /\  /\          /\  /\     
    /\/\/\/\        /\/\/\/\    
   /\      /\      /\      /\   
  /\/\    /\/\    /\/\    /\/\  
 /\  /\  /\  /\  /\  /\  /\  /\ 
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

Triângulo enviesado ( 28 23 caracteres)

({(⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 1⍴'○'

Explicação

  • 1 1⍴'○': Criar uma matriz de caracteres 1 × 1
  • {(⍵,∊⍵)⍪⍵,⍵}: Uma função que preenche o argumento certo à direita com espaços em branco para criar uma matriz com o dobro da largura e, em seguida, lamina o próprio argumento dobrado na parte inferior.
    Por exemplo, se tornaria
○ 
○○
  • ⍣⎕: Repita os tempos da função (entrada do usuário).

Saída de exemplo

○               
○○              
○ ○             
○○○○            
○   ○           
○○  ○○          
○ ○ ○ ○         
○○○○○○○○        
○       ○       
○○      ○○      
○ ○     ○ ○     
○○○○    ○○○○    
○   ○   ○   ○   
○○  ○○  ○○  ○○  
○ ○ ○ ○ ○ ○ ○ ○ 
○○○○○○○○○○○○○○○○

4

Python (75)

Estou dois anos atrasado para a festa, mas estou surpreso que ninguém tenha adotado essa abordagem ainda

from pylab import*
x=[[1,1],[1,0]]
for i in'123':x=kron(x,x)
imsave('a',x)

level7

Usa o produto Kronecker para substituir uma matriz por várias cópias de si mesmo.

Eu poderia salvar dois caracteres usando x=kron(x,x);x=kron(x,x)na linha três para obter uma imagem de 16x16 pixels com três níveis visíveis ou adicionar outro caracter ao iterador e terminar com uma imagem 2 ^ 16 x 2 ^ 16 = 4,3 Gigapixel e 15 níveis de triângulo.


3

Logotipo, 75 caracteres

59 caracteres apenas para a primeira função, a segunda chama a primeira com o tamanho e a profundidade / número de iterações. Assim, você pode simplesmente chamar a primeira função do intérprete com o comando: e 99 5, ou qualquer tamanho que você deseja exibir

to e :s :l
if :l>0[repeat 3[e :s/2 :l-1 fd :s rt 120]]
end
to f
e 99 5
end

+1 eu li sobre o Logo. Qual intérprete você está usando? ... O logotipo pode ser um ajuste natural para o meu desafio no sistema l .
Luser droog

Se você apenas remover o to fe endao redor e 99 5, você terá um programa executável completo em menos caracteres. Além disso, no UCBLogo (embora não em outras versões), você pode perder os dois pontos nas variáveis ​​para salvar mais caracteres.
Mark Reed

3

matlab 56

v=[1;-1;j];plot(filter(1,[1,-.5],v(randi(3,1,1e4))),'.')

insira a descrição da imagem aqui


3

J (18 caracteres)

' *'{~(,,.~)^:9 ,1

Resultado

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

3

Python (90 caracteres)

from turtle import*
def l():left(60)
def r():right(60)
def f():forward(1)
def L(n):
 if n:n-=1;R(n);l();L(n);l();R(n)
 else:f()
def R(n):
 if n:n-=1;L(n);r();R(n);r();L(n)
 else:f()
l();L(8)

Experimente online

Desenhar linha fractal preenchendo o triângulo de Sierpinsky


Antes de executar, recomendo inserir ht();speed(0);up();goto(20-window_width()/2, 20-window_height()/2);down()após a importação. Isso executará muito mais rápido e garantirá que a saída caiba na tela.
mbomb007

3

Mathematica 67

ListPlot@NestList[(#+RandomChoice@{{0,0},{2,0},{1,2}})/2&,{0,0},8!]

insira a descrição da imagem aqui

Mathematica 92

Graphics@Polygon@Nest[Join@@(Mean/@#&/@#~Tuples~2~Partition~3&/@#)&,{{{0,0},{2,0},{1,1}}},3]

insira a descrição da imagem aqui


3

Mathematica , 29 bytes

Image@Array[BitAnd,{2,2}^9,0]

Imagem @ matriz [BitAnd, {2,2} ^ 9,0]

O tetraedro de Sierpinski pode ser desenhado de maneira semelhante:

Image3D[1-Array[BitXor,{2,2,2}^7,0]]

Image3D [1 matriz [BitXor, {2,2,2} ^ 7,0]]


3

J , 37 35 bytes

-2 bytes graças ao FrownyFrog

(,.~,~' '&,.^:#)@[&0' /\',:'/__\'"_

Experimente online!

Esta é a versão ascii art de Peter Taylor convertida em J. Poderia salvar bytes com uma versão menos bonita, mas por quê?

       /\       
      /__\      
     /\  /\     
    /__\/__\    
   /\      /\   
  /__\    /__\  
 /\  /\  /\  /\ 
/__\/__\/__\/__\

@]^:[-> @[&0and ' /\ '->' /\'
FrownyFrog

Você sabe onde o &0truque está documentado?
Jonah

1
Mencionado aqui na parte inferior da página. Enquanto ele salva um byte, você perde a capacidade de ter um número negativo de repetições.
FrownyFrog

Ah, você deve conseguir trocar os operandos por ,~aí.
FrownyFrog

3

Script Lua em Golly , 54 bytes

g=golly()
g.setrule("W60")
g.setcell(0,0,1)
g.run(512)

Golly é um simulador de autômato celular com suporte a scripts Lua e Python.

Este script define a regra como Wolfram Rule 60, define a célula em (0,0) como 1 e executa 512 etapas.

insira a descrição da imagem aqui


2

Postscript, 205 203

[48(0-1+0+1-0)49(11)43(+)45(-)/s{dup
0 eq{exch{[48{1 0 rlineto}49 1 index
43{240 rotate}45{120 rotate}>>exch
get exec}forall}{exch{load
exch 1 sub s}forall}ifelse 1 add}>>begin
9 9 moveto(0-1-1)9 s fill

Reescreva usando seqüências de caracteres e recursão termina exatamente na mesma contagem. Mas as limitações de profundidade da abordagem macro são superadas.

Editar: fill é menor que stroke.

Recuado e comentado.

%!
[   % begin dictionary
    48(0-1+0+1-0) % 0
    49(11)        % 1
    43(+)         % +
    45(-)         % -
    /s{ % string recursion-level
        dup 0 eq{ % level=0
            exch{  % iterate through string
                [
                    48{1 0 rlineto} % 0
                    49 1 index      % 1 
                    43{240 rotate}  % +
                    45{120 rotate}  % -
                >>exch get exec % interpret turtle command
            }forall
        }{ % level>0
            exch{  % iterate through string
                load exch  % lookup charcode
                1 sub s    % recurse with level-1
            }forall
        }ifelse
        1 add  % return recursion-level+1
    }
>>begin
9 9 moveto(0-1-1)9 s fill % execute and fill

A adição 0 setlinewidthdá uma melhor impressão de quão profunda é essa.

revisar imagem usando <code> fill </code> (praticamente o mesmo)


Este é o meu favorito.
precisa saber é o seguinte

Existe uma maneira de torná-lo mais curto com essa lib externa que escrevi após o fato e não posso usar. : P
luser droog


2

Assíntota, 152 bytes

Vou acrescentar isso, principalmente porque eu tenho visto mais ou menos nenhuma resposta em assíntota neste site. Alguns bytes desperdiçados para boa formatação e generalidade, mas posso conviver com isso. Alterar A, B e C mudará onde estão os cantos do triângulo que o contém, mas provavelmente não da maneira que você pensa. Aumente o número na desigualdade para aumentar a profundidade.

pair A=(0,0),B=(1,0),C=(.5,1);void f(pair p,int d){if(++d<7){p*=2;f(p+A*2,d);f(p+B*2,d);f(p+C*2,d);}else{fill(shift(p/2)*(A--B--C--cycle));}}f((0,0),0);

ou ungolfed e legível

pair A=(0,0), B=(1,0), C=(.5,1);

void f(pair p, int d) {
    if (++d<7) {
        p *= 2;
        f(p+A*2,d);
        f(p+B*2,d);
        f(p+C*2,d);
    } else {
        fill(shift(p/2)*(A--B--C--cycle));
    }
}

f((0,0),0);

Portanto, a assíntota é uma linguagem elegante de gráficos vetoriais com sintaxe semelhante ao C. Bastante útil para diagramas um pouco técnicos. A saída é, obviamente, em um formato vetorial por padrão (eps, pdf, svg), mas pode ser convertida em basicamente tudo o que o imagemagick suporta. Resultado:

Triângulo de Sierpinski


2

Haskell , 166 154 bytes

(-12 bytes graças a Laikoni, (compreensão de zip e lista em vez de zipWith e lambda, melhor maneira de gerar a primeira linha))

i#n|let k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]];x=1<$[2..2^n]=mapM(putStrLn.map("M "!!))$take(2^n)$1!(x++0:x)

Experimente online!

Explicação:

A função i#ndesenha um triângulo ASCII de altura 2^napós ietapas da iteração.

A codificação usada internamente codifica posições vazias como 1e posições completas como 0. Por conseguinte, a primeira linha do triângulo é codificado como [1,1,1..0..1,1,1]com 2^n-1aquelas de ambos os lados do zero. Para construir esta lista, começamos com a lista x=1<$[2..2^n], ou seja, a lista [2..2^n]com tudo mapeado 1. Em seguida, criamos a lista completa comox++0:x

O operador k!p(explicação detalhada abaixo), dado um índice de linha ke um correspondente, pgera uma lista infinita de linhas a seguir p. Nós o chamamos com 1e a linha de partida descrita acima para obter o triângulo inteiro e, em seguida, pegar apenas as primeiras 2^nlinhas. Em seguida, simplesmente imprimimos cada linha, substituindo 1por espaço e 0por M(acessando a lista "M "no local 0ou 1).

Operador k!pé definido da seguinte maneira:

k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]]

Primeiro, geramos três versões de p: 1:pqual é pcom um 1prefixo em psi e tail p++[1]que é tudo, exceto o primeiro elemento de p, com um 1anexo. Em seguida, compactamos essas três listas, fornecendo todos os elementos efetivamente de pseus vizinhos esquerdo e direito, como (l,m,r). Usamos uma compreensão de lista para calcular o valor correspondente na nova linha:

m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))    

Para entender essa expressão, precisamos entender que existem dois casos básicos a serem considerados: ou simplesmente expandimos a linha anterior ou estamos em um ponto em que um ponto vazio no triângulo começa. No primeiro caso, temos um local preenchido se algum dos locais do bairro estiver preenchido. Isso pode ser calculado como m*l*r; se algum desses três for zero, o novo valor será zero. O outro caso é um pouco mais complicado. Aqui, precisamos basicamente da detecção de borda. A tabela a seguir fornece as oito vizinhanças possíveis com o valor resultante na nova linha:

000 001 010 011 100 101 110 111
 1   1   1   0   1   1   0   1

Uma fórmula simples para gerar essa tabela seria a 1-m*r*(1-l)-m*l*(1-r)que simplifica m*(2*l*r-l-r)+1. Agora precisamos escolher entre esses dois casos, que é onde usamos o número da linha k. Se mod k (2^(n-i)) == 0precisarmos usar o segundo caso, caso contrário, usaremos o primeiro caso. Portanto, o termo 0^(mod k(2^n-i))é 0se tivermos que usar o primeiro caso e 1se tivermos que usar o segundo caso. Como resultado, podemos usar

m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i)) 

no total - se usarmos o primeiro caso, simplesmente obtemos m*l*r, enquanto no segundo caso, um termo adicional é adicionado, fornecendo o total geral de m*(2*l*r-l-r)+1.


1
154 bytes: Experimente online! Boa explicação pelo caminho!
Laikoni

@Laikoni Ooh, algumas melhorias muito boas lá!
Sacchan

1

C, 106 caracteres

i,j;main(){for(;i<32;j>i/2?puts(""),j=!++i:0)
printf("%*s",j++?4:33-i+i%2*2,i/2&j^j?"":i%2?"/__\\":"/\\");}

(Ainda me diverte que puts("")é a maneira mais curta de gerar uma nova linha em C.)

Observe que você pode criar juntas maiores (ou menores) substituindo o teste 32no forcircuito por uma potência maior (menor) de dois, desde que você também substitua a 33no meio da printf()com a potência de duas mais 1.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.