22

# 样本输入/输出

8

Stewie Griffin

1
@StewieGriffin我见过很多排序难题，但没有一个仅处理基本的整数列表。对于某些语言而言，存在许多挑战，而在其他语言中则存在许多挑战。
Michelfrancis Bustillos

2

sergiol '17

23

# 05AB1E，2个字节

``````œß
``````

Jelly答案相同的算法。计算输入的所有排列并弹出最小的排列。

``````E[ß,Ž
``````

6

Michelfrancis布斯蒂略斯

6
@MichelfrancisBustillos很好，如果他们做到了，那将是一个内置函数，不是吗？

facepalm42

17

# 果冻，3个字节

``````Œ!Ṃ
``````

# 果冻，4个字节

``````ṂrṀf
``````

### 怎么运行的

``````ṂrṀf  Main link. Argument: A (list/comma-separated string)

Ṃ     Compute the minimum of A.
Ṁ   Compute the maximum of A.
r    Yield the inclusive range from the minimum to the maximum.
f  Filter the range by presence in A.
``````

O（非常）。使用很多排序。
mbomb007 '16

22

FlipTack

2
@FlipTack我也不是。可能更高一些，因为那里有n个！长度为n的数组。

1

12

# Python，46 45字节

``````lambda l:[l.pop(l.index(min(l)))for _ in 1*l]
``````

4
`l[:]`可能是`1*l`
feersum '16

9

# Brachylog，12 7字节

``````p.'(s>)
``````

### 说明

``````p.       Unifies the output with a permutation of the input
'(  )  True if what's inside the parentheses cannot be proven, else backtrack and
try with another permutation of the input.
s    Take an ordered subset from the output
>   True if the first element is bigger than the second (hence not sorted)
We don't need to check that the subset is 2 elements long because > will be false
for inputs that are not 2 elements long anyway
``````

9

``````h%t|(a,b)<-span(<h)t=a++h:b
foldr(%)[]``````

`foldr(%)[]`然后，该操作通过从输入列表中反复插入元素来从空构建一个排序列表。

``````f(h:t)|(a,b)<-span(<h)\$f t=a++h:b
f x=x``````

41个字节的另一种策略：

``````f[]=[]
f l|x<-minimum l=x:f(filter(/=x)l)``````

8

## JavaScript（ES6），51个字节

``````a=>a.map(_=>m=Math.min(...a.filter(e=>e>m)),m=-1/0)
``````

@BenjaminGruenbaum“输入将不包含重复项。”

8

## Python 2，34个字节

``def f(s):m=min(s);print m;f(s-{m})``

``````def f(s):
if s:m=min(s);print m;f(s-{m})``````

``````l=input()
while l:m=min(l);print m;l-={m}``````

``````def f(l):m=min(l);print m;f(set(l)-{m})
def f(l):m=min(l);print(m);f({*l}-{m})``````

8

``````f u=filter(`elem`u)[(minBound::Int)..]
``````

`filter`是短一个：`f u=filter(`elem`u)[minimum u..maximum u]`
xnor

xnor

@xnor：我是这样认为的。假设调用时，`f [1,3,0]`元素默认`Integer`为未绑定的类型，因此`..`永不结束。如果您必须这样称呼`f ([1, 3, 0]::[Int])`我，那么类型注释必须包含在字节数中。
nimi

feersum '16

1
@feersum：没有，但是挑战说：“输入将不包含重复项”。
nimi 2016年

8

# Oracle SQL 11.2，205字节

``WITH s AS(SELECT COLUMN_VALUE||''e FROM XMLTABLE(('"'||REPLACE(:1,',','","')||'"'))),v(p,f)AS(SELECT e,e FROM s UNION ALL SELECT p||','||e,e FROM v,s WHERE e+0>f)SELECT p FROM v WHERE LENGTH(p)=LENGTH(:1);         ``

``````WITH
s AS  -- Split the string using ',' as separator
(     -- ||'' cast the xml type to varchar
SELECT COLUMN_VALUE||''e FROM XMLTABLE(('"'||REPLACE(:1,',','","')||'"'))
),
v(p,f) AS  -- Recursive view : p = sorted string, f last number added
(
SELECT e,e FROM s -- use each number as seed
UNION ALL         -- only add a number if it is > the last added
SELECT p||','||e,e FROM v,s WHERE e+0>f  -- +0 is needed to compare int and not strings
)
-- The valid string has the same length as the input
SELECT p FROM v WHERE LENGTH(p)=LENGTH(:1)          ``````

8

# x86-64 / 32机器码（JumpDownSort）21 19字节

• 感谢@ ped7g的`lodsb`/ `cmp [si],al`想法，并将其与我一直在看的指针增量/重置放在一起。不需要`al`/ `ah`让我们对较大的整数使用几乎相同的代码。

• 新的（但相关的）算法，实现方式有很多变化：Bubbly SelectionSort允许使用较小的x86-64实现字节或双字；在x86-16上达到收支平衡（字节或字）。还避免了我的BubbleSort出现的size = 1错误。见下文。

• 事实证明，每次找到新的最小值时，带有交换的“气泡选择排序”已经是一种已知的算法JumpDown排序。在《泡泡排序：考古学算法分析》中提到了这一点（即，泡泡排序如何在吮吸时变得很流行）。

Bubble Sort会降低性能，但是我已经读到它是在机器代码中最小的实现之一。当存在用于交换相邻元素的特殊技巧时，这似乎尤其正确。这几乎是它的唯一优势，但是有时（在现实生活中的嵌入式系统中）这足以将其用于非常短的列表。

NASM列表（`nasm -l /dev/stdout`），或纯来源

`````` 2 address  16-bit       bubblesort16_v2:
3          machine      ;; inputs: pointer in ds:si,  size in in cx
4          code         ;; requires: DF=0  (cld)
5          bytes        ;; clobbers: al, cx=0
6
7 00000000 49               dec     cx          ; cx = max valid index.  (Inner loop stops 1 before cx, because it loads i and i+1).
8                       .outer:                 ; do{
9 00000001 51               push    cx          ;   cx = inner loop counter = i=max_unsorted_idx
10                       .inner:                 ;   do{
11 00000002 AC               lodsb               ;     al = *p++
12 00000003 3804             cmp     [si],al     ;     compare with *p (new one)
13 00000005 7D04             jge     .noswap
14 00000007 C144FF08         rol     word [si-1], 8    ; swap
15                       .noswap:
16 0000000B E2F5             loop    .inner      ;   } while(i < size);
17 0000000D 59               pop     cx          ;  cx = outer loop counter
18 0000000E 29CE             sub     si,cx       ;  reset pointer to start of array
19 00000010 E2EF             loop    .outer      ; } while(--size);
20 00000012 C3               ret

22 00000013  size = 0x13 = 19 bytes.
``````

`cx`围绕内部循环的push / pop 表示它以`cx`= external_cx降至0运行。

# x86-64 / x86-32 JumpDown排序，19个字节（对int32_t的排序）

`int bubblyselectionsort_int32(int dummy, int *array, int dummy, unsigned long size);` （返回值= max（array []））。

`xchg`使用mem有一个隐式`lock`前缀，这会使这特别慢。可能比有效的加载/存储交换慢大约一个数量级；`xchg m,r`在Skylake上，每23c吞吐量是一个，但是使用tmp reg进行加载/存储/移动以进行有效的swap（reg，mem）可以使每个时钟移动一个元素。在`loop`指令速度快并且不会对内部循环造成太大瓶颈的AMD CPU上，这可能是一个更糟糕的比率，但是分支未命中仍然是一个大瓶颈，因为交换很常见（随着未排序区域变小，这种情况会变得更加普遍。 ）。

`````` 2 Address               ;; hybrib Bubble Selection sort
3        machine         bubblyselectionsort_int32:   ;; working, 19 bytes.  Same size for int32 or int8
4        code               ;; input: pointer in rsi, count in rcx
5        bytes              ;; returns: eax = max
6
7                           ;dec  ecx           ; we avoid this by doing edi=esi *before* lodsb, so we do redundant compares
8                                               ; This lets us (re)enter the inner loop even for 1 element remaining.
9                       .outer:
10                           ; rsi pointing at the element that will receive min([rsi]..[rsi+rcx])
11 00000000 56               push   rsi
12 00000001 5F               pop    rdi
13                           ;mov    edi, esi     ; rdi = min-search pointer
16 00000003 51               push   rcx          ; rcx = inner counter
17                       .inner:                   ; do {
18                           ; rdi points at next element to check
19                           ; eax = candidate min
20 00000004 AF               scasd                 ; cmp eax, [rdi++]
21 00000005 7E03             jle  .notmin
22 00000007 8747FC           xchg   [rdi-4], eax   ; exchange with new min.
23                         .notmin:
24 0000000A E2F8             loop  .inner          ; } while(--inner);
26                           ; swap min-position with sorted position
27                           ; eax = min.  If it's not [rsi-4], then [rsi-4] was exchanged into the array somewhere
28 0000000C 8946FC           mov    [rsi-4], eax
29 0000000F 59               pop   rcx           ; rcx = outer loop counter = unsorted elements left
30 00000010 E2EE             loop  .outer        ; } while(--unsorted);
32 00000012 C3               ret

