Sort an Integer List

23

1

The Challenge

It's quite simple really, sort a list of numbers.

Details

You must sort a list of numbers in ascending order, without using any built-in sorting functions/libraries/etc (i.e. list.sort() in Python).

Input/output can be done in any method you choose, as long as it is human readable.

Standard loopholes are disallowed as always.

Shortest code in bytes wins.

You must explain/list what sort method you used (Bubble, Insertion, Selection, etc.)

Input will not contain duplicates.

Sample Input/Output

Input: 99,-2,53,4,67,55,23,43,88,-22,36,45

Output: -22,-2,4,23,36,43,45,53,55,67,88,99

Note: A near direct opposite of Sort a List of Numbers

Michelfrancis Bustillos

Posted 2016-04-15T12:42:31.060

Reputation: 695

8I'm very surprised if this isn't a duplicate, but I don't have the time to check. Anyway, "built-in sorting functions" should be better defined. Can you use a function that indexes all values? [7 2 4 1] -> [4 2 3 1]. Also, can the CSV list be inside brackets? Also, the specific input format is very suitable for some languages, and bad for others. This makes input parsing a big part for some submissions, and unnecessary for others. – Stewie Griffin – 2016-04-15T12:52:06.573

1@StewieGriffin I've seen many sorting challenges, but none dealing with sorting just a basic integer list. There are many challenges that are easier for some languages, and much more difficult in others. – Michelfrancis Bustillos – 2016-04-15T13:00:35.593

This is very similar, but has a O(Nlog(N)) restriction. – Nathan Merrill – 2016-04-15T14:06:21.807

2

