Das Happy-End-Problem (eigentlich ein Theorem) besagt das
Jede Menge von fünf Punkten in der Ebene an allgemeiner Position hat eine Teilmenge von vier Punkten, die die Eckpunkte eines konvexen Vierecks bilden.
Das Problem wurde von Paul Erdős so benannt, als sich die beiden Mathematiker Ester Klein und George Szekeres verlobten und heirateten.
Klarstellungen:
- Allgemeine Position bedeutet hier, dass keine drei Punkte kollinear sind.
Das von den vier Eckpunkten gebildete Viereck wird unabhängig von der Reihenfolge der Punkte immer als nicht schneidend betrachtet. Zum Beispiel, da die vier Punkte
[1 1]
,[1 2]
,[2 1]
,[2 2]
ist das beabsichtigte Viereck der Platz, nicht die Fliege:Ein sich nicht schneidendes Viereck ist konvex, wenn kein Innenwinkel 180 Grad überschreitet. oder gleichwertig, wenn beide Diagonalen im Viereck liegen.
Die Herausforderung
Bei 5 Punkten mit positiven Ganzzahlkoordinaten werden 4 Punkte ausgegeben, die ein konvexes Viereck bilden.
Regeln
Wenn es mehrere Lösungen gibt (dh mehrere Sätze mit 4 Punkten), können Sie durchgehend eine oder alle ausgeben.
Eingabe- und Ausgabeformate sind wie gewohnt flexibel (Arrays, Listen, Listenlisten, Zeichenfolgen mit angemessenen Trennzeichen usw.).
Code Golf, gewinnt die wenigsten Bytes.
Testfälle
Eingang:
[6 8] [1 10] [6 6] [5 9] [8 10]
Es gibt nur eine mögliche Ausgabe:
[6 8] [1 10] [6 6] [5 9]
Eingang:
[3 8] [7 5] [6 9] [7 8] [5 1]
Es gibt fünf Lösungen:
[3 8] [7 5] [6 9] [7 8] [3 8] [7 5] [6 9] [5 1] [3 8] [7 5] [7 8] [5 1] [3 8] [6 9] [7 8] [5 1] [7 5] [6 9] [7 8] [5 1]
Eingang:
[4 8] [1 9] [9 9] [10 2] [1 6]
Es gibt drei Lösungen:
[4 8] [1 9] [10 2] [1 6] [4 8] [9 9] [10 2] [1 6] [1 9] [9 9] [10 2] [1 6]
Zur Veranschaulichung sind hier die drei Lösungen für diesen Fall:
Antworten:
CJam,
373432 BytesIch bin mir nicht sicher, ob
:-V
ich glücklich genug bin, aber wie K Zhang betont, gibt es=}
das Ende. :)Dies gibt nur eine Lösung aus, da das Entfernen von Duplikaten teurer wäre.
Teste es hier.
Erläuterung
Die Idee ist ziemlich einfach. Wir generieren alle möglichen Vierecke (einschließlich aller Anordnungen der Punkte) und wählen dann nur die konvexen aus. Wir testen die Konvexität, indem wir jedes Kantenpaar untersuchen und prüfen, ob sich alle in die gleiche Richtung drehen.
Der Drehsinn kann ziemlich leicht von einem Skalarprodukt erhalten werden. Wenn Sie die drei aufeinanderfolgenden Punkte auf einem Viereck nehmen und Linien vom ersten zum zweiten und vom ersten zum dritten Punkt zeichnen und dann den letzteren auf die Senkrechte des ersteren projizieren, erhalten Sie eine Zahl, deren Vorzeichen Ihnen sagt ob diese drei Punkte nach links oder rechts drehen. (Ich sollte dafür wahrscheinlich ein Diagramm hinzufügen.) Dieses "Projizieren auf die Senkrechte" klingt ziemlich kompliziert, bedeutet aber eigentlich nur, dass wir einen der beiden Vektoren umkehren und die Komponenten nach der Multiplikation subtrahieren, anstatt sie zu addieren. Also hier ist der Code ...
quelle
!}
MATLAB, 67 Bytes
Die Eingabe erfolgt in Form einer 2D-Matrix mit den Spalten X und Y:
Alle Sätze von 4 Punkten, die konvexe Vierecke erzeugen, werden im gleichen Format angezeigt.
Hier ist eine Demo , die leicht modifiziert wurde, um mit Octave zu arbeiten
Erläuterung
Diese Lösung nimmt alle Teilmengen von 4 Punkten der Eingabe (Reihenfolge spielt keine Rolle). Dazu schaffen wir die Identitätsmatrix und negieren es:
~eye(5)
. Wir durchlaufen die Spalten dieser Matrix undk
(der Schleifenindex) ist ein logisches Array, das angibt, welcher der 4 Punkte berücksichtigt werden soll. Wir verwenden dies dann, um diese 4 XY-Punkte von der Eingabe (I(k,:)
) zu erfassen .Wir berechnen dann die konvexe Hülle dieser 4 Punkte (
convhull
). Die Ausgabe vonconvhull
sind die Indizes der Eingabe, die den Punkten entsprechen, aus denen die konvexe Hülle besteht (wobei der erste Index dupliziert wird, um die Hülle zu schließen).Bei einem konvexen Viereck sind alle vier Punkte Teil der konvexen Hülle derselben Punkte (
nnz(convhull(points)) > 4
). Wenn wir feststellen, dass dies der Fall ist, zeigen wir die Punkte an, die für diese bestimmte Iteration verwendet wurden.quelle
Javascript (ES6),
306293283 BytesErklärung :
Die Funktion
c
berechnet das Kreuzprodukt des Vektors zwischen 3 benachbarten Punkten des Polygons und gibt 1 zurück, wenn es positiv ist, und ansonsten 0 (Hinweis: Das Kreuzprodukt kann nicht null sein, da die Punkte nicht kolinear sein können).Die Funktion
k
undj
generieren alle zyklischen Permutationen (ohne Umkehrung der Reihenfolge) des Eingabearrays.Die Funktion 'i' wird dann für jede zyklische Permutation aufgerufen, um die Summe der Funktionen
c
für jedes der 4 Tripletts benachbarter Koordinaten zu berechnen . Wenn die Kreuzprodukte alle das gleiche Vorzeichen haben, sind sie alle entweder 0 oder 1 und summieren sich zu 0 (Modulo 4), und das Polygon ist konkav und wird in das Ausgabearray verschoben. Wenn ein Triplett ein anderes Vorzeichen hat, ist die Summe ungleich Null (Modulo 4) und das Polygon ist konvex.Die Funktion
f
wird verwendet, um das Ausgabearray zu initialisieren und dann die obigen Funktionen aufzurufen, bevor die Ausgabe zurückgegeben wird.Tests :
Bearbeiten :
Kann auch mit kolinearen Punkten umgehen, wenn die ursprüngliche Version verwendet wird und die ersten beiden Linien folgendermaßen geändert werden:
Da dieser Fall in der Frage jedoch ausdrücklich ausgeschlossen ist, sind die zusätzlichen Zeichen nicht erforderlich.
quelle
Mathematica
10596 BytesSelect[#~Subsets~{4},f@#&]&
Wählt aus einer Liste von (5) Punkten die Teilmengen von 4 Punkten aus, die erfüllt sindf
.f
wenn jeder Punkt erfüllt ist, der 4 Punkte in einem Satz, liegt auf derRegionBoundary
von derConvexHull
der 4 Punkte.Testfälle
1. Betrachten wir die 5 konvexen Hüllen von Teilmengen (jeweils 4 Punkte) von {{6, 8}, {1, 10}, {6, 6}, {5, 9}, {8, 10}}. .
{{{6, 8}, {1, 10}, {6, 6}, {5, 9}}
{{6, 8}, {1, 10}, {6, 6}, {5, 9}} ist die einzige Lösung. Jeder der vier Punkte dient als Scheitelpunkt der konvexen Hülle (mit den gleichen 4 Punkten).
{{6, 8}, {1, 10}, {6, 6}, {8, 10}} ist keine Lösung. Der konvexe Rumpf hat nur 3 Eckpunkte. {6, 8} liegt im Rumpf.
Die übrigen Teilmengen sind ebenfalls keine Lösungen:
2. {{4, 8}, {1, 9}, {9, 9}, {10, 2}, {1, 6}} hat drei Lösungen.
{
{{4, 8}, {1, 9}, {10, 2}, {1, 6}},
{{4, 8}, {9, 9}, {10, 2}, {1, 6} }},
{{1, 9}, {9, 9}, {10, 2}, {1, 6}
}
3. {{3, 8}, {7, 5}, {6, 9}, {7, 8}, {5, 1}} hat 5 Lösungen.
{
{{3, 8}, {7, 5}, {6, 9}, {7, 8}},
{{3, 8}, {7, 5}, {6, 9}, {5, 1 }},
{{3, 8}, {7, 5}, {7, 8}, {5, 1}},
{{3, 8}, {6, 9}, {7, 8}, {5 , 1}},
{{7, 5}, {6, 9}, {7, 8}, {5, 1}
}
Beachten Sie, dass jeder der fünf Punkte an der Grenze der konvexen Hülle aller Punkte liegt.
Wenn einer der Punkte entfernt wird, sind die verbleibenden 4 Punkte jeweils Eckpunkte der reduzierten konvexen Hülle.
quelle