Étant donné une n
sortie entière, la n
ième itération de la courbe de Hilbert en ASCII en utilisant les caractères _
et |
.
Voici les 4 premières itérations:
n=1
_
| |
n=2
_ _
| |_| |
|_ _|
_| |_
n=3
_ _ _ _
| |_| | | |_| |
|_ _| |_ _|
_| |_____| |_
| ___ ___ |
|_| _| |_ |_|
_ |_ _| _
| |___| |___| |
n=4
_ _ _ _ _ _ _ _
| |_| | | |_| | | |_| | | |_| |
|_ _| |_ _| |_ _| |_ _|
_| |_____| |_ _| |_____| |_
| ___ ___ | | ___ ___ |
|_| _| |_ |_| |_| _| |_ |_|
_ |_ _| _ _ |_ _| _
| |___| |___| |_| |___| |___| |
|_ ___ ___ ___ ___ _|
_| |_ |_| _| |_ |_| _| |_
| _ | _ |_ _| _ | _ |
|_| |_| | |___| |___| | |_| |_|
_ _ | ___ ___ | _ _
| |_| | |_| _| |_ |_| | |_| |
|_ _| _ |_ _| _ |_ _|
_| |___| |___| |___| |___| |_
Clarifications
- Ma question est similaire à Dessiner la courbe de Hilbert et Dessiner la courbe de Hilbert à l'aide de barres obliques .
- La conversion entre les traits de soulignement (
_
) et les barres verticales (|
) estu=2*v-1
oùu
est le nombre de_
s etv
le nombre de|
s. - Pour maintenir la cohérence avec mon message d'origine, la courbe doit commencer et se terminer en bas.
- Vous pouvez avoir un programme complet ou une fonction.
- Sortie vers stdout (ou quelque chose de similaire).
- Vous pouvez avoir des espaces blancs de début ou de fin, la sortie n'a qu'à s'aligner pour ressembler aux exemples.
- C'est le code-golf, donc la réponse la plus courte en octets gagne.
Réponses:
Befunge,
444368323 octetsEssayez-le en ligne!
L'approche typique pour dessiner la courbe de Hilbert consiste à suivre le chemin sous la forme d'une série de traits et de virages, en rendant le résultat sous forme de bitmap ou d'une zone de mémoire, puis en écrivant ce rendu lorsque le chemin est terminé. Ce n'est tout simplement pas possible dans Befunge lorsque nous n'avons que 2000 octets de mémoire pour travailler, et cela inclut la source du programme lui-même.
Donc, l'approche que nous avons adoptée ici est de trouver une formule qui nous indique exactement quel caractère afficher pour une coordonnée x, y donnée. Pour comprendre comment cela fonctionne, il est plus facile d'ignorer le rendu ASCII pour commencer, et il suffit de penser de la courbe comme composée de caractères de la boîte:
┌
,┐
,└
,┘
,│
et─
.Lorsque nous regardons la courbe comme ça, nous pouvons immédiatement voir que le côté droit est un miroir exact du côté gauche. Les personnages à droite peuvent simplement être déterminés en regardant leur partenaire sur la gauche et en le réfléchissant horizontalement (c'est-à-dire les occurrences de
┌
et┐
sont permutées, comme le sont└
et┘
).Ensuite, en regardant dans le coin inférieur gauche, encore une fois, nous pouvons voir que la moitié inférieure est un reflet de la moitié supérieure. Ainsi, les caractères en bas sont simplement déterminés en recherchant leur partenaire au-dessus et en le réfléchissant verticalement (c'est-à-dire les occurrences de
┌
et└
sont permutées, comme le sont┐
et┘
).La moitié restante de ce coin est un peu moins évidente. Le bloc de droite peut être dérivé d'une réflexion verticale du bloc diagonalement adjacent à lui.
Et le bloc de gauche peut être dérivé d'une réflexion verticale du bloc tout en haut à gauche de la courbe complète.
À ce stade, tout ce qui nous reste est le coin supérieur gauche, qui est juste une autre itération de Hilbert Curve inférieure. En théorie, nous devrions maintenant simplement devoir répéter le processus à nouveau, mais il y a un petit problème - à ce niveau, les moitiés gauche et droite du bloc ne sont pas des miroirs exacts l'une de l'autre.
Donc, à tout autre chose qu'au niveau supérieur, les caractères du coin inférieur doivent être traités comme un cas spécial, où le
┌
caractère est reflété comme─
, et le│
caractère est reflété comme└
.Mais à part cela, nous pouvons vraiment répéter ce processus récursivement. Au dernier niveau, nous codons en dur le caractère en haut à gauche comme
┌
, et le caractère en dessous comme│
.Maintenant que nous avons un moyen de déterminer la forme de la courbe à une coordonnée x, y particulière, comment traduire cela en rendu ASCII? Il s'agit en fait d'un simple mappage qui traduit chaque tuile possible en deux caractères ASCII.
┌
devient_
(espace plus souligné)┐
devient└
devient|_
(barre verticale plus souligné)┘
devient|
(barre verticale plus espace)│
devient|
(encore une barre verticale plus un espace)─
devient__
(deux traits de soulignement)Ce mappage n'est pas intuitif au début, mais vous pouvez voir comment cela fonctionne en regardant deux rendus correspondants côte à côte.
Et c'est essentiellement tout ce qu'il y a à faire. En fait, l'implémentation de cet algorithme dans Befunge est un autre problème, mais je vais laisser cette explication pour une autre fois.
la source
C, 267 octets
Essayez-le en ligne!
h()
utilise la récursivité pour générer les traits de la courbe hlibert.t()
imprime uniquement le caractère de trait si la position du crayonp
est égale à la position de sortie actuelleq
.C'est inefficace mais simple.
Si la courbe commence en haut à gauche, le code peut être réduit à 256 octets.
la source
puts("")
au lieu deputchar(10)
et"..."+l*8+d*2
au lieu de&"..."[l*8+d*2]
etn--?h(d+r...-r,n):0
au lieu den--&&(h(d+r...-r,n))