これをすばやく並べ替えます!


27

まあ... がタグ付けされた59(現在60)の質問がありますが、簡単なクイックソートはありません。

修正する必要があります。

クイックソートに不慣れな方のために、Wikipedia-

  1. 配列から、ピボットと呼ばれる要素を選択します。
  2. ピボットより小さい値を持つすべての要素がピボットの前に来るように配列を並べ替え、ピボットより大きい値を持つすべての要素がその後に来るようにします(等しい値はどちらの方向にも進むことができます)。この分割後、ピボットは最終位置になります。これは、パーティション操作と呼ばれます。
  3. 上記の手順を、値の小さい要素のサブ配列に、値の大きい要素のサブ配列に個別に再帰的に適用します。

ルール

ルールは簡単です:

  • 選択したプログラミング言語で数値クイックソートを実装します。
  • ピボットは、ランダムに選択する、中央値3(1番目、最後、および中間要素)で選択する必要があります。
  • プログラムは、完全なプログラムまたは機能になります。
  • STDIN、コマンドライン引数、または関数パラメーターを使用して入力を取得できます。文字列入力を使用する場合、入力はスペースで区切られます。
  • 入力には、10進数と負の値が含まれる場合があります。ただし、重複はありません。
  • STDOUTに出力するか、関数から戻ることができます。
  • 組み込みのソート(またはソート関連)機能や標準の抜け穴はありません。
  • リストの長さは任意です。

ボーナス1:長さ<= 5のリストまたはサブリストでは、挿入ソートを使用して少し速度を上げます。報酬:-15%。

ボーナス#2:言語が並行性をサポートしている場合、リストを並列に並べ替えます。サブリストで挿入ソートを使用している場合、最終的な挿入ソートは並列である必要はありません。組み込みのスレッドプール/スレッドスケジューリングが許可されます。報酬:-15%。

注:3人の中央値は一部の人々を混乱させていたので、ここに説明があります(再度)ウィキペディア:

ピボットのパーティションの最初、中央、最後の要素の中央値を選択する

得点

これはです。基本スコアはバイト単位です。ボーナスを1つ獲得した場合は、その数を15%引きます。両方入手した場合は、30%オフにしてください。それは本当に売り込みのように聞こえます。

これは、全体の最短回答を見つけることではなく、各言語で最短の回答を見つけることです。

そして今、リーダーボードスニペットの恥知らずなコピー。

リーダーボード

この投稿の下部にあるスタックスニペットは、a)言語ごとの最短ソリューションのリストとして、b)全体的なリーダーボードとして、回答からカタログを生成します。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

## Language Name, N bytes

Nは提出のサイズです。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

## Ruby, <s>104</s> <s>101</s> 96 bytes

ヘッダーに複数の数字を含める場合(たとえば、スコアが2つのファイルの合計であるか、インタープリターフラグペナルティーを個別にリストする場合)、実際のスコアがヘッダーの最後の数字であることを確認します。

## Perl, 43 + 2 (-p flag) = 45 bytes

言語名をリンクにして、スニペットに表示することもできます。

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


4
「ピボットは、ランダムに選択するか、中央値3(1番目、最後、および中央の要素)で選択する必要があります。」これは何を意味するのでしょうか?以前に選択した要素は1つだけだと言っていました。
msh210

2
@danieroスニペットが修正されました
ダニエルM.

1
中央値選択アルゴリズムは厳しい要件ですか?リンクリストをプライマリ配列タイプ(Haskell、LISP)として使用する言語では非現実的であり(パフォーマンスが低下するなど)、ルールを無視する回答が少なくとも1つ既にあります。
ジョンドヴォルザーク

2
リストベースの言語では、ランダムピボットと3の中央値の両方に問題があります。どちらも配列へのランダムアクセスを必要とし、リンクリストの最後へのアクセスはO(n)です。最初の3つの要素の中央値を取得することは、同じ種類の仕事をまったく行いません(とにかく3つの分割内で同じピボットを取得するため)、正当な理由もなくコードを複雑にします。
ジョン・ドヴォルザーク

1
Haskellでは、ランダムピボットにも問題があります。サイコロを転がし始めると、関数を記述しなくなります。配列を生成するI / Oアクションを定義しています。引数としてRNG状態をとる関数を定義できますが、それも大きすぎません。
ジョンドヴォルザーク

