Перестановка квадратного кореня


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

Чи правильно я б сказав, що для перестановки мати квадратний корінь, якщо він містить n циклів довжиною m, то або n парне, або m непарне?
Ніл

@Neil Так. В іншому випадку перестановка може бути представлена ​​як непарна кількість свопів.
jimmy23013

Ага так, це набагато кращий спосіб поставити це.
Ніл

Відповіді:


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 карти та за
Тон Євангелія

Ой. Має сенс.
CalculatorFeline

2

Математика, 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@#]&

Напівгольф:

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

За якою магією це працює?
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

3
Я б міг уявити, що це потребує експоненціального часу.
feersum

Авжеж. Мені доведеться це виправити.
AtnNn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.