Bei einer ganzzahligen n
Ausgabe die n
Iteration der Hilbertkurve in ASCII mit den Zeichen _
und |
.
Hier sind die ersten 4 Iterationen:
n=1
_
| |
n=2
_ _
| |_| |
|_ _|
_| |_
n=3
_ _ _ _
| |_| | | |_| |
|_ _| |_ _|
_| |_____| |_
| ___ ___ |
|_| _| |_ |_|
_ |_ _| _
| |___| |___| |
n=4
_ _ _ _ _ _ _ _
| |_| | | |_| | | |_| | | |_| |
|_ _| |_ _| |_ _| |_ _|
_| |_____| |_ _| |_____| |_
| ___ ___ | | ___ ___ |
|_| _| |_ |_| |_| _| |_ |_|
_ |_ _| _ _ |_ _| _
| |___| |___| |_| |___| |___| |
|_ ___ ___ ___ ___ _|
_| |_ |_| _| |_ |_| _| |_
| _ | _ |_ _| _ | _ |
|_| |_| | |___| |___| | |_| |_|
_ _ | ___ ___ | _ _
| |_| | |_| _| |_ |_| | |_| |
|_ _| _ |_ _| _ |_ _|
_| |___| |___| |___| |___| |_
Klarstellungen
- Meine Frage ähnelt dem Zeichnen der Hilbert-Kurve und dem Zeichnen der Hilbert-Kurve mit Schrägstrichen .
- Die Umwandlung zwischen Unterstrichen (
_
) und vertikalen Stangen (|
) ist ,u=2*v-1
wou
die Anzahl der ist ,_
s undv
ist die Anzahl von|
s. - Um die Konsistenz mit meinem ursprünglichen Beitrag zu gewährleisten, muss die Kurve unten beginnen und enden.
- Sie können ein vollständiges Programm oder eine Funktion haben.
- Ausgabe auf stdout (oder ähnliches).
- Sie können führende oder nachfolgende Leerzeichen verwenden. Die Ausgabe muss nur so ausgerichtet sein, dass sie den Beispielen entspricht.
- Dies ist Code-Golf, also gewinnt die kürzeste Antwort in Bytes.
Antworten:
Befunge,
444368323 BytesProbieren Sie es online!
Der typische Ansatz zum Zeichnen der Hilbert-Kurve besteht darin, dem Pfad als Folge von Strichen und Kurven zu folgen, das Ergebnis in eine Bitmap oder einen Speicherbereich zu rendern und dieses Rendern dann auszuschreiben, wenn der Pfad vollständig ist. Dies ist in Befunge einfach nicht möglich, wenn nur 2000 Byte Arbeitsspeicher zur Verfügung stehen und dies auch die Quelle des Programms selbst einschließt.
Wir haben uns hier also eine Formel ausgedacht, die genau angibt, welches Zeichen für eine bestimmte x, y-Koordinate ausgegeben werden soll. Um zu verstehen , wie dies funktioniert, ist es am einfachsten , das ASCII - Rendering zu ignorieren , mit zu beginnen, und man denke nur an der Kurve als Kasten Zeichen aus:
┌
,┐
,└
,┘
,│
, und─
.Wenn wir die Kurve so betrachten, können wir sofort erkennen, dass die rechte Seite ein exakter Spiegel der linken Seite ist. Die Zeichen auf der rechten Seite können einfach bestimmt werden, indem der Partner auf der linken Seite nachgeschlagen und horizontal reflektiert wird (dh das Auftreten von
┌
und┐
wird wie└
und vertauscht┘
).Wenn wir dann die untere linke Ecke betrachten, können wir wieder sehen, dass die untere Hälfte eine Reflexion der oberen Hälfte ist. So werden die Zeichen auf der Unterseite einfach dadurch bestimmt, dass ihr Partner oben nachgeschlagen und vertikal reflektiert wird (dh Vorkommen von
┌
und└
werden vertauscht, so wie┐
und┘
).Die verbleibende Hälfte dieser Ecke ist etwas weniger auffällig. Der rechte Block kann aus einer vertikalen Reflexion des diagonal angrenzenden Blocks abgeleitet werden.
Der linke Block kann aus einer vertikalen Reflexion des Blocks ganz links oben in der vollständigen Kurve abgeleitet werden.
An diesem Punkt bleibt uns nur die obere linke Ecke, die nur eine weitere Hilbert-Kurve ist, die eine Iteration tiefer liegt. Theoretisch sollten wir den Vorgang jetzt nur noch einmal wiederholen müssen, aber es gibt einen kleinen Haken - auf dieser Ebene sind die linke und die rechte Hälfte des Blocks keine exakten Spiegel voneinander.
Auf allen anderen Ebenen als der obersten Ebene müssen die Zeichen in der unteren Ecke als Sonderfall behandelt werden, in dem das
┌
Zeichen als─
und das│
Zeichen als reflektiert wird└
.Davon abgesehen können wir diesen Vorgang wirklich nur rekursiv wiederholen. Auf der letzten Ebene wird das Zeichen oben links als
┌
und das Zeichen darunter als fest codiert│
.Nachdem wir nun die Form der Kurve an einer bestimmten x, y-Koordinate bestimmen können, wie übersetzen wir das in das ASCII-Rendering? Es ist eigentlich nur eine einfache Zuordnung, die jede mögliche Kachel in zwei ASCII-Zeichen übersetzt.
┌
wird_
(Leerzeichen plus Unterstrich)┐
wird└
wird|_
(senkrechter Strich plus Unterstrich)┘
wird|
(senkrechter Strich plus Leerzeichen)│
wird|
(wieder ein vertikaler Strich plus Leerzeichen)─
wird__
(zwei Unterstriche)Dieses Mapping ist zunächst nicht intuitiv, aber Sie können sehen, wie es funktioniert, wenn Sie zwei entsprechende Renderings nebeneinander betrachten.
Und das ist im Grunde alles, was dazu gehört. Eigentlich ist die Implementierung dieses Algorithmus in Befunge ein weiteres Problem, aber ich werde diese Erklärung für ein anderes Mal belassen.
quelle
C 267 Bytes
Probieren Sie es online!
h()
Verwendet die Rekursion, um die Striche der Hubert-Kurve zu erzeugen.t()
druckt das Strichzeichen nur aus, wenn die Stiftpositionp
der aktuellen Ausgabeposition entsprichtq
.Dies ist ineffizient, aber einfach.
Beginnt die Kurve oben links, kann der Code auf 256 Byte reduziert werden.
quelle
puts("")
anstelle vonputchar(10)
und"..."+l*8+d*2
anstelle von&"..."[l*8+d*2]
undn--?h(d+r...-r,n):0
anstelle vonn--&&(h(d+r...-r,n))