回答:


10

C ++、440.3 405 388バイト

518バイト-挿入ソートの15%ボーナス= 440.3バイト

477バイト-挿入ソートの15%のボーナス= 405.45バイト

474バイト-挿入ソートの15%ボーナス= 402.9バイト

456 bytes - 15% bonus for insertion sort = 387.6 bytes

3バイト(本当に2バイト)を節約してくれた@Lukeに感謝します。

18(本当に15)バイトを節約してくれた@Dúthomhasに感謝します。

私はここに新しく、これが私の最初の投稿であることに注意してください。

これは.h(ヘッダー)ファイルです。

圧縮コード:

#include<iostream>
#include<ctime>
#include<cstdlib>
void s(int a[],int i,int j){int t=a[i];a[i]=a[j];a[j]=t;}int z(int a[],int b,int e){int p=a[(rand()%(e-b+1))+b];b--;while(b<e){do{b++;}while(a[b]<p);do{e--;}while(a[e]>p);if(b<e){s(a, b, e)}}return b;}void q(int a[],int b,int e){if(e-b<=5){for(int i=b;i<e;i++){for(int j=i;j>0;j--){if(a[j]<a[j-1]){s(a,j,j-1);}else{break;}}}return;}int x=z(a,b,e);q(a,b,x);q(a,x,e);}void q(int a[],int l){q(a,0,l);}

完全なコード:

#include <iostream>
#include <ctime>
#include <cstdlib>

void swapElements(int toSort[], int i, int j) {
    int temp = toSort[i];
    toSort[i] = toSort[j];
    toSort[j] = temp;
}

int partitionElements(int toSort[], int beginPtr, int endPtr)
{
    int pivot = toSort[(rand() % endPtr - beginPtr + 1) + beginPtr];
    beginPtr--;
    while (beginPtr < endPtr) {
        do {
            beginPtr++;
        } while (toSort[beginPtr] < pivot);
        do {
            endPtr--;
        } while (toSort[endPtr] > pivot);
        if (beginPtr < endPtr) {
            // Make sure they haven't crossed yet
            swapElements(toSort, beginPtr, endPtr);
        }
    }
    return beginPtr;
}

void quickSort(int toSort[], int beginPtr, int endPtr)
{
    if (endPtr - beginPtr <= 5) { // Less than 5: insertion sort
        for (int i = beginPtr; i < endPtr; i++) {
            for (int j = i; j > 0; j--) {
                if (toSort[j] < toSort[j - 1]) {
                    swapElements(toSort, j, j - 1);
                } else {
                    break;
                }
            }
        }
        return;
    }
    int splitIndex = partitionElements(toSort, beginPtr, endPtr);
    quickSort(toSort, beginPtr, splitIndex );
    quickSort(toSort, splitIndex, endPtr);
}

void quickSort(int toSort[], int length)
{
    quickSort(toSort, 0, length);
}

5
quickSortの代わりに1文字の名前を使用し、最後の関数呼び出しでスペースを削除して、10バイトを保存できます。そして、ボーナスを避けてより良いスコアを得ることができると
確信して

1
引数の角括弧を単一のアスタリスクに置き換えることにより、さらに5バイト節約できます。いくつかのマクロマジックは、さらにいくつかのバイトを削ることができると思います。
cadaniluk

2
後にスペースは必要ありません#include
ルーク

への呼び出しを削除して34バイトを取り除きsrand(time(NULL));ますrand()。から擬似乱数を取得できます。
Dúthomhas

9

APL、49 42バイト

{1≥⍴⍵:⍵⋄(∇⍵/⍨⍵<p),(⍵/⍨⍵=p),∇⍵/⍨⍵>p←⍵[?⍴⍵]}

これにより、右側の配列を受け入れる名前のない再帰的な単項関数が作成されます。ボーナスの対象にはなりません。

説明:

{1≥⍴⍵:⍵⋄                                     ⍝ If length(⍵) ≤ 1, return ⍵
                                  p←⍵[?⍴⍵]}  ⍝ Choose a random pivot
                           ∇⍵/⍨⍵>            ⍝ Recurse on >p
                  (⍵/⍨⍵=p),                  ⍝ Concatenate with =p
        (∇⍵/⍨⍵<p),                           ⍝ Recurse on <p

