Manchmal, wenn ich wirklich gelangweilt bin ( wirklich gebohrt), ich mag ein Liniensegment zeichnen und darauf verweisen zu ziehen.
Zuerst zeichne ich ein Liniensegment einer bestimmten Größe, die 2 ^ N für einen Wert von N ist. Die Linie wird durch eine Reihe von .
Zeichen dargestellt.
................
Dann zeichne ich einen Punkt am linken Ende. Punkte werden durch X
Zeichen dargestellt.
X...............
Dann folge ich einem Muster. Beginnend mit dem zuletzt gezeichneten Punkt (den ich als A bezeichne) gehe ich zum nächsten gezeichneten Punkt (B) auf der Linie (nach Bedarf umlaufend). Dann gehe ich zum nächsten eingezeichneten Punkt auf der Linie (C). Dann zeichne ich einen neuen Punkt auf halbem Weg zwischen diesem dritten Punkt (C) und dem nächsten bereits gezeichneten Punkt (D).
Immer wenn Sie die Linie umbrechen, wird die "Mitte" in umbrechender Weise bestimmt. Der neu gezeichnete Punkt befindet sich immer rechts von C.
Angenommen, die folgende Zeile war meine aktuelle Zeile. Hier ist, wie ich die nächsten zwei Punkte aufzeichnen würde. In diesem Beispiel beschrifte ich jeden wichtigen Punkt mit einem Buchstaben.
X...A...X.X...X.
^
X...A...B.X...X.
^
X...A...B.C...X.
^
X...A...B.C...D.
^
X...X...X.X.A.X.
^
X...X...X.X.A.B.
^
C...X...X.X.A.B.
^
C...D...X.X.A.B.
^
X.A.X...X.X.X.X.
^
Zurück zum vorherigen Beispiel, der nächste Punkt wird in der Mitte der Linie gezeichnet.
X.......X.......
Dies ist vielleicht ein kleiner Sonderfall: Wenn Sie zum nächsten Punkt voranschreiten, bleiben Sie einfach dort, wo Sie begonnen haben. Der einzig nützliche halbe Punkt ist der "zyklische" halbe Punkt (der halbe Punkt auf der Linie), im Gegensatz dazu, einen Punkt auf sich selbst zu zeichnen.
Unten ist die Reihe von Punkten, die ich von hier bis zum Ende auf der Linie zeichnen würde.
X.......X.......
X.......X...X...
X.......X.X.X...
X...X...X.X.X...
X...X...X.XXX...
X.X.X...X.XXX...
X.X.X...XXXXX...
Es gibt keinen Platz mehr, um den nächsten Punkt zu zeichnen, da er zwischen zwei benachbarten Punkten eingeklemmt werden müsste, sodass ich die maximale Tiefe für den angegebenen Wert von N = 4 erreicht habe. Die letzte Zeile in der obigen Liste ist "vollständig" . "
Die Herausforderung
Das Ziel ist es, das kürzeste Programm / die kürzeste benannte Funktion zu schreiben, das / die die abgeschlossene Zeile für einen gegebenen Wert von N ausgibt / zurückgibt. Das Obige zeigt N = 4.
Eingang
Die Eingabe ist eine einzelne nicht negative Ganzzahl N. Die Länge der erzeugten Zeile beträgt dann 2 ^ N.
Ausgabe
Die Ausgabe erfolgt in der vollständigen Zeile der Länge 2 ^ N, die aus den Zeichen .
und besteht X
. Ein abschließender Zeilenumbruch spielt keine Rolle.
Beispiel I / O
0
X
1
XX
2
X.XX
3
X.X.XXX.
4
X.X.X...XXXXX...
5
X.X.X...X...X...X.XXX.XXX.......
(c%b+b)%b
? Erwarten Siec
, negativ zu sein?c=0
undd=0
kann verkürzt werden , um einfachc
undd
.int
Auf Klassenebene definierte Typen werden automatisch auf 0 initialisiert.Haskell, 182 Bytes
Verbrauch:
f 5
. Ausgang:X.X.X...X...X...X.XXX.XXX.......
.Leider hat Haskell in den Standardbibliotheken keine Merge-Funktion, daher muss ich meine eigene bereitstellen (->
%
). Glücklicherweise muss ich nur unendliche Listen zusammenführen, damit ich die Basisfälle, dh leere Listen, nicht abdecken muss. Es kostet immer noch 40 Bytes.So funktioniert es: Anstatt die
X
s direkt in einem Array festzulegen, behalte ich eine Liste der Positionen, an denen sie sich befinden. Außerdem mache ich keinen Umlauf um,2^N
sondern erhöhe die Positionen immer weiter in Richtung unendlich (z. B.X
sieht die Positionsliste für N = 2 mit einem vorne aus[0,4,8,12,16,20,…]
). Ich nehme das 3. und 4. Element (c
undd
), berechne die neue Position(c+d)/2
, behalte sie für die Ausgabeliste, füge die alte Positionsliste ab Position 4 (died
) mit einer neuen zusammen, beginnend mit(c+d)/2
und wiederhole sie. Ich höre auf, wenn es(c+d)/2
gleich istc
. Schließlich füge ich0
der Ausgabeliste ein hinzu und druckeX
s an den angegebenen Stellen und an.
anderer Stelle.quelle
Mathematica,
110102112108quelle