Su tarea: generar un copo de nieve Koch hasta la enésima profundidad. No necesita hacer un copo de nieve Koch completo, solo un lado del triángulo inicial. Wikipedia sobre copos de Koch: https://en.wikipedia.org/wiki/Koch_snowflake .
Reglas:
- El programa debe generar un lado del copo de nieve de Koch hasta la enésima profundidad.
- La salida debe ser ASCII.
- Usted puede generar todo el copo de nieve; Esto no es obligatorio.
- Se aplican reglas estándar para entrada / salida y lagunas y demás.
- El espacio en blanco no importa, siempre y cuando todos los personajes estén en el lugar correcto entre sí.
- ¡El código más corto gana!
Casos de prueba:
n = 0:
__
n = 1:
__/\__
n = 2:
__/\__
\ /
__/\__/ \__/\__
n = 3:
__/\__
\ /
__/\__/ \__/\__
\ /
/_ _\
\ /
__/\__ __/ \__ __/\__
\ / \ / \ /
__/\__/ \__/\__/ \__/\__/ \__/\__
Espero que esto tenga sentido. Observe que en cada caso de prueba, el fractal se puede dividir en tres partes de igual longitud. Observe también que el ancho de cada copo de nieve es tres veces el ancho de la generación anterior del copo de nieve.
__/\__
con dos subrayados, lo que hace que cada iteración sea 3 veces más grande que la anterior. El uso de un solo subrayado parece dar contradicciones que comienzan a ponerse realmente incómodas en n = 3 Por ejemplo, las partes exteriores tienen anchura 12 mientras que la parte media tiene solamente la anchura 10, como consecuencia de la/_
y_\
que son demasiado estrechos. E incluso antes de eso, se ha_
expandido al doble del ancho de/
y\
./_
y_\
son la única parte realmente fatal: los guiones bajos deben desaparecer, porque deben estar en la misma posición que el/
y\
. Una vez hecho esto, las cosas pueden expandirse 3 veces desde n = 1 en adelante (pero n = 0 no encaja)Respuestas:
Haskell ,
308300299 bytesEdiciones:
zipWith(+)
azipWith(-)
y ajuste de codificaciones y las compensaciones se deshizo de toda señal de negación.#
que se eliminaran varios nombres de variables mediante el uso enr=reverse
lugar de la coincidencia directa de patrones.zipWith(-)
.o=[0,0]
para acortar las constantes de la lista.?
.Pruébalo en línea! (Lamentablemente, cualquier cosa mayor que n = 3 queda horriblemente envuelta e ilegible, pero puede copiarla en otro programa para verla).
Variaciones
[6]
a[6,4,4]
, se obtiene todo un copo de nieve. Pruébalo en línea!,3..gcd 3x
, obtiene una curva en el estilo con el que originalmente se le dio esta pregunta. Pruébalo en línea!Cómo funciona
k
es la función principal, toma unInt
n
y devuelve aString
.iterate(>>=(:[1,4,1]))[6]
genera una lista infinita que contiene, para cada n, los giros entre líneas consecutivas en esa iteración de curva, estilo de gráficos de tortuga, como números nominalmente entre0
y5
. Cada iteración es solo la anterior con los giros1,4,1
intercalados. La única razón por las listas secundarias comienzan con6
en lugar de0
es hacer elgcd
truco enf
el trabajo evitandof 0
.scanl1(+)
convierte los giros en direcciones "absolutas", hasta el módulo 6. A0
significa hacia la derecha, luego cada número más alto es 60 grados en sentido antihorario desde el anterior. (Bueno, sería 60 grados si este fuera un dibujo adecuado en lugar de ASCII).f
convierte una dirección absoluta en una lista de pares (codificación de caracteres, desplazamiento) que codifica qué caracteres agregar a la curva (para direcciones horizontales genera dos pares, de lo contrario, uno) y cómo cambia la posición relativa.#
operador recorre la lista anterior de pares (caracteres, codificación offset), generando pares reales (coordenadas, caracteres)._/\
nominalmente representa una línea dibujada desde una esquina inicial a través de una celda rectangular hasta una esquina final diferente.[y,x]
, de arriba a abajo, de izquierda a derecha, de modo que se ordenan en el orden en que queremos imprimirlas. Las columnas están basadas en 1. Se utilizan listas en lugar de tuplas para aritmética vectorial más corta con(&)=zipWith(-)
.[y,x]
que la celda en su esquina superior izquierda. Esto garantiza que todos los desplazamientos desde una esquina a sus celdas vecinas no sean negativos, evitando constantes negativas.[y1,x1,x2,y2]
donde[y1,x1]
está el desplazamiento de coordenadas desde la esquina inicial a la celda de caracteres y[y2,x2]
es el desplazamiento desde la esquina final a la celda de caracteres. Esto significa:3
...5
son solo el reverso de las listas para0
...2
, lo que permite que se generen con[id,r]<*>
.(&)=zipWith(-)
una lista de codificación o su reverso.?
, lo que genera el final aString
partir de ellos.x?l@(([_,w],c):r)
x
es la coordenada x del carácter anterior que se muestra en esta línea, o0
si está al comienzo de una línea;l
es la lista actual completa,w
es la coordenada x del siguiente carácter que se va a agregar,c
es el carácter yr
es la lista restante.\
y/
, por lo que se ordena en último lugar si se superpone con otro carácter en la misma posición. Por lo tanto, se detecta un guión bajo redundante comprobando que se ha repetido una coordenada x.fuente