オンラインで試す

マリヌスのおかげで(8バイトのコストで)問題を修正し、トーマス・クワのおかげで7バイト節約しました!


質問は、重複がないことを指定します。(それを見るのにどのくらい時間がかかったのかわからない...)
リトシアスト

5

C ++ 17、254の 199 195バイト

#include<vector>
#include<cstdlib>
#define P push_back(y)
using V=std::vector<int>;V q(V a){int p=a.size();if(p<2)return a;p=rand()%p;V l,r;for(y:a)(y<a[p]?l:r).P;l=q(l);for(y:q(r))l.P;return l;}

空白あり:

V q(V a) {
    int p = a.size();

    if (p < 2)
        return a;

    p = rand() % p;
    V l,r;

    for (y : a)
        (y < a[p] ? l : r).P;

    l=q(l);

    for (y : q(r))
        l.P;

    return l;
}

srand(time(NULL))は不要です。消去の必要はありません。値を分割し、「if(a.empty())」を「if(a.size()<2)」に変更し、「lP(x)」を削除します。
クリスジェファーソン

消去を削除すると、大量のバイトを節約できました。ありがとうございました!
リン

もう1つの小さなもの:「r = q(r)」を割り当てる必要はなく、「for(y:q(r))」を使用しますが、それだけです!
クリスジェファーソン

好奇心から:ここで特にC ++ 17はどこで使用されますか?
kirbyfan64sos

1
for (y : a)そうでなければ、for (auto y : a)またはである必要がありますfor (int y : a)。(実際にclang++は、これをC ++ 1z拡張機能と呼びますが、実際にはC ++ 17のようには見えませんか?知りませんし、夜中に調べても遅すぎます。)
Lynn

4

Pyth、25バイト

L?tbsyMa_,]JObf<TJbf>TJbb

これは、y入力として数値のリストを受け取る関数を定義します。

オンラインで試す:デモンストレーション

説明

L?tbsyMa_,]JObf<TJbf>TJbb
L                          define function y(b), that returns: 
 ?tb                         if t[1:] (if the list has more than one element):
            Ob                 choose a random element of b
           J                   save it in J
          ]                    put J in a list
         ,    f<TJb            create a pair, that contains ^ and a list of 
                               all numbers smaller than J: [[J], [smaller than J]] 
        _                      reverse this list: [[smaller than J], [J]]
       a           f>TJb       append a list with all elements bigger than J: 
                               [[smaller than J], [J], [bigger than J]]
     yM                        call y recursively for each sublist
    s                          combine the results and return it
                        b    else: simply return b

Pyth、21バイト(おそらく無効)

内部的にソートを使用する「グループ化」メソッドを使用します。元のリストを3つのサブリストに分割するために使用します(すべての要素がピボットより小さい、ピボット、およびすべての要素がピボットより大きい)。「group-by」でのソートなしでは、これら3つのリストを異なる順序で返す可能性があります。

前述のように、これはおそらく無効です。それにもかかわらず、私はここでそれを維持します。なぜなら、それは興味深い解決策だからです。

L?tb&]JObsyM.g._-kJbb

オンラインで試す:デモンストレーション

説明

L?tb&]JObsyM.g._-kJbb
L                      def y(b): return
 ?tb                     if t[1:] (if the list has more than one element):
       Ob                  choose a random element of b
      J                    save it in J
    &]                     put it in an array and call "and" 
                           (hack which allows to call 2 functions in one statement)

            .g     b       group the elements in b by:
              ._-kJ           the sign of (k - J)
                           this generates three lists
                             - all the elements smaller than J
                             - J
                             - all the elements bigger than J
          yM               call y recursively for all three lists
         s                 and combine them
                    b    else: return b

3

> <>(魚)、313 309バイト

!;00l[l2-[b1.
>:0)?v~$:@&vl2,$:&${:}$
^-1@{< ]]. >055[3[5b.
?v~~@~ v:}@:}@:}:}@:}@}}}(}(}({{:@=
.>=$~?$>~]]
.001-}}d6.{$}1+}d6
?v:{:}@{(?v08.}:01-=
 >{$~~{09.>95.v-1@{<   v-1}$<
.:@}:@{=${::&@>:0)?^~}&>:0)?^~+}d6
 1-:0a.{{$&l&1+-: >:0)?v~:1)?!v62fb.