Very closely related to this question, but since some answers here (e.g. Dennis' range filtering) require the input to be integers I won't vote to close as dupe.

– Peter Taylor – 2016-04-15T20:55:09.650

1

Relevant: https://www.youtube.com/user/AlgoRythmics/videos — An Youtube channel which teaches sorting algorithms through Hungarian dances!

– sergiol – 2017-04-30T12:05:50.983

Answers

23

05AB1E, 2 bytes

Code:

ϧ

Same algorithm as the Jelly answer. Computes all permutations of the input and pops out the smallest one.

Try it online!


A more efficient method is:

E[ß,Ž

Performs selection sort. Uses CP-1252 encoding.

Try it online!

Adnan

Posted 2016-04-15T12:42:31.060

Reputation: 41 965

6Accepting this temporarily as I don't see anyone getting less than 2. – Michelfrancis Bustillos – 2016-04-15T14:30:31.260

6@MichelfrancisBustillos well, if they did, it would be a builtin, wouldn't it? – Destructible Lemon – 2016-08-22T07:15:51.357

I just looked at 05AB1E/Base a minute ago, and then I looked at this. Coincidence? – facepalm42 – 2019-07-11T08:52:31.370

17

Jelly, 3 bytes

Œ!Ṃ

This generates all permutations of the input list, then selects the lexographically smallest permutation. Very efficient.

Credits to @Adnan who had the same idea independently.

Try it online!


Jelly, 4 bytes

ṂrṀf

This builds the range from the minimum of the list to the maximum of the list, then discards the range elements not present in the original list. This is technically a bucket sort, with very small buckets. I'm not aware of a name for this specific variant.

Try it online!

How it works

Ṃ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.

Dennis

Posted 2016-04-15T12:42:31.060

Reputation: 196 637

O(very). Uses much sort. – mbomb007 – 2016-04-15T19:14:22.557

23So O. Very uses. Much sort. Amaze! (Sorry, what?) – Dennis – 2016-04-15T19:19:41.950

I'm not great at complexity of algorithms, would this be O(n!)? – FlipTack – 2017-01-28T21:48:47.577

2@FlipTack Neither am I. Probably a bit higher, since there are n! arrays of length n. – Dennis – 2017-01-28T22:15:43.480

1Just selecting the smallest lexographically is O(n*n!) since each of the n! arrays must be compared sequentially, and lexographical comparison is O(n). Generation can be done in O(n*n!) as well if done efficiently so I would bet the algorithm is only O(n*n!) if well implemented – PunPun1000 – 2017-08-28T18:59:16.593

13

Python, 46 45 bytes

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

Simple selection sort.

orlp

Posted 2016-04-15T12:42:31.060

Reputation: 37 067

4l[:] could be 1*l – feersum – 2016-04-16T06:18:05.127

9

Brachylog, 12 7 bytes

p.'(s>)

This uses permutation sort, which is obviously terrible, but hey it's shorter than Pyth!

Explanation

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

Fatalize

Posted 2016-04-15T12:42:31.060

Reputation: 32 976

9

Haskell, 38 bytes

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

The binary function % insert a new element h into a sorted list t by partitioning t into a prefix a of elements <h and a suffix b of elements >h, and sticks in h between them.

The operation foldr(%)[] then builds up a sorted list from empty by repeatedly inserting elements from the input list.

This is one byte shorter than the direct recursive implementation

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

Another strategy for 41 bytes:

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

xnor

Posted 2016-04-15T12:42:31.060

Reputation: 115 687

So this is https://en.wikipedia.org/wiki/Insertion_sort, with % as the insertion inner loop and foldr to apply it as the outer loop.

– Peter Cordes – 2017-11-26T05:50:46.020

8

x86-16 machine code (BubbleSort int8_t), 20 19 bytes

x86-64/32 machine code (JumpDownSort) 21 19 bytes

Changelog:

  • Thanks to @ped7g for the lodsb/cmp [si],al idea, and putting that together with a pointer increment / reset that I'd been looking at. Not needing al/ah lets us use nearly the same code for larger integers.

  • New (but related) algorithm, many implementation changes: Bubbly SelectionSort allows a smaller x86-64 implementation for bytes or dwords; break-even on x86-16 (bytes or words). Also avoids the bug on size=1 that my BubbleSort has. See below.

  • It turns out that my Bubbly Selection Sort with swaps every time you find a new min is already a known algorithm, JumpDown Sort. It's mentioned in Bubble Sort: An Archaeological Algorithmic Analysis (i.e. how did Bubble Sort become popular despite sucking).


Sorts 8-bit signed integers in-place. (Unsigned is the same code size, just change the jge to a jae). Duplicates are not a problem. We swap using a 16-bit rotate by 8 (with a memory destination).

Bubble Sort sucks for performance, but I've read that it's one of the smallest to implement in machine code. This seems especially true when there are special tricks for swapping adjacent elements. This is pretty much its only advantage, but sometimes (in real life embedded systems) that's enough advantage to use it for very short lists.

I omitted the early termination on no swaps. I used Wikipedia's "optimized" BubbleSort loop which avoids looking at the last n − 1 items when running for the n-th time, so the outer loop counter is the upper bound for the inner loop.

NASM listing (nasm -l /dev/stdout), or plain source

 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.

push/pop of cx around the inner loop means it runs with cx = outer_cx down to 0.

Note that rol r/m16, imm8 is not an 8086 instruction, it was added later (186 or 286), but this isn't trying to be 8086 code, just 16-bit x86. If SSE4.1 phminposuw would help, I'd use it.

A 32-bit version of this (still operating on 8-bit integers but with 32-bit pointers / counters) is 20 bytes (operand-size prefix on rol word [esi-1], 8)

Bug: size=1 is treated as size=65536, because nothing stops us from entering the outer do/while with cx=0. (You'd normally use jcxz for that.) But fortunately the 19-byte JumpDown Sort is 19 bytes and doesn't have that problem.


Original x86-16 20 byte version (without Ped7g's idea). Omitted to save space, see the edit history for it with a description.


Performance

Partially-overlapping store/reload (in memory-destination rotate) causes a store-forwarding stall on modern x86 CPUs (except in-order Atom). When a high value is bubbling upwards, this extra latency is part of a loop-carried dependency chain. Store/reload sucks in the first place (like 5 cycle store-forwarding latency on Haswell), but a forwarding stall brings it up to more like 13 cycles. Out-of-order execution will have trouble hiding this.

See also: Stack Overflow: bubble sort for sorting string for a version of this with a similar implementation, but with an early-out when no swaps are needed. It uses xchg al, ah / mov [si], ax for swapping, which is 1 byte longer and causes a partial-register stall on some CPUs. (But it may still be better than memory-dst rotate, which needs to load the value again). My comment there has some suggestions...


x86-64 / x86-32 JumpDown Sort, 19 bytes (sorts int32_t)

Callable from C using the x86-64 System V calling convention as
int bubblyselectionsort_int32(int dummy, int *array, int dummy, unsigned long size); (return value = max(array[])).

This is https://en.wikipedia.org/wiki/Selection_sort, but instead of remembering the position of the min element, swap the current candidate into the array. Once you've found the min(unsorted_region), store it to the end of the sorted region, like normal Selection Sort. This grows the sorted region by one. (In the code, rsi points to one past the end of the sorted region; lodsd advances it and mov [rsi-4], eax stores the min back into it.)

The name Jump Down Sort is used in Bubble Sort: An Archaeological Algorithmic Analysis. I guess my sort is really a Jump Up sort, because high elements jump upwards, leaving the bottom sorted, not the end.

This exchange design leads to the unsorted part of the array ending up in mostly reverse-sorted order, leading to lots of swaps later on. (Because you start with a large candidate, and keep seeing lower and lower candidates, so you keep swapping.) I called it "bubbly" even though it moves elements the other direction. The way it moves elements is also a little bit like a backwards insertion-sort. To watch it in action, use GDB's display (int[12])buf, set a breakpoint on the inner loop instruction, and use c (continue). Press return to repeat. (The "display" command gets GDB to print the whole array state every time we hit the breakpoint).

xchg with mem has an implicit lock prefix which makes this extra slow. Probably about an order of magnitude slower than an efficient load/store swap; xchg m,r is one per 23c throughput on Skylake, but load / store / mov with a tmp reg for an efficient swap(reg, mem) can shift one element per clock. It might be a worse ratio on an AMD CPU where the loop instruction is fast and wouldn't bottleneck the inner loop as much, but branch misses will still be a big bottleneck because swaps are common (and become more common as the unsorted region gets smaller).

 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
14 00000002 AD               lodsd
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

Same code size for int8_t: use lodsb / scasb, AL, and change the [rsi/rdi-4] to -1. The same machine-code works in 32-bit mode for 8/32-bit elements. 16-bit mode for 8/16-bit elements needs to be re-built with the offsets changed (and 16-bit addressing modes use a different encoding). But still 19 bytes for all.

It avoids the initial dec ecx by comparing with the element it just loaded before moving on. On the last iteration of the outer loop, it loads the last element, checks if it's less than itself, then is done. This allows it to work with size=1, where my BubbleSort fails (treats it as size = 65536).

I tested this version (in GDB) using the this caller: Try it online!. You can run this it on TIO, but of course no debugger or printing. Still, the _start that calls it exits with exit-status = largest element = 99, so you can see it works.

Peter Cordes

Posted 2016-04-15T12:42:31.060

Reputation: 2 810

There might be room to improve on the inner-loop loop condition, it seems to be using a lot of bytes. Maybe push/pop cx and use loop for both? Maybe loop the other way, from back to front of the array so we count an index down to zero? (And increment bx because the sorted portion is at the end you loop towards). – Peter Cordes – 2017-11-25T15:32:17.093

1

Got it down to 19B, but with lot of changes, also input regs (some changes probably not needed, but as I was toying around, they remained there from earlier experiments)... it's still based on your work, so reluctant to post it as answer, you can check it on pastebin: https://pastebin.com/0VMzdUjj

– Ped7g – 2017-11-26T02:54:27.650

@Ped7g: Nice! I'd considered sub si, cx as part of the outer loop using a pointer instead of indexing, but I hadn't thought of lodsb / cmp [si], al. I'd been considering lodsw / dec si, or lodsb /xchg al,ahto still set up for cmp ah,al – Peter Cordes – 2017-11-26T03:44:51.520

@Ped7g: oh, your version requires cld, or I guess we could make that part of the calling convention. AFAIK, having DF cleared is not a standard part of 16-bit calling conventions, only 32/64. Or is it just that you can't assume it in a bootloader? But with a custom register calling convention, this is as much of a code fragment as a function, so sure, why not require DF=0. (And if we want, ES=DS so we could scasb instead of lodsb if that's more convenient.) – Peter Cordes – 2017-11-26T03:48:16.680

I can't recall any 16b calling convention (I never used them, my asm was always custom, using custom set of registers per function, not even having uniform convention), so I don't know about DF either. (as I don't know rules of this site, I may have broken it by using completely custom scheme and DF=0 requirement. But overall; is even x86-16b calling convention a thing? Didn't have pretty much every language compiler its own? I'm pretty sure BorlandC vs WatcomC was not compatible by default, Pascal was different too, DOS int 21h completely custom, etc... it's stone age and anarchy ;) :) ) – Ped7g – 2017-11-26T04:33:39.297

1@Ped7g: I have no idea about 16-bit conventions, all I know is that you couldn't always assume DF was cleared. But I think that's mostly in a bootloader context. I've never run anything I've written on real DOS. I was on Atari Mega 4 STe (68000/68020), then Linux (on a Pentium MMX), so I managed to avoid 16-bit x86 entirely until SO questions rammed it down my throat. – Peter Cordes – 2017-11-26T04:39:45.663

@Ped7g: In pure assembly language, you can make up whatever calling convention you want. It's only interfacing with compilers or other libraries that you need to stick to any kind of standard. Thus, an asm function can do whatever you like, IMO as long as it's something you might reasonably expect your caller to do. (e.g. not copy an arg to multiple registers, but any arbitrary register is fine.) – Peter Cordes – 2017-11-26T04:41:49.903

@Ped7g: Anyway, I updated this answer. It's pretty common for people to suggest improvements, even major changes, and people edit them into their answers. That works better for the site than having multiple answers in the same language that use basically the same strategy. Thanks again. – Peter Cordes – 2017-11-26T04:43:57.777

I went through Z80 (ZX Spectrum) to x86-16, because we had few 286 PC AT computers around at universities in city (where I could "break in" through some adults from family)... did whole "sprite editor" in 320x200 in pure x86-16 at high school, then a friend somewhere downloaded Watcom C and we learned to use DOS4GW for 32b protected mode under DOS ... but our first PC demo was in 16b ... would be lot of pain today, but as I was coming from ZX, it was nice change to have several(!) 64kiB memory banks available, compared to ~39kiB of ZX 48k and 128kiB banking of 128k. 450+kiB RAM = astonishing! – Ped7g – 2017-11-26T04:49:08.033

@Ped7g: x86-64 version for 32-bit integers only costs 2 extra bytes. Your lodsb/cmp idea was key. IDK if it's reasonable for the function to expect the caller to pass the max idx in the first place, instead of the size. I don't think anyone would complain, but I'd rather golf this function than "cheat" that way. – Peter Cordes – 2017-11-26T07:01:03.590

@Ped7g: x86-64 version is down to 19 bytes, using a new algo that isn't quite SelectionSort. (And an xchg with mem to thoroughly destroy performance :P). It avoids the initial dec ecx by comparing with the element it just loaded before moving on. – Peter Cordes – 2017-11-27T15:22:18.670

8

JavaScript (ES6), 51 bytes

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

Each loop finds the smallest number that hasn't been found so far.

Neil

Posted 2016-04-15T12:42:31.060

Reputation: 95 035

Calling this on [1,2,3,4,5,4,3,2,1] produces [1, 2, 3, 4, 5, Infinity, Infinity, Infinity, Infinity] – Benjamin Gruenbaum – 2016-04-16T21:55:26.730

@BenjaminGruenbaum "Input will not contain duplicates." – Neil – 2016-04-17T09:33:23.307

I have the exact same bytecount with a different approach – Bálint – 2016-05-19T19:02:55.023

Actually, 1 byte less – Bálint – 2016-05-19T19:32:25.217

This algorithm is a https://en.wikipedia.org/wiki/Selection_sort

– Peter Cordes – 2017-11-26T05:52:47.170

8

Haskell, 42 41 38 bytes

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

Loops through all integers (signed 64bit, on my machine) and keeps those that are in u. Of course it doesn't finish in reasonable time.

The previous version looped through [minimum u..maximum u] which has the same worst case running time.

Edit: @xnor saved a byte. Thanks!

nimi

Posted 2016-04-15T12:42:31.060

Reputation: 34 639

filter is one shorter: f u=filter(`elem`u)[minimum u..maximum u] – xnor – 2016-04-15T16:26:32.070

How brute force! Does [minimum u..] not work for type reasons? – xnor – 2016-04-15T23:06:09.457

@xnor: I think so. When calling, let's say f [1,3,0], the elements default to type Integer which is unbound, so the .. never ends. If you have to call it like f ([1, 3, 0]::[Int]) then I guess, the type annotation has to be included in the byte count. – nimi – 2016-04-15T23:53:29.720

How does it detect elements that occur more than once? – feersum – 2016-04-16T06:19:27.337

1@feersum: it doesn't, but the challenge says: "Input will not contain duplicates". – nimi – 2016-04-16T13:21:06.520

8

Oracle SQL 11.2, 205 bytes

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);         

