Bozosの並べ替え


8

前書き

この課題は、3つの(悪い)ソートアルゴリズムについてです:Bogosort、および私が思いついた2つの他のバリアント(ただし、ある時点で他の人によって考えられていた):(BogoswapAKA Bozosort)およびBogosmart

Bogosort完全にランダムに配列をシャッフルし、それがソートされた(昇順)になったかどうかをチェックすることで機能します。そうでない場合は、繰り返します。

Bogoswap2つの要素をランダムに選択し、それらを交換することで機能します。ソートされるまで(昇順で)繰り返します。

Bogosmart2つの要素をランダムに選択し、配列をソート(昇順)に近づける場合にのみそれらを交換することで機能します。インデックスが低い要素がもともと高い要素よりも大きい場合。ソートされるまで繰り返します。

チャレンジ

この課題では、これら3つのソートアルゴリズムのそれぞれの効率(または欠如)を探ります。ゴルフされたコードは

  1. 1から8までの整数の8要素配列のシャッフルを生成します(これをどのように行うかを確認するために読み続けてください)。

  2. この配列に各アルゴリズムを適用します。そして

  3. 元の配列を表示し、その後に、各アルゴリズムに必要な計算数を1つのスペース(末尾スペースok)で区切って、の形式で表示します<ARRAY> <BOGOSORT> <BOGOSWAP> <BOGOSMART>

プログラムは10個のテストケースを生成します。最初に10個すべてを生成することも、一度に1個ずつ生成することもできます。以下の出力例。

詳細:

の場合Bogosort、配列がシャッフルされた回数を記録する必要があります。

についてはBogoswap、行われたスワップの数を記録する必要があります。

についてはBogosmart、行われたスワップの数を記録する必要があります。

出力例:

87654321 1000000 100 1
37485612 9050000 9000 10
12345678 0 0 0 
28746351 4344 5009 5
18437256 10000 523 25
15438762 10000 223 34
18763524 58924 23524 5
34652817 9283 21 445
78634512 5748 234 13
24567351 577 24 34

私はこれらの数字を作りました。もちろん、プログラムは異なる出力を同じ形式で出力します。

ルール

  • プログラムで使用されるすべてのランダム性は、利用可能な疑似乱数ジェネレーターから取得する必要があります。それ以外の場合は、ユーザーが広範囲に計算することはできません。種を気にする必要はありません。
  • プログラムに時間制限はありません。
  • 配列は昇順でソートされます。
  • 末尾のスペースや余分な改行は大したことではありません。
  • の場合Bogosort、配列は、説明で明示的に指定されている、Fisher-YatesやKnuth Shufflingなどの公平なシャッフルアルゴリズムを使用してシャッフルされます。組み込みのシャッフルメソッドは許可されていません。同じ方法でテスト配列を生成します。
  • 配列をシャッフルまたは交換した後も同じままの場合は、それでもカウントされ、プログラムのカウントに含める必要があります。たとえば、偶然に配列をそれ自体にシャッフルするとシャッフルとしてカウントされ、要素をそれ自体と交換すると、これらの操作のいずれによっても配列が変更されない場合でも、スワップとしてカウントされます。
  • 私の記憶が適切に機能する場合、8つの要素の配列は、3つのアルゴリズムのいずれについても、それほど長くはかかりません。実際、10要素の配列の場合は数回考えてみましたが、実際に試したところ、Bogoswap数千(またはそれ以下)の実際のシャッフルと10秒未満で済みました。
  • コードは実際に配列をソートする必要があり、期待される答えに対して期待される値や数学的計算を与えるだけではありません。
  • これはコードゴルフの挑戦なので、バイト単位で最も短いプログラムが勝ちます。

次に、各ソートアルゴリズムのサンプルステップをいくつか示します。

BOGOSORT
56781234
37485612
28471653
46758123
46758123
12685734
27836451
12345678

BOGOSWAP
56781234
16785234
17685234
12685734
12685743
12685734
12485763
12385764
12385764
12345768
12345678

BOGOSMART
56781234
16785234
12785634
12785364
12785364
12385764
12385674
12345678

この場合、プログラムはを出力56781234 7 10 7し、同じことを10回実行します。並べ替えの実行中に配列を出力する必要はありませんが、各アルゴリズムの動作と計算のカウント方法を理解できるように、上記のサンプル手順を示しました。


2
8つあります!= 8要素の配列に対して40,320の可能なオーダー。私の数学はこれをボゴソートの予想される(平均)数に変換するには十分ではありません。しかし、直感的には、少なくともその数の桁の範囲内である必要があります。私の理論では、bogosortとbogoswapは同じ平均ステップ数を必要とするということです。bogoswapの1つのステップだけが安価なので、時間が短くなります。
Reto Koradi