34 00000013 13           .size: db \$ - bubblyselectionsort_int32
0x13 = 19 bytes long
``````

`dec ecx`通过与继续前进之前刚加载的元素进行比较，它避免了初始值。在外循环的最后一次迭代中，它加载最后一个元素，检查它是否小于自身，然后完成。这使它可以与size = 1一起工作，而我的BubbleSort失败（将其处理为size = 65536）。

1

Ped7g

@ Ped7g：太好了！我曾考虑`sub si, cx`使用指针而不是索引来作为外部循环的一部分，但是我没有想到`lodsb`/ `cmp [si], al`。我一直在考虑`lodsw`/ `dec si`，或者`lodsb`/ `xchg al,ah`仍然打算参加`cmp ah,al`
Peter Cordes

@ Ped7g：哦，您的版本需要`cld`，或者我想我们可以将其作为调用约定的一部分。已`DF`清除的AFAIK 不是16位调用约定的标准部分，只有32/64。还是只是您不能在引导加载程序中使用它？但是，使用自定义寄存器调用约定，这和功能一样多，因此可以肯定，为什么不要求DF = 0。（如果需要，ES = DS，所以我们可以`scasb`代替它，`lodsb`这是更方便的方法。）
Peter Cordes

1
@ Ped7g：我不了解16位约定，我只知道您不能总是假定DF已清除。但是我认为这主要是在引导加载程序环境中。我从未在真正的DOS上运行过任何写过的东西。我当时使用的是Atari Mega 4 STe（68000/68020），然后是Linux（在奔腾MMX上），因此我设法完全避免使用16位x86，直到SO问题将其淹没为止。