>:0)?v~:}:1)?v~69.^@{-1<>.!]]~<
^@{-1<:}@@73.>69@@:3+[{[b1.

これは私が書くのに非常に長い時間がかかりました。ここ試すことができます。プログラムを実行する前に、コンマで区切られた初期スタックにソートする必要のあるリストを置くだけです。

使い方

プログラムは、初期スタックの最初、中間、および最後の要素を取得し、これら3つの中央値を計算します。
次に、スタックを次のように変更します。

[リスト1]要素[リスト2]

リスト1のすべてが要素以下で、リスト2のすべてがより大きい場合。
リスト全体がソートされるまで、リスト1とリスト2でこのプロセスを再帰的に繰り返します。


2

CJam、40バイト

{_1>{_mR:P-PaL@{_P<{+}{@\+\}?}/J\J+}&}:J

これは、スタック上の配列を予期し、その配列をプッシュで返す名前付き関数です。

CJamインタープリターでオンラインで試してください。

上記のコードは、可能な限り仕様に準拠しています。必要ない場合は、12バイトを保存できます。

{_1>{_mR:P;_{P<},J_@^J+}&}:J

2

Pythonの3、123、122。

アーロンのおかげで1バイト節約されました。

ソートアルゴリズムを実際に作成するのに苦労したのはこれが初めてです。実際、思っていたよりも少し簡単です。

from random import*
def q(s):
 if len(s)<2:return s
 p=choice(s);return q([d for d in s if d<=p])+q([d for d in s if d>p])

ゴルフをしていない:

from random import choice
def quick_sort(seq):
    if len(seq) < 2:
        return seq
    low = []
    high = []
    pivot = choice(seq)
    for digit in seq:
        if digit > pivot:
            high += [digit]
        else:
            low += [digit]
    return quick_sort(low) + quick_sort(high)

これは、<=比較のために機能しない可能性があります- p適切な場所にあることを保証するものではなく、おそらくそれを排他的な不等式に変更pし、中間を独立して追加する必要があります(私はテストしていない/できるコードをテストしないでください)。
VisualMelon

@VisualMelon私はそれをさまざまなケースでテストしましたが、間違った結果は得られませんでしたが、それを破るテストケースを見つけることができたら、私に知らせてください。また、重複では機能しない可能性がありますが、課題では重複がないことを指定しています。
モーガンスラップ

[2, 1, 3]ピボットを2に選択すると、低いリストになりますので、1/3の時間でそれが壊れると思っていたでしょう。[2, 1]申し訳ありませんが、今は自分でテストできません。
VisualMelon

@VisualMelonさて、確かに、しかしそれは再帰的に再びソートされます。
モーガントラップ

ああ、申し訳ありませんが、
Quicksort

2

Javascript(ES2015)、112

q=l=>{let p=l[(Math.random()*l.length)|0];return l.length<2?l:q(l.filter(x=>x<=p)).concat(q(l.filter(x=>x>p)));}

説明

//Define lambda function q for quicksort
q=l=>{

    //Evaluate the pivot
    let p=l[(Math.random()*l.length)|0];

    //return the list if the length is less than 2
    return l.length < 2 ? l:

    //else return the sorted list of the elements less or equal than 
      the pivot concatenated with the sorted list of the elements 
      greater than the pivot
    q(l.filter(x=>x<=p)).concat(q(l.filter(x=>x>p)));
}

ES6はおそらくこれを短縮できます。
ニッサ

1

ルビー、 87 60バイト

q=->a,p=a.sample{a[1]?(l,r=a.partition{|e|e<p};q[l]+q[r]):a}

ゴルフをしていない:

def quicksort(a, pivot=a.sample)
  if a.size > 1
    l,r = a.partition { |e| e < pivot}
    quicksort(l) + quicksort(r)
  else
    a
  end
end

テスト:

q[[9, 18, 8, 5, 13, 20, 7, 14, 16, 15, 10, 11, 2, 4, 3, 1, 12, 17, 6, 19]]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

1

オクターブ、76 75バイト

function u=q(u)n=numel(u);if n>1 k=u(randi(n));u=[q(u(u<k)),q(u(u>=k))];end

複数行バージョン:

function u=q(u) 
   n=numel(u);
   if n>1 
      k=u(randi(n));
      u=[q(u(u<k)),q(u(u>=k))];
   end

1

ジュリア、83バイト

Q(x)=endof(x)<2?x:(p=rand(x);[Q((f=filter)(i->i<p,x));f(i->i==p,x);Q(f(i->i>p,x))])

これにより、Q配列を受け入れて配列を返す再帰関数が作成されます。条件付きで挿入ソートを使用しないため、ボーナスは適用されません。

ゴルフをしていない:

function Q(x::AbstractArray)
    if endof(x)  1
        # Return on empty or 1-element arrays
        x
    else
        # Select a random pivot
        p = rand(x)

        # Return the function applied to the elements less than
        # the pivot concatenated with those equal to the pivot
        # and the function applied to those greater than the pivot
        [Q(filter(i -> i < p, x));
         filter(i -> i == p, x);
         Q(filter(i -> i > p, x))]
    end
end

問題を修正し、Glen Oのおかげで数バイト節約しました!


繰り返し要素(コード内に既に存在する)が失われる可能性のある問題は別として、fを初めて使用するときに割り当て、の代わりにを使用することでfilter、ここで数バイトを節約できます。endoflengthQ(x)=endof(x)<2?x:(p=rand(x);[Q((f=filter)(i->i<p,x));p;Q(f(i->i>p,x))])
グレンO

@GlenO提案をありがとう。私はそれを実装し、繰り返される要素の問題を修正しました。
アレックスA.

私はそれが問題になる可能性があると言いましたが、質問のポスターに説明を求め、「入力には10進数と負の値が含まれる場合があります。ただし、重複はありません」
グレンO

1

R、78バイト

Q=function(x)if(length(x)>1)c(Q(x[x<(p=sample(x,1))]),x[x==p],Q(x[x>p]))else x

これにより、Qベクトルを受け入れてベクトルを返す再帰関数が作成されます。条件付きで挿入ソートを適用しないため、ボーナスはありません。

ゴルフをしていない:

Q <- function(x) {
    # Check length
    if (length(x) > 1) {
        # Select a random pivot
        p <- sample(x, 1)

        # Recurse on the subarrays consisting of
        # elements greater than and less than p,
        # concatenate with those equal to p
        c(Q(x[x < p]), x[x == p], Q(x[x > p]))
    } else {
        x
    }
}

オンラインで試す

flodelのおかげで4バイト節約されました!


長さの比較から「> 1」を削除することにより、数バイトを削ることができます。これは暗黙的に0と比較しますが、再帰の余分な層は問題ではありません
-Miff

@Miffご意見をお寄せいただきありがとうございますが、私はそれを試してみましたが、期待した結果が得られません。
アレックスA.

1

K、41バイト

s:{$[#x;(s@x@&x<p),p,s@x@&x>p:x@*1?#x;x]}

APL !!! ボーナスは何もしません。


1

ハスケル、 137136バイト

f=filter
m a b c=max(min a b)(min(max a b)c)
q[]=[]
q l=let{n=m(head l)(head$drop(length l`div`2)l)(last l)}in(q$f(<n)l)++(n:(q$f(>n)l))

以下に、拡張されていない変数名と関数名、およびいくつかの中間結果が追加されたバージョンがあります。

median a b c = max (min a b) (min (max a b) c)
quicksort [] = []
quicksort l = let mid = median (head l) (middle l) (last l)
                  lesser = filter (< mid) l
                  greater = filter (> mid) l
                  middle l = head $ drop (length l `div` 2) l
              in (quicksort lesser) ++ (mid : (quicksort greater))

2つの厳密な比較を使用するための重複がないという事実を利用しています。Data.List.partitionただし、importステートメントを追加する必要があることを考慮しても、物事が短くならないかどうかを確認する必要があります。Data.List.insertソート関連の機能と見なされるため、挿入ソートボーナスを取得していません。したがって禁止されています。使用しない場合、挿入ソートを追加するとコードが246バイト、ボーナスで209.1にプッシュされるため、価値がありません。

編集:使用するエイリアスを作成する提案をRobAuに感謝しますf=filter。1バイトしか保存できませんが、すべてが役立ちます。


1
f=filterいくつかのバイトを削る可能性があります。
-RobAu

たぶん、あなたは、2つの冗長処理するための関数を作ることによって、いくつかのバイトを剃ることができますq$f(>n)lし、q$f(<n)l電話を?
チョイス

1

Tcl、138バイト

proc q v {if {$v eq {}} return
lassign {} a b
foreach x [lassign $v p] {if {$x<$p} {lappend a $x} {lappend b $x}}
concat [q $a] $p [q $b]}

これは非常に標準的なクイックソートです。

ピボットは単に各サブアレイの最初の要素です(これは乱数であると私は主張します。https://xkcd.com/221/

メモリの使用量の点では特に効率的ではありませんtailcallが、2回目の再帰とn <1要素の基本ケースでいくらか改善できます。

読みやすいバージョンは次のとおりです。

proc quicksort xs {
  if {![llength $xs]} return
  set lhs [list]
  set rhs [list]
  foreach x [lassign $xs pivot] {
    if {$x < $pivot} \
      then {lappend lhs $x} \
      else {lappend rhs $x}
  }
  concat [quicksort $lhs] $pivot [quicksort $rhs]
}

すべての入力で機能し、重複を許可します。ああ、それも安定しています。次のような単純なものでテストできます。

while 1 {
  puts -nonewline {xs? }
  flush stdout
  gets stdin xs
  if {$xs eq {}} exit
  puts [q $xs]    ;# or [quicksort $xs]
  puts {}
}

楽しい!:O)


あなたは交換バイト保存することができますforeachlmap
sergiol

1

JavaScript(ES6)、191

Q=(a,l=0,h=a.length-1)=>l<h&&(p=((a,i,j,p=a[i+(0|Math.random()*(j-i))])=>{for(--i,++j;;[a[i],a[j]]=[a[j],a[i]]){while(a[--j]>p);while(a[++i]<p);if(i>=j)return j}})(a,l,h),Q(a,l,p),Q(a,p+1,h))

// More readable
U=(a,l=0,h=a.length-1)=>l<h && 
  (p=( // start of partition function
    (a,i,j,p=a[i+(0|Math.random()*(j-i))])=>
    {
      for(--i,++j;;[a[i],a[j]]=[a[j],a[i]])
      {
        while(a[--j]>p);
        while(a[++i]<p);
        if(i>=j)return j
      }
    } // end of partition function
  )(a,l,h),U(a,l,p),U(a,p+1,h))

// This is the shortest insertion sort that I could code, it's 72 bytes
// The bonus is worth  ~30 bytes - so no bonus
I=a=>{for(i=0;++i<a.length;a[j]=x)for(x=a[j=i];j&&a[j-1]>x;)a[j]=a[--j]}


// TEST
z=Array(10000).fill().map(_=>Math.random()*10000|0)

Q(z)

O.innerHTML=z.join(' ')
<div id=O></div>


1

セイロン(JVMのみ)、183 170

ボーナスは適用されません。

import ceylon.math.float{r=random}{Float*}q({Float*}l)=>if(exists p=l.getFromFirst((r()*l.size).integer))then q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))}else[];

Ceylonで乱数を生成するクロスプラットフォームの方法はないようですので、これはJVM専用です。(最後に、JSでも動作する、ランダムではないバージョンがあります。

これは、floatの反復可能要素を取り、そのソートされたバージョンを返す関数を定義します。

import ceylon.math.float {
    r=random
}

{Float*} q({Float*} l) {
    if (exists p = l.getFromFirst((r() * l.size).integer)) {
        return q(l.filter((e) => e < p)).chain { p, *q(l.filter((e) => p < e)) };
    } else {
        return [];
    }
}

(仕様に反して)重複したエントリが渡された場合、それらは除外されます。

これは183バイトです。 import ceylon.math.float{r=random}{Float*}q({Float*}l){if(exists p=l.getFromFirst((r()*l.size).integer)){return q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))};}else{return[];}}

