順列平方根


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

なぜなら、すべての1≤k≤nに対してττ(k))= σ(k)だからです。

入力

順列を表す、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

順列が平方根を持ち、長さmのnサイクルを含む場合、nは偶数かmが奇数であると言うのは正しいでしょうか?
ニール

@ニールはい。それ以外の場合、順列は奇数のスワップとして表されます。
jimmy23013

ああ、それはそれを置くよりはるかに良い方法です。
ニール

回答:


4

Perl、124 122バイト

+3を含む -alp

STDINで1ベースの順列で実行します。

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)ですか?
電卓

@CatsAreFluffyそれは愚かなプログラムだからです:-)。要素の各ペア(既に処理されている場合でもO(n ^ 2))を考慮し、それらのサイクルを一緒に圧縮し(停止するタイミングを知らない場合でもO(n))、それが平方根の適切なサイクルであるかどうかをチェックします。プログラムでは、3つのネストされたループを2つのマップおよびfor
Ton Hospel

ああ。理にかなっています。
電卓

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@#]&

セミゴルフ:

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

これはどのような魔法で機能しますか?
電卓

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.