Für eine gegebene DAG (gerichteter azyklischer Graph) ist jede ihrer topologischen Sortierungen eine Permutation aller Eckpunkte, wobei für jede Kante (u, v) in der DAG u vor v in der Permutation erscheint.
Ihre Aufgabe ist es, die Gesamtzahl der topologischen Sorten einer bestimmten DAG zu berechnen.
Regeln
- Sie können ein beliebiges Format verwenden, um das Diagramm darzustellen, z. B. die Adjazenzmatrix, die Adjazenzliste oder die Kantenliste, sofern Sie in Ihrer Codierung keine nützlichen Berechnungen durchführen. Sie können auch Dinge wie die Anzahl der Scheitelpunkte oder die Scheitelpunktliste in der Eingabe haben, wenn diese nützlich sind.
- Sie können davon ausgehen, dass das Diagramm in der Eingabe immer eine DAG ist (keine Zyklen).
- Ihr Programm sollte theoretisch für jede Eingabe funktionieren. Es kann jedoch fehlschlagen, wenn der grundlegende Ganzzahltyp in Ihrer Sprache überläuft.
- Die Namen von Scheitelpunkten können beliebige aufeinanderfolgende Werte in einem beliebigen Typ sein. Zum Beispiel: Zahlen, die bei 0 oder 1 beginnen. (Und natürlich nur, wenn Sie keinen Code in dieser Zahl speichern.)
- Das ist Code-Golf. Der kürzeste Code gewinnt.
Beispiel
Dies ist die gleiche Eingabe in verschiedenen Formaten. Ihr Programm muss nicht alle akzeptieren. Scheitelpunkte sind immer ganze Zahlen, die bei 0 beginnen.
Adjacency list:
[ [1 2 3 5] [2 4] [] [2] [] [3] ]
Adjacency matrix:
[ [0 1 1 1 0 1] [0 0 1 0 1 0] [0 0 0 0 0 0] [0 0 1 0 0 0] [0 0 0 0 0 0] [0 0 0 1 0 0] ]
Edge list:
6 [ [0 1] [0 2] [0 3] [0 5] [1 2] [1 4] [3 2] [5 3] ]
Es ist die Grafik in diesem Bild:
Die Ausgabe sollte sein:
9
Die topologischen Sorten sind:
[0 1 4 5 3 2]
[0 1 5 4 3 2]
[0 1 5 3 4 2]
[0 1 5 3 2 4]
[0 5 1 4 3 2]
[0 5 1 3 4 2]
[0 5 1 3 2 4]
[0 5 3 1 4 2]
[0 5 3 1 2 4]
code-golf
combinatorics
graph-theory
permutations
jimmy23013
quelle
quelle
Antworten:
CJam - 25
Mit großer Hilfe von user23013 :)
Probieren Sie es online aus
Erläuterung:
Der allgemeine Algorithmus ist der gleiche wie in der Python-Lösung von xnor .
Der Schlüssel hier ist der
j
Operator, der die gespeicherte Rekursion ausführt. Für die Definition der Rekursion sind ein Parameter, ein Wert oder ein Array für die Anfangswert (e) (wie in f (0), f (1) usw.) und ein Block erforderlich. Derj
Operator wird innerhalb des Blocks erneut verwendet, um rekursive (und gespeicherte) Aufrufe an denselben Block auszuführen. Es kann auch mit mehreren Parametern verwendet werden, ist hier jedoch nicht der Fall.Die große Innovation von user23013 besteht darin, j mit verschiedenen Datentypen zu verwenden und dabei die Adjazenzliste als Array von Anfangswerten zu verwenden.
quelle
Python, 58
Die Eingabe besteht aus einem Adjazenzwörterbuch
G
und einem ScheitelpunktsatzV
.Der Code ist rekursiv. Das Set
V
speichert alle Knoten, die noch besucht werden müssen. Für jeden potenziellen nächsten Knoten überprüfen wir seine Eignung, indem wir prüfen, ob keine verbleibenden Scheitelpunkte darauf zeigen,V-G[v]==V
indem wir dies überprüfenV
undG[v]
disjunkt sind. Für alle geeigneten solchen Eckpunkte addieren wir die Anzahl der topologischen Sortierungen, wobei sie entfernt wurden. Als Basisfall ergibt die leere Menge 1.quelle
Mathematica,
805751 BytesSehr einfache Umsetzung der Definition. Ich generiere nur alle Permutationen und zähle, wie viele davon gültig sind. Um zu überprüfen, ob eine Permutation gültig ist, erhalte ich alle Eckpunktpaare in der Permutation. Praktischerweise
Subsets[l,{2}]
gibt es mir nicht nur alle Paare, sondern behält auch die Reihenfolge bei, in der sie sich befindenl
- genau das, was ich brauche.Das Obige ist eine Funktion, die die Scheitelpunktliste und die Kantenliste wie erwartet erwartet
wenn Sie die Funktion aufrufen
f
.Ich werde versuchen, dies zu spielen, oder später einen anderen Ansatz verwenden.
quelle
Pyth, 27 Bytes
Definiert eine 2 Eingabefunktion ,
g
. Die erste Eingabe ist die Anzahl der Eckpunkte, die zweite die Liste der gerichteten Kanten.Zu testen:
Probieren Sie es hier aus.
quelle
^UGG
, der alleG
Eintragslisten von generiertrange(len(G))
.[0, 1, ...]
direkt in der Eingabe verwenden?^GlG
vs.^UGG
.Haskell,
1021071008985 BytesDie Eingabe ist die höchste Scheitelpunktnummer (beginnend mit 0) und eine Kantenliste, wobei eine Kante eine Liste mit zwei Elementen ist. Anwendungsbeispiel:
5 # [[0,1], [0,2], [0,3], [0,5], [1,2], [1,4], [3,2], [5,3]]
So funktioniert es: Zählen Sie alle Permutationen
p
der Eckpunkte, für die alle Kanten[u,v]
erfüllt sind: Die Position vonu
inp
ist kleiner als die Position vonv
inp
. Das ist eine direkte Implementierung der Definition.Bearbeiten: Meine erste Version hat die topologischen Sortierungen selbst zurückgegeben und nicht, wie viele es gibt. Behoben.
Bearbeiten II: funktionierte nicht für Diagramme mit nicht verbundenen Scheitelpunkten. Behoben.
quelle