Un-golfed

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)          

As for what sort method it is, I have no idea, ORDER BY made sure I forgot them.

Jeto

Posted 2016-04-15T12:42:31.060

Reputation: 1 601

I barely know SQL, but from your comments I think you're selecting the min or max from the remaining unsorted elements, and appending that to the end of a sorted list. That makes this a https://en.wikipedia.org/wiki/Selection_sort.

– Peter Cordes – 2017-11-26T05:58:07.627

8

Python 2, 34 bytes

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

Takes input as a set, printing its elements in increasing order, terminating with error.

A clean termination can be done in 41 bytes:

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

or

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

The input can be take as a list for 39 bytes, or 38 bytes in Python 3.5:

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

xnor

Posted 2016-04-15T12:42:31.060

Reputation: 115 687

This is a https://en.wikipedia.org/wiki/Selection_sort, using m=min(s) / s - (m) as the inner loop to find and remove the min from the unsorted elements, and recursion as the outer.

– Peter Cordes – 2017-11-26T05:45:55.207

6

C, 72 bytes

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. The first argument is a pointer to the array, the second argument is the length of the array. Works with gcc.

mIllIbyte

Posted 2016-04-15T12:42:31.060

Reputation: 1 129

This really needs an ungolfed version to be readable; it's really hard to keep track of where the ternary operators start / end. – Peter Cordes – 2017-11-26T05:44:04.480

