Racine carrée de permutation

21

En mathématiques, une permutation σ d'ordre n est une fonction bijective des entiers 1 ... n à elle-même. Cette liste:

2 1 4 3

représente la permutation σ telle que σ (1) = 2, σ (2) = 1, σ (3) = 4 et σ (4) = 3.

Une racine carrée d'une permutation σ est une permutation qui, appliquée à elle-même, donne σ . Par exemple, 2 1 4 3a la racine carrée τ = 3 4 2 1.

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

car τ ( τ (k)) = σ (k) pour tout 1≤k≤n.

Contribution

Une liste de n > 0 entiers, tous compris entre 1 et n inclus, représentant une permutation. La permutation aura toujours une racine carrée.

Vous pouvez utiliser une liste de 0 ... n-1 à la place tant que vos entrées et sorties sont cohérentes.

Production

Racine carrée de la permutation, également sous forme de tableau.

Restrictions

Votre algorithme doit s'exécuter en temps polynomial en n . Cela signifie que vous ne pouvez pas simplement parcourir tous les n ! permutations d'ordre n .

Tous les builtins sont autorisés.

Cas de test:

Notez que de nombreuses entrées ont plusieurs sorties possibles.

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
la source
Aurais-je raison de dire que pour une permutation d'avoir une racine carrée, alors si elle contient n cycles de longueur m, alors n est pair ou m est impair?
Neil
@Neil Oui. Sinon, la permutation peut être représentée comme un nombre impair de swaps.
jimmy23013
Ah oui, c'est une bien meilleure façon de le dire.
Neil
1
en relation
Liam

Réponses:

4

Perl, 124 122 octets

Comprend +3 pour -alp

Exécutez avec la permutation basée sur 1 sur 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 complexité est O (n ^ 3)

Ton Hospel
la source
Pourquoi la complexité O (n ^ 3)?
CalculatorFeline
@CatsAreFluffy Parce que c'est un programme stupide :-). Il considère chaque paire d'éléments (même s'ils sont déjà manipulés, O (n ^ 2)) et zippe leurs cycles ensemble (ne sachant même pas quand s'arrêter, O (n)) puis vérifie si ce serait un cycle approprié pour une racine carrée . Dans le programme, vous pouvez voir les 3 boucles imbriquées comme 2 cartes et une pour
Ton Hospel
Oh. Logique.
CalculatorFeline
2

Mathematica, 165 167 octets

Une fonction sans nom.

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

Semi-non golfé:

PermutationList[
    Cycles@Join[
        Riffle@@@Partition[SortBy[Select[#,EvenQ@*Length],Length], 2],
        #[[Mod[(Length@#+1)/2Range@Length@#,Length@#,1]]]& /@ Select[#,OddQ@*Length]
    ]& @@ PermutationCycles @ #,
    Max@#
]&
feersum
la source
Par quelle magie cela fonctionne-t-il?
CalculatorFeline
1
@CatsAreFluffy si j'ai bien compris le code semi-non golfé, il divise la permutation en cycles, les regroupe par longueur, puis pour les impairs il les élève à la puissance (longueur + 1) / 2 tandis que pour les pairs il les jumeler et les riffles ensemble. (Si les cycles pairs ne peuvent pas être associés, la partition n'a pas de racine carrée.)
Neil
0

Prolog - 69 caractères

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

Explication:

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
la source
3
J'imagine que cela prend un temps exponentiel.
feersum
Oh, c'est vrai. Je vais devoir arranger ça.
AtnNn