Considere una permutación de los enteros 1
, ..., n
como este para n = 6
:
[5,2,4,3,6,1]
Si ve la permutación como un mapeo de [1,2,3,4,5,6]
a [5,2,4,3,6,1]
, la permutación puede descomponerse en ciclos disjuntos . Un ciclo es un subconjunto de elementos que se asignan entre sí. Por ejemplo, 1
se asigna a 5
, que se asigna a 6
, que se vuelve a asignar 1
. Entonces un ciclo es [1,5,6]
. Los otros ciclos son [2]
y [3,4]
. Por lo tanto, el número de ciclos para esta permutación es 3
.
En general, los ciclos de una permutación son únicos (hasta el orden), y el número de ciclos para una permutación de tamaño n
varía de 1
a n
.
El reto
Dada una permutación no vacía, genera su número de ciclos.
De entrada es una matriz formada por los n
números enteros 1
, 2
, ..., n
, donde n > 0
. Cada número entero ocurre exactamente una vez. El orden en que aparecen define la permutación, como en el ejemplo anterior.
En lugar de una matriz, puede usar una lista, una cadena con un separador entre los números, una entrada separada para cada número o cualquier cosa que sea razonable.
Para una permutación de tamaño n
, en lugar del conjunto de enteros basado en 1 1
, ..., n
puede usar consistentemente el conjunto basado en 0 0
, ..., n-1
. Si es así, indíquelo en su respuesta.
El código debería funcionar n
hasta 20
en un tiempo razonable, digamos menos de un minuto.
Código de golf. Todas las construcciones permitidas.
Casos de prueba
Esto supone una entrada de matriz basada en 1.
[1] -> 1
[3,2,1] -> 2
[2,3,4,5,1] -> 1
[5,2,4,3,6,1] -> 3
[8,6,4,5,2,1,7,3] -> 2
[4,5,11,12,7,1,3,9,10,6,8,2] -> 1
[4,2,5,11,12,7,1,3,9,10,6,8] -> 5
[5,8,6,18,16,9,14,10,11,12,4,20,15,19,2,17,1,13,7,3] -> 3
[14,5,17,15,10,18,1,3,4,13,11,16,2,12,9,7,20,6,19,8] -> 7
Relacionado
Este desafío relacionado pide los ciclos reales de la permutación, no el número de ellos. Requerir solo el número de ciclos puede conducir a algoritmos más cortos que eluden la generación de los ciclos reales.
fuente
1
, ...,n
en ese orden. ¿Puedes aclarar cómo puede un mapeo ser una entrada? ¿Es una estructura de datos?dict
. Quiero tener{1: 2, 2: 1}
como entrada en lugar de[2, 1]
.Respuestas:
J, 4 bytes
Esto supone que la permutación está basada en 0. Utiliza el incorporado
C.
que proporciona una lista que representa una permutación directa y genera una lista de ciclos. Luego#
compuesto@
sobre eso devuelve el número de ciclos en esa lista.Pruébalo aquí
fuente
JavaScript,
9998 bytesEsta solución asume que la matriz y sus valores están indexados a cero (p
[2, 1, 0]
. Ej .).Explicación
fuente
Mathematica, 45 bytes
Genera un gráfico y cuenta sus componentes conectados.
fuente
Mathematica,
372827 bytesGracias @alephalpha por guardar 9 bytes y @miles por 1 byte más.
fuente
PermutationCycles[#,Length]&
PermutationCycles
podría tomar un segundo argumento para alterar la cabeza de su salida. También puede usar la notación infija para guardar otro byte#~PermutationCycles~Length&
.#&
es bastante más corto queIdentity
. ;)Python,
776967 bytesfuente
(not p[i-1])
se puede hacer tan0**p[i-1]
Jalea,
12109 bytesGuardado 1 byte gracias a @ Dennis .
Esto usa permutaciones basadas en 1. Funciona aplicando la permutación repetidamente hasta que alcanza una permutación previa mientras mantiene sus valores anteriores. Al realizar un seguimiento de los cambios, creará la órbita para cada valor a lo largo de las columnas de esa tabla. Luego, al encontrar el mínimo o el máximo de cada columna, se puede crear una etiqueta para ese ciclo. Luego deduplica esa lista de etiquetas y obtén su longitud, que será el número de ciclos disjuntos.
Pruébalo aquí
Explicación
fuente
ị³$ÐĿ«/QL
Deberia trabajar.Python, 64 bytes
Este código de golf resulta ser idiomático y legible. Utiliza indexación 0.
Cada valor mira a qué apunta y a qué apunta el valor señalado, y apunta al menor de los dos. Después de suficientes repeticiones, cada elemento apunta al elemento más pequeño de su ciclo. El número de elementos distintos señalados es entonces el número de ciclos.
Es suficiente hacer
n
iteraciones. Alternativamente, podríamos iterar hasta que la lista ya no cambie. Esta estrategia me dio una función recursiva de la misma longitud, 64 bytes:La reducción fue de 65 bytes
Las
set(_)
conversiones pueden acortarse{*_}
en Python 3.5, ahorrando 2 bytes.fuente
Haskell, 111 bytes
Utiliza indexación basada en 0
fuente
1l!i|iIi!!1ll1|
Pyth, 9 bytes
Utiliza índices basados en 0. Pruébalo en línea .
Cómo funciona
fuente
JavaScript (ES6), 49 bytes
Utiliza indexación basada en cero. Explicación:
reduce
se utiliza para invocar la función internag
en cada elemento de la matriz.c
es el recuento de ciclos,e
es el elemento de la matriz,i
es el índice de la matriz. Si el elemento es menor que el índice, entonces es un ciclo potencial: el elemento se usa para indexar en la matriz para encontrar el siguiente elemento en el ciclo de forma recursiva. Si comenzamos o terminamos con el índice original, entonces este es un nuevo ciclo e incrementamos la cuenta del ciclo. Si en algún momento encontramos un valor mayor que el índice, contaremos ese ciclo más adelante.fuente
[2,1,0,3,4,5]
, se bloqueó con este mensaje "Se excedió el tamaño máximo de la pila de llamadas".C, 90 bytes
Llamada
f()
con unaint
matriz mutable , 1 indexación basada. El segundo parámetro es el tamaño de la matriz. La función devuelve el número de ciclos.Pruébalo con ideone .
El algoritmo:
fuente
GAP , 30 bytes
Directamente, el segundo argumento
Cycles
da el conjunto sobre el cual debe actuar la permutación:fuente