新しい(Ceylon 1.2)を使用すると、少し改善できます if式ます。

import ceylon.math.float {
    r=random
}

{Float*} q({Float*} l) =>
        if (exists p = l.getFromFirst((r() * l.size).integer))
        then q(l.filter((e) => e < p)).chain { p, *q(l.filter((e) => p < e)) }
        else [];

これは170バイトです。 import ceylon.math.float{r=random}{Float*}q({Float*}l)=>if(exists p=l.getFromFirst((r()*l.size).integer))then q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))}else[];


以下は非ランダムバージョンです。

{Float*} r({Float*} l) =>
        if (exists p = l.first)
        then r(l.filter((e) => e < p)).chain { p, *r(l.filter((e) => p < e)) }
        else [];

スペースがない場合、これは107バイトになります。 {Float*}r({Float*}l)=>if(exists p=l.first)then r(l.filter((e)=>e<p)).chain{p,*r(l.filter((e)=>p<e))}else[];


0

AutoIt320.45 304.3バイト

これは非常に高速です(とにかくAutoItの場合)。挿入ソートボーナスの対象となります。最終ゴルフが行われた後に説明を追加します。

入力はq(Array, StartingElement, EndingElement)です。

Func q(ByRef $1,$2,$3)
$5=$3
$L=$2
$6=$1[($2+$3)/2]
If $3-$2<6 Then
For $i=$2+1 To $3
$4=$1[$i]
For $j=$i-1 To $2 Step -1
$5=$1[$j]
ExitLoop $4>=$5
$1[$j+1]=$5
Next
$1[$j+1]=$4
Next
Else
Do
While $1[$L]<$6
$L+=1
WEnd
While $1[$5]>$6
$5-=1
WEnd
ContinueLoop $L>$5
$4=$1[$L]
$1[$L]=$1[$5]
$1[$5]=$4
$L+=1
$5-=1
Until $L>$5
q($1,$2,$5)
q($1,$L,$3)
EndIf
EndFunc

