Introducción
¡Las permutaciones lexicográficas de una lista con n elementos pueden numerarse de 0 a n ! - 1. Por ejemplo, los 3! = 6 permutaciones de (1,2,3)
serían (1,2,3)
, (1,3,2)
, (2,1,3)
, (2,3,1)
, (3,1,2)
, (3,2,1)
.
Cuando se aplica una permutación a una lista, sus elementos se ordenan en el mismo orden que los números de la permutación. Por ejemplo, aplicando la permutación (2,3,1)
a los l = (a,b,c)
rendimientos (l[2],l[3],l[1]) = (b,c,a)
.
La inversa de una permutación se define como la permutación que invierte esta operación, es decir, aplicar una permutación y luego su inversa (o viceversa) no modifica la matriz. Por ejemplo, el inverso de (2,3,1)
es (3,1,2)
, ya que aplica eso a los (b,c,a)
rendimientos (a,b,c)
.
Además, la inversa de una permutación aplicada a la permutación misma produce los enteros 1 ... n . Por ejemplo, aplicando (3,1,2)
a (2,3,1)
rendimientos (1,2,3)
.
Ahora definimos la función revind ( x ) como el índice de la permutación inversa de la permutación con el índice x . (Esto es A056019 , si está interesado).
Dado que una permutación con índice i solo modifica los últimos k elementos de la lista iff 0 ≤ i < k !, Podemos agregar cualquier número de elementos al comienzo de la lista sin afectar revind ( i ). Por lo tanto, la longitud de la lista no afecta el resultado.
Desafío
Su tarea es implementar revind ( x ). Escribirás un programa o función completa que tome un solo entero x no negativo como entrada / argumento y produzca / devuelva el resultado como un solo entero no negativo.
La entrada y la salida pueden estar indexadas a 0 o indexadas a 1, pero esto debe ser coherente entre ellas.
Las incorporaciones que generan permutaciones por índice, devuelven el índice de una permutación o encuentran la permutación inversa están prohibidas. (Se permiten las construcciones que generan todas las permutaciones o la próxima permutación).
Aplican reglas estándar de código de golf .
Ejemplos
Los siguientes ejemplos están indexados a 0.
Input Output
0 0
1 1
2 2
3 4
4 3
5 5
6 6
13 10
42 51
100 41
1000 3628
2000 3974
10000 30593
100000 303016
Implementación de referencia (Python 3)
def revind(n):
from math import factorial
from itertools import permutations, count
l = next(filter(lambda x: factorial(x) > n, count(1)))
pms = list(permutations(range(l)))
return [k for k in range(len(pms)) if tuple(pms[n][i] for i in pms[k]) == pms[0]][0]
fuente
(a,b,c)
extremadamente poco claro. Incluya una explicación adecuada de lo que es una permutación inversa.Ụ
(grado superior) que clasifica los índices de una matriz por sus valores correspondientes. Esto sucede para invertir una permutación de 1, ..., n , pero no funciona para otras permutaciones. ¿EstáỤ
prohibido incorporarlo?Respuestas:
Jalea , 6 bytes
I / O usa indexación basada en 1. Muy lento y hambriento de memoria.
Verificación
¡Mientras la entrada no exceda de 8! = 40320 , es suficiente considerar todas las permutaciones de la matriz [1, ..., 8] . Para el último caso de prueba, las permutaciones de [1, ..., 9] son suficientes.
Con un código ligeramente modificado que solo considera las permutaciones de los primeros 8 o 9 enteros positivos, ¡puede probarlo en línea! o verificar todos los casos de prueba restantes .
Cómo funciona
Enfoque alternativo, 6 bytes (no válido)
Es igual de largo y usa el átomo de graduación prohibido
Ụ
, pero es (posiblemente) más idiomático.Al anteponer 8 (o 9 para el último caso de prueba), en realidad podemos probarlo en línea.
Cómo funciona
fuente
Mathematica, 74 bytes
Utiliza 1-indexación. Muy ineficiente (usa ~ 11GB de memoria cuando la entrada es
11
)Explicación
Genere una lista del 1 al N. Almacénelo en
j
.Encuentra todas las permutaciones de
j
. Almacene eso eni
.Almacene la
Position
función enk
. (para reducir el conteo de bytes cuando se usaPosition
nuevamente)Encuentre la permutación inversa de la enésima permutación.
Encuentre el
k
(Position
) de la permutación inversa eni
(todas las permutaciones)Usando incorporados,
4643 bytes1 indexado.
fuente
MATL , 15 bytes
La entrada y la salida están basadas en 1.
Similar a la respuesta CJam de @ MartinEnder , pero encuentra la permutación inversa al componer todas las permutaciones posibles con la especificada por la entrada, y ver cuál se ha convertido en la permutación de identidad.
Se queda sin memoria en el compilador en línea para entrada
10
.Pruébalo en línea!
Explicación
fuente
Pyth, 12 bytes
Banco de pruebas
0 indexado.
Explicación:
fuente
05AB1E ,
1413 bytesMuy memoria ineficiente.Ahora aún más memoria ineficiente (pero 1 byte más corto).Rango basado en 0.
Utiliza la codificación CP-1252 .
Pruébalo en línea! o como un conjunto de pruebas modificado
Explicación
fuente
CJam , 16 bytes
Los índices están basados en 0.
Pruébalo en línea!
No soy mucho más ineficiente que esto ... se queda sin memoria con la configuración predeterminada de Java para entradas mayores que
8
(pero funciona en principio para entradas arbitrarias dado un número suficiente de universos de tiempo y memoria).Explicación
fuente
GAP , 108 bytes
1 indexado. Las nuevas líneas no cuentan, no son necesarias. Realmente no tengo que asignar la función final a un nombre, pero ...
h
es una función curry que toma una lista de permutaciones y un índice en esa lista y devuelve el índice de la permutación inversa. Sin restricciones, solo lo haríaPosition(l,l[n]^-1)
.f
llama a esa función con las permutaciones ordenadas de un grupo simétrico lo suficientemente grande y el dadon
.Podría escribir
SymmetricGroup(n)
, luego la función podría calcularse para valores de hasta 9. Como ya existen soluciones mucho más pequeñas, prefiero poder hacer esto:¡Una solución indexada 0 realmente eficiente que funciona para argumentos por debajo de 99! (y se puede hacer que funcione para argumentos por debajo de 999! a costa de un byte) es este:
Después de eliminar espacios en blanco, esto tiene 255 bytes.
fuente
JavaScript (ES6),
163120110 bytes0 indexado. Funciona convirtiendo el índice en una permutación, invirtiéndolo y luego volviendo a convertirlo en un índice. Editar: ahorró alrededor del 25% al
f
invertir y revertir la permutación, luegog
convertir la permutación revertida a un índice. Ahorró otros 10 bytes combinando las dos llamadas recursivas en una sola función. Sin golf:fuente
f
invertir la permutación en lugar deg
...J
5550 bytesBasado en el ensayo J sobre el índice de permutación .
Este código solo requiere memoria en el orden de
n
pero usa más tiempo ya que clasifica losn
tiempos de la lista y lo buscan
cada índice.Usando el incorporado
/:
que es capaz de encontrar el grado de una lista y el inverso de una permutación, hay una solución de 42 bytes que es más eficiente.Esta versión solo requiere 44 segundos para calcular el último caso de prueba en comparación con la otra que requiere 105 segundos.
Uso
fuente
Gelatina ,
14 139 bytes-4 bytes gracias a @Dennis (que jugó más usando el rápido
⁺
en su respuesta )Otra implementación muy lenta.
La indexación basada en 1 se utiliza aquí, por lo que los resultados esperados son:
No tiene sentido incluso poner un enlace IDE en línea, ya que TIO mata a una entrada de
10
. Resultados locales (¡el último es muy lento y requiere una tonelada de memoria!):¿Cómo?
Nota: no es necesario ordenar las permutaciones ya que estamos usando el mismo orden para encontrar la permutación y es inversa.
fuente
ÇịịÇ$iR
?R
antesŒ!
está implícito, por lo queŒ!ịịŒ!$iR
debería hacer el trabajo.Python 2,
116114 bytesrepl.it
Basado en 0. Lento y memoria hambriento pero corto en bytes.
No usar funciones de permutación; Memoria y tiempo eficiente.
289285 bytes-4 bytes gracias a @Christian Sievers (permutación completa ya formada)
Sé que es código de golf, pero creo que @ Pietu1998 también está interesado en implementaciones eficientes.
Véalo en acción en repl.it
Si bien esto usa más bytes que la implementación de referencia en comparación para
n=5000000
:f
es la función de índice inverso.f
primero obtiene el siguiente factorial anteriorn
,t
y el entero cuyo factorial es,x
al llamarh(n)
y estableceg=range(x)
, los elementos que formarán la permutacióno=g[:]
, y el titular de la permutación,r=[]
A continuación se construye la permutación en el índice
n
por elpop
ing los índices de la base de la representación factorial den
a su vez de los artículos,o
y añadiéndolos ar
. La representación base factorial se encuentra por div y mod den
cont
dondet
se divide porx
yx
disminuye hasta1
.Finalmente encuentra el índice de la permutación inversa llamando
i
con la permutación inversa,[r.index(v)for v in g]
h
es una función de doble propósito para calcular un factorial de un entero no negativo o calcular tanto el siguiente factorial sobre un entero no negativo como el entero que hace ese factorial.En su estado predeterminado
v=1
y lo hace multiplicandov
porx
(también inicialmente1
) e incrementandox
hasta quen
sea al menos tan grande, luego devuelvev
yx-1
una tupla.Para calcular
n!
una llamadah(n,0)
que se multiplicax
(inicialmente1
) porn
y disminuyen
hasta quen
es0
cuando regresax
.i
proporciona el índice lexicográfico de una permutación,p
, de los artículos[0,1,...n]
mediante la suma de los productos de la factorial de la base factorial de cada índice,h(len(p)-j-1,0)
y el número de elementos a la derecha del índice es menor que el valor de ese índice,sum(k<p[j]for k in p[j+1:])
.fuente
t/=x
.(r+o)
porr
.Python 2,
130129 bytesfuente
En realidad ,
1811 bytesEsta respuesta usa el algoritmo en la respuesta de Dennis 'Jelly pero está indexada en 0. Sugerencias de golf bienvenidas! Pruébalo en línea!
No golfista
fuente