Bestimmen Sie bei 5 verschiedenen Punkten auf einer zweidimensionalen Ebene die Art des Kegelschnitts, der durch die Punkte gebildet wird. Der Ausgang wird einer der folgenden sein circle
, hyperbola
, ellipse
, oder parabola
.
Regeln
- Die Punkte befinden sich im Allgemeinen in einer linearen Position, was bedeutet, dass keine drei Punkte kollinear sind und daher der durch sie verlaufende Kegel eindeutig ist.
- Die Koordinaten der 5 Punkte sind Dezimalzahlen zwischen -10 und 10 einschließlich.
- Die Genauigkeit für die Dezimal- / Gleitkommawerte sollte der Genauigkeit des systemeigenen Gleitkomma- / Dezimaltyps Ihrer Sprache entsprechen. Wenn Ihre Sprache / Ihr Datentyp eine willkürliche Genauigkeit hat, können Sie 12 Nachkommastellen als die maximal erforderliche Genauigkeit verwenden, die auf Null gerundet wird (z
1.0000000000005 == 1.000000000000
. B. ). - Die Kapitalisierung der Ausgabe spielt keine Rolle.
- Das Ausgeben,
ellipse
wenn der Kegelschnitt tatsächlich ein Kreis ist, ist nicht zulässig. Alle Kreise sind Ellipsen, Sie müssen jedoch die spezifischste ausgeben.
Bei Gleitkommaungenauigkeiten und -genauigkeiten:
Ich versuche, dies so einfach wie möglich zu gestalten, damit Probleme mit Gleitkommaungenauigkeiten nicht im Wege stehen. Das Ziel ist, wenn der Datentyp "magical infinite precision value" anstelle von float / double wäre, würde alles perfekt funktionieren. Da es jedoch keinen "magischen unendlichen Genauigkeitswert" gibt, schreiben Sie Code, der davon ausgeht, dass Ihre Werte unendliche Genauigkeit haben, und alle Probleme, die aufgrund von Gleitkommaungenauigkeiten auftreten, sind Funktionen, keine Fehler.
Testfälle
(0, 0), (1, 5), (2, 3), (4, 8), (9, 2) => hyperbola
(1.2, 5.3), (4.1, 5.6), (9.1, 2.5), (0, 1), (4.2, 0) => ellipse
(5, 0), (4, 3), (3, 4), (0, 5), (0, -5) => circle
(1, 0), (0, 1), (2, 1), (3, 4), (4, 9) => parabola
circle
scheint es für Ausgaben wie erforderlich zu sein, die Gleichheit der Floats zu überprüfen, um sie von einer sehr runden Ellipse zu unterscheiden. Welche Präzision sollen wir hier annehmen?Antworten:
Matlab, 154 Bytes
Dank Suevers Vorschlägen konnten einige Bytes eingespart werden.
Übernimmt die Eingabe als
[x1 y1;x2 y2;x3 y3; etc]
. Dies verwendete eine Vandermonde-Matrix und fand die Basis ihres Nullraums, der immer ein einzelner Vektor sein wird. Dann berechnet es die Diskriminante und verwendet sie, um einen Index zwischen 1 und 4 zu erstellen, der zum Abrufen der Zeichenfolge verwendet wird.Ungolfed:
Der
sign(...)
Teil berechnet die Diskriminante und gibt 1, wenn sie positiv ist (Hyperbel), -1, wenn sie negativ ist (Ellipse) und 0, wenn sie 0 ist (Parabel). Dermax(...)
subtrahiert 1 weg, wenn es ein Kreis ist. Matlab-Arrays sind einseitig indiziert. Fügen Sie also 3 hinzu, um die Werte 1, 2, 3, 4 zu erhalten, und indizieren Sie damit das Array mit den Namen der konischen Abschnitte.quelle
max() == 0
, können Sie zu vereinfachen~max()
ones(length(p),1)
Ihnen könnte tun1+p(:,1)*0
max()
Sache war albern von mir, ich hatte dort schon Vergleiche und wurde offensichtlich faul! Diese Art, das zu bekommen,ones
ist auch sehr schön.JavaScript (ES6), 316
323 347Jede Sprache, die besser für den Umgang mit Matrix und Determinante geeignet ist, sollte besser abschneiden (APL, J, CJAM, Jelly).
Literatur: Allgemeine Form eines Kegels , Fünf Punkte bestimmen einen Kegel , Lineares Gleichungssystem , Determinante
In der kartesischen Ebene ist die allgemeine Gleichung eines Kegels
mit A oder B oder C ungleich 0 (sonst ist es eine gerade Linie)
A ... F sind sechs Unbekannte zu finden. Mit fünf Paaren von (x, y) können wir ein lineares System mit fünf Gleichungen aufbauen und durch Skalieren eine Dimension entfernen. Das heißt, wir können eines von A, B oder C auf 1 setzen, wenn es nicht 0 ist (und wir wissen, dass mindestens eines nicht 0 ist).
Ich baue und versuche 3 Systeme zu lösen: Zuerst versuche ich A = 1. Wenn nicht lösbar, dann B = 1, dann C. (Es könnte einen besseren Weg geben, aber das ist mein bester zu der Zeit)
Mit den Werten von A, B, C können wir den Kegel klassifizieren, der die Diskriminante betrachtet
d=B*B-4*A*C
Weniger golfen
Prüfung
quelle
Python - 234 Bytes
Ich drucke nie
circle
oderparabola
weilt
undd[1]
traf nie genau0
, aber OP sagte, das sei in Ordnung.quelle
C 500
Meine JavaScript-Antwort wurde auf C portiert. Nur um zu sehen, ob dies möglich ist.
Verwendung: 10 Werte von der Standardeingabe lesen
Ausgabe:
Test (ideone)
Weniger golfen
quelle
Salbei, 247 Bytes
Probieren Sie es online aus
Diese Funktion nimmt einen iterable von
(x,y)
Paaren als Eingabe versucht die Diskriminante von jeder der möglichen linearen 3 Systemen Berechnen (A=1
,B=1
, undC=1
), und gibt den Typ des konischen Abschnitts auf der Grundlage der Werte der Diskriminanzfunktion,A
,B
, undC
.Es ist wahrscheinlich noch ein bisschen mehr Golf zu spielen, aber ich bin mit Sage verrostet und müde, also werde ich am nächsten Morgen weiter daran arbeiten.
quelle