5

MATL, 11 10 bytes

Y@t!d0>AY)

Extremely inefficient examination of all permutations of the input.

Try it Online!

Explanation

        % 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

Suever

Posted 2016-04-15T12:42:31.060

Reputation: 10 257

5

Ruby, 40 bytes

Selection sort. Anonymous function; takes the list as argument.

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

Value Ink

Posted 2016-04-15T12:42:31.060

Reputation: 10 608

4

Python 3, 91 62 47 bytes

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

Thanks to wnnmaw and Seeq for golfing help.

The argument z should be a list. This is a variant of selection sort.

I'm not sure how min stacks up against built-in sorting functions, since I'm not sure how Python implements min. Hopefully, this solution is still okay. Any golfing suggestions in the comments or in PPCG chat are welcome.

Sherlock9

Posted 2016-04-15T12:42:31.060

Reputation: 11 664

Make sure to state what type of sort you are using. – Michelfrancis Bustillos – 2016-04-15T13:32:44.453

@MichelfrancisBustillos I've honestly forgotten what algorithm this is. Might be selection sort? – Sherlock9 – 2016-04-15T13:33:45.240

1Just out of curiosity, why not just directly take a list? The question allows for open input format – wnnmaw – 2016-04-15T15:02:23.817

1@wnnmaw Dang it, I wrote one up but forgot to post it. Thanks for the reminder :D – Sherlock9 – 2016-04-15T16:56:11.920

