Étant donné un graphique dirigé, affichez le cycle le plus long.
Règles
- Tout format d'entrée raisonnable est autorisé (par exemple, liste des bords, matrice de connectivité).
- Les étiquettes ne sont pas importantes, vous pouvez donc imposer des restrictions sur les étiquettes dont vous avez besoin et / ou que vous désirez, tant qu'elles ne contiennent pas d'informations supplémentaires non fournies dans l'entrée (par exemple, vous ne pouvez pas exiger que les nœuds dans les cycles soient étiquetés avec des entiers, et les autres nœuds sont étiquetés avec des chaînes alphabétiques).
- Un cycle est une séquence de nœuds qui sont tous connectés, et aucun nœud n'est répété, à l'exception du nœud qui est le début et la fin du cycle (
[1, 2, 3, 1]
est un cycle, mais[1, 2, 3, 2, 1]
ne l'est pas). - Si le graphique est acyclique, le cycle le plus long a une longueur de 0 et devrait donc produire une sortie vide (par exemple une liste vide, pas de sortie du tout).
- La répétition du premier nœud à la fin de la liste des nœuds du cycle est facultative (
[1, 2, 3, 1]
et[1, 2, 3]
dénote le même cycle). - S'il existe plusieurs cycles de la même longueur, l'un d'entre eux ou tous peuvent être sortis.
- Les prédéfinitions sont autorisées, mais si votre solution en utilise une, vous êtes encouragé à inclure une solution alternative qui n'utilise pas de prédéfinitions banalisantes (par exemple une prédéfinie qui génère tous les cycles). Cependant, la solution alternative ne comptera pas du tout dans votre score, elle est donc entièrement facultative.
Cas de test
Dans ces cas de test, l'entrée est donnée sous la forme d'une liste d'arêtes (où le premier élément est le nœud source et le deuxième élément est le nœud de destination), et la sortie est une liste de nœuds sans répétition du premier / dernier nœud.
[(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]
Réponses:
Mathematica,
8058 octets22 octets sauvés grâce à JungHwan Min
est le caractère à usage privé de trois octetsU+F3D5
représentant\[DirectedEdge]
. Fonction pure avec le premier argument#
censé être une liste d'arêtes dirigées. Trouve desAll
cycles de longueur au plusInfinity
dansGraph@#
, puis remplace la liste vide par la liste des auto-boucles. Les cycles sont représentés sous forme de listes d'arêtes et triés par longueur, nous prenons donc le dernier cycle de ce type, puis de toutes ses arêtes, nous prenons le premier argument afin d'obtenir une liste de sommets dans le format de sortie spécifié.Si seulement Mathematica traitait les boucles comme un cycle de longueur
1
(AcyclicGraphQ @ CycleGraph[1, DirectedEdges -> True]
donneTrue
, sérieusement), alors nous pourrions économiser un autre26
octet:la source
MaximalBy
car le résultat deFindCycle
est déjà trié par longueur (le dernier élément est le plus long). De plus, le premier argument deFindCycle
peut être une liste de\[DirectedEdge]
(au lieu de aGraph
). De plus, vous pouvez utiliser 2 octets;;
(=1;;-1
) au lieu du 3 octetsAll
dansPart
pour enregistrer un octet. -22 octets (58 octets):(FindCycle[#,∞,All]/.{}->{Cases[#,v_v_]})[[-1,;;,1]]&
Haskell ,
157 154150 octetsEssayez-le en ligne!
Merci @Laikoni et @Zgrab d'avoir enregistré un tas d'octets!
Il s'agit d'un programme très inefficace:
La première fonction
#
prend une liste de cheminsl
(une liste de listes de nombres) et essaie d'étendre les éléments del
en ajoutant chaque bord possible (une liste de longueur 2)g
à chaque élément del
. Cela ne se produit que si l'élément del
n'est pas déjà un cycle et si le nouveau nœud qui serait ajouté n'est pas déjà contenu dans l'élément del
. Si c'est déjà un cycle, on ne rajoute rien mais on l'ajoute à nouveau à la nouvelle liste de chemins, si on peut l'étendre, on ajoute le chemin étendu à la nouvelle liste, sinon on ne l'ajoute pas à la nouvelle liste .Maintenant, la fonction
h
essaie à plusieurs reprises d'étendre ces chemins (en commençant par la liste des bords elle-même) jusqu'à ce que nous atteignions un point fixe, c'est-à-dire que nous ne pouvons plus étendre aucun chemin. À ce stade, nous n'avons que des cycles dans notre liste. Il suffit ensuite de choisir le cycle le plus long. Évidemment, les cycles apparaissent plusieurs fois dans cette liste car chaque rotation cyclique possible d'un cycle est à nouveau un cycle.la source
(p:q)<-l
.<$>
au lieu demap
devrait enregistrer un autre octet((,)=<<length)<$>[]:
.d@(p:q)<-l
enregistre certains octets.d@(p:q)
c'est vraiment sympa, merci de m'avoir montré!Pyth, 20 octets
Suite de tests
Prend une liste d'arêtes, comme dans les exemples.
Explication:
la source
Bash + bsdutils, 129 octets
tsort fait tout le gros du travail, mais son format de sortie est plutôt unique et il ne détecte pas les cycles de longueur 1. Notez que cela ne fonctionne pas avec GNU tsort.
Vérification
la source
JavaScript (ES6),
173163156145139 octets5 octets enregistrés grâce à @Neil
Extrait de test
Afficher l'extrait de code
la source
map
vous fait économiser quelques octets?.filter().map()
, donc presque certainement pas. Le commutateur m'a permis d'économiser 10 octets (même si ce n'était pas aussi complet qu'aujourd'hui)a.filter(z=>!e).map(z=>d)
vous pouvez utilisera.map(z=>e?0:d)
.a+a?
plus :-)Haskell ,
109108 octetsUne solution de force brute: générer toutes les listes d'arêtes de longueurs croissantes jusqu'à la longueur de l'entrée, conserver celles qui sont des cycles, renvoyer la dernière. Prend le graphique au format
[(1,2),(2,3),(2,4),(4,1)]
. Essayez-le en ligne!Explication
la source
MATLAB,
291octetsPrend une matrice d'adjonction
A
où un bord(i,j)
est désigné par un1
inA(i,j)
etA
est nul dans toutes les autres entrées. La sortie est une liste d'un cycle le plus long. La liste est vide s'il n'y a pas de cycle du tout, et la liste inclut le début et la fin s'il y a un cycle. Il utilise1
indexation basée sur.Cette solution n'utilise aucune fonction intégrée liée aux graphiques.
Malheureusement, cela ne fonctionne pas dans TryItOnline car il utilise une fonction dans une fonction, qui est récursive. Un peu de modification vous permet de l'essayer sur octave-online.net .
Pour le tout dernier test, j'ai trouvé un cycle plus long alternatif
[0 2 1 4 3 5 7 8 9 11 10 6 0]
(cette notation utilise une indexation basée sur 0)Explication
L'approche de base ici est que nous effectuons un BFS à partir de chaque nœud et prenons soin de ne visiter aucun des nœuds intermédiaires à l'exception du nœud de départ. Avec cette idée, nous pouvons collecter tous les cycles possibles et choisir facilement le plus long.
la source