Votre tâche pour aujourd'hui: dessinez une courbe de dragon!
Dans le cas où vous ne savez pas ce qu'est une courbe de dragon, voici une vidéo d'introduction ViHart (vraiment cool, regardez!)
Votre tâche: dessiner une courbe de dragon, répétée au moins 9 fois. Vous n'avez pas besoin d'afficher les itérations 1 à 9, il vous suffit de montrer la courbe finale produite après avoir terminé (au moins) 9 itérations. La courbe doit être tracée sous forme de lignes droites reliant les points sur la courbe; la sortie doit correspondre à l'une des images ci-dessous qui montre 9 itérations ou plus (jusqu'à la réflexion, la rotation, la mise à l'échelle et la variation de la largeur de ligne, de la couleur de la ligne et de la couleur d'arrière-plan). Votre sortie doit être suffisamment grande pour que les lignes individuelles et les "boîtes" qu'elles forment puissent être distinguées les unes des autres; si deux lignes ne se coupent pas dans la courbe, elles ne doivent pas occuper les mêmes pixels ou des pixels adjacents dans la sortie (il doit y avoir au moins un pixel de l'arrière-plan visible entre eux). Vous pouvez afficher l'image à l'écran ou enregistrer l'image dans un fichier est accepté. La sortie doit être graphique - il ne peut pas s'agir d'art ASCII.
Le code le plus court en octets gagne, mais les directives pour les bibliothèques ne doivent pas être incluses dans le nombre d'octets, et vous pouvez utiliser des bibliothèques graphiques ou d'autres bibliothèques écrites pour la langue de votre choix si elles ont été écrites avant la publication.
Veuillez inclure une image de la sortie de votre programme.
Ignorez ce paragraphe si vous avez regardé la vidéo:Pour ceux d'entre vous qui ont décidé de ne pas regarder la vidéo, les 12 premières itérations de la courbe du dragon sont présentées ci-dessous. Aux fins de cette tâche, une courbe de dragon est une courbe générée par la règle suivante: prenez le point final de la courbe actuelle, créez une seconde courbe tournée de 90 degrés autour de ce point final de sorte que le point final de l'original courbe est le point de départ de la nouvelle courbe et joignent les deux courbes en une seule courbe où elles se rencontrent. Dans les images ci-dessous, chaque nouvelle itération est générée en tournant l'itération précédente de 90 degrés dans le sens des aiguilles d'une montre autour du point final de chaque itération. Lorsque la courbe est affichée à l'écran, il n'est pas évident de savoir quelle extrémité compte comme «point final», mais lorsque la courbe est stockée sous forme de tableau de points, il est facile de définir le «point final» comme dernier point de le tableau.
L'art ascii est apprécié, mais n'est pas accepté: il s'agit d'une sortie graphique, pas d'un art ascii.
la source
Réponses:
x86, MSDOS, 16 octets
J'ai écrit cela il y a quelque temps, à ma connaissance, la plus petite routine pour produire une fractale de dragon. Il n'utilise pas de véritables itérations, mais trace directement chaque pixel discret contenu à l'intérieur de la fractale, montrant l' image finale . Il est inclus avec de nombreuses autres petites productions dans ce pack . La version 16 octets a été la fin de mes efforts pour obtenir la fractale du dragon aussi petite que possible, à partir de 2014 avec cette production de 32 octets .
Hex
Code
la source
Python 2/3,
1691671501119878 octetsNotez que l'importation n'est pas incluse dans le nombre d'octets, selon les spécifications du défi.
Merci à @AlexHall pour avoir économisé 39 (!) Octets et @ nedla2004 pour 13 autres
Commence par générer une liste ou des virages à droite (90) et à gauche (-90), puis parcourt la liste et déplace la tortue.
Sortie générée:
EDIT: Si c'est trop ennuyeux, regardez aussi, ajoutez
speed(0)
juste avant le premierfd(5)
. Il fonctionnera de la même manière, sauf que la tortue se déplacera beaucoup plus rapidement.la source
Logo, 43 octets
Essayez avec un interprète sur http://www.calormen.com/jslogo/#
Cela utilise le même principe que ma réponse art ASCII précédente et la formule sur wikipedia sauf que j'ai inversé la direction pour correspondre à l'image de la question:
bitand :i -:i
trouve le bit le moins significatif dei
. Nous divisonsi
par ceci pour chier ài
droite le montant requis, en donnant le nombre impair requisk
. Il n'est pas nécessaire de distinguer les virages à gauche et à droite; nous tournons simplement à gauche park*90
degrés et comptons sur le fait que la rotation est une opération modulo 360 pour effectuer le modulo pour nous.Production
utiliser
ht
pour cacher la tortue si nécessaire.Sortie (modifiée)
Ce qui suit montre comment la courbe est un simple brin.
la source
LindenMASM , 51 octets
LindenMASM était un langage que j'ai créé pour un défi il y a quelque temps et qui vivra pour toujours dans le bac à sable. Il utilise le concept des systèmes Lindenmayer pour dessiner des choses comme des courbes Dragon, des plantes fractales, des triangles Sierpinski, etc.
Le code source est le suivant:
Pour configurer cela par
n = 6
exemple:Cela produit l'image suivante via Python 3
turtle
:Il peut y avoir une légère différence de numérotation pour les itérations, car dans le système Lindenmayer, la première itération est une seule ligne. Voici à quoi cela ressemble
n = 10
:Juste pour le plaisir, voici à quoi cela ressemble avec 15 générations (avec une instruction supplémentaire
MOV 2
pour le rendre un peu plus petit):Une fois que vous avez jusqu'à 20 générations (avec
MOV 0.5
), vous ne pouvez plus vraiment voir les lignes, et cela prend BEAUCOUP d'étapes à créer (les paires de+-
et-+
ne sont pas optimisées). Voici ce que vous obtenez:Notez que l'interpréteur actuel peut présenter des problèmes graphiques pour de plus petites quantités de générations, c'est-à-dire éventuellement ne pas dessiner à l'écran. Malheureusement, quand cet interprète a été créé, il n'y avait aucun problème, un changement possible dans Python 3 aurait pu causer cela ou il pourrait simplement s'agir de mon système
la source
Sous-charge, 196 octets
J'ai pensé qu'il pourrait être intéressant d'essayer ce défi dans un esolang de faible puissance; La sous-charge fonctionne assez bien pour une langue avec un si petit nombre de commandes.
La sortie est un fichier SVG avec des balises très fortement imbriquées et quelques raccourcis de golf. Jusqu'à présent, je n'ai pas trouvé de navigateur capable de l'afficher (Firefox se bloque pendant plusieurs minutes en essayant de le charger, et Firefox et Chromium donnent un écran vide). La plupart des programmes de traitement d'image ne peuvent pas non plus le charger (ce qui rend difficile la conversion vers un autre format), mais j'ai réussi à le charger dans la visionneuse d'images Eye of Gnome (qui fait partie de l'installation par défaut sur Ubuntu). J'ai donc pris une capture d'écran de l'image pour que vous puissiez la voir (l'image réelle a un fond transparent, mais vous ne pouvez pas vraiment faire de capture d'écran transparente):
Nous devons spécifier explicitement la taille de l'image. Choisir une orientation appropriée pour l'image, dessiner tout à la taille légale minimale et effectuer le nombre minimum d'itérations spécifié par le défi, nous donne une image qui tient juste en 99 pixels de large, économisant un octet. C'est bien quand les choses fonctionnent comme ça.
L'algorithme général utilisé pour dessiner l'image consiste à maintenir deux variables (Underload ne nomme pas les variables, mais je les ai considérées comme x et y ), toutes deux initialement vides. Ensuite, nous remplaçons à plusieurs reprises ( x , y ) par ( x , tournez à gauche et avancez, y ) et ( x , tournez à droite et avancez, y ). Après dix itérations, x et y détiennent une courbe de dragon à neuf itérations.
Il existe également quelques micro-optimisations et astuces spécifiques à Underload. Afin d'éviter de trop déconner avec le haut de la pile, à chaque itération de boucle, nous commençons par combiner x et y dans la fonction "retourne la chaîne créée en concaténant: x , une instruction turn, l'argument de la fonction, un move- transmettre l'instruction, et y . " Cette fonction ne prend qu'un espace sur la pile, nous pouvons donc la dupliquer, l'appeler avec
-90
comme argument, échanger la valeur de retour sous le doublon et l'appeler avec90
comme argument, pour obtenir de nouvelles valeurs pour x et ysans jamais avoir à toucher plus que les deux premiers éléments de la pile (qui sont de loin les plus accessibles). Cette fonction est générée par du code lors de l'exécution. Le générateur lui-même est également généré au moment de l'exécution, afin de lui permettre de réutiliser la chaîne<g transform="translate
qui est également utilisée pour définir l'origine de l'image. Nous générons d'abord toutes les balises ouvertes, puis parce que toutes les balises de fermeture sont justes</g>
, nous pouvons générer 1024 balises de fermeture en répétant simplement la chaîne, sans se soucier de les faire correspondre aux balises ouvertes. (L'écriture efficace de nombres dans Underload est un problème intéressant en soi; cependant,(:*)::*:**:*
c'est probablement le moyen le plus efficace d'écrire 1024, ce qui se traduit par "2 à la puissance de (1 + 2 × 2) × 2").Underload n'a pas de bibliothèques graphiques, donc je produis du SVG en utilisant une combinaison de lignes de dessin dans une position fixe et en faisant tourner l'image autour d'un point donné; au lieu de tourner le stylo, nous tournons le papier. L'idée est qu'en dessinant une ligne, en faisant pivoter l'image entière, en dessinant une autre ligne, en faisant à nouveau pivoter l'image, etc., nous pouvons simuler efficacement des graphiques de tortues sans avoir à faire d'arithmétique ni utiliser de bibliothèques graphiques, car toutes les lignes sont dessinées au même endroit. Bien sûr, cela signifie que nous avons des balises de rotation d'image très fortement imbriquées, ce qui déroute de nombreux visualiseurs SVG.
Le style de l'image compterait par rapport au nombre d'octets, donc je devais donner le style minimum nécessaire pour afficher l'image. Cela s'avère être
stroke="#"
, ce qui se traduit plus ou moins par "la ligne doit être de couleur"; cela semble être étendu au dessin en noir. (Normalement, vous spécifiez la couleur comme, par exemple, "# 000".) L'arrière-plan est transparent par défaut. Nous ne spécifions pas de largeur de trait, mais le choix choisi par Eye of Gnome laisse tout visible.De nombreux interprètes Underload ont du mal avec ce programme, par exemple celui sur Try It Online plante, car il génère en interne de très grandes chaînes. L'interprète en ligne original de Underload fonctionne cependant. (Fait intéressant, le tout premier interprète était en ligne, donc la langue était utilisable en ligne avant d'être utilisable hors ligne.)
Quelque chose qui m'inquiète un peu, c'est qu'il ne semble y avoir que 1023 segments de ligne ici, et nous nous attendons à 1024. Il se pourrait que l'un des segments à la fin ne soit pas dessiné avec cet algorithme (ce serait à la place sur l'itération suivante). Si c'est disqualifiant, il peut être possible d'adapter le programme, mais cela pourrait bien se prolonger considérablement plus longtemps. (Ce n'est pas comme si ce défi allait gagner la compétition de toute façon; il y a déjà plusieurs entrées plus courtes.)
la source
MATL , 26 octets
Si différentes échelles dans les deux axes sont acceptées, le code peut être réduit à 19 octets:
Les figures ci-dessous correspondent à la version à échelle égale (26 octets).
Le code ci-dessus produit la 9ème (base 0) itération, c'est-à-dire la dixième image du défi:
Pour les autres valeurs, modifiez le
9
dans le code ou remplacez-le pari
pour prendre le nombre comme entrée utilisateur. Par exemple, le résultat pour13
est:Explication
Cela utilise une boucle pour construire progressivement un tableau des étapes suivies de la courbe dans le plan complexe. Par exemple, les deux premières étapes sont
1j
(haut) et-1
(gauche).Dans chaque itération, le tableau des étapes jusqu'à présent est copié. La copie du tableau est inversée , multipliée par
1j
(pour pivoter de 90 degrés) et concaténée à l'original.Après la boucle, une somme cumulative des étapes donne les points réels, qui sont ensuite tracés dans le plan complexe.
la source
Mathematica 86 octets
Comment ça marche:
{1,-1}
Sorties{1,-1}
. Il "le pousse essentiellement vers la pile". Cette valeur peut être rappelée avec%
.r=Reverse
renomme simplement la fonction Reverse parce que je l'utilise deux fois dans le code. LeGraphics@Line@
prend simplement une liste de points et trace une ligne les reliant. La viande réelle du problème se produit dans ce segment de code:Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]
. Laissez-moi vous dire - ce segment est compliqué comme f ****** ck. Voici ce quiNest
fait:Nest[f,x,9]
affiche le résultat de l'appelf[f[f[f[f[f[f[f[f[x]]]]]]]]]
.Dans mon code, ce premier argument
f
est :,Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
le deuxième argumentx
est{{0,0},%}
(qui évalue à{{0,0},{1,-1}}
), et le troisième argument estn
, qui est juste 9 (qui appliquera juste le premier argument au deuxième argument 9 fois).La partie la plus complexe de toutes est ce premier argument:,
Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
qui est un gâchis géant de sucre syntaxique presque pur. J'utilisais vraiment le sucre syntaxique de mathématique pour celui-ci. Cette ligne de code représente la version mathématique d'une fonction anonyme, sauf pour raccourcir les choses, j'ai en fait défini deux fonctions anonymes distinctes au sein de cette fonction anonyme. Oui, c'est légal, les amis. Décomposons-le.Join
prend deux arguments. Le premier estl=Last@#;h=#-l&/@#
, et le second estr[r@#%&/@h]
.Le premier argument de Join: à l' intérieur de la fonction anonyme "principale",
#
est une liste de tous les points à l'itération courante dans la courbe. Celal=Last@#;
signifie donc "Prenez le point dans la liste des points que vous avez reçus en entrée, et affectez ce point à la variablel
. Le segment suivant,,h=#-l&/@#
est un peu plus complexe. Cela signifie" Vous avez une fonction. Cette fonction prend un point en entrée, en soustraitl
et renvoie le résultat. Maintenant, appliquez cette fonction à chaque élément de la liste des points que vous avez reçus en entrée pour générer une liste de points décalés et affectez cette nouvelle liste à la variableh
.Le deuxième argument de Join:
r[r@#%&/@h]
a littéralement la syntaxe la plus complexe que j'ai jamais écrite. Je ne peux pas croire qu'un segment de code puisse contenir quelque chose comme@#%&/@
- on dirait que je maudis comme un personnage de dessin animé au milieu d'un programme! Mais il est possible de le décomposer. Rappelez-vous -r[x]
prend une liste de points et retourne cette liste dans l'ordre inverse.r@#%&
est une fonction anonyme qui inverse son entrée, puis la multiplie par la valeur stockée dans%
(qui est{1,-1}
) et renvoie le résultat. Fondamentalement, il tourne son entrée de 90 degrés, mais dans un code aussi court que possible. Signifie ensuiter@#%&/@h
"Produire une nouvelle liste qui est chaque point enh
rotation à 90 degrés."Donc, dans l'ensemble,
Join[l=Last@#;h=#-l&/@#,r[r@#*%&/@h]]&
c'est une fonction qui prend une liste de points en entrée et ajoute cette même liste de points pivotés de 90 degrés pour obtenir la prochaine itération de la courbe. Ceci est répété 9 fois pour obtenir la courbe du dragon. Ensuite, c'est la liste résultante de points qui est dessinée à l'écran sous forme de ligne. Et la sortie:la source
0{,}
... fonctionne parce que0 x
c'est0
pour presque tousx
et{,}
est du sucre syntaxique pour{Null,Null}
.Python 2, 43 octets
Cette réponse est de 43 octets n'incluant pas la déclaration d'importation et elle est largement basée sur la réponse Logo de Level River St et leur utilisation
i/(i&-i)
dans leur code. Essayez-le en ligne sur trinket.ioVoici une image de la sortie.
la source
The shortest code in bytes wins, however include directives for libraries shouldn't be included in the byte count, and you may use graphics libraries or other libraries written for your language of choice if they were written before the posting.
Mathematica,
5655 octetsExplication: OEIS A034947
Juste pour le plaisir, voici une version colorée de la 19ème itération.
la source
Mathematica, 63 octets
En utilisant
AnglePath
la source
HTML + JavaScript, 182
la source
Haskell + diagrammes, 179 octets
La sortie est un fichier svg de 99 pixels de large avec un fond transparent (une image de 9 pixels de large aurait un trait trop épais pour reconnaître quoi que ce soit). Ici, il est redimensionné et composé sur un fond blanc:
la source
tosh , 518 octets
tosh est Scratch , mais avec du texte au lieu de blocs. À 518 octets, cette réponse est probablement encore pire que Java.
Cette réponse utilise la même logique que la réponse Python de @ Theo , mais avec des chaînes de "L" et "R" au lieu de nombres, car les capacités de liste de Scratch (et donc de tosh) sont horribles.
Vous pouvez l'exécuter en tant que projet Scratch ici . (tosh compile pour les projets Scratch)
Explication:
Cette première partie fait fonctionner le programme lorsque le drapeau vert est cliqué (
when flag clicked
), définit la variable de chemin sur "R" et obtient le sprite et la scène dans l'état approprié pour être prêt à dessiner.Nous arrivons maintenant au code de génération de chemin. Il utilise la même logique que la réponse Python de @ Theo , sauf avec des chaînes de "R" et "L" au lieu de nombres, et nous utilisons des boucles imbriquées au lieu de listes de compréhension.
Enfin, nous dessinons le chemin en parcourant chaque lettre de la variable de chemin et en tournant à gauche ou à droite selon la lettre.
la source