Ihre Aufgabe für heute: Zeichnen Sie eine Drachenkurve!
Falls Sie nicht wissen, was eine Drachenkurve ist, finden Sie hier ein einführendes ViHart-Video (Wirklich cool, bitte sehen Sie es sich an!)
Ihre Aufgabe: Zeichnen Sie eine Drachenkurve, die mindestens neunmal iteriert wurde. Sie müssen nicht die Iterationen 1 bis 9 anzeigen, sondern nur die endgültige Kurve, die nach Abschluss von (mindestens) 9 Iterationen erstellt wurde. Die Kurve muss als gerade Linie gezeichnet werden, die die Punkte auf der Kurve verbindet. Die Ausgabe sollte mit einem der folgenden Bilder übereinstimmen, das 9 oder mehr Iterationen enthält (bis zu Reflexion, Drehung, Skalierung und Variation der Linienbreite, Linienfarbe und Hintergrundfarbe). Ihre Ausgabe muss groß genug sein, damit die einzelnen Zeilen und die "Kästchen", die sie bilden, voneinander unterschieden werden können. Wenn sich zwei Linien in der Kurve nicht schneiden, sollten sie nicht dieselben oder benachbarte Pixel in der Ausgabe belegen (zwischen ihnen sollte mindestens ein Pixel des Hintergrunds sichtbar sein). Sie können entweder das Bild auf dem Bildschirm anzeigen oder das in einer Datei gespeicherte Bild wird akzeptiert. Die Ausgabe muss grafisch sein - es kann sich nicht um ASCII-Grafik handeln.
Der kürzeste Code in Bytes gewinnt, jedoch sollten Include-Anweisungen für Bibliotheken nicht in die Byteanzahl einbezogen werden, und Sie können Grafikbibliotheken oder andere Bibliotheken verwenden, die für die Sprache Ihrer Wahl geschrieben wurden, wenn sie vor dem Posten geschrieben wurden.
Bitte fügen Sie ein Bild der Ausgabe Ihres Programms bei.
Überspringen Sie diesen Absatz, wenn Sie sich das Video angesehen haben:Für diejenigen unter Ihnen, die sich entschieden haben, das Video nicht anzusehen, sind die ersten 12 Iterationen der Drachenkurve unten aufgeführt. Im Rahmen dieser Aufgabe ist eine Drachenkurve eine Kurve, die nach der folgenden Regel erstellt wird: Nehmen Sie den Endpunkt der aktuellen Kurve und erstellen Sie eine zweite Kurve, die um 90 Grad um diesen Endpunkt gedreht wird, sodass der Endpunkt des Originals erreicht wird Kurve ist der Startpunkt der neuen Kurve und verbindet die beiden Kurven zu einer einzigen Kurve, in der sie sich treffen. In den unten gezeigten Bildern wird jede neue Iteration durch Drehen der vorherigen Iteration um 90 Grad im Uhrzeigersinn um den Endpunkt jeder Iteration generiert. Wenn die Kurve auf dem Bildschirm angezeigt wird, ist es nicht offensichtlich, welches Ende als "Endpunkt" gilt. Wenn die Kurve jedoch als eine Reihe von Punkten gespeichert wird, ist es einfach, den "Endpunkt" als den letzten Punkt in zu definieren das Array.
ASCII-Kunst wird geschätzt, aber nicht akzeptiert: Dies ist eine grafische Ausgabe, keine ASCII-Kunst.
quelle
Antworten:
x86, MSDOS, 16 Bytes
Ich habe dies vor einiger Zeit geschrieben, meines Wissens nach die kleinste Routine für die Herstellung eines Drachen-Fraktals. Es werden keine echten Iterationen verwendet, sondern jedes einzelne Pixel im Fraktal wird direkt gezeichnet und das endgültige Bild angezeigt. Es ist mit vielen anderen kleinen Produktionen in diesem Paket enthalten . Die 16-Byte-Version war das Ende meiner Bemühungen, das Drachen-Fraktal so klein wie möglich zu machen, und startete 2014 mit dieser 32-Byte-Produktion .
Verhexen
Code
quelle
Python 2/3,
1691671501119878 BytesBeachten Sie, dass der Import gemäß den Herausforderungsspezifikationen nicht in der Byteanzahl enthalten ist.
Vielen Dank an @AlexHall für das Speichern von 39 (!) Bytes und @ nedla2004 für weitere 13 Bytes
Beginnt damit, eine Liste zu erstellen oder dreht sich nach rechts (90) und links (-90), geht dann die Liste durch und bewegt die Schildkröte.
Erzeugte Ausgabe:
BEARBEITEN: Wenn dies zu langweilig ist, füge es
speed(0)
direkt vor dem ersten hinzufd(5)
. Es läuft genauso, nur dass sich die Schildkröte viel schneller bewegt.quelle
Logo, 43 Bytes
Versuchen Sie es mit einem Dolmetscher unter http://www.calormen.com/jslogo/#
Dies verwendet das gleiche Prinzip wie meine vorherige ASCII-Kunstantwort und die Formel auf Wikipedia, außer dass ich die Richtung umgekehrt habe, um das Bild in der Frage abzugleichen:
bitand :i -:i
findet das niedrigstwertige Bit voni
. Wir dividiereni
dies, umi
die erforderliche Menge richtig zu schieben und die erforderliche ungerade Zahl zu erhaltenk
. Es ist nicht erforderlich, zwischen Links- und Rechtskurven zu unterscheiden. Wir drehen uns nurk*90
graduell nach links und verlassen uns auf die Tatsache, dass Rotation eine Modulo-360-Operation ist, um das Modulo für uns durchzuführen.Ausgabe
verwenden
ht
, um die Schildkröte bei Bedarf zu verstecken.Ausgang (modifiziert)
Das Folgende zeigt, wie die Kurve ein Einzelstrang ist.
quelle
LindenMASM , 51 Bytes
LindenMASM war eine Sprache, die ich vor einiger Zeit für eine Herausforderung geschaffen habe, die für immer in der Sandbox leben wird. Es nutzt das Konzept der Lindenmayer-Systeme, um Dinge wie Drachenkurven, fraktale Pflanzen, Sierpinski-Dreiecke usw. zu zeichnen.
Der Quellcode lautet wie folgt:
So richten Sie dies
n = 6
beispielsweise ein:Dies erzeugt das folgende Bild über Python 3
turtle
:Es kann einen kleinen Unterschied in der Nummerierung für Iterationen geben, da im Lindenmayer-System die erste Iteration eine einzelne Zeile ist. So sieht es aus
n = 10
:Nur zum Spaß, so sieht es mit 15 Generationen aus (mit einer zusätzlichen Anweisung
MOV 2
, um es ein bisschen kleiner zu machen):Sobald Sie bis zu 20 Generationen (mit
MOV 0.5
) erreicht haben, können Sie die Linien nicht mehr wirklich sehen, und es sind VIELE Schritte erforderlich, um sie zu erstellen (Paare von+-
und-+
sind nicht optimiert). Folgendes erhalten Sie:Beachten Sie, dass der aktuelle Interpreter möglicherweise grafische Probleme für kleinere Mengen von Generationen aufweist, dh möglicherweise nicht auf dem Bildschirm angezeigt wird. Als dieser Interpreter erstellt wurde, gab es leider keine Probleme, eine mögliche Änderung in Python 3 könnte dies verursacht haben oder es könnte nur mein System sein
quelle
Unterlast, 196 Bytes
Ich dachte, es könnte interessant sein, diese Herausforderung in einem Esolang mit niedriger Leistung zu versuchen. Unterlast ist für eine Sprache mit einer so geringen Anzahl von Befehlen recht gut.
Die Ausgabe ist eine SVG-Datei mit sehr stark verschachtelten Tags und einigen Golf-Shortcuts. Bisher habe ich keinen Browser gefunden, der es anzeigen kann (Firefox bleibt einige Minuten lang hängen und versucht, es zu laden, und sowohl Firefox als auch Chromium zeigen einen leeren Bildschirm an). Die meisten Bildverarbeitungsprogramme können es auch nicht laden (was die Konvertierung in ein anderes Format erschwert), aber ich habe es geschafft, es in den Bildbetrachter Eye of Gnome zu laden (der Teil der Standardinstallation unter Ubuntu ist). Also habe ich einen Screenshot des Bildes gemacht, damit Sie es sehen können (das tatsächliche Bild hat einen transparenten Hintergrund, aber Sie können nicht wirklich einen transparenten Screenshot machen):
Wir müssen die Bildgröße explizit angeben. Durch Auswahl einer geeigneten Ausrichtung für das Bild, Zeichnen aller Elemente in der zulässigen Mindestgröße und Ausführen der Mindestanzahl von Iterationen, die durch die Herausforderung angegeben werden, erhalten wir ein Bild, das nur in eine Breite von 99 Pixel passt und ein Byte speichert. Es ist schön, wenn es so läuft.
Der allgemeine Algorithmus, der zum Zeichnen des Bildes verwendet wird, besteht darin, zwei Variablen beizubehalten (Unterlast nennt keine Variablen, aber ich habe sie als x und y betrachtet ), die beide anfangs leer waren. Dann ersetzen wir wiederholt ( x , y ) durch ( x , drehen Sie sich nach links und bewegen Sie sich vorwärts, y ) und ( x , drehen Sie sich nach rechts und bewegen Sie sich vorwärts, y ). Nach zehn Iterationen halten sowohl x als auch y eine Drachenkurve mit neun Iterationen.
Es gibt auch einige Mikrooptimierungen und unterlastungsspezifische Tricks. Um zu vermeiden, dass bei jeder Schleifeniteration zu viel mit der Stapelspitze herumgespielt wird, kombinieren wir zunächst x und y in der Funktion "Rückgabe des durch Verketten erzeugten Strings: x , eine Turn-Anweisung, das Funktionsargument, eine Move-Anweisung". Vorwärtsanweisung und y . " Diese Funktion belegt nur ein Leerzeichen im Stapel, sodass wir sie duplizieren,
-90
als Argument aufrufen , den Rückgabewert unter dem Duplikat austauschen und90
als Argument aufrufen können , um neue Werte für x und y zu erhaltenohne jemals mehr als die beiden obersten Elemente des Stapels berühren zu müssen (die bei weitem am häufigsten zugänglich sind). Diese Funktion wird zur Laufzeit durch Code generiert. Der Generator selbst wird auch zur Laufzeit mit Code generiert, damit er die Zeichenfolge wiederverwenden kann<g transform="translate
, mit der auch der Ursprung des Bildes festgelegt wird. Wir generieren zuerst alle offenen Tags und können dann, da alle schließenden Tags gerecht sind</g>
, 1024 schließende Tags durch einfaches Wiederholen der Zeichenfolge ausgeben, ohne dass wir uns darum kümmern müssen, sie mit den offenen Tags abzugleichen. (Effizientes Schreiben von Zahlen in Unterlast ist ein interessantes Problem für sich; es(:*)::*:**:*
ist jedoch wahrscheinlich die effizienteste Methode, 1024 zu schreiben, was "2 hoch (1 + 2 × 2) × 2" bedeutet.Unterlast hat keine Grafikbibliotheken, daher erstelle ich SVG, indem ich Linien an einer festen Position zeichne und das Bild um einen bestimmten Punkt drehe. anstatt den Stift zu drehen, drehen wir das Papier. Die Idee ist, dass wir durch Zeichnen einer Linie, Drehen des gesamten Bilds, Zeichnen einer anderen Linie, erneutes Drehen des Bilds usw. Schildkrötengrafiken effektiv simulieren können, ohne Arithmetik ausführen oder Grafikbibliotheken verwenden zu müssen, da alle Linien gezeichnet werden am selben Ort. Das bedeutet natürlich, dass wir einige sehr stark verschachtelte Tags zum Drehen des Bildes haben, was viele SVG-Betrachter verwirrt.
Das Stylen des Bildes würde gegen die Byteanzahl anrechnen, daher musste ich das minimale Stylen angeben, das zum Anzeigen des Bildes erforderlich ist. Es stellt sich heraus, dass
stroke="#"
dies mehr oder weniger bedeutet, dass die Linie eine Farbe haben muss. dies scheint erweitert zu werden, um es in schwarz zu zeichnen. (Normalerweise geben Sie die Farbe als "# 000" an.) Der Hintergrund ist standardmäßig transparent. Wir geben keine Strichbreite an, aber die Auswahl von Eye of Gnome lässt alles sichtbar.Viele Unterlast-Interpreten haben Probleme mit diesem Programm, z. B. das auf Try It Online stürzt ab, weil es intern einige sehr große Zeichenfolgen generiert. Der ursprüngliche Online-Unterlast-Interpreter funktioniert jedoch. (Interessanterweise war der allererste Dolmetscher online, sodass die Sprache online verwendet werden konnte, bevor sie offline verwendet werden konnte.)
Etwas, das mir etwas unbehaglich ist, ist, dass es hier nur 1023 Liniensegmente zu geben scheint und wir 1024 erwarten würden. Es könnte sein, dass eines der Segmente am Ende nicht mit diesem Algorithmus gezeichnet wird (es würde sein) stattdessen in der nächsten Iteration gezeichnet). Wenn dies disqualifiziert, kann das Programm möglicherweise angepasst werden, es kann aber auch erheblich länger dauern. (Es ist ohnehin nicht so, dass diese Herausforderung den Wettbewerb gewinnen wird; es gibt bereits mehrere kürzere Einsendungen.)
quelle
MATL , 26 Bytes
Wenn unterschiedliche Maßstäbe in den beiden Achsen akzeptiert werden, kann der Code auf 19 Byte reduziert werden:
Die folgenden Abbildungen entsprechen der 26-Byte-Version.
Der obige Code erzeugt die 9. (0-basierte) Iteration, dh das zehnte Bild in der Challenge:
Für andere Werte ändern Sie den
9
Code oder ersetzen Sie ihn durchi
, um die Nummer als Benutzereingabe zu verwenden. Das Ergebnis für13
lautet beispielsweise:Erläuterung
Hierbei wird eine Schleife verwendet, um schrittweise ein Array der Schritte zu erstellen, auf die die Kurve in der komplexen Ebene folgt. Zum Beispiel sind die ersten beiden Schritte
1j
(oben) und-1
(links).In jeder Iteration wird das Array der bisherigen Schritte kopiert. Die Kopie des Arrays wird umgekehrt , multipliziert mit
1j
(Drehen um 90 Grad) und verketteten das Original.Nach der Schleife ergibt eine kumulative Summe der Schritte die tatsächlichen Punkte, die dann in der komplexen Ebene aufgetragen werden.
quelle
Mathematica 86 Bytes
Wie es funktioniert:
{1,-1}
Ausgänge{1,-1}
. Im Grunde "drückt es auf den Stapel". Dieser Wert kann mit aufgerufen werden%
.r=Reverse
benennt einfach die Umkehrfunktion um, da ich sie zweimal im Code verwende. DerGraphics@Line@
nimmt einfach eine Liste von Punkten und zeichnet eine Linie, die sie verbindet. Das eigentliche Fleisch des Problems geschieht in diesem Codesegment:Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]
. Ich möchte Ihnen sagen, dass dieses Segment kompliziert ist. FolgendesNest
bewirkt:Nest[f,x,9]
Gibt das Ergebnis des Aufrufs ausf[f[f[f[f[f[f[f[f[x]]]]]]]]]
.In meinem Code ist das erste Argument
f
:Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
Das zweite Argumentx
ist{{0,0},%}
(was ergibt{{0,0},{1,-1}}
) und das dritte Argument istn
, was nur 9 ist (was nur das erste Argument neunmal auf das zweite Argument anwendet).Der komplexeste Teil von allem ist dieses erste Argument: Es
Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
ist ein riesiges Durcheinander von fast reinem syntaktischem Zucker. Ich habe den syntaktischen Zucker von mathematica wirklich für diesen missbraucht. Diese Codezeile stellt die mathematische Version einer anonymen Funktion dar, mit der Ausnahme, dass ich tatsächlich zwei separate anonyme Funktionen innerhalb dieser anonymen Funktion definiert habe. Ja, das ist legal, Leute. Lassen Sie es uns aufschlüsseln.Join
nimmt zwei Argumente. Der erste istl=Last@#;h=#-l&/@#
und der zweite istr[r@#%&/@h]
.Das erste Argument von Join: In der anonymen Funktion "main"
#
ist eine Liste aller Punkte der aktuellen Iteration in der Kurve. Dasl=Last@#;
bedeutet also: "Nehmen Sie den Punkt in der Liste der Punkte, die Sie als Eingabe erhalten haben, und weisen Sie diesen Punkt der Variablen zul
. Das nächste Segmenth=#-l&/@#
ist etwas komplexer. Es bedeutet:" Sie haben eine Funktion. Diese Funktion nimmt einen Punkt als Eingabe, subtrahiertl
ihn und gibt das Ergebnis zurück. Wenden Sie diese Funktion nun auf jedes Element in der Liste der Punkte an, die Sie als Eingabe erhalten haben, um eine Liste der verschobenen Punkte zu generieren, und weisen Sie diese neue Liste der Variablen zuh
.Das zweite Argument von Join:
r[r@#%&/@h]
hat buchstäblich die komplexeste Syntax, die ich je geschrieben habe. Ich kann nicht glauben, dass ein Codesegment so etwas enthalten könnte@#%&/@
- es sieht so aus, als würde ich wie eine Zeichentrickfigur mitten in einem Programm fluchen! Aber es ist möglich, es zu brechen. Denken Sie daran -r[x]
nimmt eine Liste von Punkten und gibt diese Liste in umgekehrter Reihenfolge zurück.r@#%&
ist eine anonyme Funktion , dass sie die Eingabe umkehrt, um den Wert vervielfacht es dann in stockwerkartig%
(das ist{1,-1}
), und gibt das Ergebnis. Grundsätzlich dreht es seine Eingabe um 90 Grad, aber in Code so kurz, wie ich nur schreiben könnte. Dannr@#%&/@h
heißt es "Eine neue Liste ausgeben, die jeden Punkth
um 90 Grad gedreht hat."Insgesamt
Join[l=Last@#;h=#-l&/@#,r[r@#*%&/@h]]&
ist dies eine Funktion, die eine Liste von Punkten als Eingabe verwendet und dieselbe Liste von Punkten um 90 Grad gedreht hinzufügt, um die nächste Iteration der Kurve zu erhalten. Dies wird 9 Mal wiederholt, um die Drachenkurve zu erhalten. Dann wird die resultierende Punkteliste als Linie auf den Bildschirm gezeichnet. Und die Ausgabe:quelle
0{,}
... funktioniert, weil0 x
es0
für fast jeden geeignet istx
und{,}
syntaktischer Zucker für{Null,Null}
.Python 2, 43 Bytes
Diese Antwort umfasst 43 Bytes ohne die Importanweisung und basiert größtenteils auf der Antwort von Level River Sts Logo und deren Verwendung
i/(i&-i)
in ihrem Code. Probieren Sie es online bei trinket.ioHier ist ein Bild der Ausgabe.
quelle
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,
56-55BytesErläuterung: OEIS A034947
Nur zum Spaß ist hier eine farbige Version der 19. Iteration.
quelle
Mathematica, 63 Bytes
Verwenden
AnglePath
quelle
HTML + JavaScript, 182
quelle
Haskell + Diagramme, 179 Bytes
Die Ausgabe ist eine 99 Pixel breite SVG-Datei mit transparentem Hintergrund (ein 9 Pixel breites Bild hätte einen zu dicken Strich, um irgendetwas zu korrigieren). Hier wird es über einen weißen Hintergrund skaliert und komponiert:
quelle
tosh , 518 bytes
tosh ist Scratch , aber mit Text anstelle von Blöcken. Mit 518 Bytes ist diese Antwort wahrscheinlich noch schlechter als Java.
Diese Antwort verwendet die gleiche Logik wie @ Theos Python-Antwort , aber mit Zeichenfolgen von "L" und "R" anstelle von Zahlen, da die Listenfunktionen von Scratch (und damit von tosh) schrecklich sind.
Sie können es als ein Scratch - Projekt laufen hier . (tosh kompiliert zu Scratch Projekten)
Erläuterung:
In diesem ersten Teil wird das Programm ausgeführt, wenn auf die grüne Flagge geklickt wird (
when flag clicked
), die Pfadvariable auf "R" gesetzt und das Sprite und die Bühne in den richtigen Zustand versetzt, um zum Zeichnen bereit zu sein.Nun kommen wir zum Code für die Pfadgenerierung. Es verwendet die gleiche Logik wie die Python-Antwort von @ Theo , außer dass Zeichenfolgen mit "R" und "L" anstelle von Zahlen verwendet werden und verschachtelte Schleifen anstelle von Listenverständnissen.
Schließlich zeichnen wir den Pfad, indem wir jeden Buchstaben der Pfadvariablen durchgehen und je nach Buchstabe nach links oder rechts abbiegen.
quelle