El Triángulo de Sierpinsky es un fractal creado tomando un triángulo, disminuyendo la altura y el ancho en 1/2, creando 3 copias del triángulo resultante, y colocándolos de tal manera que cada triángulo toque a los otros dos en una esquina. Este proceso se repite una y otra vez con los triángulos resultantes para producir el triángulo de Sierpinski, como se ilustra a continuación.
Escribe un programa para generar un triángulo de Sierpinski. Puede usar cualquier método que desee para generar el patrón, ya sea dibujando los triángulos reales o usando un algoritmo aleatorio para generar la imagen. Puede dibujar en píxeles, arte ascii o lo que quiera, siempre que el resultado sea similar a la última imagen que se muestra arriba. Pocos personajes ganan.
Respuestas:
HTML + JavaScript, 150 caracteres (ver notas de 126 caracteres)
Espacio en blanco insertado para facilitar la lectura y no contado.
El núcleo de esto es aplicar la regla de colorear píxeles para los cuales
x & y == 0
por el condicionalx&y||
, que produce un "triángulo rectángulo de Sierpinski"; yx-~y/2,k-y
son una transformación de coordenadas para producir la visualización aproximadamente equilátera.Una versión menos correcta (HTML-wise) tiene 126 caracteres:
(La forma en que esto es menos correcto es que omite el
title
elemento y la etiqueta final delcanvas
elemento, los cuales son necesarios para un documento correcto aunque omitirlos no cambie la interpretación del documento).Se pueden guardar tres caracteres eliminando
k
a favor de la constante64
, a costa de un resultado menor; No contaría la8
opción ya que no tiene suficientes detalles.Tenga en cuenta que un tamaño de 256 o superior requiere atributos en el
<canvas>
para aumentar el tamaño del lienzo del valor predeterminado.fuente
<canvas id=c>
y luegoc.getContext
. Acortar bucles:for(x=k=128;x--;)for(y=k;y--;)
x&y?0:
se puede reemplazar conx&y||
una solución agradable.GolfScript (
4342 caracteres)Salida:
Cambia el "3" a un número mayor para un triángulo más grande.
fuente
Pitón (234)
Máximo golf, pequeña imagen:
Requiere
python3-cairo
.Para obtener una imagen grande y bonita necesitaba 239 caracteres.
fuente
import cairo as c
te ahorraría algunos personajesMathematica - 32 caracteres
Mathematica - 37 caracteres
Esto producirá una tabla 2D de 0 y 1, donde los 1s están dibujando el Triángulo de Sierpinski.
fuente
ArrayPlot@CellularAutomaton[90, {{1}, 0}, 31]
oMatrixPlot@CellularAutomaton[90, {{1}, 0}, 31]
.ReliefPlot@
...Python,
10186Utiliza la regla 90 autómata.
Esto es más largo, pero más bonito.
Editar: jugar con cuerdas directamente, deshacerse de los cortes odiosamente largos, hacer que la salida sea más bonita.
Salida:
fuente
J
No es ideal, ya que el triángulo es asimétrico y seguido de mucho espacio en blanco, pero, no obstante, me pareció interesante.
Salida:
Una explicación rápida:
El verbo
(,~,.~)
es lo que está haciendo el trabajo aquí. Es un gancho que primero cose,.
el argumento para sí mismo (o
->oo
) y luego agrega el argumento original a la salida:se convierte
Este verbo se repite 6 veces
^:6
con la salida de cada iteración convirtiéndose en la entrada de la siguiente iteración. Asi quese convierte
que a su vez se convierte
Luego, he usado el adverbio oblicuo en append
,/.
para leer las filas en diagonal para enderezar (ish) el triángulo. No necesitaba hacer esto, como señala randomra . Podría haber invertido|.
el lote para obtener el mismo resultado. Aún mejor, podría haber usado(,,.~)^:6,'o'
para guardar el paso inverso por completo.Ah bueno, vives y aprendes. :-)
fuente
|.(,~,.~)^:6,'o'
Es más corto y sin espacios adicionales. ¡Y(,~,.~)^:6,1
también proporciona una entrada decente en solo 12 caracteres!APL (51)
Explicación:
A←67⍴0
: A es un vector de 67 cerosA[34]←1
: el elemento 34 es 1{...}A
: comenzando con A, hacer:~⊃⍵:
: si el primer elemento de la fila actual es cero⍵,∇
: agrega la fila actual a la respuesta, y recurse con:(1⌽⍵)≠¯1⌽⍵
: el vector donde cada elemento es el XOR de sus vecinos en la generación anterior⋄⍬
: de lo contrario, hemos terminado32 67⍴
: formatee esto en una matriz 67x321+
: agregue uno para seleccionar el valor correcto de la matriz de caracteres' ○'[
...]
: genera un espacio (no es parte del triángulo) o un círculo (cuando es parte del triángulo)Salida:
fuente
Haskell (291)
No soy muy bueno en los códigos de golf de Haskell.
Salida de
solve 4
es:fuente
QBasic 151 Personajes
Como ejemplo, así es como se puede hacer en QBasic.
fuente
Pitón (42)
Originalmente quería publicar algunas sugerencias sobre la solución de boothbys (que en realidad usa la regla 18 :), pero no tenía suficiente reputación para comentar, así que lo convertí en otra respuesta. Como cambió su enfoque, agregué alguna explicación. Mis sugerencias habrían sido:
que habría llevado al siguiente código (93 caracteres):
Pero optimicé aún más, primero usando una clave larga en lugar de una matriz entera y simplemente imprimiendo la representación binaria (75 caracteres):
Y finalmente imprimiendo la representación octal, que ya es compatible con la interpolación printf (42 caracteres):
Todos ellos imprimirán:
Por supuesto, también hay una solución gráfica (131 caracteres):
:RE
fuente
x=8**31;exec"print'%o'%x;x^=x/8;"*32
8086 Código de máquina: 30 bytes.
NOTA: Este no es mi código y no debe aceptarse como respuesta . Encontré esto mientras trabajaba en un problema de CG diferente para emular una CPU 8086 . El archivo de texto incluido da crédito a David Stafford , pero eso es lo mejor que se me ocurrió.
Estoy publicando esto porque es inteligente, breve, y pensé que querrías verlo.
Utiliza códigos de operación superpuestos para empacar más instrucciones en un espacio más pequeño. Sorprendentemente inteligente. Aquí está el código de la máquina:
Un decodificador directo se ve así:
Cuando corres, cuando ocurre el salto en 0x0115, observa que vuelve a saltar a 0x010C, justo en el medio de una instrucción anterior:
¡Brillante! Espero que no les importe que comparta esto. Sé que no es una respuesta per se, pero es interesante para el desafío.
Aquí está en acción:
fuente
C
12711911610865Este usa el truco de la respuesta HTML de
^ i & j
conseguir que imprima una salida bonita tomaría 1 char más (puede obtener una salida realmente fea sacrificando laa^
).Para que sea bastante gire
(32^i&j)
a(32|!(i&j))
y convertirlo a partir++i<a
de++i<=a
. Sin embargo, el desperdicio de caracteres en miradas me parece poco gótico.Salida fea:
De hecho, me gusta cómo se ve. Pero si insiste en que sea bonita, puede acoplar cuatro caracteres. Salida bonita:
Dejando la versión anterior de 108 caracteres, autómatas celulares.
Así que no creo que vaya a hacerlo mucho más corto que esto, así que explicaré el código.Dejaré esta explicación, ya que algunos de los trucos podrían ser útiles.Alguna salida
fuente
Código 80x86 / MsDos - 10 bytes
Como sizecoder especializado en introducciones muy pequeñas en MsDos, logré crear un programa que ocupa solo 10 bytes.
en hexadecimal:
en asm:
La primera versión que codifiqué fue "Colpinski", que tiene un tamaño de 16 bytes, e incluso interactiva de manera que puede cambiar el color con el teclado y el mouse. Junto con "Frag", otro codificador de tamaño, lo redujimos a 13 bytes, lo que permite un programa de 10 bytes que solo contiene la rutina central.
Se vuelve un poco más interesante cuando las cosas están animadas, por lo que mencionaré otra versión, Zoompinski 64 , tratando de imitar el comportamiento exacto de "Zoompinski C64" en 512 bytes, también para MsDos, 64 bytes de tamaño como su nombre indica.
Es posible optimizar esto más abajo hasta 31 Bytes, mientras se pierde elegancia, colores y simetría (fuente y ejecutable disponible detrás del enlace de arriba)
Descarga el original y comenta en "Pouet"
fuente
PostScript, 120 caracteres
Salida de Ghostscript:
Esto es dibujar la figura triplicando recursivamente lo que ya está dibujado.
El primer paso es dibujar una línea. La línea se guarda como una ruta de usuario, luego la ruta de usuario se agrega dos veces más después de rotar 120 grados cada vez.
[2 0 0 2 7 4]concat
mueve el "punto de rotación" al centro del próximo gran "triángulo central" blanco que debe estar encerrado por las réplicas del triángulo que ya tenemos. Aquí, volvemos al paso 1 (crear un upath que se triplica por rotación).El número de iteraciones está controlado por el primer número en la línea 3.
fuente
J (9 caracteres)
Fácilmente lo más feo, realmente necesitas entrecerrar los ojos para ver la salida;)
produce la salida
Por supuesto, puede mostrarlo gráficamente:
fuente
APL,
3732 (2823)Triángulo vertical (
3732-char)Explicación
1 2⍴'/\'
: Crear una matriz de 1 × 2 caracteres/\
{((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}
: Una función que rellena el argumento correcto en ambos lados con espacios en blanco para crear una matriz doble de ancho, luego lamina el argumento derecho en sí mismo doblado en la parte inferior.Por ejemplo,
/\
se convertiría⍣⎕
: Repetir los tiempos de la función (entrada del usuario).Salida de ejemplo
Triángulo sesgado (
2823-char)Explicación
1 1⍴'○'
: Crear una matriz de caracteres 1 × 1○
{(⍵,∊⍵)⍪⍵,⍵}
: Una función que rellena el argumento derecho a la derecha con espacios en blanco para crear una matriz doble de ancho, luego lamina el argumento derecho en sí mismo doblado en la parte inferior.Por ejemplo,
○
se convertiría⍣⎕
: Repetir los tiempos de la función (entrada del usuario).Salida de ejemplo
fuente
Pitón (75)
Llego dos años tarde a la fiesta, pero me sorprende que nadie haya tomado este enfoque todavía
Utiliza el producto Kronecker para reemplazar una matriz por múltiples copias de sí mismo.
Podría guardar dos caracteres utilizando la
x=kron(x,x);x=kron(x,x)
línea tres para obtener una imagen de 16x16 píxeles con tres niveles visibles o agregar otro carácter al iterador y terminar con una imagen de 2 ^ 16 x 2 ^ 16 = 4.3 Gigapíxeles y 15 niveles de triángulo.fuente
Logo, 75 caracteres
59 caracteres para la primera función, la segunda llama a la primera con el tamaño y la profundidad / número de iteraciones. Entonces, puede llamar a la primera función del intérprete con el comando: e 99 5, o el tamaño que desee generar
fuente
to f
yend
alrededore 99 5
, tiene un programa ejecutable completo en menos caracteres. Además, en UCBLogo (aunque no en otras versiones) puede perder los dos puntos en las variables para guardar más caracteres.matlab 56
fuente
J (18 caracteres)
Resultado
fuente
Python (90 caracteres)
Pruébalo en línea
Dibuja una línea fractal que llena el Triángulo de Sierpinsky
fuente
ht();speed(0);up();goto(20-window_width()/2, 20-window_height()/2);down()
después de la importación. Esto lo ejecutará mucho más rápido y garantizará que la salida se ajuste al lienzo.Mathematica 67
Mathematica 92
fuente
Mathematica , 29 bytes
El tetraedro de Sierpinski se puede dibujar de manera similar:
fuente
J ,
3735 bytes-2 bytes gracias a FrownyFrog
Pruébalo en línea!
Esta es la versión de arte ascii de Peter Taylor convertida a J. Podría guardar bytes con una versión menos bonita, pero ¿por qué?
fuente
@]^:[
->@[&0
y' /\ '
->' /\'
&0
está documentado el truco?,~
alrededor.Lua script en Golly , 54 bytes
Golly es un simulador de autómatas celulares con soporte para secuencias de comandos Lua y Python.
Este script establece la regla en Wolfram Rule 60, establece la celda en (0,0) en 1 y ejecuta 512 pasos.
fuente
Posdata,
205203Reescribir usando cadenas y la recursión termina exactamente en el mismo recuento. Pero se superan las limitaciones de profundidad del enfoque macro.
Editar:
fill
es más corto questroke
.Sangrado y comentado.
Agregar
0 setlinewidth
da una mejor impresión de cuán profundo es este.fuente
APL (Dyalog Classic) , 12 bytes
Pruébalo en línea!
fuente
Asíntota, 152 bytes
Agregaré esto, principalmente porque no he visto más o menos respuestas en la asíntota en este sitio. Algunos bytes desperdiciados para un buen formato y generalidad, pero puedo vivir con eso. Cambiar A, B y C cambiará dónde están las esquinas del triángulo contenedor, pero probablemente no en la forma en que piensas. Aumente el número en la desigualdad para aumentar la profundidad.
o no golfista y legible
Entonces, asíntota es un lenguaje de gráficos vectoriales limpio con una sintaxis algo similar a C. Muy útil para diagramas algo técnicos. La salida es, por supuesto, en un formato vectorial de forma predeterminada (eps, pdf, svg), pero se puede convertir en básicamente todo lo que admite imagemagick. Salida:
fuente
Haskell ,
166154bytes(-12 bytes gracias a Laikoni, (comprensión de zip y lista en lugar de zipWith y lambda, mejor forma de generar la primera línea))
Pruébalo en línea!
Explicación:
La función
i#n
dibuja un triángulo de altura ASCII2^n
después dei
pasos de iteración.La codificación utilizada internamente codifica posiciones vacías como
1
y posiciones completas como0
. Por lo tanto, la primera línea del triángulo está codificada como[1,1,1..0..1,1,1]
con2^n-1
unos en ambos lados del cero. Para construir esta lista, comenzamos con la listax=1<$[2..2^n]
, es decir, la lista[2..2^n]
con todo lo mapeado1
. Luego, construimos la lista completa comox++0:x
El operador
k!p
(explicación detallada a continuación), dado un índice de líneak
y su correspondientep
genera una lista infinita de líneas que siguenp
. Lo invocamos con1
y la línea de inicio descrita anteriormente para obtener el triángulo completo, y luego solo tomamos las primeras2^n
líneas. Luego, simplemente imprimimos cada línea, reemplazando1
con espacio y0
conM
(accediendo a la lista"M "
en la ubicación0
o1
).El operador
k!p
se define de la siguiente manera:Primero, generamos tres versiones de
p
:1:p
que estáp
con un1
antepuesto, enp
sí mismo ytail p++[1]
que es todo menos el primer elemento dep
, con un1
adjunto. Luego comprimimos estas tres listas, dándonos efectivamente todos los elementosp
con sus vecinos izquierdo y derecho, como(l,m,r)
. Usamos una lista de comprensión para luego calcular el valor correspondiente en la nueva línea:Para entender esta expresión, debemos darnos cuenta de que hay dos casos básicos a considerar: o simplemente expandimos la línea anterior o estamos en un punto donde comienza un punto vacío en el triángulo. En el primer caso, tenemos un lugar lleno si alguno de los lugares en el vecindario está lleno. Esto se puede calcular como
m*l*r
; si alguno de estos tres es cero, entonces el nuevo valor es cero. El otro caso es un poco más complicado. Aquí, básicamente, necesitamos detección de bordes. La siguiente tabla muestra los ocho vecindarios posibles con el valor resultante en la nueva línea:Una fórmula sencilla para obtener esta tabla sería la
1-m*r*(1-l)-m*l*(1-r)
que se simplificam*(2*l*r-l-r)+1
. Ahora tenemos que elegir entre estos dos casos, que es donde usamos el número de líneak
. Simod k (2^(n-i)) == 0
, tenemos que usar el segundo caso, de lo contrario, usamos el primer caso. Por lo0^(mod k(2^n-i))
tanto, el término es0
si tenemos que usar el primer caso y1
si tenemos que usar el segundo caso. Como resultado, podemos usaren total: si usamos el primer caso, simplemente obtenemos
m*l*r
, mientras que en el segundo caso, se agrega un término adicional, dando el total general dem*(2*l*r-l-r)+1
.fuente
C, 106 caracteres
(Todavía me divierte que esa
puts("")
es la forma más corta de generar una nueva línea en C.)Tenga en cuenta que puede crear juntas más grandes (o más pequeñas) reemplazando la prueba
32
en elfor
bucle con una potencia más grande (más pequeña) de dos, siempre y cuando también reemplace la33
en el medioprintf()
con la potencia de dos más uno.fuente