ランダムテスト入力+出力:

862, 543, 765, 577, 325, 664, 503, 524, 192, 904, 143, 483, 146, 794, 201, 511, 199, 876, 918, 416
143, 146, 192, 199, 201, 325, 416, 483, 503, 511, 524, 543, 577, 664, 765, 794, 862, 876, 904, 918

興味深い、これまでAutoItについて聞いたことがない
ダニエルM.

0

Java、346バイト

407 bytes - 15% bonus for insertion sort = 345.95 bytes

圧縮コード:

class z{Random r=new Random();void q(int[] a){q(a,0,a.length);}void q(int[] a,int b,int e){if(e-b<6){for(int i=b;i<e;i++){for(int j=i;j>0&a[j]<a[j-1];j--){s(a,j,j-1);}}return;}int s=p(a,b,e);q(a,b,s);q(a,s,e);}int p(int[] a,int b,int e){int p=a[r.nextInt(e-b)+b--];while(b<e){do{b++;}while(a[b]<p);do{e--;}while(a[e]>p);if(b<e){s(a,b,e);}}return b;}void s(int[] a,int b,int e){int t=a[b];a[b]=a[e];a[e]=t;}}

完全なコード:

public class QuickSort {

    private static final Random RANDOM = new Random();

    public static void quickSort(int[] array) {
        quickSort(array, 0, array.length);
    }