Hmm, maybe def f(z):\nwhile z:m=min(z);z.remove(m);yield m – seequ – 2016-04-15T22:13:35.300

This is definitely https://en.wikipedia.org/wiki/Selection_sort. It scans the entire remaining list of elements for the min element (using m=min(z);), and returns it as the next generated value with yield. min() implements the inner loop of Selection Sort, while z: implements the outer loop. .remove may be a lot less efficient than swapping the new min into place (remove has to find it again), but it's still Selection in a loop.

– Peter Cordes – 2017-11-26T05:31:59.257

4

MATL, 11 bytes

`t4#X<2#)tn

Try it online!

This sorts by the following procedure, which is O(n2):

  1. Take the minimum of the array.
  2. Remove that value from the array, and store it for subsequent display.
  3. Apply the same procedure with the rest of the array, until it becomes empty.
  4. Display all numbers in the order in which they were obtained.

MATL is stack-based. The array with remaining values is kept at the top of the stack. The removed values are below, in order. At the end of the program all those values are displayed. The array at the top would also be displayed, but since it's empty it's not shown.

`        % 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

Luis Mendo

Posted 2016-04-15T12:42:31.060

Reputation: 87 464

4

Python, 120 Bytes

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]

This probably won't be the shortest answer but I feel like this algorithm belongs here. call with a list of integers, they'll be printed in a sorted manner to stdout. I wouldn't try it with too large numbers though.

CensoredUsername

Posted 2016-04-15T12:42:31.060

Reputation: 951

Nice first post! And nice username. :P – Rɪᴋᴇʀ – 2016-04-15T17:05:12.057

4

MIPS, 68 bytes

I wrote a simple unoptimized bubble sort implementation a while ago. Byte count begins at loop and ends at li $v0, 10, assuming that the list address and list length are already in memory.

 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
0x0040001c  0x01505020  add $10,$10,$16       14           add     $t2, $t2, $s0   # Combined address
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]
0x00400028  0x21290001  addi $9,$9,1          18           addi    $t1, $t1, 1     # i++
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

Now I wait to be blown out of the water with x86...

qwr

Posted 2016-04-15T12:42:31.060

Reputation: 8 929

1

You can leave out the swapped=true early-out check and count down based on the array size. See my 20 byte x86-16 version that sorts 8-bit integer. I might make a normal 32 or 64-bit x86 version that sorts 32-bit integers at some point, but 8-bit integers in 16-bit mode is kind of a sweet spot for x86.

– Peter Cordes – 2017-11-25T16:00:15.770

4

Awk, 66 bytes

{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}

Arrays in awk are like dictionaries, not like C arrays. The indexes can be non-contiguous, and they grow (and are created) as needed. So, we create an array a for the input, with each line being a key. And we save the min and max values. Then we loop from min to max, and print all keys which exist in a. b is just to avoid repeated usage of $0.

muru

Posted 2016-04-15T12:42:31.060

Reputation: 331

3

Pyth - 15 13 11 10 bytes

Two bytes saved thanks to @Jakube.

Bogosort.

f!s>VTtT.p

Try it online here.

I don't need the h cuz we are guaranteed no duplicates.

Maltysen

Posted 2016-04-15T12:42:31.060

Reputation: 25 023

@Jakube I feel stupid, thanks. – Maltysen – 2016-04-15T13:27:49.530

@Suever as I said in my answer, we are guaranteed no duplicates as per OP. – Maltysen – 2016-04-15T13:54:11.997

Sorry about that! Missed that point. – Suever – 2016-04-15T13:57:42.957

3

Seriously, 6 bytes

,;l@╨m

Try it online!

This does the same thing as many other answers: generate all permutations, select minimum. I kinda forgot that this would work while I was working on the below solution.

Explanation:

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

Seriously, 25 bytes (non-competing)

This would be competitive if it wasn't for a bug in the shuffle command that I just fixed.

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

Try it online! This implements the best sorting algorithm ever: Bogosort!

Explanation:

,1WX╚;;pX@dXZ`i@-0<`MπYWX
,                          get input
 1W                    WX  do-while:
   X                         discard
    ╚                        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)

Mego

Posted 2016-04-15T12:42:31.060

Reputation: 32 998

3

Java 8, 112 92 bytes

Here is another selection sort. The input is a List t of integers and the sorted output is printed to standard out.

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

Update

  • -20 [16-08-21] Used a lambda

NonlinearFruit

Posted 2016-04-15T12:42:31.060

Reputation: 5 334

Hi Nonlinear, and welcome to PPCG! – isaacg – 2016-04-15T21:07:08.587

Welcome to Programming Puzzles & Code Golf! It appears your code assumes a variable t to exist, which makes it a snippet; we require submissions to be full programs or functions which utilize our default I/O formats. We also require imports to factor into the byte count. Let me know if you have any questions!

– Alex A. – 2016-04-16T06:53:57.547

Thanks for the resources! I modified my answer to be a function and to include the import. – NonlinearFruit – 2016-04-16T13:27:53.227

3

MATL, 17 16 bytes

Saved one byte creating null array thanks to @LuisMendo