私はこれを以前にやったことがあり、あなたの考えが現実とどのように異なるか驚くことでしょう。当然のことながら、Bogosortの計算数が最も多く、Bogoswapのほうが計算量が少なく、Bogosmartのほうがはるかに少ないことがわかります。あなたもよく40320.の下、ボゴソートが必要とどのようにいくつかの計算で驚かれることでしょう
Faraz Masroor

要するに、この挑戦​​があなたのコンピュータを台無しにしたり、あなたの記憶を押しつぶしたりすることを期待していません。
Faraz Masroor 2015年

2
関連。(シャッフルとボゴソートの部分について)
Martin Ender

ソートを行わずに、数学的に正しい分布からステップ数を出力できますか?
xnor

回答:


3

Pyth、62 60バイト

VTjd[jkKJ=boO0=ZS8fqZ=KoO0K0fqZ=XJO.CJ2)0fqZ=Xb*>F=NO.Cb2N)0

とても楽しかったです。これが有効かどうかはわかりませんが、おそらくいくつかの未記述の抜け穴を使用しています。

出力例は次のとおりです。

23187456 22604 23251 110
42561378 125642 115505 105
62715843 10448 35799 69
72645183 7554 53439 30
61357428 66265 6568 77
62348571 1997 105762 171
78345162 96931 88866 241
17385246 51703 7880 80
74136582 36925 19875 100
26381475 83126 2432 25

説明:

私のシャッフル機能は組み込み関数を使用していますorder-by。基本的に、リストの各要素に間隔の乱数を割り当て[0-1)、それらを基準にリストを並べ替えます。これは私に公平なランダムシャッフルを与えます。

アウターループ

VT開始時には、次のコードを10回繰り返します。

準備

jkKJ=boO0=ZS8
           S8        create the list [1, 2, 3, 4, 5, 6, 7, 8]
         =Z          and store in Z
      oO0            shuffle
    =b               and store in b
   J                 and store in J
  K                  and store in K (3 copies of the same shuffled array)
jkK                  join K with ""

ボゴソート

fqZ=KoO0K0 
     oO0K            shuffle K
   =K                and store the result in K
f        0           repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

ボゴスワップ

fqZ=XJO.CJ2)0  
       .CJ2          give all possible pairs of elements of J
      O              take a random one
    XJ     )         swap these two elements in J
   =                 and store the result in J
f           0        repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

ボゴスマート

fqZ=Xb*>F=NO.Cb2N)0
            .Cb2     give all possible pairs of elements of b
           O         take a random one
         =N          assign it to N
       >F N          check if N[0] > N[1]
      *         N    multiply the boolean with N
    Xb           )   swap the two (or zero) values in b
   =                 and assign to b
f                 0  repeat ^ until:
 qZ                    Z == b
                     and give the number of repeats

印刷

jd[
  [                  put all 4 values in a list
jd                    join by spaces and print

=JXJO.cJ2)と同じです=XJO.cJ2)-拡張割り当て。同じことが=bXb後でもあてはまる。また、スワップではペアが置換(.C)で選択されることになっていると思われます
isaacg

@isaacgありがとう、修正されました。.cまたは.Cが許可されているかどうかは不明です。たとえば.C[3 1 2)2、ペアは返されません[2, 1]。これは私がアルゴリズムで利用しているプロパティです。
ジャクベ

多分*JJそれから?また、1文字短いので便利です。
isaacg

2

JavaScript(ES6)、319 345

当然のことながら、これはかなり長いです。

ランダムシャッフルの場合、@ core1024へのクレジット(同じchellengeで私のものより優れています)

スニペットの実行をテストする(Firefoxは通常どおりのみ)

// FOR TEST : redefine console
var console = { log: (...p)=>O.innerHTML += p.join(' ')+'\n' }
// END 

// Solution
R=n=>Math.random()*n|0, 
S=a=>(a.map((c,i)=>(a[i]=a[j=R(++i)],a[j]=c)),a), // shuffle
T=f=>{for(a=[...z];a.join('')!=s;)f(a)}, // apply sort 'f'  algorithm until sorted

s='12345678';
for(i=0;i<10;i++)
  z=S([...s]),
  n=l=m=0,
  T(a=>S(a,++n)),
  T(a=>(t=a[k=R(8)],a[k]=a[j=R(8)],a[j]=t,++m)),
  T(a=>(t=a[k=R(8)],u=a[j=R(8)],(t<u?j<k:k<j)&&(a[k]=u,a[j]=t,++l))),
  console.log(z.join(''),n,m,l)
<pre id=O></pre>


「コードスニペットの実行」リンクが機能しません。それが私のブラウザ/システムであるかどうかはわかりませんが、スニペットリンクは過去に機能しました。
Reto Koradi

同じように、コードスニペットは私のブラウザでは機能し
ません

2
@Reto et al EcmaScript 6:Firefoxでのみ実行できます。
edc65
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.