快速排序!


27

好吧...有59个(现在有60个)标记为问题,但没有简单的quicksorts。

必须解决。

对于那些不熟悉quicksort的人,以下是细分,由Wikipedia提供:

  1. 从数组中选择一个元素,称为数据透视
  2. 对数组重新排序,以使所有值小于枢轴的元素都位于枢轴之前,而所有值大于枢轴的元素都位于枢轴之后(相等的值可以任意选择)。分割之后,枢轴处于其最终位置。这称为分区操作。
  3. 将上述步骤递归应用于值较小的元素的子数组,并分别应用于值较大的元素的子数组。

规则

规则很简单:

  • 用您选择的编程语言实现数字快速排序。
  • 支点应随机选择,选择三个中间值(第一个,最后一个和中间元素)。
  • 您的程序可以是完整的程序或功能。
  • 您可以使用STDIN,命令行参数或函数参数获取输入。如果使用字符串输入,则输入以空格分隔。
  • 输入中可能包含十进制和负值。但是,不会重复。
  • 您可以输出到STDOUT或从函数返回。
  • 没有内置的排序功能(或与排序相关的功能)或标准漏洞。
  • 该列表可以是任意长度。

奖金#1:在长度<= 5的列表或子列表上,使用插入排序可以稍微加快速度。奖励:-15%。

奖金2:如果您的语言支持并发,则可以对列表进行并行排序。如果在子列表上使用插入排序,则最终的插入排序不需要并行。内置线程池/线程调度是允许的。奖励:-15%。

注意:中位数3使某些人感到困惑,因此(再次)由Wikipedia提供以下说明:

选择枢轴分区的第一个,中间和最后一个元素的中位数

计分

这是。基本分数以字节为单位。如果您获得一笔红利,请从该数字中扣除15%。如果两者兼得,则可享30%的折扣。听起来确实像是推销。

这并不是要找到总体上最短的答案,而是要找到每种语言中最短的答案。

现在,这是排行榜片段的无耻复制。

排行榜

这篇文章底部的Stack Snippet从答案a)生成目录,答案是每种语言的最短解决方案列表,b)则是总体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

其中N是您提交的文件的大小。如果您提高了分数,则可以通过打败旧分数来保持标题。例如:

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

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

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

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

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


4
“应该随机选择枢轴,或者选择中间值三个(第一个,最后一个和中间元素)。” 这是什么意思?您先前曾说过只选择了一个元素。
msh210

2
@daniero片段现在固定
丹尼尔M.

1
中位数选择算法是硬性要求吗?使用链接列表作为其主要数组类型的语言(Haskell,LISP)在语言中是不切实际的(例如,会降低性能),并且已经有至少一个答案忽略了该规则。
John Dvorak

2
在基于列表的语言中,随机支点和三个位数的中位数都是有问题的。两者都需要随机访问数组,并且访问链表的末尾是O(n)。取前三个元素的中位数并不能完成相同的工作(同样是因为无论如何,您将在三个分割中抓住相同的支点),并且仅出于毫无理由使代码复杂化。
John Dvorak

1
在Haskell中,随机数据透视也是有问题的,还有另一个原因-一旦开始掷骰子,就不再需要编写函数。您正在定义一个生成数组的I / O操作。您可以定义一个以RNG状态作为参数的函数,但是它也不是很大。
John Dvorak

Answers:


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

感谢@Luke节省了3个字节(真的2个字节)。

感谢@Dúthomhas节省了18(实际上是15)字节。

请注意,我是新来的,这是我的第一篇文章。

这是一个.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来保存10个字节,并在最后一个函数调用中删除空格。我敢打赌,您可以在避免奖金的情况下取得更好的成绩(15%不够)
edc65

1
您可以通过用单个星号替换参数的方括号来节省另外5个字节。我猜有些宏魔术可以删除更多的字节。
cadaniluk 2015年

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

在线尝试

通过marinus修复了一个问题(以8个字节为代价),并通过Thomas Kwa修复了7个字节!


问题指定将没有重复项。(不知道我花了这么长时间才看到...)
lirtosiast

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)”。
克里斯·杰斐逊

消除擦除使我节省了大量字节。谢谢!
林恩

另一个微小的问题:无需分配'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个列表。

如前所述,这可能是无效的。不过,我将其保留在这里,因为这是一个有趣的解决方案。

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

> <>(FISH),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.

这花了我很长时间写。您可以在这里尝试,只需在运行程序之前将必须排序的列表放入用逗号分隔的初始堆栈中即可。

怎么运行的

该程序获取初始堆栈中的第一个,中间和最后一个元素,并计算这三个元素的中位数。
然后将堆栈更改为:

[列表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 2015年

@VisualMelon我用一堆不同的案例进行了测试,但从未得到错误的结果,但是如果您发现一个破坏它的测试案例,请告诉我。同样,它可能不适用于重复项,但是挑战指出不会重复项。
Morgan Thrapp 2015年

我以为[2, 1, 3]会折断它1/3的时间,因为当它选择枢轴为2时,它的清单就会很低[2, 1]-抱歉,我现在无法自己测试。
VisualMelon 2015年

@VisualMelon好吧,当然,但是然后它再次递归排序。
Morgan Thrapp 2015年

啊,对不起,错过了完全,不太我怎么会希望实现的快速排序-有一个给予好评的困惑我
VisualMelon

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,并使用endof代替来在此处节省一些字节lengthQ(x)=endof(x)<2?x:(p=rand(x);[Q((f=filter)(i->i<p,x));p;Q(f(i->i>p,x))])
Glen O

@GlenO感谢您的建议。我已经实现了这一点,并通过重复的元素解决了该问题。
Alex A.

我说这可能是一个问题,但我请发帖人澄清,“输入的内容可能包含小数和负值。但是,不会重复”
Glen 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感谢您的输入,但我尝试了此操作,但它对我没有产生预期的结果。
Alex 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))

我利用没有重复的事实来使用两个严格的比较。我将不得不检查是否Data.List.partition不会使事情变得更短,即使考虑到我将不得不添加导入语句。我不考虑插入排序奖励,因为我认为它Data.List.insert是与排序相关的功能(因此被禁止),如果不使用它,添加插入排序会将代码推送到246字节(带奖励)为209.1,因此不值得。

编辑:感谢RobAu提出的创建别名以供使用的建议f=filter。它可能只保存一个字节,但一切都有帮助。


1
f=filter可能会刮掉一些字节。
RobAu

也许您可以通过使一个函数来处理两个冗余q$f(>n)lq$f(<n)l调用来剃一些字节?
Cyoce

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第二次递归和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中使用,并且较小。)

这定义了一个函数,该函数采用浮点数的迭代,并返回其排序后的版本。

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
Daniel M.15年

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)代替新的int来保存字节。4.使用Math.random()和强制转换可能比创建Random对象要短。
2016年

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 =列表,h =头(第一个元素),t =尾(剩余或其余元素)):

(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

Japt,23个字节

每个奖金必须不超过三个字节才能在总分中得到回报,因此我没有获得任何奖金。

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.

在线尝试!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.