    private static void quickSort(int[] array, int begin, int end) {
        if (end - begin <= 5) {
            for (int i = begin; i < end; i++) {
                for (int j = i; j > 0 && array[j] < array[j - 1]; j--) {
                    swap(array, j, j - 1);
                }
            }
            return;
        }
        int splitIndex = partition(array, begin, end);
        quickSort(array, begin, splitIndex);
        quickSort(array, splitIndex, end);
    }

    private static int partition(int[] array, int begin, int end) {
        int pivot = array[RANDOM.nextInt(end - begin) + begin];
        begin--;
        while (begin < end) {
            do {
                begin++;
            } while (array[begin] < pivot);
            do {
                end--;
            } while (array[end] > pivot);
            if (begin < end) {
                // Make sure they haven't crossed yet
                swap(array, begin, end);
            }
        }
        return begin;
    }

    private static void swap(int[] array, int begin, int end) {
        int temp = array[begin];
        array[begin] = array[end];
        array[end] = temp;
    }

}

いくつかの改善:1.メソッドヘッダーのint []とaの間のスペースを取り除きます。2.変数にアクセスする最後の場所でforループの増分または減分を行います。3.クラスint(またはカップル)を作成して、新しいintの代わりにそれを使用してバイトを節約します。4. Math.random()を使用してキャストすることは、Randomオブジェクトを作成するよりも短い場合があります。
ブルー