6

# C，72个字节

``````i,j;a(int*l,int n){for(i=0;i=i?:--n;j>l[n]?l[i]=l[n],l[n]=j:0)j=l[--i];}
``````

Bubblesort。第一个参数是指向数组的指针，第二个参数是数组的长度。与gcc一起使用。

5

# MATL，11个10字节

``````Y@t!d0>AY)
``````

``````        % Implicitly grab input array
Y@      % Compute all permutations (each permutation as a row)
t       % Duplicate this matrix
!d      % Transpose and take the differences between the values
0>A     % Find the rows where all differences are > 0
Y)      % Return only the row where this is true
% Implicitly display the result
``````

5

# Ruby，40个字节

``````->a{r=[];r<<a.delete(a.min)while[]!=a;r}
``````

4

# Python，120字节

``````def f(a):import time,threading;[threading.Thread(None,lambda b=b,c=min(a):print(time.sleep(b-c)or b)).start()for b in a]
``````

Rɪᴋᴇʀ

4

# MIPS，68个字节

`````` Address    Code        Basic                     Source

0x00400000  0x3c011001  lui \$1,4097           5    main:   la      \$s0, list       # List address
0x00400004  0x34300000  ori \$16,\$1,0
0x00400008  0x2411000a  addiu \$17,\$0,10       6            li      \$s1, 10         # List length
0x0040000c  0x24080000  addiu \$8,\$0,0         8    loop:   li      \$t0, 0          # swapped
0x00400010  0x24090001  addiu \$9,\$0,1         9            li      \$t1, 1          # for loop "i"
0x00400014  0x1131000b  beq \$9,\$17,11         11   for:    beq     \$t1, \$s1, fend  # break if i==length
0x00400018  0x00095080  sll \$10,\$9,2          13           sll     \$t2, \$t1, 2     # Temp index, multiply by 4
0x00400020  0x8d4b0000  lw \$11,0(\$10)         15           lw      \$t3, 0(\$t2)     # list[i]
0x00400024  0x8d4cfffc  lw \$12,-4(\$10)        16           lw      \$t4, -4(\$t2)    # list[i-1]
0x0040002c  0x016c082a  slt \$1,\$11,\$12        20           ble     \$t4, \$t3, for   # if list[i-1] > list[i]
0x00400030  0x1020fff8  beq \$1,\$0,-8
0x00400034  0xad4bfffc  sw \$11,-4(\$10)        21           sw      \$t3, -4(\$t2)    # swap and store
0x00400038  0xad4c0000  sw \$12,0(\$10)         22           sw      \$t4, 0(\$t2)
0x0040003c  0x24080001  addiu \$8,\$0,1         23           li      \$t0, 1          # swapped=true
0x00400040  0x08100005  j 0x00400014          24           j       for
0x00400044  0x20010001  addi \$1,\$0,1          26   fend:   subi    \$s1, \$s1, 1     # length--
0x00400048  0x02218822  sub \$17,\$17,\$1
0x0040004c  0x1500ffef  bne \$8,\$0,-17         27           bnez    \$t0, loop       # Repeat if swapped==true
0x00400050  0x2402000a  addiu \$2,\$0,10        29           li      \$v0, 10
0x00400054  0x0000000c  syscall               30           syscall
``````

