Корень перестановки

21

В математике перестановка σ порядка n является биективной функцией от целых чисел 1 ... n до самой себя. Этот список:

2 1 4 3

представляет перестановку σ такую, что σ (1) = 2, σ (2) = 1, σ (3) = 4 и σ (4) = 3.

Квадратный корень перестановки σ - это перестановка, которая при применении к себе дает σ . Например, 2 1 4 3имеет квадратный корень τ = 3 4 2 1.

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

потому что τ ( τ (k)) = σ (k) для всех 1≤k≤n.

вход

Список из n > 0 целых чисел, все от 1 до n включительно, представляющих перестановку. Перестановка всегда будет иметь квадратный корень.

Вместо этого вы можете использовать список 0 ... n-1, если ваши входные и выходные данные согласованы.

Выход

Квадратный корень перестановки, также в виде массива.

ограничения

Ваш алгоритм должен работать за полиномиальное время по n . Это означает, что вы не можете просто пройти через все n ! перестановки порядка n .

Любые встроенные функции разрешены.

Тестовые случаи:

Обратите внимание, что многие входы имеют несколько возможных выходов.

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
источник
Буду ли я прав, говоря, что для перестановки иметь квадратный корень, то если она содержит n циклов длины m, то либо n четно, либо m нечетно?
Нил
@ Нейл Да. В противном случае перестановка может быть представлена ​​как нечетное количество перестановок.
jimmy23013
Ах, да, это гораздо лучший способ выразить это.
Нил
1
связанные
Лиам

Ответы:

4

Perl, 124 122 байта

Включает +3 для -alp

Запустите с 1 перестановкой на основе 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}"

Сложность O (n ^ 3)

Тон Хоспел
источник
Почему сложность O (n ^ 3)?
CalculatorFeline
@CatsAreFluffy Потому что это глупая программа :-). Он рассматривает каждую пару элементов (даже если они уже обработаны, O (n ^ 2)) и объединяет их циклы (даже не зная, когда остановиться, O (n)), а затем проверяет, будет ли это правильный цикл для квадратного корня , В программе вы можете видеть 3 вложенных цикла в виде 2 карт и для
Ton Hospel
Ой. Имеет смысл.
CalculatorFeline
2

Mathematica, 165 167 байт

Безымянная функция.

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

Semi-ungolfed:

PermutationList[
    Cycles@Join[
        Riffle@@@Partition[SortBy[Select[#,EvenQ@*Length],Length], 2],
        #[[Mod[(Length@#+1)/2Range@Length@#,Length@#,1]]]& /@ Select[#,OddQ@*Length]
    ]& @@ PermutationCycles @ #,
    Max@#
]&
feersum
источник
По какой магии это работает?
CalculatorFeline
1
@CatsAreFluffy, если я правильно понял полуэгольфированный код, он разбивает перестановку на циклы, группирует их по длине, затем для нечетных он увеличивает их до степени (длина + 1) / 2, а для четных - объединяет их в пару и смешивает их вместе. (Если четные циклы не могут быть спарены, то раздел не имеет квадратного корня.)
Нейл
0

Пролог - 69 символов

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

Объяснение:

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
источник
3
Я предполагаю, что это занимает экспоненциальное время.
feersum
О верно. Я должен это исправить.
AtnNn