Raíz cuadrada de permutación

21

En matemáticas, una permutación σ de orden n es una función biyectiva de los enteros 1 ... n a sí misma. Esta lista:

2 1 4 3

representa la permutación σ tal que σ (1) = 2, σ (2) = 1, σ (3) = 4 y σ (4) = 3.

Una raíz cuadrada de una permutación σ es una permutación que, cuando se aplica a sí misma, da σ . Por ejemplo, 2 1 4 3tiene la raíz cuadrada τ = 3 4 2 1.

k           1 2 3 4
τ(k)        3 4 2 1
τ(τ(k))     2 1 4 3

porque τ ( τ (k)) = σ (k) para todos los 1≤k≤n.

Entrada

Una lista de n > 0 enteros, todos entre 1 y n inclusive, que representan una permutación. La permutación siempre tendrá una raíz cuadrada.

En su lugar, puede usar una lista de 0 ... n-1 siempre que su entrada y salida sean consistentes.

Salida

La raíz cuadrada de la permutación, también como una matriz.

Restricciones

Su algoritmo debe ejecutarse en tiempo polinómico en n . ¡Eso significa que no puedes simplemente recorrer todo n ! permutaciones de orden n .

Se permite cualquier construcción.

Casos de prueba:

Tenga en cuenta que muchas entradas tienen múltiples salidas posibles.

2 1 4 3
3 4 2 1

1
1

3 1 2
2 3 1

8 3 9 1 5 4 10 13 2 12 6 11 7
12 9 2 10 5 7 4 11 3 1 13 8 6

13 7 12 8 10 2 3 11 1 4 5 6 9
9 8 5 2 12 4 11 7 13 6 3 10 1
lirtosiast
fuente
¿Sería correcto decir que para que una permutación tenga una raíz cuadrada, si contiene n ciclos de longitud m, entonces n es par o m es impar?
Neil
@Neil Sí. De lo contrario, la permutación se puede representar como un número impar de intercambios.
jimmy23013
Ah sí, esa es una forma mucho mejor de decirlo.
Neil
1
relacionado
Liam

Respuestas:

4

Perl, 124 122 bytes

Incluye +3 para -alp

Ejecute con la permutación basada en 1 en STDIN:

rootperm.pl <<< "8 3 9 1 5 4 10 13 2 12 6 11 7"

rootperm.pl:

map{//;@{$G[-1]^$_|$0{$_}}{0,@G}=(@G=map{($n+=$s{$_=$F[$_-1]}++)?():$_}(0+$',0+$_)x@F)x2,%s=$n=0for@F}@F;$_="@0{1..@F}"

La complejidad es O (n ^ 3)

Ton Hospel
fuente
¿Por qué la complejidad O (n ^ 3)?
CalculatorFeline
@CatsAreFluffy Porque es un programa estúpido :-). Considera cada par de elementos (incluso si ya se manejó, O (n ^ 2)) y comprime sus ciclos (sin saber cuándo detenerse, O (n)) y luego comprueba si ese sería un ciclo adecuado para una raíz cuadrada . En el programa puedes ver los 3 bucles anidados como 2 mapas y un para
Ton Hospel
Oh. Tiene sentido.
CalculatorFeline
2

Mathematica, 165 167 bytes

Una función sin nombre.

PermutationList[Cycles@Join[Riffle@@@#~(s=Select)~EvenQ@*(l=Length)~SortBy~l~Partition~2,#[[Mod[(#+1)/2Range@#,#,1]&@l@#]]&/@#~s~OddQ@*l]&@@PermutationCycles@#,l@#]&

Semi-no-golfista:

PermutationList[
    Cycles@Join[
        Riffle@@@Partition[SortBy[Select[#,EvenQ@*Length],Length], 2],
        #[[Mod[(Length@#+1)/2Range@Length@#,Length@#,1]]]& /@ Select[#,OddQ@*Length]
    ]& @@ PermutationCycles @ #,
    Max@#
]&
Feersum
fuente
¿Por qué magia funciona esto?
CalculatorFeline
1
@CatsAreFluffy si he entendido correctamente el código semi-no-golfizado, divide la permutación en ciclos, los agrupa por longitud, luego para los impares los eleva a la potencia (longitud + 1) / 2 mientras que para los pares los empareja y los revuelve juntos. (Si los ciclos pares no se pueden emparejar, entonces la partición no tiene raíz cuadrada).
Neil
0

Prolog - 69 caracteres

p([],_,[]). p([H|T],B,[I|U]):-p(T,B,U),nth1(H,B,I). f(X,Y):-p(Y,Y,X).

Explicación:

permutate([], _, []).                 % An empty permutation is empty
permutate([X|Xs], List, [Y|Ys]) :-    % To permutate List
  permutate(Xs, List, Ys),            % Apply the rest of the permutation
  nth1(X, List, Y).                   % Y is the Xth element of List

root(Permutation, Root) :-            % The root of Permutation
  permutate(Root, Root, Permutation). % Applied to itself, is Permutation
AtnNn
fuente
3
Me imagino que esto lleva un tiempo exponencial.
fiesta
Correcto. Tendré que arreglar eso.
AtnNn