Bogosortを実装する


29

数独を解くのは難しいですか?でも、ブルートフォースバージョン?これは少し簡単なコーディング演習です。私は願います。:-P

bogosortを実装する最短の関数を作成します。具体的には、関数は次のことを行う必要があります。

  • 入力として配列(またはあなたの言語の同等物)を取る
  • 要素が並べ替えられているかどうかを確認します。もしそうなら、配列を返します
  • そうでない場合は、要素をシャッフルし、再度開始します

最短のエントリーが勝ちです。同点の場合、カスタムコンパレータ(および/または擬似乱数ジェネレータ)をサポートする関数が優先されます。残りの関係は、以前の提出を支持することによって解決されます。


明確化:もちろん、それらを注文する方法がある限り、任意の要素タイプを使用できます。また、シャッフルは均一でなければなりません。この「私はそれをクイックソートしてシャッフルしたと呼ぶ」ビジネスはありません。:-)


要素タイプは何ですか?intまたは文字列?
アレクサンドル

@Alexandru:どちらでも結構です。選んで。
クリスジェスターヤング

カスタムコンパレーターを追加すると、コード長が長くなるため、受賞エントリにはカスタムコンパレーターがありません。ネクタイを破ることは意味をなさないと思います。
アレクサンドル

1
疑似ランダムジェネレーターを使用すると、このアルゴリズムが失敗する可能性があります。たとえば、リストの長さが2000を超える場合、2000があります!prngの内部状態の数を超える可能性のあるリストの状態。
ニブラー

2
はい、ウィキペディアの関連する引用「しかし、擬似乱数ジェネレーターがランダムソースの代わりに使用された場合、これらは長期的な循環動作を示すため、終了しない可能性があります。」
ニブラー

回答:


8

APL(Dyalog)、20

{⍵≡⍵[⍋⍵]:⍵⋄∇⍵[?⍨⍴⍵]}

説明

(右)引数
⍵≡⍵[⍋⍵]ソートがそれ自体に等しいかどうかをチェックします:
:⍵はいの場合、次に戻り
∇⍵[?⍨⍴⍵]ます:そうでない場合、1から⍴⍵(長さ)の配列をランダムな順序で生成し、その順序に従って並べ替え(⍵[...])、それに関数を適用します(


突然この問題を再検討し...

APL(Dyalog)、19

{∧/2≤/⍵:⍵⋄∇⍵[?⍨⍴⍵]}

チェックで配列をソートすることを考えただけで、それは無意味になります(Bogosortに意味があると言っているわけではありません)、より正確な実装はであり∧/2≤/⍵、それは文字数を減らすために起こります。


15

Perl 6:23文字

@s.=pick(*)until[<=] @s

1
これはperlの関数ですか?よさそうだ:)
Eelvex

1
わからない[<=]場合は、リストがソートされているかどうかをチェックします:[<=] (1, 2, 3,) == (1 <= 2 <= 3) == (1 <= 2) and (2 <= 3).pick(n)リストからn個のランダムな要素を選択し、.pick(*)Perlにすべての要素を選択させます。use.perl.org/~masak/journal/40459
明唐

これは私が見たことがないのPerl 6でなければならないpickおろか、前に使用します[<=]。それらはドキュメントのどこにありますか?
ラマ氏

@GigaWattこれはPerl 6(Perl 5ではありません)です。[]角括弧の間に演算子をとるreduce演算子です。たとえば、[<=] 1, 2, 3is 1 <= 2 <= 3(そして、はい、Perl 6ではこのような範囲を行います)。この場合、要素が正しいかどうかを判断するために使用されます。.pick(*)この方法は、リスト(シャッフルpick(N)ピックNリストから要素)。.=メソッドを呼び出し、結果を変数に割り当てます。ドキュメントに関しては-まあ、今のところPerl 6仕様だけが存在します-feather.perl6.nl/synが存在します。
コンラッドボロスキー14年

7

APL(22)

{(⍳X←⍴⍵)≡⍋⍵:⍵⋄∇⍵[X?X]}

使用法:

    {(⍳X←⍴⍵)≡⍋⍵:⍵⋄∇⍵[X?X]} 3 2 1
1 2 3