1

4

# Awk，66个字节

``````{b=\$0;a[b]}m<b{m=b}n>b{n=b}END{for(i=n;i<=m;i++)if(i in a)print i}
``````

awk中的数组就像字典，而不是C数组。索引可以是不连续的，并且可以根据需要增长（并创建）。因此，我们`a`为输入创建一个数组，每一行都是一个键。然后保存最小值和最大值。然后，我们从min到max循环，并打印中存在的所有键`a``b`只是为了避免重复使用`\$0`

4

# Python 3，91 62 47字节

``````def f(z):
while z:m=min(z);z.remove(m);yield m``````

Michelfrancis Bustillos

@MichelfrancisBustillos我真的忘记了这是什么算法。可能是选择排序吗？
Sherlock16年

1

wnnmaw '16

1
@wnnmaw Dang，我写了一篇，却忘了发帖了。感谢您的提醒：D
Sherlock9

Seequ 2016年

4

# MATL，11个字节

```````t4#X<2#)tn
``````

1. 取数组的最小值。
2. 从数组中删除该值，并将其存储以供后续显示。
3. 对数组的其余部分应用相同的过程，直到它变空。
4. 按获得顺序显示所有数字。

MATL是基于堆栈的。剩余值的数组保留在堆栈的顶部。删除的值按顺序在下面。在程序结束时，将显示所有这些值。顶部的数组也将显示，但由于为空，因此未显示。

```````        % Do...while loop
t      %   Duplicate. Implicitly take input in the first iteration
4#X<   %   Compute index of mininum of the array
2#)    %   Push the minimum, and then the array with remaining entries
tn     %   Duplicate and push number of elements, to be used as loop condition
% Implicitly end do...while loop
% Implicitly display stack contents
``````

3

# Pyth- 15 13 11 10字节

Bogosort。

``````f!s>VTtT.p
``````

@Jakube我很傻，谢谢。
Maltysen '16

Maltysen '16

Suever 2016年

3

## 严重的是6个字节

``````,;l@╨m
``````

``````,;l@╨m
,;l@    push len(input), input
╨m  minimum permutation
``````

## 严重地，25个字节（非竞争）

``````,1WX╚;;pX@dXZ`i@-0<`MπYWX
``````

``````,1WX╚;;pX@dXZ`i@-0<`MπYWX
,                          get input
1W                    WX  do-while:
╚                        shuffle
;;                      dupe twice
pX@dX                 remove first element of first dupe and last element of second dupe
Z                zip
`i@-0<`MπY      test if all differences are positive (if any are not, the list is not sorted), negate (1 if not sorted else 0)
``````

