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.
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.
Respostas:
HTML + JavaScript, 150 caracteres (ver notas para 126 caracteres)
Espaço em branco inserido para facilitar a leitura e não contado.
O núcleo disso é a aplicação da regra de colorir pixels, pela qual,
x & y == 0
pela condicionalx&y||
, produz um "triângulo retângulo de Sierpinski"; ex-~y/2,k-y
são uma transformação de coordenadas para produzir a exibição aproximadamente equilateral.Uma versão menos correta (em HTML) tem 126 caracteres:
(A maneira pela qual isso é menos correto é que ele omite o
title
elemento e a tag final docanvas
elemento, 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
k
favor da constante64
, ao custo de um resultado menor; Eu não contaria a8
opçã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.fonte
<canvas id=c>
e entãoc.getContext
. Encurtar loops:for(x=k=128;x--;)for(y=k;y--;)
x&y?0:
pode ser substituída porx&y||
uma solução agradável.GolfScript (
4342 caracteres)Resultado:
Mude o "3" para um número maior para um triângulo maior.
fonte
Python (234)
Golfe máximo, imagem minúscula:
Requer
python3-cairo
.Para obter uma boa imagem grande, eu precisava de 239 caracteres.
fonte
import cairo as c
whould poupar alguns personagensMathematica - 32 caracteres
Mathematica - 37 caracteres
Isso produzirá uma tabela 2D de 0 e 1, onde 1s estão desenhando o triângulo de Sierpinski.
fonte
ArrayPlot@CellularAutomaton[90, {{1}, 0}, 31]
ouMatrixPlot@CellularAutomaton[90, {{1}, 0}, 31]
.ReliefPlot@
...Python,
10186Usa o autômato da regra 90.
Isso é mais longo, mas mais bonito.
Edit: tocando diretamente com as cordas, se livrando de fatias desagradáveis, tornando a saída mais bonita.
Resultado:
fonte
J
Não é o ideal, já que o triângulo é torto e seguido por muito espaço em branco - mas interessante, no entanto, pensei.
Resultado:
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:torna-se
Esse verbo é repetido 6 vezes,
^:6
com a saída de cada iteração se tornando a entrada da próxima iteração. assimtorna-se
que por sua vez se torna
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. :-)
fonte
|.(,~,.~)^:6,'o'
é mais curto e sem espaços extras. E(,~,.~)^:6,1
também oferece entrada decente em apenas 12 caracteres!APL (51)
Explicação:
A←67⍴0
: A é um vetor de 67 zerosA[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, terminamos32 67⍴
: formate isso em uma matriz 67x321+
: 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:
fonte
Haskell (292)
Eu não sou muito bom em códigos de haskell de golfe.
Saída de
solve 4
is:fonte
QBasic 151 caracteres
Como um exemplo, aqui está como isso pode ser feito no QBasic.
fonte
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:
o que levaria ao seguinte código (93 caracteres):
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):
E, finalmente, imprimindo a representação octal, que já é suportada pela interpolação printf (42 caracteres):
Todos eles imprimirão:
Claro que também existe uma solução gráfica (131 caracteres):
: D
fonte
x=8**31;exec"print'%o'%x;x^=x/8;"*32
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:
Uma decodificação direta é assim:
Quando executado, quando o salto em 0x0115 acontece, observe que ele volta para 0x010C, bem no meio de uma instrução anterior:
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:
fonte
C
12711911610865Este usa o truque da resposta HTML para
^ i & j
fazê-lo imprimir uma saída bonita levaria mais 1 caractere (você pode obter uma saída realmente feia sacrificando oa^
).Para torná-lo bonito, vire
(32^i&j)
para(32|!(i&j))
e++i<a
para++i<=a
. No entanto, desperdiçar caracteres na aparência parece-me um absurdo.Saída feia:
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.
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.Alguma saída
fonte
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:
em asm:
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"
fonte
PostScript, 120 caracteres
Saída 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]concat
move 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.
fonte
J (9 caracteres)
Facilmente o mais feio, você realmente precisa apertar os olhos para ver a saída;)
produz a saída
é claro que você pode exibi-lo graficamente:
fonte
APL,
3732 (2823)Triângulo vertical (
3732 caracteres)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 (
2823 caracteres)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
fonte
Python (75)
Estou dois anos atrasado para a festa, mas estou surpreso que ninguém tenha adotado essa abordagem ainda
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.fonte
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
fonte
to f
eend
ao redore 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.matlab 56
fonte
J (18 caracteres)
Resultado
fonte
Python (90 caracteres)
Experimente online
Desenhar linha fractal preenchendo o triângulo de Sierpinsky
fonte
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.Mathematica 67
Mathematica 92
fonte
Mathematica , 29 bytes
O tetraedro de Sierpinski pode ser desenhado de maneira semelhante:
fonte
J ,
3735 bytes-2 bytes graças ao FrownyFrog
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ê?
fonte
@]^:[
->@[&0
and' /\ '
->' /\'
&0
truque está documentado?,~
aí.Script Lua em Golly , 54 bytes
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.
fonte
Postscript,
205203Reescreva 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 questroke
.Recuado e comentado.
A adição
0 setlinewidth
dá uma melhor impressão de quão profunda é essa.fonte
APL (Dyalog Classic) , 12 bytes
Experimente online!
fonte
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.
ou ungolfed e legível
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:
fonte
Haskell ,
166154 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))
Experimente online!
Explicação:
A função
i#n
desenha um triângulo ASCII de altura2^n
apósi
etapas da iteração.A codificação usada internamente codifica posições vazias como
1
e posições completas como0
. Por conseguinte, a primeira linha do triângulo é codificado como[1,1,1..0..1,1,1]
com2^n-1
aquelas de ambos os lados do zero. Para construir esta lista, começamos com a listax=1<$[2..2^n]
, ou seja, a lista[2..2^n]
com tudo mapeado1
. Em seguida, criamos a lista completa comox++0:x
O operador
k!p
(explicação detalhada abaixo), dado um índice de linhak
e um correspondente,p
gera uma lista infinita de linhas a seguirp
. Nós o chamamos com1
e a linha de partida descrita acima para obter o triângulo inteiro e, em seguida, pegar apenas as primeiras2^n
linhas. Em seguida, simplesmente imprimimos cada linha, substituindo1
por espaço e0
porM
(acessando a lista"M "
no local0
ou1
).Operador
k!p
é definido da seguinte maneira:Primeiro, geramos três versões de
p
:1:p
qual ép
com um1
prefixo emp
si etail p++[1]
que é tudo, exceto o primeiro elemento dep
, com um1
anexo. Em seguida, compactamos essas três listas, fornecendo todos os elementos efetivamente dep
seus vizinhos esquerdo e direito, como(l,m,r)
. Usamos uma compreensão de lista para calcular o valor correspondente na nova linha: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:Uma fórmula simples para gerar essa tabela seria a
1-m*r*(1-l)-m*l*(1-r)
que simplificam*(2*l*r-l-r)+1
. Agora precisamos escolher entre esses dois casos, que é onde usamos o número da linhak
. Semod k (2^(n-i)) == 0
precisarmos usar o segundo caso, caso contrário, usaremos o primeiro caso. Portanto, o termo0^(mod k(2^n-i))
é0
se tivermos que usar o primeiro caso e1
se tivermos que usar o segundo caso. Como resultado, podemos usarno total - se usarmos o primeiro caso, simplesmente obtemos
m*l*r
, enquanto no segundo caso, um termo adicional é adicionado, fornecendo o total geral dem*(2*l*r-l-r)+1
.fonte
C, 106 caracteres
(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
32
nofor
circuito por uma potência maior (menor) de dois, desde que você também substitua a33
no meio daprintf()
com a potência de duas mais 1.fonte