0

Mathematica、93 90バイト

If[Length@#>1,pv=RandomChoice@#;Join[qs2[#~Select~(#<pv&)],{pv},qs2[#~Select~(#>pv&)]],#]&

ボーナスはありません。挿入ソートを行う最小限の方法はまだありません。最近C ++を学んでいたとき、ここでさまざまなソートアルゴリズムの比較を行いました。


0

Python2、120バイト

def p(a):
 if[]==a[1:]:return a
 b,c,m=[],[],__import__("random").choice(a)
 for x in a:[b,c][x>m]+=[x];return p(b)+p(c)

if[]==a[1:]正確に同じ長さですif len(a)>2が、よりゴルフのように見えます。


0

Lua、242バイト

function f(t,p)if(#t>0)then local P,l,r,i=math.random(#t),{},{},table.insert p=t[P]for k,v in ipairs(t)do if(k~=P)then i(v<p and l or r,v)end end t={}for k,v in pairs(f(l))do i(t,v)end i(t,p)for k,v in pairs(f(r))do i(t,v)end end return t end

非ゴルフ&説明

function f(t,p)                                             # Assign 'p' here, which saves two bytes, because we can't assign it to t[P] IN the local group.
    if(#t>0)then                                            # Just return 0 length lists...
        local P,l,r,i=math.random(#t),{},{},table.insert    # Using local here actually makes the a,b=1,2 method more efficient here. Which is unnormal for Lua
        p = t[P]                                            # P is the index of the pivot, p is the value of the pivot, l and r are the sub-lists around the pivot, and i is table.insert to save bytes.
        for k,v in ipairs(t) do                             # We use a completely random pivot, because it's cheaper on the bytes.
            if(k~=P)then                                    # Avoid 'sorting' the pivot.
                i(v<p and l or r,v)                         # If the value is less than the pivot value, push it to the left list, otherwise, push it to the right list.
            end                                             #
        end                                                 #
        t = {}                                              # We can re-use t here, because we don't need it anymore, and it's already a local value. Saving bytes!
        for k,v in pairs(f(l)) do                           # Quick sort the left list, then append it to the new output list.
            i(t,v)                                          #
        end                                                 #
        i(t,p)                                              # Append the pivot value.
        for k,v in pairs(f(r)) do                           # Ditto the right list.
            i(t,v)                                          #
        end                                                 #
    end                                                     #
    return t                                                # Return...
end                                                         #

0

ラケット121バイト

(λ(l)(if(null? l)l(let((h(car l))(t(cdr l)))(append(qs (filter(λ(x)(< x h))t))(list h)(qs (filter(λ(x)(>= x h))t))))))

ゴルフされていない(l = list、h = head(最初の要素)、t = tail(残りまたは残りの要素)):

(define qs
  (λ(l)
    (if (null? l) l
        (let ((h (first l))
              (t (rest  l)))
          (append (qs (filter (λ(x) (< x h) ) t))
                  (list h) 
                  (qs (filter (λ(x) (>= x h)) t))  )))))

テスト:

(qs (list 5 8 6 8 9 1 2 4 9 3 5 7 2 5))

出力:

'(1 2 2 3 4 5 5 5 6 7 8 8 9 9)

0

ジャプト、23バイト

合計スコアで完済するためには、各ボーナスが3バイト以下である必要があるため、ボーナスを受け取りませんでした。

Z=Uö;Ê<2?UUf<Z)cßUf¨Z
Z=Uö;                   // Take a random element from the input for partitioning.
     Ê<2                // If the input is shorter than two elements,
        ?U              // return it.
          :             // Otherwise
           ß      ß     // recursively run again
            Uf<Z        // with both items that are smaller than the partition
                   Uf¨Z // and those that are larger or equal,
                )c      // returning the combined result.

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


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