vTbtX<-QI$(f8M+q

Bucket sort. Don't try it with a range greater than 231-1.

Try it online!

Explanation

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

TIL:

  • You can initialize an empty array in MATL using [] and grow it, just like in MATLAB
  • How to use ( for assignment indexing
  • How to use the M automatic clipboard

New day, new TIL:

  • vertcat magically creates an empty array when there's nothing on the stack to concatenate

beaker

Posted 2016-04-15T12:42:31.060

Reputation: 2 349

Add to your TIL: an initial [] can be replaced by v. This is because the default number of inputs of v is the number of elements in the stack – Luis Mendo – 2016-04-18T15:21:38.633

@LuisMendo Sooo... if there is one array on the stack... ? Investigating. – beaker – 2016-04-18T15:27:44.397

Then it does nothing. Think of it as vertcat(STACK{:}) – Luis Mendo – 2016-04-18T15:30:14.597

3

Julia, 28 27 bytes

x->colon(extrema(x)...)∩x

Try it online!

Dennis

Posted 2016-04-15T12:42:31.060

Reputation: 196 637

Does this build a range from min to max, and intersect with the original list? That would be a flavour of https://en.wikipedia.org/wiki/Counting_sort, like a couple other answers: https://codegolf.stackexchange.com/a/117648/30206. (The question does specifically require answers to say what kind of sort it is.)

– Peter Cordes – 2017-11-26T05:37:24.097

3

R, 68 Bytes

Takes input i and outputs o which is the sorted list.

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

Explanation:

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

Avoiding the permutations means it can sort large lists relatively quickly. The "trick" is that subtracting the smallest value from the input leaves a single 0 that determine both the smallest value and the position of the smallest value.

Forgottenscience

Posted 2016-04-15T12:42:31.060

Reputation: 417

2

Clojure, 73 35 bytes

Bogosort :)

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

Earlier version:

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

Reduces to a sorted list r by splitting it into "smaller than i" and "larger than i" parts. I guess this is the insertion sort.

NikoNyrh

Posted 2016-04-15T12:42:31.060

Reputation: 2 361

Nice! I did not know you could recur on an anonymous function. Also didn't know about shuffle. – Matias Bjarland – 2018-05-22T08:47:47.930

2

Ruby, 26 24 bytes

Selection sort, similar to Value Ink's answer, but using a different approach for greater golfiness.

According to the specification: "Input/output can be done in any method you choose, as long as it is human readable". I think this fits the description, output is an array of arrays with a single element.

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

example:

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

G B

Posted 2016-04-15T12:42:31.060

Reputation: 11 099

2

Java 7, 106 104 bytes

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;}}

Here's a good ole bubble sort. The function parameter is modified in place so I don't have to return anything. Still trying to squeeze some bytes out of this so I can beat the java lambda that someone posted.

-1 byte thanks to Geobits for pointing out that normal swapping beats xor'ing
-1 byte thanks to Leaky Nun for pointing out that I can move all the int declarations into the for-loop

Try it online!

Poke

Posted 2016-04-15T12:42:31.060

Reputation: 3 075

2

Ruby, 22 bytes

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

Builds an array out of the range between the minimum and maximum elements of the input array. Returns the intersection between the two arrays.

dkudriavtsev

Posted 2016-04-15T12:42:31.060

Reputation: 5 781

I guess that's a kind of https://en.wikipedia.org/wiki/Counting_sort.

– Peter Cordes – 2017-11-26T04:48:43.903

@PeterCordes That was kinda the point – dkudriavtsev – 2017-11-26T04:52:13.223

The question asks you to describe what kind of sort it is, so I thought it was useful to link to the well-known algorithm as well as just describing what it actually does. – Peter Cordes – 2017-11-26T04:54:06.270

True. Thanks @PeterCordes – dkudriavtsev – 2017-11-26T04:55:08.173

2

Python 3, 53 bytes

lambda l:[i for i in range(min(l),max(l)+1)if i in l]

Try it online!

totallyhuman

Posted 2016-04-15T12:42:31.060

Reputation: 15 378

This is essentially a bucket sort, right? So it fails if the input doesn't fall in the range of the hash table size? Can that happen? – Jakob – 2017-08-28T00:02:36.500

@Jakob I don't think so? To me it's just a range between min and max values, filtered with the input list – ASCII-only – 2017-08-28T00:14:32.503

@ASCII-only: agreed. Filtering the range between min and max looks like an implementation of https://en.wikipedia.org/wiki/Counting_sort to me, because it's sort of like making a histogram. (Same as @Mendeleev's Ruby answer)

– Peter Cordes – 2017-11-26T04:57:22.000

2

Retina, 95

Modified bubble sort. I suspect there are much better ways to do this, even without the retina sort builtin.

