Zeichnen Sie ein einfaches ASCII-Kunstbild mit einer geraden Linie. Es ist ähnlich wie dies und das, aber mit unterschiedlichen Spezifikationen.
Eingang
Sie können dieses Eingabeformat an Ihren Code anpassen.
- ganze Zahl
width
- ganze Zahl
height
- ganze Zahl
x0
- ganze Zahl
y0
- ganze Zahl
x1
- ganze Zahl
y1
Ausgabe
Ein gefülltes ASCII-Kunstbild mit der angegebenen Breite und Höhe, das eine Linie von Pixel (x0, y0)
zu Pixel enthält (x1, y1)
.
Jede Standardform der Textausgabe ist akzeptabel, es werden jedoch keine integrierten Strichzeichnungsfunktionen verwendet.
Einzelheiten
Die Linie muss mit einem einzelnen druckbaren Zeichen (z. B. #
) gezeichnet werden , während der Hintergrund mit einem anderen Zeichen (z. B. .
) gefüllt wird . Sie müssen die erforderlichen nachgestellten Zeichen drucken, damit die Bildgröße korrekt ist.
Pixelkoordinaten können 0-indiziert oder 1-indiziert sein und in jeder Ecke des Bildes beginnen. Die Linie sollte gezeichnet werden, indem eine 0-breite Subpixel-Linie vorgestellt wird, die die Zentren der Start- und Endpixel verbindet. Jedes Pixel, in das die Linie eintritt, sollte ausgefüllt werden.
Gewinnen
Übliche Code-Golf-Regeln. Kürzester Code gewinnt.
Beispiele
IN: width, height, x0, y0, x1, y1
IN: 7, 6, 0, 0, 6, 5
OUT:
.....##
....##.
...##..
..##...
.##....
##.....
IN: 3, 3, 1, 1, 1, 1
OUT:
...
.#.
...
IN: 3, 3, 0, 2, 2, 0
OUT:
#..
.#.
..#
IN: 6, 3, 0, 0, 5, 2
OUT:
....##
.####.
##....
IN: 4, 4, -1, -1, 0, 3
OUT:
#...
#...
#...
....
Antworten:
Mathematica,
166137 BytesMehr lesbare Version:
Dies definiert eine aufgerufene Funktion
f
. Ich habe die Eingabe- und Ausgabespezifikationen ziemlich großzügig ausgelegt. Die Funktionf
nimmt Eingaben im Format vorf[{x0, y0}, {x1, y1}, height, width]
und das Raster ist 1-indiziert, beginnend oben links. Ausgänge sehen aus wiemit der Linie als
1
s und dem Hintergrund als0
s (hier gezeigt fürf[{2, 6}, {4, 2}, 5, 7]
). Die Aufgabe, eine Mathematica-Matrix aus1
s und0
s in eine Zeichenfolge aus#
s und.
s zu verwandeln, wurde bereits in vielen anderen Herausforderungen bewältigt, sodass ich nur eine Standardmethode verwenden konnte, aber ich denke nicht, dass dies etwas Interessantes hinzufügt.Erläuterung:
Die allgemeine Idee ist, dass, wenn die Linie durch ein Pixel verläuft, mindestens eine der vier Ecken des Pixels über der Linie liegt und mindestens eine unter der Linie liegt. Wir prüfen, ob eine Ecke über oder unter der Linie liegt, indem wir den Winkel zwischen den Vektoren (
{x0,y0}
zur Ecke) und ({x0,y0}
zur{x1,y1}
) untersuchen: Wenn dieser Winkel positiv ist, befindet sich die Ecke über und wenn der Winkel negativ ist, befindet sich die Ecke unter der Linie .Wenn wir zwei Vektoren
{a1,b1}
und haben{a2,b2}
, können wir überprüfen, ob der Winkel zwischen ihnen positiv oder negativ ist, indem wir das Vorzeichen der Determinante der Matrix finden{{a1,b1},{a2,b2}}
. (Meine alte Methode benutzte die Arithmetik komplexer Zahlen, was viel zu… na ja, komplex war.)Im Code funktioniert das folgendermaßen:
{p-l+#,p-q}&/@Tuples[.5{1,-1},2]
Ruft die vier Vektoren von{x0,y0}
und die vier Ecken des Pixels (mitl:={i,j}
den zuvor definierten Koordinaten des Pixels) sowie den Vektor zwischen{x0,y0}
und ab{x1,y1}
.s@Det@...
findet die Zeichen der Winkel zwischen der Linie und den vier Ecken (mits=Sign
). Diese sind gleich -1, 0 oder 1.Abs@Mean[...]<.6
prüft, ob einige der Winkel positiv und einige negativ sind. Die 4-Tupel von Zeichen, die diese Eigenschaft haben, haben alle Mittelwerte zwischen -0,5 und 0,5 (einschließlich), daher vergleichen wir mit 0,6, um ein Byte zu sparen, indem wir<
anstelle von verwenden<=
.Es gibt immer noch ein Problem: Dieser Code geht davon aus, dass sich die Linie für immer in beide Richtungen erstreckt. Wir müssen daher die Linie zuschneiden, indem wir sie mit
1-Max[s[p-l]s[q-l],0]
(durch Versuch und Irrtum gefunden) multiplizieren , das sich1
innerhalb des durch die Endpunkte der Linie definierten Rechtecks befindet, und0
außerhalb davon.Der Rest des Codes bildet ein Raster aus diesen Pixeln.
(Als Bonus ist hier ein früherer Versuch mit einer völlig anderen Methode für 181 Bytes :)
quelle
CJam, 122 Bytes
Probieren Sie es online aus
Dies kombiniert im Wesentlichen zwei Antworten, die ich zuvor für andere Herausforderungen geschrieben habe (hauptsächlich die Berechnungen aus der 2. Funktion
l
).(0, 0) ist natürlich die linke obere Ecke, nicht die linke untere wie in den Beispielen in der Anweisung.
Überblick:
{),V>{[I\]E.*A.+}/}:F;
Definiert die Funktion F, die beim Erzeugen aller Pixel (Koordinatenpaare) für eine bestimmte x-Koordinate hilft,l~]2/~@:S~'.*f*\@:A.-_:g:E;:z:D
liest und verarbeitet die Eingabe und erstellt eine Punktmatrix,0=:B{D~I2*)*+:U(2/B/FU2/B/:V;}fI
die über alle x-Koordinaten mit Ausnahme der letzten iteriert, und generiert, dass alle entsprechenden PixelD~\:I;F
dasselbe für tun Die letzte x-Koordinate{_Wf>\S.<+:*},
behält nur die Pixel bei, die im Bild erscheinen sollen.{~_3$=@0tt}/
Setzt eine 0 in die Matrix für jedes Pixel,N*
das mit Zeilenumbruchzeichen zur Anzeige in die Matrix eingefügt wirdquelle