Eine algebraische Kurve ist eine bestimmte "1D-Teilmenge" der "2D-Ebene", die als Nullmenge {(x,y) in R^2 : f(x,y)=0 }
eines Polynoms beschrieben werden kann f
. Hier betrachten wir die 2D-Ebene als die reale Ebene, R^2
so dass wir uns leicht vorstellen können, wie eine solche Kurve aussehen könnte, im Grunde eine Sache, die Sie mit einem Bleistift zeichnen können.
Beispiele:
0 = x^2 + y^2 -1
ein Kreis mit Radius 10 = x^2 + 2y^2 -1
eine Ellipse0 = xy
eine Kreuzform, im Allgemeinen der Vereinigung der x-Achse und die y-Achse0 = y^2 - x
eine Parabel0 = y^2 - (x^3 - x + 1)
eine elliptische Kurve0 = x^3 + y^3 - 3xy
das Folium von Descartes0 = x^4 - (x^2 - y^2)
eine Lemniskate0 = (x^2 + y^2)^2 - (x^3 - 3xy^2)
ein Trifolium0 = (x^2 + y^2 - 1)^3 + 27x^2y^2
ein Astroid
Aufgabe
Ausgehend von einem Polynom f
(wie unten definiert) und den x / y-Bereichen wird ein Schwarzweißbild mit mindestens 100 x 100 Pixeln ausgegeben, das die Kurve als schwarze Linie auf weißem Hintergrund darstellt.
Einzelheiten
Farbe : Sie können zwei beliebige andere Farben Ihrer Wahl verwenden. Es sollte einfach sein, sie voneinander zu unterscheiden.
Plot : Anstelle eines Pixelbildes können Sie dieses Bild auch als ASCII-Grafik ausgeben, wobei der Hintergrund "Pixel" ein Leerzeichen / Unterstrich oder ein anderes Zeichen sein sollte, das "leer aussieht", und die Linie kann aus einem Zeichen bestehen, das aussieht. " voll "wie M
oder X
oder #
.
Sie müssen sich nicht um Aliasing kümmern.
Sie nur zu Plotlinien müssen , wo das Vorzeichen der Polynom ändert sich von einer Seite der Linie zum anderen (das heißt Sie zB den Marsch - Square - Algorithmus verwenden könnte), die Sie nicht richtig geplottet müssen „pathologische Fälle wie , 0 = x^2
wo das Zeichen tut ändert sich nicht , wenn man von einer Seite der Linie zur anderen geht, aber die Linie sollte durchgehend sein und die Bereiche der verschiedenen Zeichen von f(x,y)
.
Polynom : Das Polynom wird als (m+1) x (n+1)
Matrix / Liste von Listen von (reellen) Koeffizienten angegeben. Im folgenden Beispiel werden die Begriffe der Koeffizienten in ihrer Position angegeben:
[ 1 * 1, 1 * x, 1 * x^2, 1 * x^3, ... , 1 * x^n ]
[ y * 1, y * x, y * x^2, y * x^4, ... , y * x^n ]
[ ... , ... , ... , ... , ... , ... ]
[ y^m * 1, y^m * x, y^m * x^2, y^m * x^3 , ..., y^m * x^n]
Wenn Sie möchten, können Sie davon ausgehen, dass die Matrix quadratisch ist (dies kann immer mit dem erforderlichen Nullabstand erfolgen), und wenn Sie möchten, können Sie auch davon ausgehen, dass die Größe der Matrix als zusätzliche Eingabe angegeben wird.
Die obigen Beispiele werden im Folgenden als eine wie folgt definierte Matrix dargestellt:
Circle: Ellipse: Parabola: Cross: Elliptic Curve: e.t.c
[-1, 0, 1] [-1, 0, 1] [ 0,-1] [ 0, 0] [-1, 1, 0,-1]
[ 0, 0, 0] [ 0, 0, 0] [ 0, 0] [ 0, 1] [ 0, 0, 0, 0]
[ 1, 0, 0] [ 2, 0, 0] [ 1, 0] [ 1, 0, 0, 0]
Testfälle mit x-Bereich / y-Bereich:
(In einem nicht so lesbaren, aber besser kopierbaren Format, das hier im Pastebin verfügbar ist .)
Circle:
[-1, 0, 1] [-2,2] [-2,2]
[ 0, 0, 0]
[ 1, 0, 0]
Ellipse:
[-1, 0, 1] [-2,2] [-1,1]
[ 0, 0, 0]
[ 2, 0, 0]
Cross:
[ 0, 0] [-1,2] [-2,1]
[ 0, 1]
Parabola:
[ 0,-1] [-1,3] [-2,2]
[ 0, 0]
[ 1, 0]
Elliptic Curve:
[-1, 1, 0,-1] [-2,2] [-3,3]
[ 0, 0, 0, 0]
[ 1, 0, 0, 0]
Folium of Descartes:
[ 0, 0, 0, 1] [-3,3] [-3,3]
[ 0, -3, 0, 0]
[ 0, 0, 0, 0]
[ 1, 0, 0, 0]
Lemniscate:
[ 0, 0, -1, 0, 1] [-2,2] [-1,1]
[ 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0]
Trifolium:
[ 0, 0, 0,-1, 1] [-1,1] [-1,1]
[ 0, 0, 0, 0, 0]
[ 0, 3, 2, 0, 0]
[ 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0]
Astroid:
[ -1, 0, 3, 0, -3, 0, 1] [-1,1] [-1,1]
[ 0, 0, 0, 0, 0, 0, 0]
[ 3, 0, 21, 0, 3, 0, 0]
[ 0, 0, 0, 0, 0, 0, 0]
[ -3, 0, 3, 0, 0, 0, 0]
[ 0, 0, 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0, 0, 0]
Ich habe die Inspiration für einige Kurven aus diesem PDF.
m
xn
, sondern(m+1)
x(n+1)
. Was nehmen wir als Eingabe:m, n
oderm+1,n+1
? Oder können wir wählen?Antworten:
Haskell,
283275 BytesDie Funktion
g
sollte mit der Matrix und den beiden Bereichen als Argumente aufgerufen werden. Die Matrix ist nur eine Liste von Listen, die Bereiche jeweils eine Liste mit zwei Elementen.Hier die Ausgaben für die interessanteren Fälle: Beachten Sie, dass ich das Ergebnis von 100x100 auf ungefähr 40x40 verkleinern musste, damit es in die Konsole passt (ändern Sie einfach die fest codierte 102 in eine kleinere Zahl). Beachten Sie auch, dass die y-Achse nach unten zeigt.
quelle
$
, um ein Byte zu speichern. Beide Orte, an denen Sie sich befindenmap
könnten(<$>)
, und da Sie nure
einmal verwenden, können Sie das(0<)
Innere ziehen, um es zu definieren. Auche
könnte benannt werden(!)
, um 3 Bytes zu sparen.z
in die Definition vonv
ermöglicht es Ihnen, 4 Klammern (umz(&)
undf g
) loszuwerden .#
ein einzelnes Zeichen umbenennen (z. B.s
) und stattdessen eine Musterübereinstimmung in den Listen vornehmeng
. (zBs[a,b]=[a,a+(b-a)/102..b];g m u i=unlines$v[m!y<$>s u|y<-s i]
)Matlab,
11410092 BytesDas richtige Werkzeug für den Job? Ich benutze die interessante Methode von Matlab
printf
, um ein Polynom als Zeichenfolge zu generieren. Dieses Polynom kann angegeben werden, fürezplot
das die implizite Kurve in der angegebenen Domäne gezeichnet wird. Zur besseren Lesbarkeit wird der Code nachher mit Zeilenumbrüchen dargestellt; was nicht benötigt wird und nicht auf die Größe angerechnet wird.Golf-Fortschritt als erweiterbares Snippet.
Code-Snippet anzeigen
Ausgabe der Testfälle (zum Vergrößern anklicken):
quelle
sprintf/ezplot
!fix
stattfloor
könnte Ihnen helfen, die zweistellige Byteanzahl zu erreichen :-)[h,w]=size(A);t=0:h*w-1;
drei weitere Bytes speichern!%.0f
. Das heißt, ich kann den Boden ganz fallen lassen undprintf
reparieren lassen!Python 2, 261 Bytes
Eingabeformat:
matrix,xbounds,ybounds
(zB[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Ausgabeformat: normales PGM .Dies schätzt den Abstand von jedem Pixelzentrum zur Kurve unter Verwendung der Näherung erster Ordnung d ( x , y ) = | p ( x , y ) | / | ∇ p ( x , y ) |, wobei ∇ p der Gradient des Polynoms p ist . (Dies ist der Abstand von ( x , y ) zum Schnittpunkt der Tangentialebene bei ( x , y , p ( x , y )) mit der xy- Ebene.) Dann sind die Pixel mit d (x , y ) ist proportional zu d ( x , y ) kleiner als eine Pixelbreite der Kurve , was zu schönen Antialias-Linien führt (auch wenn dies nicht erforderlich ist).
Hier sind die gleichen Grafiken mit der Distanzfunktion geteilt durch 16 , um sie sichtbar zu machen.
quelle
print
Anweisung für den Bildkopf und eineprint
Anweisung in derwhile
Schleife für den Wert jedes Pixels.Python 3.5 + MatPlotLib + Numpy, 352 Byte:
Eine benannte Funktion. Ziemlich lange, aber hey, ich bin nur froh, dass ich die Aufgabe erfüllen konnte. Nimmt 3 Eingaben an, die die
m by n
Matrix, denx
Bereich und deny
Bereich sind, die alle in Arrays sein sollen (zum Beispiel[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Gibt das fertige Diagramm in einem neuen, grafischen, interaktiven Fenster aus. Wird das Golfspielen länger dauern, wenn ich kann, aber im Moment bin ich damit zufrieden.Endgültige Ausgaben für die Testfälle:
quelle
MATL ,
6761 BytesDieser Code wird in Version 18.5.0 der Sprache ausgeführt, die der Herausforderung vorausgeht. Input verwendet die optional
m
,n
Parameter. Die Matrix enthält Semikolons als Zeilentrennzeichen. Das genaue Eingabeformat (am Beispiel der Parabel) istDer Code erzeugt ein Bild mit der Größe 255 × 255. Dies kann mit dem MATL Online- Compiler von @Suever getestet werden , der unter anderem eine grafische Ausgabe enthält. Siehe zum Beispiel
Dieser Compiler befindet sich noch in einem experimentellen Stadium. Bitte melden Sie Probleme an @Suever im MATL-Chatroom . Wenn die Schaltfläche "Ausführen" nicht funktioniert, aktualisieren Sie die Seite und klicken Sie erneut.
Wenn Sie die ASCII-Ausgabe bevorzugen , muss der Code ein wenig geändert werden (die Änderungen betreffen nur die ersten beiden und letzten vier Zeichen des obigen Codes):
Dies erzeugt ein 100 × 100-ASCII-Gitter, das Zeichen
*
zur Darstellung der Kurve verwendet. Sie können dies auch mit @Dennis ' online testen !Plattform:Beachten Sie, dass das Seitenverhältnis der ASCII-Ausgabe geändert wird, da die Zeichen etwas höher als breit sind.
Erläuterung
Der Code berechnet zuerst das Polynom mit zwei Variablen in einem x - y- Gitter. Dabei wird das Broadcasting intensiv genutzt und ein 4D-Zwischenarray berechnet, bei dem jede Dimension x- Werte, y- Werte, x- Exponenten und y darstellt Exponenten darstellt.
Aus dieser Funktion wird die Nulllinie berechnet. Da die Abfrage angibt, dass nur Vorzeichenänderungen erkannt werden müssen, wendet der Code eine 2D-Faltung mit einem 2 × 2-Block von Einsen an und markiert ein Pixel als zur Linie gehörend, wenn nicht die vier Werte des Blocks dasselbe Vorzeichen haben.
Alle Testfälle
Hier sind alle Eingaben im entsprechenden Format, falls Sie es versuchen möchten:
quelle