-\d+
$*n
\d+
$*11
+`(1+) (n+)
$2 $1
+`\b(n+) (\1n+)|(1+)(1+) \3\b
$2$3 $1$3$4
1(1*)
$.1
n+
-$.&
  • Stage 1 - convert -ve integers to unary with n as the digit; drop the - signs.
  • Stage 2 - convert +ve and zero integers to unary with 1 as the digit; add 1 to each one, so that zero is represented by 1.
  • Stage 3 - Move all -ves to the front.
  • Stage 4 - Sort: move all -ves with the largest magnitude (i.e. smallest numerical) ahead of higher -ves. Move smaller +ves ahead of larger +ves.
  • Stage 5 - Remove 1 from, and convert +ve unaries back to decimal.
  • Stage 6 - convert -ve unaries back to decimal, including sign.

Try it online.

Digital Trauma

Posted 2016-04-15T12:42:31.060

Reputation: 64 644

Just one byte shorter! – Leaky Nun – 2016-04-16T16:37:36.200

@LeakyNun That doesn't sort the last element in the list. – mbomb007 – 2017-04-25T20:45:31.747

@mbomb007 right, never mind. – Leaky Nun – 2017-04-26T01:24:57.867

2

Ruby, 22 bytes

A quick permutation sort. Runs in O(n!) space and time.

->a{a.permutation.min}

MegaTom

Posted 2016-04-15T12:42:31.060

Reputation: 3 787

1

Tcl, 49: sleep sort

The examples so far aren't very consistent in how they take input, so this sorts command-line arguments. On particularly slow systems, where the foreach takes more than a millisecond, it might need three extra bytes (after ${x}0).

foreach x $argv {after $x puts $x}
vwait forever

tclfancier

Posted 2016-04-15T12:42:31.060

Reputation: 11

1

SmileBASIC, 79 bytes

DEF S A
FOR Z=0TO I
FOR I=1TO LEN(A)-1SWAP A[I-(A[I-1]>A[I])],A[I]NEXT
NEXT
END

It's bubble sort but instead of checking to see if it's finished, it just assumes that every input is the worst case and does n^2 (actually n*(n+2)) iterations.

12Me21

Posted 2016-04-15T12:42:31.060

Reputation: 6 110

IDK if it saves bytes in your case, but BubbleSort leaves the last Z elements sorted, so you can use the outer loop counter as the inner loop bound (if the outer loop counts down), like https://en.wikipedia.org/wiki/Bubble_sort#Optimizing_bubble_sort describes. (See my well-commented x86 asm bubblesort)

– Peter Cordes – 2017-11-26T05:03:24.230

1

Perl 5, 65 bytes

Insertion sort subroutine:

sub r{map{$t=0;$_[$_]<$_[$t]&&($t=$_)for 0..$#_;splice@_,$t,1}@_}

Try it online!

Xcali

Posted 2016-04-15T12:42:31.060

Reputation: 7 671

1

R, 47 bytes

implements bogosort.

function(l){while(is.unsorted(l))l=sample(l);l}

Try it online!

Giuseppe

Posted 2016-04-15T12:42:31.060

Reputation: 21 077

1

Dodos, 75 bytes

	/
/
	/ s w
w
	h
	/ t
s
	s R
R
	t
	h
h
	t I q
q
	dot t
	dot
I
	I dip
t
	dab

Try it online!

Only support non negative integers. Terrible runtime, especially for large numbers.


Explanation

First, define t to be the tail of a list. (all elements except the first)

Given a list [x,y] where x<y, function I computes the incremental difference (with a 0 prepended), which is used in h (head of a list, by getting the sum of all elements, subtract by the sum of all elements except the first)

Function R reverses a list of 2 elements. (concatenate the tail and the head) Generally, it rotates the first element to the last.

s sorts a list of 2 elements. Generally, given a list, it find the least non negative n such that rotate the list left by n make the list less than itself Red.

/ sorts a list of arbitrarily many elements, by / the list' tail, and then / s the result.

user202729

Posted 2016-04-15T12:42:31.060

Reputation: 14 620

1

Jolf, 13 bytes

Uses bogosort. Try it out here! Replace with \x7f. Input is a comma-separated list of numbers like 5,3,2,4,1.

W⌂Z,k)ok Tk}k

Explanation:

W⌂Z,k)ok Tk}k
W    )         while
 ⌂Z,            !isSorted
    k            input {
      ok          k =
        _Tk        shuffle(k)
           }   }
            k  out k

Conor O'Brien

Posted 2016-04-15T12:42:31.060

Reputation: 36 228

1

Python 2, 159

Implements bozosort (randomly swap two elements until the array is sorted).

It's not very efficient...

from random import randint as r
def b(l):
 s,a=len(l)-1,0
 while not a:
        c,d=r(0,s),r(0,s);l[d],l[c]=l[c],l[d];e,a=l[0],1
        for f in l:a,e=a*(f>=e),f
 return l

Numeri says Reinstate Monica

Posted 2016-04-15T12:42:31.060

Reputation: 151

2you can save a couple of bytes by indenting s,a=..., while not a: and return l with a single space, and the contents of the while loop with a single tab because tab is considered deeper indentation than space. that will make this answer python2 only, though – undergroundmonorail – 2016-05-20T00:16:10.623

@undergroundmonorail Thanks! – Numeri says Reinstate Monica – 2016-05-20T13:58:32.480

You can probably use while a<1, or if a is always 0 or 1, you can use while~-a – mbomb007 – 2017-04-25T20:46:46.533