説明:

  • ⍋⍵:アイテムのインデックスをソート順に返します。したがって⍋30 10 202 1 3
  • (⍳X←⍴⍵)≡⍋⍵:⍵入力リストの長さをXに格納します。範囲[1..X]がソートされたインデックスの順序と等しい場合、リストはソートされるため、それを返します。
  • ⋄∇⍵[X?X]:これが当てはまらない場合は、配列をシャッフルして再帰します。

7

ルビー-33文字

g=->l{l.shuffle!!=l.sort ?redo:l}

1文字少なく:g=proc{|l|0until l.sort==l.shuffle!}
AShelly

@AShelly、あなたのバージョンは動作しません。私のバージョン(5文字以下)f=->l{l.sort!=l.shuffle!?redo:l}(Ruby 1.9)
Hauleth

誰かが私に理由を説明してくださいすることができますredoとの作品procではないとの古典的な方法ではdef...endredoループでのみ動作すると思いましたか?
パトリックオスシティ

1
気にしないで、「Rubyプログラミング言語」の本で何かを見つけました:” redo[…]制御をprocまたはlambdaの先頭に戻します。それは単にその方法です。
パトリックオスシティ


5

J- 34 27

f=:({~?~@#)^:(1-(-:/:~))^:_

例えば:

f 5 4 1 3 2
1 2 3 4 5

f 'hello'
ehllo

?{~~ @#の部分は、入力をシャッフル:

({~ ?~@#) 1 9 8 4
4 8 9 1
({~ ?~@#) 'abcd'
bdca

3

Python 61

所定の位置に並べ替えます。

import random
def f(l):
 while l!=sorted(l):random.shuffle(l)

関数は成功時に配列を返しません。
hallvabo

所定の位置に並べ替えます。渡された配列が変更されます。
アレクサンドル

質問は、関数が結果を取得するために技術的に必要ではない場合でも、配列を返すことになっていると言っています。
ジョナサンMデイビス

1
from random import*文字を保存できます。
ウゴレン

1
これは常に機能するとは限りません:(Pythonのランダムモジュールのドキュメントから):「かなり小さいlen(x)の場合、xの順列の総数はほとんどの乱数ジェネレーターの周期よりも大きいことに注意してください。長いシーケンスは生成できません。」
マット

3

Python 94

from itertools import*
def f(a):return [x for x in permutations(a) if x==tuple(sorted(a))][0]

他のPythonの回答ではrandom.shuffle()を使用します。python randomモジュールの状態のドキュメント:

かなり小さいlen(x)の場合でも、xの順列の総数は、ほとんどの乱数ジェネレーターの周期よりも大きいことに注意してください。これは、長いシーケンスのほとんどの順列を生成できないことを意味します。


代わりにラムダを実行します。短くなると思います。また、あなたが行うことができますのでご注意return[x...と対照的にreturn [x...。と同じpermutations(a) if-可能性がありますpermutations(a)if
0WJYxW9FMN

lambda a: [x for x in __import__("itertools").permutations(a) if x==tuple(sorted(a))][0]88バイト
有名な1622

3

K、31 25

{while[~x~x@<x;x:x@(-#x)?#x];x}

{x@(-#x)?#x}/[{~x~x@<x};]

k){x@(-#x)?#x}/[{~x~x@<x};] 3 9 5 6 7 9 1
`s#1 3 5 6 7 9 9

k){x@(-#x)?#x}/[{~x~x@<x};] "ascsasd"
`s#"aacdsss"

2

Python(69文字)

from random import*
def f(a):
 while a>sorted(a):shuffle(a)
 return a

整数を昇順でソートします。次のような再帰的なソリューションに注意してください

from random import*;f=lambda a:a>sorted(a)and(shuffle(a)or f(a))or a

Pythonは末尾呼び出しの最適化を行わないため、小さな入力(N> 5など)でもスタックオーバーフローが原因で失敗します。


2

カスタムコンパレータなしのD:59文字

R f(R)(R r){while(!isSorted(r))r.randomShuffle();return r;}

より読みやすく:

R f(R)(R r)
{
    while(!r.isSorted)
        r.randomShuffle();

    return r;
}

カスタムコンパレータを使用したD:69文字

R f(alias p,R)(R r){while(!isSorted!p(r))r.randomShuffle();return r;}

より読みやすく:

R f(alias p, R)(R r)
{
    while(!isSorted!p(r))
        r.randomShuffle();

    return r;
}

2

Scala 73:

def s(l:Seq[Int]):Seq[Int]=if(l==l.sorted)l else s(util.Random.shuffle l)

Scalaでは、コンパイラーが末尾呼び出しの最適化を行ったかどうかを確認できます。

@annotation.tailrec
def s(l:Seq[Int]):Seq[Int]=if(l==l.sorted)l else s(util.Random shuffle l)

はい、そうでした。ただし、100個の値の短いリストの場合:

val rList = (1 to 100).map(x=>r.nextInt (500))
s(rList) 

完了するにはほぼ4か月かかりました。;)


2

C#(184文字)

T[]S<T>(T[]i)where T:IComparable<T>{T l=default(T);while(!i.All(e=>{var r=e.CompareTo(l)>=0;l=e;return r;})){i=i.OrderBy(a=>Guid.NewGuid()).ToArray();l=default(T);}return i.ToArray();}

C#でこれを行うのはあまり良くありません。値型と参照型の両方をサポートするには、ジェネリックをサポートする必要があります。配列シャッフル関数または何かがソートされているかどうかをチェックする関数はありません。

これを改善するためのヒントはありますか?

int(134文字)のみをソートするバージョンの編集:

int[]S(int[]i){var l=0;while(!i.All(e=>{var r=e>=l;l=e;return r;})){i=i.OrderBy(a=>Guid.NewGuid()).ToArray();l=0;}return i.ToArray();}

2

GNU / BASH 65

b(){ IFS=$'\n';echo "$*"|sort -C&&echo "$*"||b $(shuf -e "$@");}

うーん、bash関数は文字通り符号なしバイトのみを返すことができるので、配列ルールを返すための特別な例外を取得できますか?
小次郎

2

C ++ 11、150文字

#include<deque>
#include<algorithm>
void B(std::deque &A){while(!std::is_sorted(A.begin(),A.end())std::random_shuffle(myvector.begin(),myvector.end());}

ただ..楽しみのために作られました。


1
std :: random_shuffleは均一ではありません。明確化では、「シャッフルは均一でなければなりません」
-STDQ

わかりました...私はそれが均一ではなかったことを知りませんでした。

均一ではないrand()に依存しています-open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3924.pdfを参照してください。フォローしている人はあまりいないので、大したことではないでしょう。
STDQ

srand(time(0))を使用するような完全にランダムなものを使用する場合、それはカウントされますか?

問題は、randは均一性はもちろんのこと、乱数の品質が良いことを保証されていないことであり、一部はランダムでない低次ビットを生成します。私はそれが最終的には問題ではないと思います。std :: shuffleなどを備えた均一なディストリビュータを使用して、もう8バイトしか得られませんでした。
STDQ

2

Python-61文字

再帰的

from random import*;f=lambda l:l==sorted(l)or shuffle(l)>f(l)

関数は配列ではなくTrueまたはFalseを返します。
hallvabo

2
また、再帰的なソリューションは、小さな入力であっても失敗する運命にあることに注意してください。
hallvabo

1
@hallvabo:実際には、Schemeで末尾再帰ソリューションを書きたいのですが、もちろんスタックを使い果たすことはありません。
クリスジェスターヤング

@ hallvabo、Alexandruはすでに明らかなPythonソリューションを実行していたので、ここで何か違うことをしようとしていました。もちろん、再帰的な解決策は楽しみのためだけであり、深刻な候補ではありません
ニブラー

from random import*短いかもしれません。
0WJYxW9FMN

2

PowerShell85 82 56 55 52バイト

-26バイト、mazzyの提案に
感謝-1バイト、AdmBorkBorkに
感謝-3バイト、mazzyに感謝

for($l=$args;"$l"-ne($l|sort)){$l=$l|sort{random}}$l

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

PowerShellには、文字列にキャストして比較することで、比較的安価な配列比較があります。


2
param初期化を初期化に移動してforバイトを保存しますfor($l=$args;
AdmBorkBork

1
いいね -ne右演算子を左演算子のスカラー型にキャストします。そのため、数バイト節約できます。オンラインで試してみてください!
奇抜な

1

Javascript 291文字

function f(e){var t=[].concat(e).sort();t.e=function(e){var n=true;t.forEach(function(t,r){if(t!=e[r])n=false});return n};while(!t.e(e.sort(function(){return Math.floor(Math.random()*2)?1:-1}))){console.log(e)}return e}

ウンミン

function f(a) {
var b = [].concat(a).sort();
b.e = function (z) {
    var l = true;
    b.forEach(function (v, i) {
        if (v != z[i]) l = false;
    });
    return l
};
while (!b.e(a.sort(function () {
    return Math.floor(Math.random() * 2) ? 1 : -1;
}))) {
    console.log(a);
}
return a;
}

これは前にも言ったような気がしますが、すべて削除できますvar。それらをすべて暗黙のグローバルにするだけで、コードをできるだけ短くするだけです。
-gcampbell

1

Matlab、59バイト

比較的単純なアプローチ:

x=input('');while~issorted(x);x=x(randperm(numel(x)));end;x

1

J、22バイト

$:@({~?~@#)`]@.(-:/:~)

これは、アジェンダを使用した再帰的で暗黙のモナドです。仕組みは次のとおりです。

yリストにしましょう。まず、議題の右側の動詞は-:/:~です。これはLeaky Nunによって丁寧に提供された動詞です。-:入力が/:~モナドフックを使用してソートされているかどうか()に一致します()。((f g) y = y f (g y))これにより、1または0が返されます。議題の左側は2つの動詞の動詞です。右側はアイデンティティ動詞]、左側は再帰が行われる場所です。アジェンダ1、リストソートされている場合は位置のアイデンティティ動詞を選択し、リストソートされていない0場合は位置の長い動詞を選択します。

$:@({~?~@#)on $:の結果に{~?~@#加えて(含まれる最長の動詞)を呼び出しますy。これはリストをシャッフルします。これ?~@#は、の長さの順列を取り、のyインデックスをランダムにソートしたものですy{~、モナドフックでは、yインデックスが正しい引数であるリストを返します。このシャッフルされたリストはアジェンダで再度呼び出され、ソートされるまで繰り返されます。


1

C ++ 14、158バイト

#include <algorithm>
#include <random>
[](int*a,int s){std::random_device r;for(std::knuth_b g(r());!std::is_sorted(a,a+s);std::shuffle(a,a+s,g));return a;};

1

ゼリー、6バイト、言語のポストデートチャレンジ

ẊŒ¿’$¿

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

説明

ẊŒ¿’$¿
     ¿  While
 Œ¿’$     the input is not in its earliest possible permutation (i.e. sorted)
Ẋ       shuffle it

Œ¿リストの各順列に番号を割り当てます。1はソートされ、2は最後の2つの要素が交換されます。リストの長さの階乗(逆順のリスト)まで。したがって、ソートされたリストの場合、これは値1を持ち、whileループ条件でブール値として使用できる「ソートされていない」テストを生成するために、値をデクリメントできます。これ$は、条件をグループとして解析することです。


1

C ++、166バイト

えー

#import<algorithm>
#import<random>
#define r b.begin(),b.end()
template<class v>
v f(v b){auto a=std::mt19937();while(!std::is_sorted(r))std::shuffle(r,a);return b;}

これはbegin()、とを持つすべてのSTLコンテナで機能するはずend()です。

ゴルフをしていない:

#include <algorithm>
#include <random>
template <class v>
v f(v b) {
    auto a = std::mt19937();
    while (!std::is_sorted(b.begin(),b.end()))
        std::shuffle(b.begin(),b.end(),a);

    return b;
}


1

Brachylog、5バイト

∈&ṣ≤₁

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

私が最初にais523のBrachylogの答えを見たとき(彼のジェリーの答えとは対照的に、ユーザー62131も間違っていなかったので)だから、最初はを試しましたṣ≤₁。ランダムに何かを選択しても、1つの出力が非決定的に生成されるだけなので、複数の出力は生成されないため、シャッフル述語をバックトラックすることはできません。最初の試行で。その後、私pṣ≤₁はほとんどの場合うまくいきましたが、有限の長いリストには有限の多くの順列があるため、時々ランダムに失敗しました。長さの短縮を達成するという目標を放棄した後、私は最終的にこれを思いつきました:

         The input
∈        is an element of
         an unused implicit variable,
 &       and the input
  ṣ      shuffled randomly
   ≤₁    which is increasing
         is the output.

(ランダム性の実証)

I / Oにある程度の自由を与えれば、実際には少し短くなる可能性があります...

Brachylog、4バイト

⊆ṣ≤₁

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

出力を有効にするには、入力の並べ替えに加えて、このbogosort述語がランダムな数の重複要素とゼロを追加するため、入力に重複要素が含まれていてはなりません。(仮に、それは何かを追加することができますが、それは何もしません。)通常、私はこれまで正しく機能することから遠く離れた何かに言及することはありませんが、それは挑戦の精神にあると感じます。

⊆        An ordered superset of the input
 ṣ       shuffled randomly
  ≤₁     which is increasing
         is the output.


1

Pyth、11バイト

Wn=Q.SQSQ;Q

これにかなり満足して、おそらくもう少しゴルフすることができます

説明


Wn=Q.SQSQ;Q
W    While
  =Q.SQ    Variable Q (input variable) shuffled 
 n  Does not equal
       SQ    Variable Q sorted
             ;  Do nothing (loop ends)
              Q    And output variable Q

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


あなたは短縮することができます=Q.SQ=.SQ(のような、あまりにも他の事業者と作品の-1バイト=QhQ- > =hQ
ar4093

1

Japt11 9 バイト

_eZñ}a@öx

それを試してみてください

_eZñ}a@öx     :Implicit input of array U
_             :Function taking an array as argument via parameter Z
 e            :  Test Z for equality with
  Zñ          :  Z sorted
    }         :End function
     a        :Repeat and return the first result that returns true
      @       :Run this function each time and pass the result to the first function
       öx     :  Random permutation of U

1

Brachylog(v2)、5バイト

≤₁|ṣ↰

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

関数の提出。(TIOリンクは、関数を完全なプログラムに自動的にラップするコマンドライン引数を使用します。)

説明

≤₁|ṣ↰
≤₁      Assert that {the input} is (nonstrictly) sorted in ascending order
  |     Output it
  |     Exception handler: if an assertion fails:
   ṣ      Randomly shuffle {the input}
    ↰     and run this function recursively on it, {outputting its output}

Prolog(Brachylogがコンパイルする言語)は末尾再帰であるため、この関数は最終的にタイトループにコンパイルされます。


0

C(203文字、入力ループなし:funcのみ)

#include <stdio.h>
#define P (int*a,int n){
#define F for(i=0;i<n;i++){
int i,j,v;s P F if(a[i]>a[i+1])return 0;}return 1;}void h P F v=a[i];a[i]=a[j=rand()%n];a[j]=v;}}void b P while(!s(a,n-1))h(a,n);}

これは次と同じです。ここでは、stdinから配列を読み取り、ソートされた配列を書き出します。Qはプログラム全体ではなく機能を要求したので...

C(296文字)

#include <stdio.h>
#define P (int*a,int n){
#define F for(i=0;i<n;i++){
int i,j,n,v,x[999];s P F if(a[i]>a[i+1])return 0;}return 1;}void h P F j=rand()%n;v=a[i];a[i]=a[j];a[j]=v;}}void b P while(!s(a,n-1))h(a,n);}main(){while(scanf("%d",&v)==1)x[n++]=v;if(!s(x,n))b(x,n);F printf("%d\n",x[i]);}}

コンパイルにより警告が発生する場合があります(暗黙の宣言)。999要素のハードエンコードされた配列サイズ制限。壊れやすい。

配列が並べ替えられているかどうかを事前に確認する必要がない場合は、284で行うことができます。

C(251文字、284でした)

#include <stdio.h>
#define F for(i=0;i<n;i++){
int i,j,n,v,a[999];s(int n){F if(a[i]>a[i+1])return 0;}return 1;}void h(){F v=a[i];a[i]=a[j=rand()%n];a[j]=v;}}void b(){while(!s(n-1))h();}main(){while(scanf("%d",&a[n++])>0);b();F printf("%d\n",a[i]);}}

(関数引数の代わりにグローバルを使用)。

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