3

# MATL，17 16字节

@LuisMendo，节省了一个字节，创建了空数组

``````vTbtX<-QI\$(f8M+q
``````

``````v                  % push an empty array
T                 % push 1
b                % bubble the input array up to the top of the stack
t               % duplicate it
X<             % find the minimum
-            % subtract min from input array
Q           % and increment to adjust for 1-based indexing
I\$(        % resulting array used as indices of empty array
% (the [] way up at the top) that are assigned 1 (from T)
f       % find the nonzero indices
8M     % magically retrieve the 4th previous function input :/
(aka, the min input array value)
+    % add it to the indices
q   % and decrement
``````

• 您可以使用MATL在MATL中初始化一个空数组`[]`并对其进行增长，就像在MATLAB中一样
• 如何`(`用于分配索引
• 如何使用`M`自动剪贴板

• `vertcat` 当堆栈上没有要连接的内容时，会神奇地创建一个空数组

Luis Mendo

@LuisMendo Sooo ...如果堆栈上只有一个数组...？正在调查。

Luis Mendo

3

# R，68字节

``````o<-i
for(j in 1:length(i)){
x<-(i-min(i))==0
o[j]<-i[x]
i<-i[!x]
}
o
``````

``````o<-i                      # Defines output as o
for(j in 1:length(i)){   # Initializes loop for length of input
x<-(i-min(i))==0        # Generates logical vector by finding the value 0
# of input less the minimum of input.
o[j]<-i[x]             # Puts the smallest value at position j
i<-i[!x]              # Removes the smallest value from input
}                   # Ends loop
o                  # Returns sorted list
``````

3

## Java 8，112 92字节

``t->{for(;0<t.size();System.out.println(t.remove(t.indexOf(java.util.Collections.min(t)))));}``

• -20 [16-08-21]使用了lambda

isaacg '16

Alex A.

NonlinearFruit16年

2

# 视网膜，95岁

``````-\d+
\$*n
\d+
\$*11
+`(1+) (n+)
\$2 \$1
+`\b(n+) (\1n+)|(1+)(1+) \3\b
\$2\$3 \$1\$3\$4
1(1*)
\$.1
n+
-\$.&
``````
• 第1阶段-将-ve整数转换为带有`n`数字的一元；放下`-`迹象。
• 第2阶段-将+ ve和零整数转换`1`为以数字为一元数；添加`1`到每一个，从而使零由下式表示`1`
• 第3阶段-将所有-ves移到最前面。
• 阶段4-排序：将具有最大幅度（即最小数值）的所有-ves移到更高的-ves之前。将较小的+ ves移至较大的+ ves。
• 阶段5-从中删除1，并将+ ve一元转换为十进制。
• 阶段6-将-ve一元转换为十进制，包括符号。

@LeakyNun不会对列表中的最后一个元素进行排序。
mbomb007 '17

@ mbomb007对，没关系。
Leaky Nun

2

# Ruby，22个字节

``````->a{a.permutation.min}
``````

2

## Clojure，73个 35字节

Bogosort :)

``````#(if(apply < %)%(recur(shuffle %)))
``````

``````#(reduce(fn[r i](let[[a b](split-with(partial > i)r)](concat a[i]b)))[]%)
``````

`r`通过将其分为“小于i”和“大于i”两部分来简化为排序列表。我猜这是插入排序

Matias Bjarland '18

2

## Ruby，26个 24字节

``````->l{l.map{l-l-=[l.min]}}
``````

``````->l{l.map{l-l-=[l.min]}}[[2,4,3,1]]
=> [[1], [2], [3], [4]]
``````

2

# Java 7中，106个 104字节

``````void a(int[]a){for(int b=a.length-1,d=0,c=0,e;d<b*b;c=++d%b)if(a[c]>a[c+1]){e=a[c];a[c++]=a[c];a[c]=e;}}
``````

-1字节感谢Geobits指出正常交换胜于异或
-1字节感谢Leaky Nun指出我可以将所有int声明移入for循环

2

## Ruby，22个字节

``````->a{[*a.min..a.max]&a}
``````

@PeterCordes这就是重点
dkudriavtsev

dkudriavtsev