Dado un gráfico dirigido, genera el ciclo más largo.
Reglas
- Se permite cualquier formato de entrada razonable (por ejemplo, lista de bordes, matriz de conectividad).
- Las etiquetas no son importantes, por lo que puede imponer restricciones a las etiquetas que necesita y / o desea, siempre que no contengan información adicional no proporcionada en la entrada (por ejemplo, no puede exigir que los nodos en los ciclos sean etiquetados con enteros y otros nodos están etiquetados con cadenas alfabéticas).
- Un ciclo es una secuencia de nodos que están todos conectados, y ningún nodo se repite, excepto el nodo que es el inicio y el final del ciclo (
[1, 2, 3, 1]
es un ciclo, pero[1, 2, 3, 2, 1]
no lo es). - Si el gráfico es acíclico, el ciclo más largo tiene una longitud 0 y, por lo tanto, debería producir una salida vacía (por ejemplo, lista vacía, sin salida).
- La repetición del primer nodo al final de la lista de nodos en el ciclo es opcional (
[1, 2, 3, 1]
y[1, 2, 3]
denota el mismo ciclo). - Si hay múltiples ciclos de la misma longitud, se puede generar uno o todos ellos.
- Las incorporaciones están permitidas, pero si su solución usa una, se le recomienda que incluya una solución alternativa que no utilice incorporaciones trivializantes (por ejemplo, una creación que genera todos los ciclos). Sin embargo, la solución alternativa no contará para su puntaje, por lo que es completamente opcional.
Casos de prueba
En estos casos de prueba, la entrada se proporciona como una lista de aristas (donde el primer elemento es el nodo de origen y el segundo elemento es el nodo de destino), y la salida es una lista de nodos sin repetición del primer / último nodo.
[(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
fuente
fuente
Respuestas:
Mathematica,
8058 bytesAhorró la friolera de 22 bytes gracias a JungHwan Min
es el carácter de uso privado de tres bytes queU+F3D5
representa\[DirectedEdge]
. La función pura con el primer argumento se#
espera que sea una lista de aristas dirigidas. EncuentraAll
ciclos de duración como máximoInfinity
enGraph@#
, luego reemplaza la lista vacía con la lista de bucles automáticos. Los ciclos se representan como listas de aristas y se ordenan por longitud, por lo que tomamos el último ciclo, luego de todas sus aristas tomamos el primer argumento para obtener una lista de vértices en el formato de salida especificado.Si solo Mathematica tratara los bucles como un ciclo de longitud
1
(AcyclicGraphQ @ CycleGraph[1, DirectedEdges -> True]
daTrue
, en serio), entonces podríamos guardar otros26
bytes:fuente
MaximalBy
porque el resultado deFindCycle
ya está ordenado por longitud (el último elemento es el más largo). Además, el primer argumento deFindCycle
puede ser una lista de\[DirectedEdge]
(en lugar de aGraph
). Además, puede utilizar el 2 bytes;;
(=1;;-1
) en lugar del 3 bytesAll
enPart
Para guardar un byte. -22 bytes (58 bytes):(FindCycle[#,∞,All]/.{}->{Cases[#,v_v_]})[[-1,;;,1]]&
Haskell ,
157 154150 bytesPruébalo en línea!
¡Gracias @Laikoni y @Zgrab por guardar un montón de bytes!
Este es un programa muy ineficiente:
La primera función
#
toma una lista de rutasl
(una lista de listas de números) e intenta extender los elementosl
al anteponer cada borde posible (una lista de longitud 2)g
a cada elemento del
. Esto sucede solo si el elemento del
no es ya un ciclo y si el nuevo nodo que se antepondrá no está contenido en el elemento del
. Si ya es un ciclo, no anteponemos nada, sino que lo agregamos nuevamente a la nueva lista de rutas, si podemos extenderlo, agregamos la ruta extendida a la nueva lista, de lo contrario no la agregamos a la nueva lista .Ahora, la función
h
intenta repetidamente extender esas rutas (comenzando con la lista de bordes en sí) hasta llegar a un punto fijo, es decir, no podemos extender ninguna ruta más. En este punto solo tenemos ciclos en nuestra lista. Entonces es solo cuestión de elegir el ciclo más largo. Obviamente, los ciclos aparecen varias veces en esta lista, ya que cada posible rotación cíclica de un ciclo es nuevamente un ciclo.fuente
(p:q)<-l
.<$>
lugar demap
debería guardar otro byte((,)=<<length)<$>[]:
.d@(p:q)<-l
guardan algunos bytes.d@(p:q)
es realmente agradable, ¡gracias por mostrarme!Pyth, 20 bytes
Banco de pruebas
Toma una lista de bordes, como en los ejemplos.
Explicación:
fuente
Bash + bsdutils, 129 bytes
tsort hace todo el trabajo pesado, pero su formato de salida es bastante único y no detecta ciclos de longitud 1. Tenga en cuenta que esto no funciona con GNU tsort.
Verificación
fuente
JavaScript (ES6),
173163156145139 bytesGuardado 5 bytes gracias a @Neil
Fragmento de prueba
Mostrar fragmento de código
fuente
map
te ahorra un par de bytes?.filter().map()
así, así que casi seguro que no. El cambio me ahorró 10 bytes (aunque no era tan completo como ahora)a.filter(z=>!e).map(z=>d)
puedes usara.map(z=>e?0:d)
.a+a?
:-)Haskell ,
109108bytesUna solución de fuerza bruta: genere todas las listas de bordes de longitudes crecientes hasta la longitud de la entrada, mantenga los que son ciclos, devuelva el último. Toma el gráfico en el formato
[(1,2),(2,3),(2,4),(4,1)]
. Pruébalo en línea!Explicación
fuente
MATLAB,
291260 bytesToma una matriz adjecency
A
donde un borde(i,j)
se denota por una1
enA(i,j)
, yA
es cero en todas las otras entradas. La salida es una lista de un ciclo más largo. La lista está vacía si no hay ningún ciclo, y la lista incluye el inicio y el punto final si hay un ciclo. Utiliza1
indexación basada en.Esta solución no utiliza ninguna función integrada relacionada con gráficos.
Lamentablemente, esto no se ejecuta en TryItOnline, ya que utiliza una función dentro de una función, que es recursiva. Un poco de modificación le permite probarlo en octave-online.net .
Para el último caso de prueba, encontré un ciclo más largo alternativo
[0 2 1 4 3 5 7 8 9 11 10 6 0]
(esta notación usa indexación basada en 0)Explicación
El enfoque básico aquí es que realizamos un BFS desde cada nodo y nos aseguramos de no visitar ninguno de los nodos intermedios, excepto el nodo de inicio. Con esa idea, podemos recopilar todos los ciclos posibles y elegir fácilmente el más largo.
fuente