Dado un n
resultado entero , la n
iteración de la curva de Hilbert en ASCII utilizando los caracteres _
y |
.
Aquí están las primeras 4 iteraciones:
n=1
_
| |
n=2
_ _
| |_| |
|_ _|
_| |_
n=3
_ _ _ _
| |_| | | |_| |
|_ _| |_ _|
_| |_____| |_
| ___ ___ |
|_| _| |_ |_|
_ |_ _| _
| |___| |___| |
n=4
_ _ _ _ _ _ _ _
| |_| | | |_| | | |_| | | |_| |
|_ _| |_ _| |_ _| |_ _|
_| |_____| |_ _| |_____| |_
| ___ ___ | | ___ ___ |
|_| _| |_ |_| |_| _| |_ |_|
_ |_ _| _ _ |_ _| _
| |___| |___| |_| |___| |___| |
|_ ___ ___ ___ ___ _|
_| |_ |_| _| |_ |_| _| |_
| _ | _ |_ _| _ | _ |
|_| |_| | |___| |___| | |_| |_|
_ _ | ___ ___ | _ _
| |_| | |_| _| |_ |_| | |_| |
|_ _| _ |_ _| _ |_ _|
_| |___| |___| |___| |___| |_
Aclaraciones
- Mi pregunta es similar a Dibujar la curva de Hilbert y Dibujar la curva de Hilbert usando barras inclinadas .
- La conversión entre guiones bajos (
_
) y barras verticales (|
) esu=2*v-1
dondeu
está el número de_
syv
es el número de|
s. - Para mantener la coherencia con mi publicación original, la curva debe comenzar y terminar en la parte inferior.
- Puede tener un programa completo o una función.
- Salida a stdout (o algo similar).
- Puede tener espacios en blanco iniciales o finales, la salida solo necesita alinearse para que se vea como los ejemplos.
- Este es el código de golf, por lo que la respuesta más corta en bytes gana.
Respuestas:
Befunge,
444368323 bytesPruébalo en línea!
El enfoque típico para dibujar la curva de Hilbert es seguir la ruta como una serie de trazos y vueltas, renderizando el resultado en un mapa de bits o alguna área de memoria, y luego escribiendo esa representación cuando se completa la ruta. Esto simplemente no es factible en Befunge cuando solo tenemos 2000 bytes de memoria para trabajar, y eso incluye la fuente del programa en sí.
Entonces, el enfoque que hemos tomado aquí es crear una fórmula que nos diga exactamente qué carácter generar para una determinada coordenada x, y. Para entender cómo funciona esto, es más fácil hacer caso omiso de la prestación ASCII para empezar, y sólo pensar en la curva como formado por caracteres de cuadro:
┌
,┐
,└
,┘
,│
, y─
.Cuando miramos la curva así, podemos ver de inmediato que el lado derecho es un espejo exacto del lado izquierdo. Los caracteres a la derecha se pueden determinar simplemente mirando a su compañero a la izquierda y reflejándolo horizontalmente (es decir, las ocurrencias de
┌
y┐
se intercambian, como son└
y┘
).Luego, mirando la esquina inferior izquierda, nuevamente podemos ver que la mitad inferior es un reflejo de la mitad superior. Por lo tanto, los caracteres en la parte inferior se determinan simplemente al buscar a su compañero arriba y reflejarlo verticalmente (es decir, las ocurrencias de
┌
y└
se intercambian, como son┐
y┘
).La mitad restante de esta esquina es un poco menos obvia. El bloque de la derecha se puede derivar de una reflexión vertical del bloque diagonalmente adyacente a él.
Y el bloque de la izquierda puede derivarse de una reflexión vertical del bloque en la esquina superior izquierda de la curva completa.
En este punto, todo lo que nos queda es la esquina superior izquierda, que es solo otra curva de Hilbert una iteración más baja. En teoría, ahora solo deberíamos repetir el proceso nuevamente, pero hay un problema: en este nivel, las mitades izquierda y derecha del bloque no son espejos exactos entre sí.
Entonces, en cualquier otra cosa que no sea el nivel superior, los caracteres de la esquina inferior deben manejarse como un caso especial, donde el
┌
personaje se refleja como─
, y el│
personaje se refleja como└
.Pero aparte de eso, realmente podemos repetir este proceso de forma recursiva. En el último nivel codificamos el carácter superior izquierdo como
┌
, y el carácter inferior como│
.Ahora que tenemos una manera de determinar la forma de la curva en una coordenada x, y particular, ¿cómo traducimos eso a la representación ASCII? En realidad, es solo un mapeo simple que traduce cada posible mosaico en dos caracteres ASCII.
┌
se convierte_
(espacio más guión bajo)┐
se convierte└
se convierte|_
(barra vertical más guión bajo)┘
se convierte|
(barra vertical más espacio)│
se convierte|
(nuevamente una barra vertical más espacio)─
se convierte__
(dos guiones bajos)Esta asignación no es intuitiva al principio, pero puede ver cómo funciona cuando mira dos representaciones correspondientes una al lado de la otra.
Y eso es básicamente todo lo que hay que hacer. En realidad, implementar este algoritmo en Befunge es otro problema por completo, pero dejaré esa explicación para otro momento.
fuente
C, 267 bytes
Pruébalo en línea!
h()
usa la recursividad para generar los trazos de la curva hlibert.t()
solo imprime el carácter de trazo si la posición del lápizp
es igual a la posición de salida actualq
.Esto es ineficiente pero simple.
Si la curva comienza en la esquina superior izquierda, el código puede reducirse a 256 bytes.
fuente
puts("")
lugar deputchar(10)
y en"..."+l*8+d*2
lugar de&"..."[l*8+d*2]
y enn--?h(d+r...-r,n):0
lugar den--&&(h(d+r...-r,n))