順列子を作成する


9

この課題では、リストを入力として受け取り、そのリストの順列を返す関数(関数は完全なプログラムである場合があります)を作成します。関数は次の要件に従う必要があります。

  • それは決定論的でなければなりません。

  • 関数自体を可変回数で構成すると、任意の順列のリストを取得できるはずです。

これはコードゴルフの質問なので、回答はバイト単位でスコアリングされ、バイト数が少ないほど優れています。

さらなるルール

  • あなたは、リストの任意のタイプ、(かかる場合があります[Integer][String][[Integer]]それ限り)を

    • 空でないことができます
    • 少なくとも16の可能な値を持つ個別のオブジェクトを含めることができます。(Haskellは使用できず[()]、関数はであると主張できませんid
    • 重複オブジェクトを含めることができます(セットなし)
  • プログラムや関数を書くことはできますが、標準入出力に準拠する必要があります。


しかしS_n、循環しているのはn<3
Leaky Nun

@LeakyNun、それは対称グループを生成する単一の順列を要求するのではなく、next_permutation関数を要求します。
Peter Taylor

0と1のリストのみを並べ替えるだけで十分でしょうか?
xnor 2017

この制限の要点がよくわかりません。ブール値のリストを許可する場合、2つの異なるアイテムに対してイテラブルを許可しないことの意味は何ですか?
デニス

@デニスあなたは良い点を作ります。ブール値のリストは許可しません。または、16未満の可能な値を持つタイプ。
アドホックガーフハンター2017

回答:


4

CJam(11バイト)

{_e!_@a#(=}

1つの重複する要素を持つ4つの要素のリストの完全なサイクルを示すオンラインデモ

解剖

{      e# Define a block
  _e!  e#   Find all permutations of the input. Note that if there are duplicate
       e#   elements in the input then only distinct permutations are produced.
       e#   Note also that the permutations are always generated in lexicographic
       e#   order, so the order is independent of the input.
  _@a# e#   Find the index of the input in the list
  (=   e#   Decrement and get the corresponding element of the list
       e#   Incrementing would also have worked, but indexing by -1 feels less
       e#   wrong than indexing by the length, and makes this more portable to
       e#   GolfScript if it ever adds a "permutations" built-in
}

2

Mathematica + Combinatorica(組み込みパッケージ)34バイト

パッケージをロードするための19バイトと関数のための15バイト。

<<"Combinatorica`";NextPermutation

使用法:

%@{c, b, a}

組み込みなし、61バイト

Extract[s=Permutations[Sort@#],Mod[s~Position~#+1,Length@s]]&

CombinatoricaはMathematicaに完全に組み込まれることになっていますが、NextPermutation関数は見過ごされていたと思います。



2

C ++、42バイト

#include <algorithm>
std::next_permutation

この正確な操作はC ++に組み込まれています。


2
なぜ後のスペース#include
Yytsi 2017

2

JavaScriptの(ES6)、145の 139 137 134 108バイト

@Neilのおかげで、なんと25バイト節約できました。

入力をアルファベット文字の配列として受け取ります。次の順列を別の配列として返します。

a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,a.concat(a.splice(x+1).sort()))

どうやって?

これは、辞書式順序生成され、各反復で次の4つのステップを処理します。

  1. 最大のインデックスを見つけるXように[X] <[X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. a [Y]> a [X]となるようにXより大きい最大のインデックスYを見つけます

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. スワップの値[X]のものと[Y]

    a[x] = a[y], a[y] = t
  4. a [X + 1]から最後の要素までのシーケンスを辞書式昇順で並べ替えます。

    a.concat(a.splice(x + 1).sort())

例:

歩数

デモ


逆転するのではなく、並べ替えることはできませんか?またv<a[i+1]&&(t=v,x=i)、バイトを節約できると思いますsplice。2つではなくを使用すると、さらに節約できる可能性がありますslice
ニール、

@ニールグッドキャッチ!
Arnauld 2017

私は2マージすることができたと思いますmap112バイトのために、同様秒:a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,t=a.splice(++x).sort(),a.concat(t))
ニール

a.concat(a.splice(++x).sort())うまくいくとは思わなかったと認めなければなりません。それ以外の場合は試してみました...
Neil

@ニールありがとう!更新しました。(私たちが本当に必要としないので4では、より保存されたバイトトンをするCONCAT() )。
Arnauld 2017

1

ゼリー、6バイト

Œ¿’œ?Ṣ

辞書式の降順で順列を循環します。

オンラインでお試しください!

使い方

Œ¿’œ?Ṣ  Main link. Argument: A (array)

Œ¿      Compute the permutation index n of A, i.e., the index of A in the
        lexicographically sorted list of permutations of A.
  ’     Decrement the index by 1, yielding n-1.
     Ṣ  Sort A.
   œ?   Getthe (n-1)-th permutation of sorted A.

1

C、161バイト

実際のO(n)アルゴリズム。

#define S(x,y){t=x;x=y;y=t;}
P(a,n,i,j,t)int*a;{for(i=n;--i&&a[i-1]>a[i];);for(j=n;i&&a[--j]<=a[i-1];);if(i)S(a[i-1],a[j])for(j=0;j++<n-i>>1;)S(a[i+j-1],a[n-j])}

使用例:

int main(int argc, char** argv) {
    int i;
    int a[] = {1, 2, 3, 4};

    for (i = 0; i < 25; ++i) {
        printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
        P(a, 4);
    }

    return 0;
}

1

Python 2、154バイト

x=input()
try:exec'%s=max(k for k in range(%s,len(x))if x[%s-1]<x[k]);'*2%tuple('i1kjii');x[i-1],x[j]=x[j],x[i-1];x[i:]=x[:i-1:-1]
except:x.sort()
print x

オンラインでお試しください!


これは、リストをインプレースで並べ替える関数としては短いと思います。
orlp

私はそれを試しましたが、exec関数にあらゆる種類のエラーを与えました
Dennis

0

ゼリー、10バイト

ṢŒ!Q©i⁸‘ị®

オンラインでお試しください!

並べ替え>すべての順列>入力の検索> 1を追加>「すべての順列」へのインデックス


@PeterTaylor直した。
Leaky Nun

順列のための特定のビルトインがあります(つまり、を実行できますŒ¿‘œ?Ṣ)。同じアルゴリズムなので、盗む気はありませんでした。
Erik the Outgolfer 2017

@EriktheOutgolfer重複を含む入力の場合、少し面倒になる可能性があります。
Nun

うーん...そうだと思いますが、以前はそれで動作するバージョンがありましたが、あなたはこのものを使っているようですQ。あなたはまだゴルフすることができṢŒ!Qµi³‘ịます。
Erik the Outgolfer 2017


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