Bei einem gerichteten Graphen den längsten Zyklus ausgeben.
Regeln
- Jedes sinnvolle Eingabeformat ist zulässig (z. B. Kantenliste, Konnektivitätsmatrix).
- Die Bezeichnungen sind nicht wichtig, daher können Sie den von Ihnen benötigten und / oder gewünschten Bezeichnungen Einschränkungen auferlegen, sofern sie keine zusätzlichen Informationen enthalten, die nicht in der Eingabe enthalten sind (z. B. können Sie nicht verlangen, dass die Knoten in Zyklen vorhanden sind mit ganzen Zahlen beschriftet, und andere Knoten sind mit alphabetischen Zeichenfolgen beschriftet).
- Ein Zyklus ist eine Folge von Knoten, die alle miteinander verbunden sind, und es wird kein Knoten wiederholt, außer dem Knoten, der Beginn und Ende des Zyklus ist (
[1, 2, 3, 1]
ein Zyklus ist, aber[1, 2, 3, 2, 1]
nicht). - Wenn der Graph azyklisch ist, hat der längste Zyklus die Länge 0 und sollte daher eine leere Ausgabe ergeben (z. B. leere Liste, überhaupt keine Ausgabe).
- Das Wiederholen des ersten Knotens am Ende der Liste der Knoten im Zyklus ist optional (
[1, 2, 3, 1]
und[1, 2, 3]
bezeichnet denselben Zyklus). - Wenn es mehrere Zyklen gleicher Länge gibt, können einer oder alle ausgegeben werden.
- Builtins sind zulässig, aber wenn Ihre Lösung eine verwendet, sollten Sie eine alternative Lösung einbeziehen, die keine trivialisierenden Builtins verwendet (z. B. ein Builtin, das alle Zyklen ausgibt). Die alternative Lösung wird jedoch nicht für Ihre Punktzahl angerechnet, so dass dies völlig optional ist.
Testfälle
In diesen Testfällen wird die Eingabe als eine Liste von Kanten (wobei das erste Element der Quellknoten und das zweite Element der Zielknoten ist) und die Ausgabe als eine Liste von Knoten ohne Wiederholung des ersten / letzten Knotens angegeben.
[(0, 0), (0, 1)] -> [0]
[(0, 1), (1, 2)] -> []
[(0, 1), (1, 0)] -> [0, 1]
[(0, 1), (1, 2), (1, 3), (2, 4), (4, 5), (5, 1)] -> [1, 2, 4, 5]
[(0, 1), (0, 2), (1, 3), (2, 4), (3, 0), (4, 6), (6, 8), (8, 0)] -> [0, 2, 4, 6, 8]
[(0, 0), (0, 8), (0, 2), (0, 3), (0, 9), (1, 0), (1, 1), (1, 6), (1, 7), (1, 8), (1, 9), (2, 1), (2, 3), (2, 4), (2, 5), (3, 8), (3, 1), (3, 6), (3, 7), (4, 1), (4, 3), (4, 4), (4, 5), (4, 6), (4, 8), (5, 0), (5, 8), (5, 4), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 9), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 8), (7, 9), (8, 0), (8, 1), (8, 2), (8, 5), (8, 9), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6)] -> [0, 9, 6, 7, 8, 2, 5, 4, 3, 1]
[(0, 0), (0, 2), (0, 4), (0, 5), (0, 7), (0, 9), (0, 11), (1, 2), (1, 4), (1, 5), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 0), (3, 1), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 11), (4, 1), (4, 3), (4, 7), (4, 8), (4, 9), (4, 10), (4, 11), (5, 0), (5, 4), (5, 6), (5, 7), (5, 8), (5, 11), (6, 0), (6, 8), (6, 10), (6, 3), (6, 9), (7, 8), (7, 9), (7, 2), (7, 4), (7, 5), (8, 8), (8, 9), (8, 2), (8, 4), (8, 7), (9, 0), (9, 1), (9, 2), (9, 3), (9, 6), (9, 10), (9, 11), (10, 8), (10, 3), (10, 5), (10, 6), (11, 2), (11, 4), (11, 5), (11, 9), (11, 10), (11, 11)] -> [0, 11, 10, 6, 9, 3, 8, 7, 5, 4, 1, 2]
code-golf
graph-theory
Mego
quelle
quelle
Antworten:
Mathematica,
8058 BytesDank JungHwan Min. Satte 22 Bytes gespart
ist das Drei-Byte-ZeichenU+F3D5
für den privaten Gebrauch\[DirectedEdge]
. Reine Funktion mit dem ersten Argument#
, das eine Liste gerichteter Kanten sein soll. Findet längsteAll
ZyklenInfinity
inGraph@#
und ersetzt dann die leere Liste durch die Liste der Selbstschleifen. Zyklen werden als Listen von Kanten dargestellt und nach Länge sortiert. Daher nehmen wir den letzten derartigen Zyklus und nehmen von allen Kanten das erste Argument, um eine Liste von Scheitelpunkten im angegebenen Ausgabeformat zu erhalten.Wenn nur Mathematica Schleifen als einen Zyklus von Länge behandelt
1
(AcyclicGraphQ @ CycleGraph[1, DirectedEdges -> True]
gibtTrue
, ernsthaft), dann könnten wir andere26
Bytes speichern :quelle
MaximalBy
da das Ergebnis vonFindCycle
bereits nach Länge sortiert ist (das letzte Element ist das längste). Das erste Argument vonFindCycle
kann auch eine Liste von\[DirectedEdge]
(anstelle von aGraph
) sein. Darüber hinaus können Sie den 2-Byte verwenden;;
(=1;;-1
) anstelle der 3-Byte -All
inPart
zu speichern ein Byte. -22 Bytes (58 Bytes):(FindCycle[#,∞,All]/.{}->{Cases[#,v_v_]})[[-1,;;,1]]&
Haskell ,
157 154150 BytesProbieren Sie es online!
Vielen Dank an @Laikoni und @Zgrab, dass sie ein paar Bytes gespart haben!
Dies ist ein sehr ineffizientes Programm:
Die erste Funktion
#
nimmt eine Liste von Pfadenl
(eine Liste von Listen von Zahlen) und versucht, die Elemente von zu erweitern,l
indem jede mögliche Kante (eine Liste der Länge 2) vong
zu jedem Element von vorangestellt wirdl
. Dies geschieht nur, wenn das Element vonl
nicht bereits ein Zyklus ist und der neue Knoten, der vorangestellt werden würde, nicht bereits im Element von enthalten istl
. Wenn es sich bereits um einen Zyklus handelt, stellen wir nichts voran, sondern fügen ihn erneut zur neuen Liste der Pfade hinzu. Wenn wir ihn erweitern können, fügen wir den erweiterten Pfad zur neuen Liste hinzu, andernfalls fügen wir ihn nicht zur neuen Liste hinzu .Jetzt
h
versucht die Funktion wiederholt, diese Pfade (beginnend mit der Liste der Kanten selbst) zu erweitern, bis wir einen festen Punkt erreichen, dh wir können keinen Pfad mehr erweitern. Zu diesem Zeitpunkt haben wir nur Zyklen in unserer Liste. Dann geht es nur noch darum, den längsten Zyklus auszuwählen. Offensichtlich erscheinen die Zyklen mehrmals in dieser Liste, da jede mögliche zyklische Drehung eines Zyklus wieder ein Zyklus ist.quelle
(p:q)<-l
.<$>
anstelle vonmap
sollte ein weiteres Byte gespeichert werden((,)=<<length)<$>[]:
.d@(p:q)<-l
einige Bytes gespart.d@(p:q)
ist wirklich schön, danke, dass du es mir gezeigt hast!Pyth, 20 Bytes
Testsuite
Nimmt eine Liste von Kanten auf, wie in den Beispielen.
Erläuterung:
quelle
Bash + bsdutils, 129 Bytes
tsort erledigt das ganze schwere Heben, aber sein Ausgabeformat ist ziemlich einzigartig und es erkennt keine Zyklen der Länge 1. Beachten Sie, dass dies mit GNU tsort nicht funktioniert.
Nachprüfung
quelle
JavaScript (ES6),
173163156145139 Bytes5 Bytes dank @Neil gespart
Testschnipsel
Code-Snippet anzeigen
quelle
map
spart Ihnen das Wechseln zu einer einfachen alten Version ein paar Bytes?.filter().map()
, also mit ziemlicher Sicherheit nicht. Der Switch hat mir 10 Bytes gespart (obwohl er nicht so gut ist wie jetzt)a.filter(z=>!e).map(z=>d)
kannst du es verwenden , anstatt es zu verwendena.map(z=>e?0:d)
.a+a?
:-)Haskell ,
109108 BytesEine Brute-Force-Lösung: Generieren Sie alle Listen von Kanten mit zunehmender Länge bis zur Länge der Eingabe, behalten Sie die Zyklen bei und geben Sie die letzte zurück. Nimmt das Diagramm im Format
[(1,2),(2,3),(2,4),(4,1)]
. Probieren Sie es online!Erläuterung
quelle
MATLAB,
291260 BytesNimmt eine Adjezenzmatrix an,
A
in der eine Kante(i,j)
durch ein1
in gekennzeichnetA(i,j)
ist undA
in allen anderen Einträgen Null ist. Die Ausgabe ist eine Liste eines längsten Zyklus. Die Liste ist leer, wenn überhaupt kein Zyklus vorhanden ist, und die Liste enthält Start- und Endpunkt, wenn ein Zyklus vorhanden ist. Es verwendet1
-basierte Indizierung.Diese Lösung verwendet keine integrierten Funktionen für Diagramme.
Leider wird dies in TryItOnline nicht ausgeführt, da eine Funktion innerhalb einer Funktion verwendet wird, die rekursiv ist. Mit ein wenig Modifikation können Sie es auf octave-online.net ausprobieren .
Für den allerletzten Testfall habe ich einen alternativen längsten Zyklus gefunden
[0 2 1 4 3 5 7 8 9 11 10 6 0]
(diese Notation verwendet eine 0-basierte Indizierung)Erläuterung
Der grundlegende Ansatz hierbei ist, dass wir von jedem Knoten ein BFS durchführen und sicherstellen, dass wir keinen der Zwischenknoten außer dem Startknoten erneut besuchen. Mit dieser Idee können wir alle möglichen Zyklen sammeln und einfach den längsten auswählen.
quelle