Das Problem : Zählen Sie die Anzahl der Löcher in einem verbundenen Polygon. Die Konnektivität des Polygons wird durch die Bedingung garantiert, dass jedes Dreieck in der Eingabetriangulation mindestens eine Seite mit einem anderen Dreieck teilt und dass es nur einen solchen verbundenen Satz von Dreiecken gibt.
Die Eingabe ist eine Liste L
von n
Punkten in der Ebene und eine Liste T
von 3 Tupeln mit Einträgen von 0...n-1
. Für jedes Element im T
Tupel (t_1,t_2,t_3)
stehen die drei Eckpunkte (aus der Liste L
) eines Dreiecks in der Triangulation. Beachten Sie, dass dies eine Triangulation im Sinne einer "Polygon-Triangulation" ist , da sich in T
dieser Überlappung niemals zwei Dreiecke befinden . Eine zusätzliche Bedingung ist, dass Sie die Eingabe nicht bereinigen müssen L
und T
keine Wiederholungen enthalten.
Beispiel 1 : Wenn L = {{0,0},{1,0},{0,1},{1,2}}
und T = {{0,1,2},{1,2,3}}
dann hat das angegebene Polygon eine Lochanzahl von 0.
Beispiel 2 : Wenn L = {{0,0},{1,0},{2,0},{2,1},{2,2},{1,2},{0,2},{0,1},{.5,.5},{1.5,.5},{1.5,1.5},{.5,1.5}}
und T = {{5,6,11},{5,10,11},{4,5,10},{3,8,10},{2,3,9},{2,8,9},{1,2,8},{0,1,8},{0,8,11},{0,7,11},{6,7,11},{3,4,10}}
dann sollte die Polygoneingabe eine Ausgabe von 2 ergeben.
Die Aufgabe besteht darin, das kürzeste Programm (oder die kürzeste Funktion) zu schreiben, das L
und T
als Eingabe verwendet und die Anzahl der Löcher zurückgibt. Der 'Gewinner' wird als Eintrag mit der geringsten Anzahl von Zeichen anerkannt (vorläufiges Enddatum 1. Juni).
Beispiel für eine Eingabeformatierung (beachten Sie die Indizierung 0):
0,0
1,0
0,1
1,2
0,1,2
1,2,3
T=1,2,3/1,2,4/5,6,7/5,6,8
. Jedes Dreieck teilt eine Kante mit einem anderen Dreieck, aber die Triangulation wird getrenntT=1,2,3/1,4,5
ist verbunden, aber nicht kantenverbunden)Antworten:
GolfScript (23 Zeichen)
Nimmt das Eingabeformat mit GolfScript-Array-Notation und Anführungszeichen (oder Integralkoordinaten) an. Z.B
( Online-Äquivalent )
oder
( Online-Äquivalent )
quelle
Python, 71
Was folgt, ist ein Programm (keine Funktion ), das die gewünschte Anzahl berechnet.
Anwendungsbeispiel:
quelle
APL, 36
Die Funktion wird
L
als linkes undT
als rechtes Argument verwendet .Beispielsweise:
Erklärung von rechts nach links:
⍴⍺,⍵
verkettet die beiden Eingabevektoren und gibt ihre Länge zurück (V + F
)¨⍵
wendet die Funktion links auf jedes Element des rechten Arguments an und gibt das Ergebnis zurück⍵,⍵
Gibt das richtige Argument zurück, das mit sich selbst verknüpft ist3 2⍴
formt das Vektorargument in drei Paare. In diesem Fall werden die ersten und zweiten, dritten und ersten sowie zweiten und dritten Elemente des Vektors miteinander gepaart.,/
verbindet das Vektorargument miteinander⍵[⍋⍵]
sortiert das richtige Argument∪/
filtert alle Duplikate heraus⍴⊃
verwandelt einen verschachtelten Skalar in einen Vektor und gibt dessen Länge zurück.E
)1
ist selbsterklärend (ich hoffe ...)Die gesamte Funktion kehrt dann zurück
1+E-(V+F)
, oder1-(F+V-E)
.quelle
Mathematica, 93 (noch nicht viel Golf gespielt)
(Leerzeichen aus Gründen der Übersichtlichkeit hinzugefügt)
Testen:
quelle
Erosion
)?Ruby, 239 Zeichen (227 Körper)
Beachten Sie, dass ich nur die Topologie betrachte. Ich verwende die Scheitelpunktpositionen in keiner Weise.
Anrufer (erwartet T im Mathematica- oder JSON-Format):
Prüfung:
quelle
Mathematica
76 73 72 6762Nach vielen Experimenten wurde mir klar, dass die genaue Position der Eckpunkte keine Rolle spielt, und so stellte ich das Problem mit Graphen dar. Die wesentlichen Invarianten, die Anzahl der Dreiecke, Kanten und Eckpunkte blieben unveränderlich (vorausgesetzt, Linienkreuzungen wurden vermieden).
Es gab zwei Arten von internen "Dreiecken" in der Grafik: Diese waren vermutlich ein Gesicht, dh ein "gefülltes" Dreieck, und diejenigen, bei denen es keine gab. Die Anzahl der Innenflächen hatte keine Beziehung zu den Kanten oder Eckpunkten. Das bedeutete, dass das Stechen von Löchern in vollständig "gefüllten" Diagrammen nur die Anzahl der Flächen reduzierte. Ich spielte systematisch mit Variationen zwischen Dreiecken und verfolgte die Flächen, Eckpunkte und Kanten. Schließlich wurde mir klar, dass die Anzahl der Löcher immer gleich 1 - # Gesichter - # Eckpunkte + # Kanten war. Es stellte sich heraus, dass dies 1 minus der Euler-Charakteristik war (von der ich nur im Zusammenhang mit regulären Polyedern gewusst hatte (obwohl die Länge der Kanten eindeutig keine Bedeutung hatte.
Die folgende Funktion gibt die Anzahl der Löcher zurück, wenn die Eckpunkte und Dreiecke eingegeben werden. Im Gegensatz zu meiner früheren Einreichung ist kein Scan eines Bildes erforderlich. Sie können es sich als 1 - Eulers Charakteristik
F
vorstellen, dh 1 - (F + V - E) wobeiV
= # Gesichter, = # Eckpunkte,E
= # Kanten. Die Funktion gibt die Anzahl der Löcher unter1 - (F + V -E)
Berücksichtigung der tatsächlichen Flächen (Dreiecke) und Eckpunkte zurück.Es kann leicht gezeigt werden, dass das Entfernen eines Dreiecks an der Außenseite des Komplexes keinen Einfluss auf die Euler-Charakteristik hat, unabhängig davon, ob es eine oder zwei Seiten mit anderen Dreiecken teilt.
Hinweis: Die Kleinbuchstaben
v
werden anstelleL
der ursprünglichen Formulierung verwendet. das heißt, es enthält die Eckpunkte selbst (nicht V, die Anzahl der Eckpunkte)f
wird für dieT
aus der Originalformulierung verwendete verwendet; Das heißt, es enthält die Dreiecke, die als geordnetes Dreifach der Scheitelpunktindizes dargestellt werden.Code
(Vielen Dank an Mr. Wizard für das Rasieren von 5 Zeichen durch Aufheben der Ersatzregel.)
Beispiel 1
v = {{0, 0}, {1, 0}, {0, 1}, {1, 2}}; f = {{0, 1, 2}, {1, 2, 3}};
Null Löcher.
Beispiel 2
v = {{0, 0}, {1, 0}, {2, 0}, {2, 1}, {2, 2}, {1, 2}, {0, 2}, {0, 1} , {.5, .5}, {1.5, .5}, {1.5, 1.5}, {.5, 1.5}}; f = {{5, 6, 11}, {5, 10, 11}, {4, 5, 10}, {3, 8, 10}, {2, 3, 9}, {2, 8, 9} , {1, 2, 8}, {0, 1, 8}, {0, 8, 11}, {0, 7, 11}, {6, 7, 11}, {3, 4, 10}};
Somit sind 2 Löcher in Beispiel 2.
quelle
MorphologicalEulerNumber[]
). Mma 9.01, Win XP.MorphologicalEulerNumber
erfordert manchmal ein Bild; Es weigert sich, ein Grafikobjekt zu akzeptieren. In diesen Fällen sind die Größe des Lochs und die Auflösung kritisch (siehe codegolf.stackexchange.com/questions/8706/… ). Hier funktioniert es jedoch direkt mit dem Graphics-Objekt, das explizit alle Scheitelpunkte enthält. Ich stellte mir vor (oder hoffte), dass es einen Ansatz geben würde, der nicht vom Bild abhängt. Ich wünschte, ich wüsste, wie es versucht hat, das Problem zu lösen. Vielleicht klärt ein bisschen Höhlenforschung im Quellcode für die Funktion die Dinge.Python, 107
Mir wurde klar, dass das direkte Aufnehmen der Paare kürzer war als das
from itertools import*
Tippencombinations()
. Ich bemerkte jedoch auch, dass meine Lösung auf den eingegebenen dreieckigen Flächen beruhte, deren Scheitelpunkte in konsistenter Reihenfolge aufgelistet waren. Daher sind die Zuwächse bei der Anzahl der Zeichen nicht so groß.Python, 115
Eulers charakteristischer Ansatz, die Ausführlichkeit von itertools scheint unmöglich zu vermeiden. Ich frage mich, ob es billiger wäre, eine direktere Technik zum Erstellen von Scheitelpunktpaaren zu verwenden.
Anwendungsbeispiel:quelle