1

Javascript 55 bytes

a=>[...a].map(b=>a.splice(a.indexOf(Math.min(...a)),1)

Bálint

Posted 2016-04-15T12:42:31.060

Reputation: 1 847

Doesn't work for me on Firefox; for the sample input I get [[-22], [-2], [4], [23], [36], [43], , , , , , ,]. – Neil – 2016-05-19T19:33:20.313

@Neil yeah, missed something – Bálint – 2016-05-19T19:44:31.313

0

C#, 125 bytes

using System.Linq;x=>{for(int i=0;i<x.Count;i++){int temp=x.GetRange(i,x.Count-i).Min();x[x.IndexOf(temp)]=x[i];x[i]=temp;}};

It uses the selection sort. I don't need to return the sorted list, because in C# lists are reference types, so the variable only holds a reference to the actual object, and if I change the object from here, it'll be visible at other places, as described in this stackoverflow question.

Horváth Dávid

Posted 2016-04-15T12:42:31.060

Reputation: 679

0

Tcl, 160 bytes

set i 0
time {incr j;set x 0;while \$x<$i {if [lindex $L $i]<[lindex $L $x] {set L [lreplace [linsert $L $x [lindex $L $i]] $j $j]};incr x};incr i} [llength $L]

Try it online!

Without even thinking on a "standard" method, I implement it by using Insertion Sort.

sergiol

Posted 2016-04-15T12:42:31.060

Reputation: 3 055

0

Attache, 36 bytes

{If[#_,Min[_]'$[Remove[_,Min!_]],_]}

Try it online!

Selection sort. Recursively sorts the list by concatenating the minimum with the sorted removed list.

Conor O'Brien

Posted 2016-04-15T12:42:31.060

Reputation: 36 228

0

Haskell, 97 bytes

s=f.map pure
a@(x:y)!b@(z:w)|x>z=z:a!w|0<1=x:y!b
a!b=a++b
d(x:y:z)=x!y:d z
d p=p
f[x]=x
f x=f$d x

Try it online!

A stable, incremental merge sort.

dfeuer

Posted 2016-04-15T12:42:31.060

Reputation: 1 016

0

Haskell, 3332 bytes

import Data.Set
s=elems.fromList

Try it online!

dfeuer

Posted 2016-04-15T12:42:31.060

Reputation: 1 016

0

Javascript

for(i=0;i<size;i++){for(j=i+1;j<size;j++){if(num[i]>num[j]){swap=num[j];num[j]=num[i];num[i]=swap;}}}for(i=0;i<size;i++)console.log(num[i])

Here's an implementation of bubble sort.

Jeyanth

Posted 2016-04-15T12:42:31.060

Reputation: 133

0

JavaScript, 42 bytes

a=>Object.keys(a.reduce((o,k)=>o[k]=o,{}))

Note: doesn't work for negative numbers. The iteration order of an object's keys are defined as such in the current spec, requiring that all numerical indexes are iterated in sorted numerical order first.

kamoroso94

Posted 2016-04-15T12:42:31.060

Reputation: 739

0

Pyth, 8 bytes

_ueg#G.p

Try it online!

  • ueg#G.p:
    • u Repeatedly apply the following function to the input until the result stops changing.
    • .p: Generate all permutations of the current list
    • g#G:
      • #: Filter the list of permutations
      • g: On being greater than or equal to
      • G: The current list
    • e: Take the last permutation in the filtered list. This will only be the same as the current list if the filter only leaves behind one list, because the permutation function .p always puts its input first.

At this point, we have the maximum permutation of the input, which is in reverse sorted order. _ reverses that to give the sorted list.


Note that Pyth does not have an opposite of g - there is no less than or equal to builtin.


I wanted to see what the intermediate lists are when sorting with this method. Putting a newline at the end of the code prints all of the intermediate lists:

Try it online!

For the input [0,7,4,1,6,5,2,3], here's what the intermediate lists look like:

[0, 7, 4, 1, 6, 5, 2, 3]
[3, 2, 5, 6, 1, 4, 7, 0]
[7, 0, 4, 1, 6, 5, 2, 3]
[7, 3, 2, 5, 6, 1, 4, 0]
[7, 4, 0, 1, 6, 5, 2, 3]
[7, 5, 3, 2, 6, 1, 0, 4]
[7, 6, 4, 0, 1, 2, 3, 5]
[7, 6, 5, 3, 2, 1, 0, 4]
[7, 6, 5, 4, 0, 1, 2, 3]
[7, 6, 5, 4, 3, 2, 1, 0]
[0, 1, 2, 3, 4, 5, 6, 7]

Basically, what's happening is that at each step, the (reverse) sorted prefix stays, and then the last number larger than the front unsorted number is moved to the front of the unsorted region, and the rest of the unsorted region is reversed. It's like a low-quality selection sort with reversals thrown in for fun.

I think this runs in approximately O(n^2 n!) time - n! permutations, n comparisons each, and O(n) rounds (at most 2n, from what I can tell.

isaacg

Posted 2016-04-15T12:42:31.060

Reputation: 39 268