Sorting algorithms/Sleep sort: Difference between revisions
(138 intermediate revisions by 75 users not shown) | |||
Line 1: | Line 1: | ||
{{task|Sorting Algorithms |
{{task|Sorting Algorithms}} |
||
{{Sorting Algorithm}} |
|||
[[Category:Sorting]] |
|||
In general, sleep sort works by starting a separate task for each item to be sorted, where each task sleeps for an interval corresponding to the item's sort key, then emits the item. Items are then collected sequentially in time. |
In general, sleep sort works by starting a separate task for each item to be sorted, where each task sleeps for an interval corresponding to the item's sort key, then emits the item. Items are then collected sequentially in time. |
||
Task: Write a program that implements sleep sort. Have it accept non-negative integers on the command line and print the integers in sorted order. If this is not idomatic in your language or environment, input and output may be done differently. Enhancements for optimization, generalization, practicality, robustness, and so on are not required. |
Task: Write a program that implements sleep sort. Have it accept non-negative integers on the command line and print the integers in sorted order. If this is not idomatic in your language or environment, input and output may be done differently. Enhancements for optimization, generalization, practicality, robustness, and so on are not required. |
||
Sleep sort was [ |
Sleep sort was [https://archive.fo/xhGo presented] anonymously on 4chan and has been [http://news.ycombinator.com/item?id=2657277 discussed] on Hacker News. |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
with Ada.Command_Line; use Ada.Command_Line; |
with Ada.Command_Line; use Ada.Command_Line; |
||
procedure SleepSort is |
procedure SleepSort is |
||
Line 21: | Line 24: | ||
TaskList(i) := new PrintTask(Integer'Value(Argument(i))); |
TaskList(i) := new PrintTask(Integer'Value(Argument(i))); |
||
end loop; |
end loop; |
||
end SleepSort;</ |
end SleepSort;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>./sleepsort 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 |
<pre>./sleepsort 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 |
||
1 2 7 8 11 14 20 20 21 25 27 30 32 35 41 42 42 43 46 50</pre> |
1 2 7 8 11 14 20 20 21 25 27 30 32 35 41 42 42 43 46 50</pre> |
||
=={{header|APL}}== |
|||
<syntaxhighlight lang="apl"> |
|||
sleepsort←{{r}⎕TSYNC{r,←⊃⍵,⎕DL ⍵}&¨⍵,r←⍬} |
|||
</syntaxhighlight> |
|||
=={{header|Assembly}}== |
|||
{{works with|flat assembler for Linux x64}} |
|||
<syntaxhighlight lang="asm"> |
|||
format ELF64 executable 3 |
|||
entry start |
|||
; parameters: argc, argv[] on stack |
|||
start: |
|||
mov r12, [rsp] ; get argc |
|||
mov r13, 1 ; skip argv[0] |
|||
.getargv: |
|||
cmp r13, r12 ; check completion of args |
|||
je .wait |
|||
mov rdi, [rsp+8+8*r13] ; get argv[n] |
|||
inc r13 |
|||
mov rax, 57 ; sys_fork |
|||
syscall |
|||
cmp rax, 0 ; continue loop in main process |
|||
jnz .getargv |
|||
push rdi ; save pointer to sort item text |
|||
call atoi_simple ; convert text to integer |
|||
test rax, rax ; throw out bad input |
|||
js .done |
|||
sub rsp, 16 ; stack space for timespec |
|||
mov [rsp], rax ; seconds |
|||
mov qword [rsp+8], 0 ; nanoseconds |
|||
lea rdi, [rsp] |
|||
xor rsi, rsi |
|||
mov rax, 35 ; sys_nanosleep |
|||
syscall |
|||
add rsp, 16 |
|||
pop rdi ; retrieve item text |
|||
call strlen_simple |
|||
mov rsi, rdi |
|||
mov byte [rsi+rax], ' ' |
|||
mov rdi, 1 |
|||
mov rdx, rax |
|||
inc rdx |
|||
mov rax, 1 ; sys_write |
|||
syscall |
|||
jmp .done |
|||
.wait: |
|||
dec r12 ; wait for each child process |
|||
jz .done |
|||
mov rdi, 0 ; any pid |
|||
mov rsi, 0 |
|||
mov rdx, 0 |
|||
mov r10, 4 ; that has terminated |
|||
mov rax, 247 ; sys_waitid |
|||
syscall |
|||
jmp .wait |
|||
.done: |
|||
xor rdi, rdi |
|||
mov rax, 60 ; sys_exit |
|||
syscall |
|||
; parameter: rdi = string pointer |
|||
; return: rax = integer conversion |
|||
atoi_simple: |
|||
push rdi |
|||
push rsi |
|||
xor rax, rax |
|||
.convert: |
|||
movzx rsi, byte [rdi] |
|||
test rsi, rsi ; check for null |
|||
jz .done |
|||
cmp rsi, '0' |
|||
jl .baddigit |
|||
cmp rsi, '9' |
|||
jg .baddigit |
|||
sub rsi, 48 ; get ascii code for digit |
|||
imul rax, 10 ; radix 10 |
|||
add rax, rsi ; add current digit to total |
|||
inc rdi |
|||
jmp .convert |
|||
.baddigit: |
|||
mov rax, -1 ; return error code on failed conversion |
|||
.done: |
|||
pop rsi |
|||
pop rdi |
|||
ret ; return integer value |
|||
; parameter: rdi = string pointer |
|||
; return: rax = length |
|||
strlen_simple: |
|||
xor rax, rax |
|||
.compare: |
|||
cmp byte [rdi+rax], 0 |
|||
je .done |
|||
inc rax |
|||
jmp .compare |
|||
.done: |
|||
ret |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
./sleepsort 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 |
|||
1 2 7 8 11 14 20 20 21 25 27 30 32 35 41 42 42 43 46 50 |
|||
</pre> |
|||
=={{header|AutoHotkey}}== |
|||
<syntaxhighlight lang="autohotkey">items := [1,5,4,9,3,4] |
|||
for i, v in SleepSort(items) |
|||
result .= v ", " |
|||
MsgBox, 262144, , % result := "[" Trim(result, ", ") "]" |
|||
return |
|||
SleepSort(items){ |
|||
global Sorted := [] |
|||
slp := 50 |
|||
for i, v in items{ |
|||
fn := Func("PushFn").Bind(v) |
|||
SetTimer, %fn%, % v * -slp |
|||
} |
|||
Sleep % Max(items*) * slp |
|||
return Sorted |
|||
} |
|||
PushFn(v){ |
|||
global Sorted |
|||
Sorted.Push(v) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>[1, 3, 4, 4, 5, 9]</pre> |
|||
=={{header|Bash}}== |
|||
<syntaxhighlight lang="bash"> |
|||
function sleep_and_echo { |
|||
sleep "$1" |
|||
echo "$1" |
|||
} |
|||
for val in "$@"; do |
|||
sleep_and_echo "$val" & |
|||
done |
|||
wait |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
$ ./sleep_sort.sh 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 |
|||
1 |
|||
2 |
|||
7 |
|||
8 |
|||
11 |
|||
14 |
|||
20 |
|||
20 |
|||
21 |
|||
25 |
|||
27 |
|||
30 |
|||
32 |
|||
35 |
|||
41 |
|||
42 |
|||
42 |
|||
43 |
|||
46 |
|||
50 |
|||
</pre> |
|||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
This does not explicitly 'sleep', but uses timers to implement the different delays. |
This does not explicitly 'sleep', but uses timers to implement the different delays. |
||
< |
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB" |
||
DIM test%(9) |
DIM test%(9) |
||
Line 52: | Line 248: | ||
DEF PROCtask7 : PRINT test%(7) : ENDPROC |
DEF PROCtask7 : PRINT test%(7) : ENDPROC |
||
DEF PROCtask8 : PRINT test%(8) : ENDPROC |
DEF PROCtask8 : PRINT test%(8) : ENDPROC |
||
DEF PROCtask9 : PRINT test%(9) : ENDPROC</ |
DEF PROCtask9 : PRINT test%(9) : ENDPROC</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 66: | Line 262: | ||
782 |
782 |
||
</pre> |
</pre> |
||
=={{header|Brainf***}}== |
|||
<syntaxhighlight lang="c"> |
|||
>>>>>,----------[++++++++ |
|||
++[->+>+<<]>+>[-<<+>>]+++ |
|||
+++++[-<------>]>>+>,---- |
|||
------<<+[->>>>>+<<<<<]>> |
|||
]>>>[<<<<[<<<[->>+<<[->+> |
|||
[-]<<]]>[-<+>]>[-<<<.>>>> |
|||
->>>>>[>>>>>]<-<<<<[<<<<< |
|||
]+<]<<<<]>>>>>[>>>>>]<] |
|||
</syntaxhighlight> |
|||
Not exactly 'sleep' sort but it is similar: it inputs an array of digits and in each iteration reduces elements by 1. When an element becomes 0 – it prints the original digit. |
|||
Input: 1539\n |
|||
Output: 1359 |
|||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<syntaxhighlight lang="c">#include <stdlib.h> |
||
#include <unistd.h> |
#include <unistd.h> |
||
#include <sys/types.h> |
#include <sys/types.h> |
||
Line 80: | Line 293: | ||
wait(0); |
wait(0); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
Running it:<lang>% ./a.out 5 1 3 2 11 6 4 |
Running it:<syntaxhighlight lang="text">% ./a.out 5 1 3 2 11 6 4 |
||
1 |
1 |
||
2 |
2 |
||
Line 88: | Line 301: | ||
5 |
5 |
||
6 |
6 |
||
11</ |
11</syntaxhighlight> |
||
If you worry about time efficiency of this sorting algorithm (ha!), you can make it a 100 times faster by replacing the <code>sleep(...</code> with <code>usleep(10000 * (c = atoi(v[c])))</code>. The smaller the coefficient, the faster it is, but make sure it's not comparable to your kernel clock ticks or the wake up sequence will be wrong. |
If you worry about time efficiency of this sorting algorithm (ha!), you can make it a 100 times faster by replacing the <code>sleep(...</code> with <code>usleep(10000 * (c = atoi(v[c])))</code>. The smaller the coefficient, the faster it is, but make sure it's not comparable to your kernel clock ticks or the wake up sequence will be wrong. |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
using System.Linq; |
using System.Linq; |
||
Line 117: | Line 330: | ||
SleepSort(arguments.Select(int.Parse)); |
SleepSort(arguments.Select(int.Parse)); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Using Tasks=== |
|||
<syntaxhighlight lang="csharp">var input = new[] { 1, 9, 2, 1, 3 }; |
|||
foreach (var n in input) |
|||
Task.Run(() => |
|||
{ |
|||
Thread.Sleep(n * 1000); |
|||
Console.WriteLine(n); |
|||
}); |
|||
</syntaxhighlight> |
|||
Output, i.e. in LINQPad: |
|||
<pre>1 |
|||
1 |
|||
2 |
|||
3 |
|||
9</pre> |
|||
=={{header|C++}}== |
|||
<syntaxhighlight lang="cpp"> |
|||
#include <chrono> |
|||
#include <iostream> |
|||
#include <thread> |
|||
#include <vector> |
|||
int main(int argc, char* argv[]) { |
|||
std::vector<std::thread> threads; |
|||
for (int i = 1; i < argc; ++i) { |
|||
threads.emplace_back([i, &argv]() { |
|||
int arg = std::stoi(argv[i]); |
|||
std::this_thread::sleep_for(std::chrono::seconds(arg)); |
|||
std::cout << argv[i] << std::endl; |
|||
}); |
|||
} |
|||
for (auto& thread : threads) { |
|||
thread.join(); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
./a.out 8 15 14 9 17 20 16 24 6 24 21 23 19 23 19 |
|||
6 |
|||
8 |
|||
9 |
|||
14 |
|||
15 |
|||
16 |
|||
17 |
|||
19 |
|||
19 |
|||
20 |
|||
21 |
|||
23 |
|||
23 |
|||
24 |
|||
24 |
|||
</pre> |
|||
=={{header|Clojure}}== |
|||
Using core.async |
|||
<syntaxhighlight lang="clojure">(ns sleepsort.core |
|||
(require [clojure.core.async :as async :refer [chan go <! <!! >! timeout]])) |
|||
(defn sleep-sort [l] |
|||
(let [c (chan (count l))] |
|||
(doseq [i l] |
|||
(go (<! (timeout (* 1000 i))) |
|||
(>! c i))) |
|||
(<!! (async/into [] (async/take (count l) c)))))</syntaxhighlight> |
|||
<syntaxhighlight lang="clojure">(sleep-sort [4 5 3 1 2 7 6]) |
|||
;=> [1 2 3 4 5 6 7]</syntaxhighlight> |
|||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
{{works_with|node.js}} |
{{works_with|node.js}} |
||
< |
<syntaxhighlight lang="coffeescript"> |
||
after = (s, f) -> setTimeout f, s*1000 |
after = (s, f) -> setTimeout f, s*1000 |
||
Line 132: | Line 423: | ||
input = (parseInt(arg) for arg in process.argv[2...]) |
input = (parseInt(arg) for arg in process.argv[2...]) |
||
sleep_sort input |
sleep_sort input |
||
</syntaxhighlight> |
|||
</lang> |
|||
output |
output |
||
<lang> |
<syntaxhighlight lang="text"> |
||
> time coffee sleep_sort.coffee 5, 1, 3, 4, 2 |
> time coffee sleep_sort.coffee 5, 1, 3, 4, 2 |
||
1 |
1 |
||
Line 145: | Line 436: | ||
user 0m0.147s |
user 0m0.147s |
||
sys 0m0.024s |
sys 0m0.024s |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header| |
=={{header|Common Lisp}}== |
||
{{works_with|SBCL}} |
|||
<lang d>import std.stdio, std.conv, std.datetime, core.thread; |
|||
<syntaxhighlight lang="lisp">(defun sleeprint(n) |
|||
(sleep (/ n 10)) |
|||
(format t "~a~%" n)) |
|||
(loop for arg in (cdr sb-ext:*posix-argv*) doing |
|||
final class SleepSorter: Thread { |
|||
(sb-thread:make-thread (lambda() (sleeprint (parse-integer arg))))) |
|||
private immutable uint val; |
|||
(loop while (not (null (cdr (sb-thread:list-all-threads)))))</syntaxhighlight> |
|||
this(in uint n) { |
|||
{{Out}} |
|||
super(&run); |
|||
<pre>$ sbcl --script ss.cl 3 1 4 1 5 |
|||
val = n; |
|||
1 |
|||
} |
|||
1 |
|||
3 |
|||
4 |
|||
5 |
|||
</pre> |
|||
=={{header|D}}== |
|||
private void run() { |
|||
<syntaxhighlight lang="d">void main(string[] args) |
|||
Thread.sleep(dur!"msecs"(1000 * val)); |
|||
{ |
|||
writef("%d ", val); |
|||
import core.thread, std; |
|||
} |
|||
args.drop(1).map!(a => a.to!uint).parallel.each!((a) |
|||
} |
|||
{ |
|||
Thread.sleep(dur!"msecs"(a)); |
|||
write(a, " "); |
|||
}); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>$ ./sorting_algorithms_sleep_sort 200 20 50 10 80 |
|||
10 20 50 80 200</pre> |
|||
=={{header|Dart}}== |
|||
void main(in string[] args) { |
|||
<syntaxhighlight lang="dart"> |
|||
if (args.length > 1) |
|||
void main() async { |
|||
foreach (arg; args[1 .. $]) |
|||
Future<void> sleepsort(Iterable<int> input) => Future.wait(input |
|||
(new SleepSorter(to!uint(arg))).start(); |
|||
.map((i) => Future.delayed(Duration(milliseconds: i), () => print(i)))); |
|||
}</lang> |
|||
<pre>sorting_algorithms_sleep_sort 1 6 2 5 3 4 |
|||
await sleepsort([3, 10, 2, 120, 122, 121, 54]); |
|||
1 2 3 4 5 6</pre> |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
2 |
|||
3 |
|||
10 |
|||
54 |
|||
120 |
|||
121 |
|||
122 |
|||
</pre> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi">program SleepSortDemo; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 231: | Line 550: | ||
Writeln; |
Writeln; |
||
ReadLn; |
ReadLn; |
||
end.</ |
end.</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 237: | Line 556: | ||
0 0 0 1 1 2 3 4 4 4 5 6 7 10 12 12 |
0 0 0 1 1 2 3 4 4 4 5 6 7 10 12 12 |
||
</pre> |
</pre> |
||
=={{header|Elena}}== |
|||
ELENA 6.0 : |
|||
<syntaxhighlight lang="elena">import extensions; |
|||
import system'routines; |
|||
import extensions'threading; |
|||
import system'threading; |
|||
static sync = new object(); |
|||
extension op |
|||
{ |
|||
sleepSort() |
|||
{ |
|||
self.forEach::(n) |
|||
{ |
|||
threadControl.start( |
|||
{ |
|||
threadControl.sleep(1000 * n); |
|||
lock(sync) |
|||
{ |
|||
console.printLine(n) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
public program() |
|||
{ |
|||
program_arguments.skipping(1).selectBy(mssgconst toInt<intConvertOp>[1]).toArray().sleepSort(); |
|||
console.readChar() |
|||
}</syntaxhighlight> |
|||
=={{header|Elixir}}== |
|||
{{trans|Erlang}} |
|||
<syntaxhighlight lang="elixir">defmodule Sort do |
|||
def sleep_sort(args) do |
|||
Enum.each(args, fn(arg) -> Process.send_after(self, arg, 5 * arg) end) |
|||
loop(length(args)) |
|||
end |
|||
defp loop(0), do: :ok |
|||
defp loop(n) do |
|||
receive do |
|||
num -> IO.puts num |
|||
loop(n - 1) |
|||
end |
|||
end |
|||
end |
|||
Sort.sleep_sort [2, 4, 8, 12, 35, 2, 12, 1]</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
2 |
|||
2 |
|||
4 |
|||
8 |
|||
12 |
|||
12 |
|||
35 |
|||
</pre> |
|||
=={{header|Emacs Lisp}}== |
|||
GNU Emacs supports threads, but it's more straightforward to do this by just using timers. |
|||
Evaluate in the *scratch* buffer by typing <code>C-M-x</code> on the expression: |
|||
<syntaxhighlight lang="lisp">(dolist (i '(3 1 4 1 5 92 65 3 5 89 79 3)) |
|||
(run-with-timer (* i 0.001) nil 'message "%d" i))</syntaxhighlight> |
|||
The output printed in the *Messages* buffer is: |
|||
<pre> |
|||
1 [2 times] |
|||
3 [3 times] |
|||
4 |
|||
5 [2 times] |
|||
65 |
|||
79 |
|||
89 |
|||
92 |
|||
</pre> |
|||
=={{header|Erlang}}== |
|||
<syntaxhighlight lang="erlang">#!/usr/bin/env escript |
|||
%% -*- erlang -*- |
|||
%%! -smp enable -sname sleepsort |
|||
main(Args) -> |
|||
lists:foreach(fun(Arg) -> |
|||
timer:send_after(5 * list_to_integer(Arg), self(), Arg) |
|||
end, Args), |
|||
loop(length(Args)). |
|||
loop(0) -> |
|||
ok; |
|||
loop(N) -> |
|||
receive |
|||
Num -> |
|||
io:format("~s~n", [Num]), |
|||
loop(N - 1) |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>./sleepsort 2 4 8 12 35 2 12 1 |
|||
1 |
|||
2 |
|||
2 |
|||
4 |
|||
8 |
|||
12 |
|||
12 |
|||
35</pre> |
|||
=={{header|Euphoria}}== |
=={{header|Euphoria}}== |
||
< |
<syntaxhighlight lang="euphoria">include get.e |
||
integer count |
integer count |
||
Line 269: | Line 702: | ||
task_yield() |
task_yield() |
||
end while |
end while |
||
end if</ |
end if</syntaxhighlight> |
||
=={{header|F_Sharp|F#}}== |
|||
<syntaxhighlight lang="fsharp"> |
|||
let sleepSort (values: seq<int>) = |
|||
values |
|||
|> Seq.map (fun x -> async { |
|||
do! Async.Sleep x |
|||
Console.WriteLine x |
|||
}) |
|||
|> Async.Parallel |
|||
|> Async.Ignore |
|||
|> Async.RunSynchronously |
|||
</syntaxhighlight> |
|||
Usage: |
|||
<syntaxhighlight lang="fsharp"> |
|||
sleepSort [10; 33; 80; 32] |
|||
10 |
|||
32 |
|||
33 |
|||
80 |
|||
</syntaxhighlight> |
|||
=={{header|Factor}}== |
|||
<syntaxhighlight lang="factor"> |
|||
USING: threads calendar concurrency.combinators ; |
|||
: sleep-sort ( seq -- ) [ dup seconds sleep . ] parallel-each ; |
|||
</syntaxhighlight> |
|||
Usage: |
|||
<syntaxhighlight lang="factor"> |
|||
{ 1 9 2 6 3 4 5 8 7 0 } sleep-sort |
|||
</syntaxhighlight> |
|||
=={{header|Fortran}}== |
|||
<syntaxhighlight lang="fortran"> |
|||
program sleepSort |
|||
use omp_lib |
|||
implicit none |
|||
integer::nArgs,myid,i,stat |
|||
integer,allocatable::intArg(:) |
|||
character(len=5)::arg |
|||
!$omp master |
|||
nArgs=command_argument_count() |
|||
if(nArgs==0)stop ' : No argument is given !' |
|||
allocate(intArg(nArgs)) |
|||
do i=1,nArgs |
|||
call get_command_argument(i, arg) |
|||
read(arg,'(I5)',iostat=stat)intArg(i) |
|||
if(intArg(i)<0 .or. stat/=0) stop& |
|||
&' :Only 0 or positive integer allowed !' |
|||
end do |
|||
call omp_set_num_threads(nArgs) |
|||
!$omp end master |
|||
!$omp parallel private(myid) |
|||
myid =omp_get_thread_num() |
|||
call sleepNprint(intArg(myid+1)) |
|||
!$omp end parallel |
|||
contains |
|||
subroutine sleepNprint(nSeconds) |
|||
integer::nSeconds |
|||
call sleep(nSeconds) |
|||
print*,nSeconds |
|||
end subroutine sleepNprint |
|||
end program sleepSort |
|||
</syntaxhighlight> |
|||
Compile and Output: |
|||
<pre> |
|||
gfortran -fopenmp sleepSort.f90 -o sleepSort |
|||
./sleepSort 0 3 1 4 1 5 9 |
|||
0 |
|||
1 |
|||
1 |
|||
3 |
|||
4 |
|||
5 |
|||
9 |
|||
</pre> |
|||
=={{header|FreeBASIC}}== |
|||
Can't use FreeBASIC '''sleep''' since it halts the program. |
|||
Instead it uses a second array filled with times based on the value of number, this array is check against the timer. If the timer is past the stored time the value is printed. |
|||
<syntaxhighlight lang="freebasic">' version 21-10-2016 |
|||
' compile with: fbc -s console |
|||
' compile with: fbc -s console -exx (for bondry check on the array's) |
|||
' not very well suited for large numbers and large array's |
|||
' positive numbers only |
|||
Sub sandman(sleepy() As ULong) |
|||
Dim As Long lb = LBound(sleepy) |
|||
Dim As Long ub = UBound(sleepy) |
|||
Dim As Long i, count = ub |
|||
Dim As Double wakeup(lb To ub) |
|||
Dim As Double t = Timer |
|||
For i = lb To ub |
|||
wakeup(i) = sleepy(i) +1 + t |
|||
Next |
|||
Do |
|||
t = Timer |
|||
For i = lb To ub |
|||
If wakeup(i) <= t Then |
|||
Print Using "####";sleepy(i); |
|||
wakeup(i) = 1e9 ' mark it as used |
|||
count = count -1 |
|||
End If |
|||
Next |
|||
Sleep (1 - (Timer - t)) * 300, 1 ' reduce CPU load |
|||
Loop Until count < lb |
|||
End Sub |
|||
' ------=< MAIN >=------ |
|||
Dim As ULong i, arr(10) |
|||
Dim As ULong lb = LBound(arr) |
|||
Dim As ULong ub = UBound(arr) |
|||
Randomize Timer |
|||
For i = lb To ub -1 ' leave last one zero |
|||
arr(i) = Int(Rnd * 10) +1 |
|||
Next |
|||
Print "unsorted "; |
|||
For i = lb To ub |
|||
Print Using "####";arr(i); |
|||
Next |
|||
Print : Print |
|||
Print " sorted "; |
|||
sandman(arr()) |
|||
Print : Print |
|||
' empty keyboard buffer |
|||
While InKey <> "" : Wend |
|||
Print : Print "hit any key to end program" |
|||
Sleep |
|||
End</syntaxhighlight> |
|||
{{out}} |
|||
<pre>unsorted 5 2 5 6 4 6 9 5 1 2 0 |
|||
sorted 0 1 2 2 4 5 5 5 6 6 9</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
"fmt" |
|||
"log" |
|||
"os" |
|||
"strconv" |
|||
"strconv" |
|||
"sync" |
|||
"time" |
|||
) |
) |
||
func main() { |
func main() { |
||
out := make(chan uint64) |
|||
lg := log.New(os.Stdout, "", 0) |
|||
for _, a := range os.Args[1:] { |
|||
var wg sync.WaitGroup |
|||
i, err := strconv.ParseUint(a, 10, 64) |
|||
wg.Add(len(os.Args) - 1) |
|||
if err != nil { |
|||
for _, a := range os.Args[1:] { |
|||
log.Fatal(err) |
|||
if i, err := strconv.ParseInt(a, 10, 64); err != nil { |
|||
} |
|||
lg.Print(err) |
|||
go func(n uint64) { |
|||
wg.Done() |
|||
time.Sleep(time.Duration(n) * time.Millisecond) |
|||
} else { |
|||
out <- n |
|||
time.AfterFunc(time.Duration(i*int64(time.Second)), func() { |
|||
}(i) |
|||
lg.Print(i) |
|||
} |
|||
wg.Done() |
|||
for _ = range os.Args[1:] { |
|||
}) |
|||
fmt.Println(<-out) |
|||
} |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
wg.Wait() |
|||
}</lang> |
|||
Usage and output: |
Usage and output: |
||
<pre>./sleepsort 3 1 4 1 5 9 |
<pre>./sleepsort 3 1 4 1 5 9 |
||
Line 308: | Line 891: | ||
9 |
9 |
||
</pre> |
</pre> |
||
=== Using sync.WaitGroup === |
|||
<syntaxhighlight lang="go">package main |
|||
import ( |
|||
"fmt" |
|||
"log" |
|||
"os" |
|||
"strconv" |
|||
"sync" |
|||
"time" |
|||
) |
|||
func main() { |
|||
var wg sync.WaitGroup |
|||
wg.Add(len(os.Args[1:])) |
|||
for _,i := range os.Args[1:] { |
|||
x, err := strconv.ParseUint(i, 10, 64) |
|||
if err != nil { |
|||
log.Println(err) |
|||
} |
|||
wg.Add(1) |
|||
go func(i uint64, wg *sync.WaitGroup) { |
|||
defer wg.Done() |
|||
time.Sleep(time.Duration(i) * time.Second) |
|||
fmt.Println(i) |
|||
}(x, &wg) |
|||
} |
|||
wg.Wait() |
|||
}</syntaxhighlight> |
|||
Usage and output are the same as the version using channels. Note that the original version would sleep for increments of 1 full second, so I made my code do the same. |
|||
=={{header|Groovy}}== |
|||
<syntaxhighlight lang="groovy"> |
|||
@Grab(group = 'org.codehaus.gpars', module = 'gpars', version = '1.2.1') |
|||
import groovyx.gpars.GParsPool |
|||
GParsPool.withPool args.size(), { |
|||
args.eachParallel { |
|||
sleep(it.toInteger() * 10) |
|||
println it |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
Sample Run: |
|||
<pre>> groovy sleepsort.groovy 42 23 16 15 8 4 |
|||
4 |
|||
8 |
|||
15 |
|||
16 |
|||
23 |
|||
42</pre> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">import System.Environment |
||
import Control.Concurrent |
import Control.Concurrent |
||
import Control.Monad |
import Control.Monad |
||
Line 317: | Line 954: | ||
sleepSort :: [Int] -> IO () |
sleepSort :: [Int] -> IO () |
||
sleepSort values = do |
sleepSort values = do |
||
chan <- newChan |
|||
forM_ values (\time -> forkIO (threadDelay (50000 * time) >> writeChan chan time)) |
|||
forM_ values (\_ -> readChan chan >>= print) |
|||
main :: IO () |
main :: IO () |
||
main = getArgs >>= sleepSort . map read</ |
main = getArgs >>= sleepSort . map read</syntaxhighlight> |
||
===Using mapConcurrently_=== |
|||
<syntaxhighlight lang="haskell">import System.Environment |
|||
import Control.Concurrent |
|||
import Control.Concurrent.Async |
|||
sleepSort :: [Int] -> IO () |
|||
sleepSort = mapConcurrently_ (\x -> threadDelay (x*10^4) >> print x) |
|||
main :: IO () |
|||
main = getArgs >>= sleepSort . map read</syntaxhighlight> |
|||
This is problematic for inputs with multiple duplicates like <code>[1,2,3,1,4,1,5,1]</code> because simultaneous <code>print</code>s are done concurrently and the 1s and newlines get output in jumbled up order. The channels-based version above doesn't have this problem. |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
The following solution only works in Unicon. |
|||
<syntaxhighlight lang="unicon">procedure main(A) |
|||
every insert(t:=set(),mkThread(t,!A)) |
|||
every spawn(!t) # start threads as closely grouped as possible |
|||
while (*t > 0) do write(<<@) |
|||
end |
|||
procedure mkThread(t,n) # 10ms delay scale factor |
|||
return create (delay(n*10),delete(t,¤t),n@>&main) |
|||
end</syntaxhighlight> |
|||
Sample run: |
|||
<pre> |
|||
->ss 3 1 4 1 5 9 2 6 |
|||
1 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
6 |
|||
9 |
|||
-> |
|||
</pre> |
|||
=={{header|J}}== |
|||
{{works with|J|903+}} |
|||
<syntaxhighlight lang="j">scheduledumb=: {{ |
|||
id=:'dumb',":x:6!:9'' |
|||
wd 'pc ',id |
|||
(t)=: u {{u y[erase n}} t=. id,'_timer' |
|||
wd 'ptimer ',":n p.y |
|||
}} |
|||
ssort=: {{ |
|||
R=: '' |
|||
poly=. 1,>./ y |
|||
poly{{ y{{R=:R,m[y}}scheduledumb m y}}"0 y |
|||
{{echo R}} scheduledumb poly"0 >:>./ y |
|||
EMPTY |
|||
}}</syntaxhighlight> |
|||
Task example: |
|||
<syntaxhighlight lang="j"> t=: ?~30 |
|||
t |
|||
11 7 22 16 17 2 1 19 23 29 9 21 15 10 12 27 3 4 24 20 14 5 26 18 8 6 0 13 25 28 |
|||
ssort t |
|||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29</syntaxhighlight> |
|||
Note that since t is the result of an RNG, the order of values in t would be different in subsequent attempts. For example: |
|||
<syntaxhighlight lang="j"> t=: ?~30 |
|||
t |
|||
23 26 24 25 10 12 4 5 7 27 16 17 14 8 3 15 18 13 19 21 2 28 22 9 6 20 11 1 29 0 |
|||
ssort t |
|||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29</syntaxhighlight> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|Java|1.5+}} |
{{works with|Java|1.5+}} |
||
< |
<syntaxhighlight lang="java5">import java.util.concurrent.CountDownLatch; |
||
public class SleepSort { |
public class SleepSort { |
||
Line 356: | Line 1,070: | ||
sleepSortAndPrint(nums); |
sleepSortAndPrint(nums); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Output (using "3 1 4 5 2 3 1 6 1 3 2 5 4 6" as arguments): |
Output (using "3 1 4 5 2 3 1 6 1 3 2 5 4 6" as arguments): |
||
<pre>1 |
<pre>1 |
||
Line 374: | Line 1,088: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript">Array.prototype.timeoutSort = function (f) { |
||
this.forEach(function (n) { |
this.forEach(function (n) { |
||
setTimeout(function () { f(n) }, 5 * n) |
setTimeout(function () { f(n) }, 5 * n) |
||
}); |
}); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Usage and output: |
Usage and output: |
||
< |
<syntaxhighlight lang="javascript">[1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0].timeoutSort(function(n) { document.write(n + '<br>'); })</syntaxhighlight> |
||
<pre> |
<pre> |
||
0 |
0 |
||
Line 394: | Line 1,108: | ||
9 |
9 |
||
</pre> |
</pre> |
||
<syntaxhighlight lang="javascript">Array.prototype.sleepSort = function(callback) { |
|||
const res = []; |
|||
for (let n of this) |
|||
setTimeout(() => { |
|||
res.push(n); |
|||
if (this.length === res.length) |
|||
callback(res); |
|||
}, n + 1); |
|||
return res; |
|||
}; |
|||
[1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0].sleepSort(console.log); |
|||
// [ 1, 0, 2, 3, 4, 5, 5, 6, 7, 8, 9 ] |
|||
</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
{{trans|Brainf***}} |
|||
Doesn't actually sleep. Instead, iterates reducing the values by one until each is zero. |
|||
<syntaxhighlight lang="jq">echo '[5, 1, 3, 2, 11, 6, 4]' | jq ' |
|||
def f: |
|||
if .unsorted == [] then |
|||
.sorted |
|||
else |
|||
{ unsorted: [.unsorted[] | .t = .t - 1 | select(.t != 0)] |
|||
, sorted: (.sorted + [.unsorted[] | .t = .t - 1 | select(.t == 0) | .v]) } |
|||
| f |
|||
end; |
|||
{unsorted: [.[] | {v: ., t: .}], sorted: []} | f | .[] |
|||
'</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
6 |
|||
11</pre> |
|||
=={{header|Julia}}== |
|||
{{works with|Julia|1.6}} |
|||
<syntaxhighlight lang="julia">function sleepsort(V::Vector{T}) where {T <: Real} |
|||
U = Vector{T}() |
|||
sizehint!(U, length(V)) |
|||
@sync for v in V |
|||
@async begin |
|||
sleep(abs(v)) |
|||
(v < 0 ? pushfirst! : push!)(U, v) |
|||
end |
|||
end |
|||
return U |
|||
end |
|||
v = rand(-10:10, 10) |
|||
println("# unordered: $v\n -> ordered: ", sleepsort(v))</syntaxhighlight> |
|||
{{out}} |
|||
<pre># unordered: [10, -1, 3, -9, 1, -5, -8, -7, -3, 3] |
|||
-> ordered: [-9, -8, -7, -5, -3, -1, 1, 3, 3, 10]</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight lang="scala">// version 1.1.51 |
|||
import kotlin.concurrent.thread |
|||
fun sleepSort(list: List<Int>, interval: Long) { |
|||
print("Sorted : ") |
|||
for (i in list) { |
|||
thread { |
|||
Thread.sleep(i * interval) |
|||
print("$i ") |
|||
} |
|||
} |
|||
thread { // print a new line after displaying sorted list |
|||
Thread.sleep ((1 + list.max()!!) * interval) |
|||
println() |
|||
} |
|||
} |
|||
fun main(args: Array<String>) { |
|||
val list = args.map { it.toInt() }.filter { it >= 0 } // ignore negative integers |
|||
println("Unsorted: ${list.joinToString(" ")}") |
|||
sleepSort(list, 50) |
|||
}</syntaxhighlight> |
|||
Sample output: |
|||
<pre> |
|||
$ java -jar sleepsort.jar 5 7 -1 2 4 1 8 0 3 9 6 |
|||
Unsorted: 5 7 2 4 1 8 0 3 9 6 |
|||
Sorted : 0 1 2 3 4 5 6 7 8 9 |
|||
</pre> |
|||
=== Using coroutines === |
|||
<syntaxhighlight lang="kotlin"> |
|||
import kotlinx.coroutines.* |
|||
fun sleepSort(list: List<Int>, delta: Long) { |
|||
runBlocking { |
|||
list.onEach { |
|||
launch { |
|||
delay(it * delta) |
|||
print("$it ") |
|||
} |
|||
} |
|||
} |
|||
} |
|||
fun main() { |
|||
val list = listOf(5, 7, 2, 4, 1, 8, 0, 3, 9, 6) |
|||
println("Unsorted: ${list.joinToString(" ")}") |
|||
print("Sorted : ") |
|||
sleepSort(list, 10) |
|||
} |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
Unsorted: 5 7 2 4 1 8 0 3 9 6 |
|||
Sorted : 0 1 2 3 4 5 6 7 8 9 |
|||
</pre> |
|||
=={{header|Lua}}== |
|||
Here's a slow implementation using only stock C Lua: |
|||
<syntaxhighlight lang="lua">function sleeprint(n) |
|||
local t0 = os.time() |
|||
while os.time() - t0 <= n do |
|||
coroutine.yield(false) |
|||
end |
|||
print(n) |
|||
return true |
|||
end |
|||
coroutines = {} |
|||
for i=1, #arg do |
|||
wrapped = coroutine.wrap(sleeprint) |
|||
table.insert(coroutines, wrapped) |
|||
wrapped(tonumber(arg[i])) |
|||
end |
|||
done = false |
|||
while not done do |
|||
done = true |
|||
for i=#coroutines,1,-1 do |
|||
if coroutines[i]() then |
|||
table.remove(coroutines, i) |
|||
else |
|||
done = false |
|||
end |
|||
end |
|||
end</syntaxhighlight> |
|||
By installing LuaSocket, you can get better than 1-second precision on the clock, and therefore faster output: |
|||
<syntaxhighlight lang="lua">socket = require 'socket' |
|||
function sleeprint(n) |
|||
local t0 = socket.gettime() |
|||
while (socket.gettime() - t0)*100 <= n do |
|||
coroutine.yield(false) |
|||
end |
|||
print(n) |
|||
return true |
|||
end |
|||
coroutines = {} |
|||
for i=1, #arg do |
|||
wrapped = coroutine.wrap(sleeprint) |
|||
table.insert(coroutines, wrapped) |
|||
wrapped(tonumber(arg[i])) |
|||
end |
|||
done = false |
|||
while not done do |
|||
done = true |
|||
for i=#coroutines,1,-1 do |
|||
if coroutines[i]() then |
|||
table.remove(coroutines, i) |
|||
else |
|||
done = false |
|||
end |
|||
end |
|||
end</syntaxhighlight> |
|||
Either way, the output is the same: |
|||
{{Out}} |
|||
<pre> |
|||
$ lua sleep_sort.lua 3 1 4 1 5 9 2 6 5 3 5 |
|||
1 |
|||
1 |
|||
2 |
|||
3 |
|||
3 |
|||
4 |
|||
5 |
|||
5 |
|||
5 |
|||
6 |
|||
9 |
|||
</pre> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
<syntaxhighlight lang="mathematica">SleepSort = RunScheduledTask[Print@#, {#, 1}] & /@ # &; |
|||
SleepSort@{1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0};</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
0 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
6 |
|||
7 |
|||
8 |
|||
9 |
|||
</pre> |
|||
=={{header|NetRexx}}== |
|||
As implemented this sample goes beyond the scope of the task as defined; it will handle negative numbers. |
|||
<syntaxhighlight lang="netrexx">/* NetRexx */ |
|||
options replace format comments java crossref symbols nobinary |
|||
import java.util.concurrent.CountDownLatch |
|||
-- ============================================================================= |
|||
class RSortingSleepsort |
|||
properties constant private |
|||
dflt = '-6 3 1 4 5 2 3 -7 1 6 001 3 -9 2 5 -009 -8 4 6 1 9 8 7 6 5 -7 3 4 5 2 0 -2 -1 -5 -4 -3 -0 000 0' |
|||
properties indirect |
|||
startLatch = CountDownLatch |
|||
doneLatch = CountDownLatch |
|||
floor = 0 |
|||
sorted = '' |
|||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
method main(args = String[]) public static |
|||
arg = Rexx(args) |
|||
if arg = '' then arg = dflt |
|||
say ' unsorted:' arg |
|||
say ' sorted:' (RSortingSleepsort()).sleepSort(arg) |
|||
return |
|||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
method sleepSort(iArg) public |
|||
setStartLatch(CountDownLatch(1)) -- used to put all threads on hold until we're ready to run |
|||
setDoneLatch(CountDownLatch(iArg.words())) -- used to indicate all work is done |
|||
loop mn = 1 to iArg.words() |
|||
setFloor(getFloor().min(iArg.word(mn))) -- save smallest -ve number so we can use it as a scale for sleep |
|||
Thread(SortThread(iArg.word(mn))).start() -- loop through input and create a thread for each element |
|||
end mn |
|||
getStartLatch().countDown() -- cry 'Havoc', and let slip the dogs of war. |
|||
do |
|||
getDoneLatch().await() -- wait for worker threads to complete |
|||
catch ix = InterruptedException |
|||
ix.printStackTrace() |
|||
end |
|||
return getSorted() |
|||
-- ============================================================================= |
|||
class RSortingSleepsort.SortThread dependent implements Runnable |
|||
properties indirect |
|||
num |
|||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
method SortThread(nm) |
|||
setNum(nm) |
|||
return |
|||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
method run() public |
|||
do |
|||
parent.getStartLatch().await() -- wait until all threads are constructed |
|||
sleepTime = getNum() + parent.getFloor().abs() -- shifted by value of smallest number (permits numbers < 0) |
|||
sleepTime = sleepTime * 250 -- scale up; milliseconds are not granular enough |
|||
Thread.sleep(sleepTime) -- wait for this number's turn to run |
|||
catch ie = InterruptedException |
|||
ie.printStackTrace() |
|||
end |
|||
do protect parent -- lock the parent to prevent collisions |
|||
parent.setSorted((parent.getSorted() num).strip()) -- stow the number in the results List |
|||
end |
|||
parent.getDoneLatch().countDown() -- this one's done; decrement the latch |
|||
return |
|||
</syntaxhighlight> |
|||
'''Output:''' |
|||
<pre> |
|||
unsorted: -6 3 1 4 5 2 3 -7 1 6 001 3 -9 2 5 -009 -8 4 6 1 9 8 7 6 5 -7 3 4 5 2 0 -2 -1 -5 -4 -3 -0 000 0 |
|||
sorted: -9 -009 -8 -7 -7 -6 -5 -4 -3 -2 -1 000 0 0 -0 1 1 001 1 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 6 7 8 9 |
|||
</pre> |
|||
=={{header|Nim}}== |
|||
Compile with <code>nim --threads:on c sleepsort</code>: |
|||
<syntaxhighlight lang="nim">import os, strutils |
|||
proc single(n: int) = |
|||
sleep n |
|||
echo n |
|||
proc main = |
|||
var thr = newSeq[TThread[int]](paramCount()) |
|||
for i,c in commandLineParams(): |
|||
thr[i].createThread(single, c.parseInt) |
|||
thr.joinThreads |
|||
main()</syntaxhighlight> |
|||
Usage: |
|||
<pre>$ ./sleepsort 5 1 3 2 11 6 4 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
6 |
|||
11</pre> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang="objeck"> |
||
use System.Concurrency; |
use System.Concurrency; |
||
use Collection; |
use Collection; |
||
Line 428: | Line 1,460: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
< |
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
||
int main(int argc, char **argv) |
int main(int argc, char **argv) |
||
{ |
{ |
||
NSOperationQueue *queue = [NSOperationQueue |
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; |
||
while (--argc) { |
while (--argc) { |
||
int i = atoi(argv[argc]); |
int i = atoi(argv[argc]); |
||
Line 444: | Line 1,476: | ||
} |
} |
||
[queue waitUntilAllOperationsAreFinished]; |
[queue waitUntilAllOperationsAreFinished]; |
||
}</ |
}</syntaxhighlight> |
||
Rather than having multiple operations that sleep, we could also dispatch the tasks after a delay: |
|||
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
|||
int main(int argc, char **argv) |
|||
{ |
|||
while (--argc) { |
|||
int i = atoi(argv[argc]); |
|||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, i * NSEC_PER_SEC), |
|||
dispatch_get_main_queue(), |
|||
^{ NSLog(@"%d\n", i); }); |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|Oforth}}== |
|||
Instead of printing numbers, each task sends its integer into a channel (after sleeping 20 * n milliseconds). This allows the main task to create a new sorted list with those integers. |
|||
20 milliseconds is used to (try to) handle scheduler tick on Windows systems (around 15 ms). On Linux systems (after kernel 2.6.8), this value can be smaller. |
|||
<syntaxhighlight lang="oforth">import: parallel |
|||
: sleepSort(l) |
|||
| ch n | |
|||
Channel new ->ch |
|||
l forEach: n [ #[ n dup 20 * sleep ch send drop ] & ] |
|||
ListBuffer newSize(l size) #[ ch receive over add ] times(l size) ;</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
100 seq 100 seq + sleepSort println |
|||
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, |
|||
14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 2 |
|||
5, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, |
|||
37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 4 |
|||
8, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, |
|||
59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 7 |
|||
0, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, |
|||
82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 9 |
|||
3, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100] |
|||
</pre> |
|||
=={{header|Ol}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
(define (sleep-sort lst) |
|||
(for-each (lambda (timeout) |
|||
(async (lambda () |
|||
(sleep timeout) |
|||
(print timeout)))) |
|||
lst)) |
|||
(sleep-sort '(5 8 2 7 9 10 5)) |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
2 |
|||
5 |
|||
5 |
|||
7 |
|||
8 |
|||
9 |
|||
10 |
|||
</pre> |
|||
=={{header|Pascal}}== |
|||
{{works with|Free Pascal}} |
|||
my limit under linux was 4000 threads nearly 2 GB. |
|||
<syntaxhighlight lang="pascal"> |
|||
program sleepsort; |
|||
{$IFDEF FPC} |
|||
{$MODE DELPHI} {$Optimization ON,ALL} |
|||
{$ElSE} |
|||
{$APPTYPE CONSOLE} |
|||
{$ENDIF} |
|||
uses |
|||
{$IFDEF UNIX} |
|||
cthreads, |
|||
{$ENDIF} |
|||
SysUtils; |
|||
const |
|||
HiLimit = 40; |
|||
type |
|||
tCombineForOneThread = record |
|||
cft_count : Uint64; |
|||
cft_ThreadID: NativeUint; |
|||
cft_ThreadHandle: NativeUint; |
|||
end; |
|||
pThreadBlock = ^tCombineForOneThread; |
|||
var |
|||
SortIdx : array of INteger; |
|||
ThreadBlocks : array of tCombineForOneThread; |
|||
gblThreadCount, |
|||
Finished: Uint32; |
|||
procedure PrepareThreads(thdCount:NativeInt); |
|||
var |
|||
i : NativeInt; |
|||
Begin |
|||
For i := 0 to thdCount-1 do |
|||
ThreadBlocks[i].cft_count:= random(2*HiLimit); |
|||
end; |
|||
procedure TestRunThd(parameter: pointer); |
|||
var |
|||
pThdBlk: pThreadBlock; |
|||
fi: NativeInt; |
|||
begin |
|||
pThdBlk := @ThreadBlocks[NativeUint(parameter)]; |
|||
with pThdBlk^ do |
|||
begin |
|||
sleep(40*cft_count+1); |
|||
fi := Finished-1; |
|||
//write(fi:5,cft_count:8,#13); |
|||
InterLockedDecrement(Finished); |
|||
SortIdx[fi]:= NativeUint(parameter); |
|||
end; |
|||
EndThread(0); |
|||
end; |
|||
procedure Test; |
|||
var |
|||
j,UsedThreads: NativeInt; |
|||
begin |
|||
randomize; |
|||
UsedThreads:= GblThreadCount; |
|||
Finished :=UsedThreads; |
|||
PrepareThreads(UsedThreads); |
|||
j := 0; |
|||
while (j < UsedThreads) do |
|||
begin |
|||
with ThreadBlocks[j] do |
|||
begin |
|||
cft_ThreadHandle := |
|||
BeginThread(@TestRunThd, Pointer(j), cft_ThreadID,16384 {stacksize} ); |
|||
If cft_ThreadHandle = 0 then break; |
|||
end; |
|||
Inc(j); |
|||
end; |
|||
writeln(j); |
|||
UsedThreads := j; |
|||
Finished :=UsedThreads; |
|||
repeat |
|||
sleep(1); |
|||
until finished = 0; |
|||
For j := 0 to UsedThreads-1 do |
|||
CloseThread(ThreadBlocks[j].cft_ThreadID); |
|||
//output of sleep-sorted data |
|||
For j := UsedThreads-1 downto 1 do |
|||
write(ThreadBlocks[SortIdx[j]].cft_count,','); |
|||
writeln(ThreadBlocks[SortIdx[0]].cft_count); |
|||
end; |
|||
begin |
|||
randomize; |
|||
gblThreadCount := Hilimit; |
|||
Writeln('Testthreads : ',gblThreadCount); |
|||
setlength(ThreadBlocks,gblThreadCount); |
|||
setlength(SortIdx,gblThreadCount); |
|||
Test; |
|||
setlength(ThreadBlocks, 0); |
|||
{$IFDEF WINDOWS} |
|||
readln; |
|||
{$ENDIF} |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>time ./sleepsort |
|||
Testthreads : 40 |
|||
40 |
|||
1,8,9,10,11,12,12,13,14,18,24,24,24,26,28,35,35,37,42,49,50,52,54,54,56,57,59,60,61,62,64,69,69,71,72,73,76,77,78,79 |
|||
real 0m3,164s</pre> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Basically the C code. |
Basically the C code. |
||
< |
<syntaxhighlight lang="perl">1 while ($_ = shift and @ARGV and !fork); |
||
sleep $_; |
sleep $_; |
||
print "$_\n"; |
print "$_\n"; |
||
wait;</ |
wait;</syntaxhighlight> |
||
A more optimal solution makes use of Coro, a cooperative threading library. It has the added effect of being much faster, fully deterministic (sleep is not exact), and it allows you to easily collect the return value: |
A more optimal solution makes use of Coro, a cooperative threading library. It has the added effect of being much faster, fully deterministic (sleep is not exact), and it allows you to easily collect the return value: |
||
< |
<syntaxhighlight lang="perl">use Coro; |
||
$ret = Coro::Channel->new; |
$ret = Coro::Channel->new; |
||
@nums = qw(1 32 2 59 2 39 43 15 8 9 12 9 11); |
@nums = qw(1 32 2 59 2 39 43 15 8 9 12 9 11); |
||
Line 466: | Line 1,672: | ||
} |
} |
||
print $ret->get,"\n" for 1..@nums;</ |
print $ret->get,"\n" for 1..@nums;</syntaxhighlight> |
||
=={{header| |
=={{header|Phix}}== |
||
Based on [[Sorting_algorithms/Sleep_sort#Euphoria|Euphoria]] |
|||
<!--<syntaxhighlight lang="phix">(notonline)--> |
|||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (multitasking)</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">sleeper</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #0000FF;">?</span> <span style="color: #000000;">key</span> <span style="color: #000080;font-style:italic;">-- (or maybe res &= key)</span> |
|||
<span style="color: #000000;">count</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #000080;font-style:italic;">--sequence s = command_line()[3..$]</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 1 4 1 5 9 2 6 5"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Nothing to sort.\n"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">else</span> |
|||
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">task</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">task_create</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sleeper</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">si</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #7060A8;">task_schedule</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">si</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">si</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #000000;">count</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #7060A8;">task_yield</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<!--</syntaxhighlight>--> |
|||
=={{header|PHP}}== |
|||
Using the MuEvent module from the Perl 6 module ecosystem. |
|||
A PHP implementation of sleep sort using process forking. |
|||
<syntaxhighlight lang="php"> |
|||
<?php |
|||
$buffer = 1; |
|||
<lang Perl6>use MuEvent; |
|||
$pids = []; |
|||
for |
for ($i = 1; $i < $argc; $i++) { |
||
$pid = pcntl_fork(); |
|||
MuEvent::timer( after => $item, cb => sub { say $item } ); |
|||
if ($pid < 0) { |
|||
die("failed to start child process"); |
|||
} |
|||
if ($pid === 0) { |
|||
sleep($argv[$i] + $buffer); |
|||
echo $argv[$i] . "\n"; |
|||
exit(); |
|||
} |
|||
$pids[] = $pid; |
|||
} |
} |
||
foreach ($pids as $pid) { |
|||
MuEvent::run;</lang> |
|||
pcntl_waitpid($pid, $status); |
|||
} |
|||
Output |
|||
</syntaxhighlight> |
|||
<pre>0 |
|||
<pre> |
|||
1 |
|||
php ./sleepsort.php 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 |
|||
1 |
1 |
||
2 |
2 |
||
7 |
|||
2 |
|||
5 |
|||
6 |
|||
8 |
8 |
||
11 |
|||
12 |
|||
14 |
14 |
||
20 |
|||
20 |
|||
21 |
|||
25 |
|||
27 |
|||
30 |
|||
32 |
|||
35 |
|||
41 |
|||
42 |
|||
42 |
|||
43 |
|||
46 |
|||
50 |
|||
</pre> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
===Sleeping in main process=== |
===Sleeping in main process=== |
||
< |
<syntaxhighlight lang="picolisp">(de sleepSort (Lst) |
||
(make |
(make |
||
(for (I . N) Lst |
(for (I . N) Lst |
||
Line 501: | Line 1,767: | ||
(pop 'Lst) |
(pop 'Lst) |
||
(task (- I)) ) ) |
(task (- I)) ) ) |
||
(wait NIL (not Lst)) ) )</ |
(wait NIL (not Lst)) ) )</syntaxhighlight> |
||
===Sleeping in child processes=== |
===Sleeping in child processes=== |
||
< |
<syntaxhighlight lang="picolisp">(de sleepSort (Lst) |
||
(make |
(make |
||
(for N Lst |
(for N Lst |
||
Line 510: | Line 1,776: | ||
(pop 'Lst) |
(pop 'Lst) |
||
(task (close @)) ) ) |
(task (close @)) ) ) |
||
(wait NIL (not Lst)) ) )</ |
(wait NIL (not Lst)) ) )</syntaxhighlight> |
||
Output in both cases: |
Output in both cases: |
||
<pre>: (sleepSort (3 1 4 1 5 9 2 6 5)) |
<pre>: (sleepSort (3 1 4 1 5 9 2 6 5)) |
||
Line 516: | Line 1,782: | ||
===Just printing (no sorted result list)=== |
===Just printing (no sorted result list)=== |
||
Basically the C code. |
Basically the C code. |
||
< |
<syntaxhighlight lang="picolisp">(for N (3 1 4 1 5 9 2 6 5) |
||
(unless (fork) |
(unless (fork) |
||
(call 'sleep N) |
(call 'sleep N) |
||
(msg N) |
(msg N) |
||
(bye) ) )</ |
(bye) ) )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>1 |
<pre>1 |
||
Line 531: | Line 1,797: | ||
6 |
6 |
||
9</pre> |
9</pre> |
||
=={{header|Pike}}== |
|||
<syntaxhighlight lang="pike"> |
|||
#!/usr/bin/env pike |
|||
int main(int argc, array(string) argv) |
|||
{ |
|||
foreach(argv[1..], string value) |
|||
{ |
|||
int v = (int)value; |
|||
if(v<0) |
|||
continue; |
|||
call_out(print, v, value); |
|||
} |
|||
return -1; |
|||
} |
|||
void print(string value) |
|||
{ |
|||
write("%s\n", value); |
|||
if(find_call_out(print)==-1) |
|||
exit(0); |
|||
return; |
|||
} |
|||
</syntaxhighlight> |
|||
Output : |
|||
<pre> |
|||
$ ./sleep-sort.pike 4 5 -3 1 2 7 6 |
|||
1 |
|||
2 |
|||
4 |
|||
5 |
|||
6 |
|||
7 |
|||
</pre> |
|||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
Works with SWI-Prolog. |
Works with SWI-Prolog. |
||
< |
<syntaxhighlight lang="prolog">sleep_sort(L) :- |
||
thread_pool_create(rosetta, 1024, []) , |
thread_pool_create(rosetta, 1024, []) , |
||
maplist(initsort, L, LID), |
maplist(initsort, L, LID), |
||
Line 543: | Line 1,845: | ||
thread_create_in_pool(rosetta, (sleep(V), writeln(V)), Id, []). |
thread_create_in_pool(rosetta, (sleep(V), writeln(V)), Id, []). |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output : |
Output : |
||
<pre> sleep_sort([5, 1, 3, 2, 11, 6, 3, 4]). |
<pre> sleep_sort([5, 1, 3, 2, 11, 6, 3, 4]). |
||
Line 559: | Line 1,861: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">NewMap threads() |
||
Procedure Foo(n) |
Procedure Foo(n) |
||
Line 575: | Line 1,877: | ||
Next |
Next |
||
Print("Press ENTER to exit"): Input() |
Print("Press ENTER to exit"): Input() |
||
EndIf</ |
EndIf</syntaxhighlight> |
||
<pre>Sleep_sort.exe 3 1 4 1 5 9 |
<pre>Sleep_sort.exe 3 1 4 1 5 9 |
||
1 |
1 |
||
Line 586: | Line 1,888: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
===Python: Using threading.Timer=== |
|||
<lang python>from time import sleep |
|||
<syntaxhighlight lang="python">from time import sleep |
|||
from threading import Timer |
from threading import Timer |
||
Line 605: | Line 1,909: | ||
print('sleep sort worked for:',x) |
print('sleep sort worked for:',x) |
||
else: |
else: |
||
print('sleep sort FAILED for:',x)</ |
print('sleep sort FAILED for:',x)</syntaxhighlight> |
||
;Sample output: |
;Sample output: |
||
<pre>sleep sort worked for: [3, 2, 4, 7, 3, 6, 9, 1]</pre> |
<pre>sleep sort worked for: [3, 2, 4, 7, 3, 6, 9, 1]</pre> |
||
===Python v3.5+: Using asyncio === |
|||
Since the introduction of async/await syntax, the implementation |
|||
could be a sole translation from the original version in Bash: |
|||
{{Works with|Python 3.5+}} |
|||
<syntaxhighlight lang="python">#!/usr/bin/env python3 |
|||
from asyncio import run, sleep, wait |
|||
from sys import argv |
|||
async def f(n): |
|||
await sleep(n) |
|||
print(n) |
|||
if __name__ == '__main__': |
|||
run(wait(map(f, map(int, argv[1:]))))</syntaxhighlight> |
|||
Example usage: |
|||
<pre> |
|||
$ ./sleepsort.py 5 3 6 3 6 3 1 4 7 |
|||
1 |
|||
3 |
|||
3 |
|||
3 |
|||
4 |
|||
5 |
|||
6 |
|||
6 |
|||
7 |
|||
</pre> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 628: | Line 1,961: | ||
;; outputs '(2 5 5 7 8 9 10) |
;; outputs '(2 5 5 7 8 9 10) |
||
(sleep-sort '(5 8 2 7 9 10 5)) |
(sleep-sort '(5 8 2 7 9 10 5)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<syntaxhighlight lang="raku" line>await map -> $delay { start { sleep $delay ; say $delay } }, |
|||
<6 8 1 12 2 14 5 2 1 0>;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0 |
|||
1 |
|||
1 |
|||
2 |
|||
2 |
|||
5 |
|||
6 |
|||
8 |
|||
12 |
|||
14</pre> |
|||
This can also be written using reactive programming: |
|||
<syntaxhighlight lang="raku" line>#!/usr/bin/env raku |
|||
use v6; |
|||
react whenever Supply.from-list(@*ARGS).start({ .&sleep // +$_ }).flat { .say }</syntaxhighlight> |
|||
{{out}} |
|||
<pre>$ ./sleep-sort 1 3 5 6 2 4 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
6</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
This sort will accept any manner of numbers, or for that matter, any character string as well. |
This sort will accept any manner of numbers, or for that matter, any character string as well. |
||
<br>REXX isn't particular what is being sorted. |
<br>REXX isn't particular what is being sorted. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program implements a sleep sort (with numbers entered from the command line (CL).*/ |
||
numeric digits 300 /*over the top, but what the hey!*/ |
numeric digits 300 /*over the top, but what the hey! */ |
||
/* (above) |
/* (above) ··· from vaudeville. */ |
||
@.= /*placeholder for the array of numbers.*/ |
|||
stuff= |
stuff= 1e9 50 5 40 4 1 100 30 3 12 2 8 9 7 6 6 10 20 0 /*alphabetically ··· so far.*/ |
||
parse arg numbers /* |
parse arg numbers /*obtain optional arguments from the CL*/ |
||
if numbers='' then numbers=stuff /*Not specified? Then use default*/ |
if numbers='' then numbers= stuff /*Not specified? Then use the default.*/ |
||
N=words(numbers) /*N is the |
N= words(numbers) /*N is the number of numbers in list. */ |
||
w=length(N) /*width of N (for nice output).*/ |
w= length(N) /*width of N (used for nice output). */ |
||
parse upper version !ver . /*obtain which REXX we're running under*/ |
|||
say N 'numbers to be sorted:' numbers /*informative informational info.*/ |
|||
!regina= ('REXX-REGINA'==left(!ver, 11) ) /*indicate (or not) if this is Regina. */ |
|||
say N 'numbers to be sorted:' numbers /*informative informational information*/ |
|||
/*from department of redundancy depart.*/ |
|||
do j=1 for N /*let's start to boogie─woogie da sort.*/ |
|||
if datatype(#.j,'Numeric') then #.j = #.j/1 /*normalize it if num.*/ |
|||
@.j= word(numbers, j) /*plug in a single number at a time. */ |
|||
if datatype(@.j, 'N') then @.j= @.j / 1 /*normalize it if it's a numeric number*/ |
|||
if !regina then call fork /*only REGINA REXX supports FORK BIF.*/ |
|||
call sortItem j /*start a sort for an array number. */ |
|||
end /*j*/ |
end /*j*/ |
||
do forever while \inOrder(N) /*wait for the sorts to complete.*/ |
do forever while \inOrder(N) /*wait for the sorts to complete. */ |
||
call |
call delay 1 /*one second is minimum effective time.*/ |
||
end /*forever while*/ /*well, other than zero seconds. */ |
end /*forever while*/ /*well heck, other than zero seconds. */ |
||
m=max(length( |
m= max(length(@.1), length(@.N) ) /*width of smallest or largest number. */ |
||
say; say 'after sort:' |
say; say 'after sort:' /*display a blank line and a title. */ |
||
/*∙∙∙but LEFT pads [much faster]*/ |
|||
do k=1 for N /*list the (sorted) array's elements.*/ |
|||
say left('', 20) 'array element' right(k, w) '───►' right(@.k, m) |
|||
end /*k*/ |
|||
exit /*stick a fork in it, we're done.*/ |
exit /*stick a fork in it, we're all done. */ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
/*───────────────────────────────────SortItem subroutine────────────────*/ |
|||
sortItem: |
sortItem: procedure expose @.; parse arg ? /*sorts a single (numeric) item. */ |
||
do Asort=1 until \switched /*sort unsorted array until it's sorted*/ |
|||
switched= 0 /*it's all hunky─dorey, happy─dappy ···*/ |
|||
do i=1 while |
do i=1 while @.i\=='' & \switched |
||
if |
if @.? >= @.i then iterate /*item is in order. */ |
||
parse value |
parse value @.? @.i with @.i @.? |
||
switched=1 /* |
switched= 1 /* [↑] swapped one.*/ |
||
end /*i*/ |
end /*i*/ |
||
if Asort//?==0 then call delay switched /*sleep if last item*/ |
|||
end /*Asort*/ |
|||
return /*Sleeping Beauty awakes. |
return /*Sleeping Beauty awakes. Not to worry: (c)=circa 1697.*/ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
/*───────────────────────────────────InOrder subroutine─────────────────*/ |
|||
inOrder: procedure expose |
inOrder: procedure expose @.; parse arg howMany /*is the array in numerical order? */ |
||
do m=1 for howMany-1; |
do m=1 for howMany-1; next= m+1; if @.m>@.next then return 0 /*¬ in order*/ |
||
end /*m*/ /*keep looking for fountain of |
end /*m*/ /*keep looking for fountain of youth. */ |
||
return 1 /*yes, indicate with an indicator.*/</ |
return 1 /*yes, indicate with an indicator. */</syntaxhighlight> |
||
Programming note: this REXX program makes use of '''DELAY''' BIF which delays (sleeps) for a specified amount of seconds. |
|||
'''output''' when using the default input |
|||
<br>Some REXXes don't have a '''DELAY''' BIF, so one is included here ──► [[DELAY.REX]]. |
|||
<pre style="height:40ex;overflow:scroll"> |
|||
19 numbers to be sorted: 1e9 50 5 40 4 1 100 30 3 12 2 8 9 7 6 6 10 20 0 |
|||
{{out|output|text= when using the internal default input:}} |
|||
<pre> |
|||
19 numbers to be sorted: 1E9 50 5 40 4 1 100 30 3 12 2 8 9 7 6 6 10 20 0 |
|||
after sort: |
after sort: |
||
array element 1 |
array element 1 ───► 0 |
||
array element 2 |
array element 2 ───► 1 |
||
array element 3 |
array element 3 ───► 2 |
||
array element 4 |
array element 4 ───► 3 |
||
array element 5 |
array element 5 ───► 4 |
||
array element 6 |
array element 6 ───► 5 |
||
array element 7 |
array element 7 ───► 6 |
||
array element 8 |
array element 8 ───► 6 |
||
array element 9 |
array element 9 ───► 7 |
||
array element 10 |
array element 10 ───► 8 |
||
array element 11 |
array element 11 ───► 9 |
||
array element 12 |
array element 12 ───► 10 |
||
array element 13 |
array element 13 ───► 12 |
||
array element 14 |
array element 14 ───► 20 |
||
array element 15 |
array element 15 ───► 30 |
||
array element 16 |
array element 16 ───► 40 |
||
array element 17 |
array element 17 ───► 50 |
||
array element 18 |
array element 18 ───► 100 |
||
array element 19 |
array element 19 ───► 1000000000 |
||
</pre> |
</pre> |
||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">require 'thread' |
||
nums = ARGV.collect(&:to_i) |
nums = ARGV.collect(&:to_i) |
||
Line 720: | Line 2,092: | ||
threads.each {|t| t.join} |
threads.each {|t| t.join} |
||
p sorted</ |
p sorted</syntaxhighlight> |
||
Example |
Example |
||
Line 727: | Line 2,099: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
<lang |
<syntaxhighlight lang="rust">use std::thread; |
||
use std::timer::sleep; |
|||
fn sleepsort<I: Iterator<Item=u32>>(nums: I) { |
|||
use std::uv::global_loop; |
|||
let threads: Vec<_> = nums.map(|n| |
|||
thread::spawn(move || { |
|||
thread::sleep_ms(n); |
|||
println!("{}", n); })).collect(); |
|||
for t in threads { t.join(); } |
|||
} |
|||
fn main() { |
fn main() { |
||
sleepsort(std::env::args().skip(1).map(|s| s.parse().unwrap())); |
|||
}</syntaxhighlight> |
|||
do task::spawn { |
|||
Output: |
|||
let n = uint::from_str(arg).get(); |
|||
<pre>$ ./sleepsort 50 34 43 3 2 |
|||
sleep(global_loop::get(), n); |
|||
2 |
|||
io::println(arg); |
|||
3 |
|||
} |
|||
34 |
|||
} |
|||
43 |
|||
}</lang> |
|||
50 |
|||
</pre> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">object SleepSort { |
||
def sort(nums:Seq[Int])=nums foreach {n => |
|||
def main(args: Array[String]): Unit = { |
|||
scala.concurrent.ops.spawn{ |
|||
val nums = args.map(_.toInt) |
|||
sort(nums) |
|||
Thread.sleep(nums.max * 21) // Keep the JVM alive for the example |
|||
} |
|||
} |
|||
def main(args:Array[String])={ |
|||
sort(args map (_.toInt)) |
|||
} |
} |
||
}</lang> |
|||
def sort(nums: Seq[Int]): Unit = |
|||
Example: |
|||
nums.foreach(i => new Thread { |
|||
<pre>> scala SleepSort 1 9 8 7 6 5 3 4 5 2 0 |
|||
override def run() { |
|||
Thread.sleep(i * 20) // just `i` is unpredictable with small numbers |
|||
print(s"$i ") |
|||
} |
|||
}.start()) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<syntaxhighlight lang="bash">$ scala SleepSort 1 3 6 0 9 7 4 2 5 8 |
|||
0 1 2 3 4 5 5 6 7 8 9 </syntaxhighlight> |
|||
=={{header|Sidef}}== |
|||
<syntaxhighlight lang="ruby">ARGV.map{.to_i}.map{ |i| |
|||
{Sys.sleep(i); say i}.fork; |
|||
}.each{.wait};</syntaxhighlight> |
|||
{{out}} |
|||
<pre>% sidef test.sf 5 1 3 2 11 6 4 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
6 |
|||
11</pre> |
|||
=={{header|Simula}}== |
|||
<syntaxhighlight lang="simula">SIMULATION |
|||
BEGIN |
|||
PROCESS CLASS SORTITEM(N); INTEGER N; |
|||
BEGIN |
|||
HOLD(N); |
|||
OUTINT(N, 3); |
|||
END; |
|||
INTEGER I; |
|||
FOR I := 3, 2, 4, 7, 3, 6, 9, 1 DO |
|||
BEGIN |
|||
REF(SORTITEM) SI; |
|||
SI :- NEW SORTITEM(I); |
|||
ACTIVATE SI; |
|||
END; |
|||
HOLD(100000); |
|||
OUTIMAGE; |
|||
END;</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 1 2 3 3 4 6 7 9 |
|||
</pre> |
|||
=={{header|SNUSP}}== |
|||
Bloated SNUSP is ideally suited to this task, since this the variant adds multithreading and an additional dimension of data space. Sleep time is simulated by the loop delay required to copy each cell value, thereby ensuring that smaller values are printed earlier than larger values. This program requires a Bloated SNUSP interpreter which returns zero on input end-of-file. |
|||
<syntaxhighlight lang="snusp"> |
|||
/$>\ input until eof |
|||
#/?<\?,/ foreach: fork |
|||
\ &/:+ copy and\ |
|||
/:\?-; delay / |
|||
\.# print and exit thread |
|||
</syntaxhighlight> |
|||
Legend: |
|||
* '''&''' - SPLIT creates a new thread. Like '''@''' ENTER, it skips one cell of code space to start its continuation. |
|||
* ''': ;''' - UP and DOWN are equivalent to '''< >''' LEFT and RIGHT, but moves the data pointer in the second dimension. |
|||
* '''#''' - in Bloated SNUSP, LEAVE only terminates the current thread. The overall program only exits when all threads have quit. |
|||
=={{header|Swift}}== |
|||
<syntaxhighlight lang="swift">import Foundation |
|||
for i in [5, 2, 4, 6, 1, 7, 20, 14] { |
|||
let time = dispatch_time(DISPATCH_TIME_NOW, |
|||
Int64(i * Int(NSEC_PER_SEC))) |
|||
dispatch_after(time, dispatch_get_main_queue()) { |
|||
print(i) |
|||
} |
|||
} |
|||
CFRunLoopRun()</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
2 |
|||
4 |
|||
5 |
|||
6 |
|||
7 |
|||
14 |
|||
20 |
|||
</pre> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
===Tcl 8.5=== |
|||
<lang tcl>#!/bin/env tclsh |
|||
<syntaxhighlight lang="tcl">#!/bin/env tclsh |
|||
set count 0 |
set count 0 |
||
proc process val { |
proc process val { |
||
Line 772: | Line 2,237: | ||
while {$count < $argc} { |
while {$count < $argc} { |
||
vwait count |
vwait count |
||
}</ |
}</syntaxhighlight> |
||
'''Demo:''' |
|||
Demonstrating: |
|||
<pre> |
<pre> |
||
bash$ sleepsort.tcl 3 1 4 5 2 3 1 6 1 3 2 5 4 6 |
bash$ sleepsort.tcl 3 1 4 5 2 3 1 6 1 3 2 5 4 6 |
||
Line 790: | Line 2,255: | ||
6 |
6 |
||
6 |
6 |
||
</pre> |
|||
===Tcl 8.6=== |
|||
<syntaxhighlight lang="tcl">set sorted {} |
|||
lmap x $argv {after $x [list lappend sorted $x]} |
|||
while {[llength $sorted] != $argc} { |
|||
vwait sorted |
|||
} |
|||
puts $sorted</syntaxhighlight> |
|||
{{out}} |
|||
<pre>$ echo 'puts [lmap _ [lrepeat 30 {}] {expr {int(rand() * 100)}}]' | tclsh | tee /dev/tty | xargs tclsh sleepsort.tcl |
|||
5 8 70 27 15 80 49 2 69 93 29 1 14 84 43 2 81 44 60 62 8 75 23 61 42 68 79 46 72 65 |
|||
1 2 2 5 8 8 14 15 23 27 29 42 43 44 46 49 60 61 62 65 68 69 70 72 75 79 80 81 84 93</pre> |
|||
===Tcl 8.6: coroutine=== |
|||
<syntaxhighlight lang="tcl">#! /usr/bin/env tclsh |
|||
package require Tcl 8.6 |
|||
# By aspect (https://wiki.tcl-lang.org/page/aspect). Modified slightly. |
|||
# 1. Schedule N delayed calls to our own coroutine. |
|||
# 2. Yield N times to grab the scheduled values. Print each. |
|||
# 3. Store the sorted list in $varName. |
|||
proc sleep-sort {ls varName} { |
|||
foreach x $ls { |
|||
after $x [info coroutine] $x |
|||
} |
|||
set $varName [lmap x $ls { |
|||
set newX [yield] |
|||
puts $newX |
|||
lindex $newX |
|||
}] |
|||
} |
|||
# Ensure the list is suitable for use with [sleep-sort]. |
|||
proc validate ls { |
|||
if {[llength $ls] == 0} { |
|||
error {list is empty} |
|||
} |
|||
foreach x $ls { |
|||
if {![string is integer -strict $x] || $x < 0} { |
|||
error [list invalid value: $x] |
|||
} |
|||
} |
|||
return $ls |
|||
} |
|||
coroutine c sleep-sort [validate $argv] ::sorted |
|||
vwait sorted</syntaxhighlight> |
|||
'''Demo:''' |
|||
<pre> |
|||
$ ./sleepsort.tcl 1 2 100 40 76 0 0 0 200 199 |
|||
0 |
|||
0 |
|||
0 |
|||
1 |
|||
2 |
|||
40 |
|||
76 |
|||
100 |
|||
199 |
|||
200 |
|||
</pre> |
</pre> |
||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
{{works with|Bourne Shell}} |
{{works with|Bourne Shell}} |
||
< |
<syntaxhighlight lang="bash">f() { |
||
sleep "$1" |
sleep "$1" |
||
echo "$1" |
echo "$1" |
||
Line 803: | Line 2,332: | ||
shift |
shift |
||
done |
done |
||
wait</ |
wait</syntaxhighlight> |
||
Usage and output: |
Usage and output: |
||
<pre> |
<pre> |
||
Line 813: | Line 2,342: | ||
5 |
5 |
||
9 |
9 |
||
</pre> |
|||
=={{header|Visual Basic .NET}}== |
|||
<syntaxhighlight lang="vbnet">Imports System.Threading |
|||
Module Module1 |
|||
Sub SleepSort(items As IEnumerable(Of Integer)) |
|||
For Each item In items |
|||
Task.Factory.StartNew(Sub() |
|||
Thread.Sleep(1000 * item) |
|||
Console.WriteLine(item) |
|||
End Sub) |
|||
Next |
|||
End Sub |
|||
Sub Main() |
|||
SleepSort({1, 5, 2, 1, 8, 10, 3}) |
|||
Console.ReadKey() |
|||
End Sub |
|||
End Module</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
1 |
|||
2 |
|||
3 |
|||
5 |
|||
8 |
|||
10 |
|||
</pre> |
|||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="vlang"> |
|||
import time |
|||
import sync |
|||
fn main() { |
|||
mut wg := sync.new_waitgroup() |
|||
test_arr := [3, 2, 1, 4, 1, 7] |
|||
wg.add(test_arr.len) |
|||
for i, value in test_arr { |
|||
go sort(i, value, mut wg) |
|||
} |
|||
wg.wait() |
|||
println('Printed sorted array') |
|||
} |
|||
fn sort(id int, value int, mut wg sync.WaitGroup) { |
|||
time.sleep(value * time.millisecond) // can change duration to second or others |
|||
println(value) |
|||
wg.done() |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
7 |
|||
Printed sorted array |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
More of a simulation than a 'true' sleep sort. |
|||
<syntaxhighlight lang="wren">import "timer" for Timer |
|||
import "io" for Stdout |
|||
import "os" for Process |
|||
var args = Process.arguments |
|||
var n = args.count |
|||
if (n < 2) Fiber.abort("There must be at least two arguments passed.") |
|||
var list = args.map{ |a| Num.fromString(a) }.toList |
|||
if (list.any { |i| i == null || !i.isInteger || i < 0 } ) { |
|||
Fiber.abort("All arguments must be non-negative integers.") |
|||
} |
|||
var max = list.reduce { |acc, i| acc = (i > acc) ? i : acc } |
|||
var fibers = List.filled(max+1, null) |
|||
System.print("Before: %(list.join(" "))") |
|||
for (i in list) { |
|||
var sleepSort = Fiber.new { |i| |
|||
Timer.sleep(1000) |
|||
Fiber.yield(i) |
|||
} |
|||
fibers[i] = sleepSort |
|||
} |
|||
System.write("After : ") |
|||
for (i in 0..max) { |
|||
var fib = fibers[i] |
|||
if (fib) { |
|||
System.write("%(fib.call(i)) ") |
|||
Stdout.flush() |
|||
} |
|||
} |
|||
System.print()</syntaxhighlight> |
|||
{{out}} |
|||
Sample run: |
|||
<pre> |
|||
$ wren Sorting_algorithms_Sleep_sort.wren 1 8 3 7 4 6 |
|||
Before: 1 8 3 7 4 6 |
|||
After : 1 3 4 6 7 8 |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
<syntaxhighlight lang="zkl">vm.arglist.apply(fcn(n){ Atomic.sleep(n); print(n) }.launch); |
|||
Atomic.waitFor(fcn{ vm.numThreads == 1 }); Atomic.sleep(2); println();</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
$ zkl bbb 7 6 9 2 4 8 1 3 5 |
|||
123456789 |
|||
$ |
|||
</pre> |
</pre> |
||
{{omit from|GUISS}} |
{{omit from|GUISS}} |
||
{{omit from|Axe}} |
Latest revision as of 14:17, 8 March 2024
You are encouraged to solve this task according to the task description, using any language you may know.
Sorting Algorithm
This is a sorting algorithm. It may be applied to a set of data in order to sort it.
For comparing various sorts, see compare sorts.
For other sorting algorithms, see sorting algorithms, or:
Heap sort | Merge sort | Patience sort | Quick sort
O(n log2n) sorts
Shell Sort
O(n2) sorts
Bubble sort |
Cocktail sort |
Cocktail sort with shifting bounds |
Comb sort |
Cycle sort |
Gnome sort |
Insertion sort |
Selection sort |
Strand sort
other sorts
Bead sort |
Bogo sort |
Common sorted list |
Composite structures sort |
Custom comparator sort |
Counting sort |
Disjoint sublist sort |
External sort |
Jort sort |
Lexicographical sort |
Natural sorting |
Order by pair comparisons |
Order disjoint list items |
Order two numerical lists |
Object identifier (OID) sort |
Pancake sort |
Quickselect |
Permutation sort |
Radix sort |
Ranking methods |
Remove duplicate elements |
Sleep sort |
Stooge sort |
[Sort letters of a string] |
Three variable sort |
Topological sort |
Tree sort
In general, sleep sort works by starting a separate task for each item to be sorted, where each task sleeps for an interval corresponding to the item's sort key, then emits the item. Items are then collected sequentially in time.
Task: Write a program that implements sleep sort. Have it accept non-negative integers on the command line and print the integers in sorted order. If this is not idomatic in your language or environment, input and output may be done differently. Enhancements for optimization, generalization, practicality, robustness, and so on are not required.
Sleep sort was presented anonymously on 4chan and has been discussed on Hacker News.
Ada
with Ada.Text_IO;
with Ada.Command_Line; use Ada.Command_Line;
procedure SleepSort is
task type PrintTask (num : Integer);
task body PrintTask is begin
delay Duration (num) / 100.0;
Ada.Text_IO.Put(num'Img);
end PrintTask;
type TaskAcc is access PrintTask;
TaskList : array (1 .. Argument_Count) of TaskAcc;
begin
for i in TaskList'Range loop
TaskList(i) := new PrintTask(Integer'Value(Argument(i)));
end loop;
end SleepSort;
- Output:
./sleepsort 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 1 2 7 8 11 14 20 20 21 25 27 30 32 35 41 42 42 43 46 50
APL
sleepsort←{{r}⎕TSYNC{r,←⊃⍵,⎕DL ⍵}&¨⍵,r←⍬}
Assembly
format ELF64 executable 3
entry start
; parameters: argc, argv[] on stack
start:
mov r12, [rsp] ; get argc
mov r13, 1 ; skip argv[0]
.getargv:
cmp r13, r12 ; check completion of args
je .wait
mov rdi, [rsp+8+8*r13] ; get argv[n]
inc r13
mov rax, 57 ; sys_fork
syscall
cmp rax, 0 ; continue loop in main process
jnz .getargv
push rdi ; save pointer to sort item text
call atoi_simple ; convert text to integer
test rax, rax ; throw out bad input
js .done
sub rsp, 16 ; stack space for timespec
mov [rsp], rax ; seconds
mov qword [rsp+8], 0 ; nanoseconds
lea rdi, [rsp]
xor rsi, rsi
mov rax, 35 ; sys_nanosleep
syscall
add rsp, 16
pop rdi ; retrieve item text
call strlen_simple
mov rsi, rdi
mov byte [rsi+rax], ' '
mov rdi, 1
mov rdx, rax
inc rdx
mov rax, 1 ; sys_write
syscall
jmp .done
.wait:
dec r12 ; wait for each child process
jz .done
mov rdi, 0 ; any pid
mov rsi, 0
mov rdx, 0
mov r10, 4 ; that has terminated
mov rax, 247 ; sys_waitid
syscall
jmp .wait
.done:
xor rdi, rdi
mov rax, 60 ; sys_exit
syscall
; parameter: rdi = string pointer
; return: rax = integer conversion
atoi_simple:
push rdi
push rsi
xor rax, rax
.convert:
movzx rsi, byte [rdi]
test rsi, rsi ; check for null
jz .done
cmp rsi, '0'
jl .baddigit
cmp rsi, '9'
jg .baddigit
sub rsi, 48 ; get ascii code for digit
imul rax, 10 ; radix 10
add rax, rsi ; add current digit to total
inc rdi
jmp .convert
.baddigit:
mov rax, -1 ; return error code on failed conversion
.done:
pop rsi
pop rdi
ret ; return integer value
; parameter: rdi = string pointer
; return: rax = length
strlen_simple:
xor rax, rax
.compare:
cmp byte [rdi+rax], 0
je .done
inc rax
jmp .compare
.done:
ret
- Output:
./sleepsort 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 1 2 7 8 11 14 20 20 21 25 27 30 32 35 41 42 42 43 46 50
AutoHotkey
items := [1,5,4,9,3,4]
for i, v in SleepSort(items)
result .= v ", "
MsgBox, 262144, , % result := "[" Trim(result, ", ") "]"
return
SleepSort(items){
global Sorted := []
slp := 50
for i, v in items{
fn := Func("PushFn").Bind(v)
SetTimer, %fn%, % v * -slp
}
Sleep % Max(items*) * slp
return Sorted
}
PushFn(v){
global Sorted
Sorted.Push(v)
}
- Output:
[1, 3, 4, 4, 5, 9]
Bash
function sleep_and_echo {
sleep "$1"
echo "$1"
}
for val in "$@"; do
sleep_and_echo "$val" &
done
wait
- Output:
$ ./sleep_sort.sh 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 1 2 7 8 11 14 20 20 21 25 27 30 32 35 41 42 42 43 46 50
BBC BASIC
This does not explicitly 'sleep', but uses timers to implement the different delays.
INSTALL @lib$+"TIMERLIB"
DIM test%(9)
test%() = 4, 65, 2, 31, 0, 99, 2, 83, 782, 1
FOR i% = 0 TO DIM(test%(),1)
p% = EVAL("!^PROCtask" + STR$(i%))
tid% = FN_ontimer(100 + test%(i%), p%, 0)
NEXT
REPEAT
WAIT 0
UNTIL FALSE
DEF PROCtask0 : PRINT test%(0) : ENDPROC
DEF PROCtask1 : PRINT test%(1) : ENDPROC
DEF PROCtask2 : PRINT test%(2) : ENDPROC
DEF PROCtask3 : PRINT test%(3) : ENDPROC
DEF PROCtask4 : PRINT test%(4) : ENDPROC
DEF PROCtask5 : PRINT test%(5) : ENDPROC
DEF PROCtask6 : PRINT test%(6) : ENDPROC
DEF PROCtask7 : PRINT test%(7) : ENDPROC
DEF PROCtask8 : PRINT test%(8) : ENDPROC
DEF PROCtask9 : PRINT test%(9) : ENDPROC
Output:
0 1 2 2 4 31 65 83 99 782
Brainf***
>>>>>,----------[++++++++
++[->+>+<<]>+>[-<<+>>]+++
+++++[-<------>]>>+>,----
------<<+[->>>>>+<<<<<]>>
]>>>[<<<<[<<<[->>+<<[->+>
[-]<<]]>[-<+>]>[-<<<.>>>>
->>>>>[>>>>>]<-<<<<[<<<<<
]+<]<<<<]>>>>>[>>>>>]<]
Not exactly 'sleep' sort but it is similar: it inputs an array of digits and in each iteration reduces elements by 1. When an element becomes 0 – it prints the original digit.
Input: 1539\n
Output: 1359
C
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int c, char **v)
{
while (--c > 1 && !fork());
sleep(c = atoi(v[c]));
printf("%d\n", c);
wait(0);
return 0;
}
Running it:
% ./a.out 5 1 3 2 11 6 4
1
2
3
4
5
6
11
If you worry about time efficiency of this sorting algorithm (ha!), you can make it a 100 times faster by replacing the sleep(...
with usleep(10000 * (c = atoi(v[c])))
. The smaller the coefficient, the faster it is, but make sure it's not comparable to your kernel clock ticks or the wake up sequence will be wrong.
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
class Program
{
static void ThreadStart(object item)
{
Thread.Sleep(1000 * (int)item);
Console.WriteLine(item);
}
static void SleepSort(IEnumerable<int> items)
{
foreach (var item in items)
{
new Thread(ThreadStart).Start(item);
}
}
static void Main(string[] arguments)
{
SleepSort(arguments.Select(int.Parse));
}
}
Using Tasks
var input = new[] { 1, 9, 2, 1, 3 };
foreach (var n in input)
Task.Run(() =>
{
Thread.Sleep(n * 1000);
Console.WriteLine(n);
});
Output, i.e. in LINQPad:
1 1 2 3 9
C++
#include <chrono>
#include <iostream>
#include <thread>
#include <vector>
int main(int argc, char* argv[]) {
std::vector<std::thread> threads;
for (int i = 1; i < argc; ++i) {
threads.emplace_back([i, &argv]() {
int arg = std::stoi(argv[i]);
std::this_thread::sleep_for(std::chrono::seconds(arg));
std::cout << argv[i] << std::endl;
});
}
for (auto& thread : threads) {
thread.join();
}
}
- Output:
./a.out 8 15 14 9 17 20 16 24 6 24 21 23 19 23 19 6 8 9 14 15 16 17 19 19 20 21 23 23 24 24
Clojure
Using core.async
(ns sleepsort.core
(require [clojure.core.async :as async :refer [chan go <! <!! >! timeout]]))
(defn sleep-sort [l]
(let [c (chan (count l))]
(doseq [i l]
(go (<! (timeout (* 1000 i)))
(>! c i)))
(<!! (async/into [] (async/take (count l) c)))))
(sleep-sort [4 5 3 1 2 7 6])
;=> [1 2 3 4 5 6 7]
CoffeeScript
after = (s, f) -> setTimeout f, s*1000
# Setting Computer Science back at least a century, maybe more,
# this algorithm sorts integers using a highly parallelized algorithm.
sleep_sort = (arr) ->
for n in arr
do (n) -> after n, -> console.log n
do ->
input = (parseInt(arg) for arg in process.argv[2...])
sleep_sort input
output
> time coffee sleep_sort.coffee 5, 1, 3, 4, 2
1
2
3
4
5
real 0m5.184s
user 0m0.147s
sys 0m0.024s
Common Lisp
(defun sleeprint(n)
(sleep (/ n 10))
(format t "~a~%" n))
(loop for arg in (cdr sb-ext:*posix-argv*) doing
(sb-thread:make-thread (lambda() (sleeprint (parse-integer arg)))))
(loop while (not (null (cdr (sb-thread:list-all-threads)))))
- Output:
$ sbcl --script ss.cl 3 1 4 1 5 1 1 3 4 5
D
void main(string[] args)
{
import core.thread, std;
args.drop(1).map!(a => a.to!uint).parallel.each!((a)
{
Thread.sleep(dur!"msecs"(a));
write(a, " ");
});
}
- Output:
$ ./sorting_algorithms_sleep_sort 200 20 50 10 80 10 20 50 80 200
Dart
void main() async {
Future<void> sleepsort(Iterable<int> input) => Future.wait(input
.map((i) => Future.delayed(Duration(milliseconds: i), () => print(i))));
await sleepsort([3, 10, 2, 120, 122, 121, 54]);
}
- Output:
2 3 10 54 120 121 122
Delphi
program SleepSortDemo;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, Classes;
type
TSleepThread = class(TThread)
private
FValue: Integer;
FLock: PRTLCriticalSection;
protected
constructor Create(AValue: Integer; ALock: PRTLCriticalSection);
procedure Execute; override;
end;
constructor TSleepThread.Create(AValue: Integer; ALock: PRTLCriticalSection);
begin
FValue:= AValue;
FLock:= ALock;
inherited Create(False);
end;
procedure TSleepThread.Execute;
begin
Sleep(1000 * FValue);
EnterCriticalSection(FLock^);
Write(FValue:3);
LeaveCriticalSection(FLock^);
end;
var
A: array[0..15] of Integer;
Handles: array[0..15] of THandle;
Threads: array[0..15] of TThread;
Lock: TRTLCriticalSection;
I: Integer;
begin
for I:= Low(A) to High(A) do
A[I]:= Random(15);
for I:= Low(A) to High(A) do
Write(A[I]:3);
Writeln;
InitializeCriticalSection(Lock);
for I:= Low(A) to High(A) do begin
Threads[I]:= TSleepThread.Create(A[I], @Lock);
Handles[I]:= Threads[I].Handle;
end;
WaitForMultipleObjects(Length(A), @Handles, True, INFINITE);
for I:= Low(A) to High(A) do
Threads[I].Free;
DeleteCriticalSection(Lock);
Writeln;
ReadLn;
end.
Output:
0 0 12 3 4 10 4 2 5 6 1 7 1 12 0 4 0 0 0 1 1 2 3 4 4 4 5 6 7 10 12 12
Elena
ELENA 6.0 :
import extensions;
import system'routines;
import extensions'threading;
import system'threading;
static sync = new object();
extension op
{
sleepSort()
{
self.forEach::(n)
{
threadControl.start(
{
threadControl.sleep(1000 * n);
lock(sync)
{
console.printLine(n)
}
})
}
}
}
public program()
{
program_arguments.skipping(1).selectBy(mssgconst toInt<intConvertOp>[1]).toArray().sleepSort();
console.readChar()
}
Elixir
defmodule Sort do
def sleep_sort(args) do
Enum.each(args, fn(arg) -> Process.send_after(self, arg, 5 * arg) end)
loop(length(args))
end
defp loop(0), do: :ok
defp loop(n) do
receive do
num -> IO.puts num
loop(n - 1)
end
end
end
Sort.sleep_sort [2, 4, 8, 12, 35, 2, 12, 1]
- Output:
1 2 2 4 8 12 12 35
Emacs Lisp
GNU Emacs supports threads, but it's more straightforward to do this by just using timers.
Evaluate in the *scratch* buffer by typing C-M-x
on the expression:
(dolist (i '(3 1 4 1 5 92 65 3 5 89 79 3))
(run-with-timer (* i 0.001) nil 'message "%d" i))
The output printed in the *Messages* buffer is:
1 [2 times] 3 [3 times] 4 5 [2 times] 65 79 89 92
Erlang
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname sleepsort
main(Args) ->
lists:foreach(fun(Arg) ->
timer:send_after(5 * list_to_integer(Arg), self(), Arg)
end, Args),
loop(length(Args)).
loop(0) ->
ok;
loop(N) ->
receive
Num ->
io:format("~s~n", [Num]),
loop(N - 1)
end.
- Output:
./sleepsort 2 4 8 12 35 2 12 1 1 2 2 4 8 12 12 35
Euphoria
include get.e
integer count
procedure sleeper(integer key)
? key
count -= 1
end procedure
sequence s, val
atom task
s = command_line()
s = s[3..$]
if length(s)=0 then
puts(1,"Nothing to sort.\n")
else
count = 0
for i = 1 to length(s) do
val = value(s[i])
if val[1] = GET_SUCCESS then
task = task_create(routine_id("sleeper"),{val[2]})
task_schedule(task,{val[2],val[2]}/10)
count += 1
end if
end for
while count do
task_yield()
end while
end if
F#
let sleepSort (values: seq<int>) =
values
|> Seq.map (fun x -> async {
do! Async.Sleep x
Console.WriteLine x
})
|> Async.Parallel
|> Async.Ignore
|> Async.RunSynchronously
Usage:
sleepSort [10; 33; 80; 32]
10
32
33
80
Factor
USING: threads calendar concurrency.combinators ;
: sleep-sort ( seq -- ) [ dup seconds sleep . ] parallel-each ;
Usage:
{ 1 9 2 6 3 4 5 8 7 0 } sleep-sort
Fortran
program sleepSort
use omp_lib
implicit none
integer::nArgs,myid,i,stat
integer,allocatable::intArg(:)
character(len=5)::arg
!$omp master
nArgs=command_argument_count()
if(nArgs==0)stop ' : No argument is given !'
allocate(intArg(nArgs))
do i=1,nArgs
call get_command_argument(i, arg)
read(arg,'(I5)',iostat=stat)intArg(i)
if(intArg(i)<0 .or. stat/=0) stop&
&' :Only 0 or positive integer allowed !'
end do
call omp_set_num_threads(nArgs)
!$omp end master
!$omp parallel private(myid)
myid =omp_get_thread_num()
call sleepNprint(intArg(myid+1))
!$omp end parallel
contains
subroutine sleepNprint(nSeconds)
integer::nSeconds
call sleep(nSeconds)
print*,nSeconds
end subroutine sleepNprint
end program sleepSort
Compile and Output:
gfortran -fopenmp sleepSort.f90 -o sleepSort ./sleepSort 0 3 1 4 1 5 9 0 1 1 3 4 5 9
FreeBASIC
Can't use FreeBASIC sleep since it halts the program. Instead it uses a second array filled with times based on the value of number, this array is check against the timer. If the timer is past the stored time the value is printed.
' version 21-10-2016
' compile with: fbc -s console
' compile with: fbc -s console -exx (for bondry check on the array's)
' not very well suited for large numbers and large array's
' positive numbers only
Sub sandman(sleepy() As ULong)
Dim As Long lb = LBound(sleepy)
Dim As Long ub = UBound(sleepy)
Dim As Long i, count = ub
Dim As Double wakeup(lb To ub)
Dim As Double t = Timer
For i = lb To ub
wakeup(i) = sleepy(i) +1 + t
Next
Do
t = Timer
For i = lb To ub
If wakeup(i) <= t Then
Print Using "####";sleepy(i);
wakeup(i) = 1e9 ' mark it as used
count = count -1
End If
Next
Sleep (1 - (Timer - t)) * 300, 1 ' reduce CPU load
Loop Until count < lb
End Sub
' ------=< MAIN >=------
Dim As ULong i, arr(10)
Dim As ULong lb = LBound(arr)
Dim As ULong ub = UBound(arr)
Randomize Timer
For i = lb To ub -1 ' leave last one zero
arr(i) = Int(Rnd * 10) +1
Next
Print "unsorted ";
For i = lb To ub
Print Using "####";arr(i);
Next
Print : Print
Print " sorted ";
sandman(arr())
Print : Print
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End
- Output:
unsorted 5 2 5 6 4 6 9 5 1 2 0 sorted 0 1 2 2 4 5 5 5 6 6 9
Go
package main
import (
"fmt"
"log"
"os"
"strconv"
"time"
)
func main() {
out := make(chan uint64)
for _, a := range os.Args[1:] {
i, err := strconv.ParseUint(a, 10, 64)
if err != nil {
log.Fatal(err)
}
go func(n uint64) {
time.Sleep(time.Duration(n) * time.Millisecond)
out <- n
}(i)
}
for _ = range os.Args[1:] {
fmt.Println(<-out)
}
}
Usage and output:
./sleepsort 3 1 4 1 5 9 1 1 3 4 5 9
Using sync.WaitGroup
package main
import (
"fmt"
"log"
"os"
"strconv"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
wg.Add(len(os.Args[1:]))
for _,i := range os.Args[1:] {
x, err := strconv.ParseUint(i, 10, 64)
if err != nil {
log.Println(err)
}
wg.Add(1)
go func(i uint64, wg *sync.WaitGroup) {
defer wg.Done()
time.Sleep(time.Duration(i) * time.Second)
fmt.Println(i)
}(x, &wg)
}
wg.Wait()
}
Usage and output are the same as the version using channels. Note that the original version would sleep for increments of 1 full second, so I made my code do the same.
Groovy
@Grab(group = 'org.codehaus.gpars', module = 'gpars', version = '1.2.1')
import groovyx.gpars.GParsPool
GParsPool.withPool args.size(), {
args.eachParallel {
sleep(it.toInteger() * 10)
println it
}
}
Sample Run:
> groovy sleepsort.groovy 42 23 16 15 8 4 4 8 15 16 23 42
Haskell
import System.Environment
import Control.Concurrent
import Control.Monad
sleepSort :: [Int] -> IO ()
sleepSort values = do
chan <- newChan
forM_ values (\time -> forkIO (threadDelay (50000 * time) >> writeChan chan time))
forM_ values (\_ -> readChan chan >>= print)
main :: IO ()
main = getArgs >>= sleepSort . map read
Using mapConcurrently_
import System.Environment
import Control.Concurrent
import Control.Concurrent.Async
sleepSort :: [Int] -> IO ()
sleepSort = mapConcurrently_ (\x -> threadDelay (x*10^4) >> print x)
main :: IO ()
main = getArgs >>= sleepSort . map read
This is problematic for inputs with multiple duplicates like [1,2,3,1,4,1,5,1]
because simultaneous print
s are done concurrently and the 1s and newlines get output in jumbled up order. The channels-based version above doesn't have this problem.
Icon and Unicon
The following solution only works in Unicon.
procedure main(A)
every insert(t:=set(),mkThread(t,!A))
every spawn(!t) # start threads as closely grouped as possible
while (*t > 0) do write(<<@)
end
procedure mkThread(t,n) # 10ms delay scale factor
return create (delay(n*10),delete(t,¤t),n@>&main)
end
Sample run:
->ss 3 1 4 1 5 9 2 6 1 1 2 3 4 5 6 9 ->
J
scheduledumb=: {{
id=:'dumb',":x:6!:9''
wd 'pc ',id
(t)=: u {{u y[erase n}} t=. id,'_timer'
wd 'ptimer ',":n p.y
}}
ssort=: {{
R=: ''
poly=. 1,>./ y
poly{{ y{{R=:R,m[y}}scheduledumb m y}}"0 y
{{echo R}} scheduledumb poly"0 >:>./ y
EMPTY
}}
Task example:
t=: ?~30
t
11 7 22 16 17 2 1 19 23 29 9 21 15 10 12 27 3 4 24 20 14 5 26 18 8 6 0 13 25 28
ssort t
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Note that since t is the result of an RNG, the order of values in t would be different in subsequent attempts. For example:
t=: ?~30
t
23 26 24 25 10 12 4 5 7 27 16 17 14 8 3 15 18 13 19 21 2 28 22 9 6 20 11 1 29 0
ssort t
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Java
import java.util.concurrent.CountDownLatch;
public class SleepSort {
public static void sleepSortAndPrint(int[] nums) {
final CountDownLatch doneSignal = new CountDownLatch(nums.length);
for (final int num : nums) {
new Thread(new Runnable() {
public void run() {
doneSignal.countDown();
try {
doneSignal.await();
//using straight milliseconds produces unpredictable
//results with small numbers
//using 1000 here gives a nifty demonstration
Thread.sleep(num * 1000);
System.out.println(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
public static void main(String[] args) {
int[] nums = new int[args.length];
for (int i = 0; i < args.length; i++)
nums[i] = Integer.parseInt(args[i]);
sleepSortAndPrint(nums);
}
}
Output (using "3 1 4 5 2 3 1 6 1 3 2 5 4 6" as arguments):
1 1 1 2 2 3 3 3 4 4 5 5 6 6
JavaScript
Array.prototype.timeoutSort = function (f) {
this.forEach(function (n) {
setTimeout(function () { f(n) }, 5 * n)
});
}
Usage and output:
[1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0].timeoutSort(function(n) { document.write(n + '<br>'); })
0 1 2 3 4 5 6 7 8 9
Array.prototype.sleepSort = function(callback) {
const res = [];
for (let n of this)
setTimeout(() => {
res.push(n);
if (this.length === res.length)
callback(res);
}, n + 1);
return res;
};
[1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0].sleepSort(console.log);
// [ 1, 0, 2, 3, 4, 5, 5, 6, 7, 8, 9 ]
jq
Doesn't actually sleep. Instead, iterates reducing the values by one until each is zero.
echo '[5, 1, 3, 2, 11, 6, 4]' | jq '
def f:
if .unsorted == [] then
.sorted
else
{ unsorted: [.unsorted[] | .t = .t - 1 | select(.t != 0)]
, sorted: (.sorted + [.unsorted[] | .t = .t - 1 | select(.t == 0) | .v]) }
| f
end;
{unsorted: [.[] | {v: ., t: .}], sorted: []} | f | .[]
'
- Output:
1 2 3 4 5 6 11
Julia
function sleepsort(V::Vector{T}) where {T <: Real}
U = Vector{T}()
sizehint!(U, length(V))
@sync for v in V
@async begin
sleep(abs(v))
(v < 0 ? pushfirst! : push!)(U, v)
end
end
return U
end
v = rand(-10:10, 10)
println("# unordered: $v\n -> ordered: ", sleepsort(v))
- Output:
# unordered: [10, -1, 3, -9, 1, -5, -8, -7, -3, 3] -> ordered: [-9, -8, -7, -5, -3, -1, 1, 3, 3, 10]
Kotlin
// version 1.1.51
import kotlin.concurrent.thread
fun sleepSort(list: List<Int>, interval: Long) {
print("Sorted : ")
for (i in list) {
thread {
Thread.sleep(i * interval)
print("$i ")
}
}
thread { // print a new line after displaying sorted list
Thread.sleep ((1 + list.max()!!) * interval)
println()
}
}
fun main(args: Array<String>) {
val list = args.map { it.toInt() }.filter { it >= 0 } // ignore negative integers
println("Unsorted: ${list.joinToString(" ")}")
sleepSort(list, 50)
}
Sample output:
$ java -jar sleepsort.jar 5 7 -1 2 4 1 8 0 3 9 6 Unsorted: 5 7 2 4 1 8 0 3 9 6 Sorted : 0 1 2 3 4 5 6 7 8 9
Using coroutines
import kotlinx.coroutines.*
fun sleepSort(list: List<Int>, delta: Long) {
runBlocking {
list.onEach {
launch {
delay(it * delta)
print("$it ")
}
}
}
}
fun main() {
val list = listOf(5, 7, 2, 4, 1, 8, 0, 3, 9, 6)
println("Unsorted: ${list.joinToString(" ")}")
print("Sorted : ")
sleepSort(list, 10)
}
Output:
Unsorted: 5 7 2 4 1 8 0 3 9 6 Sorted : 0 1 2 3 4 5 6 7 8 9
Lua
Here's a slow implementation using only stock C Lua:
function sleeprint(n)
local t0 = os.time()
while os.time() - t0 <= n do
coroutine.yield(false)
end
print(n)
return true
end
coroutines = {}
for i=1, #arg do
wrapped = coroutine.wrap(sleeprint)
table.insert(coroutines, wrapped)
wrapped(tonumber(arg[i]))
end
done = false
while not done do
done = true
for i=#coroutines,1,-1 do
if coroutines[i]() then
table.remove(coroutines, i)
else
done = false
end
end
end
By installing LuaSocket, you can get better than 1-second precision on the clock, and therefore faster output:
socket = require 'socket'
function sleeprint(n)
local t0 = socket.gettime()
while (socket.gettime() - t0)*100 <= n do
coroutine.yield(false)
end
print(n)
return true
end
coroutines = {}
for i=1, #arg do
wrapped = coroutine.wrap(sleeprint)
table.insert(coroutines, wrapped)
wrapped(tonumber(arg[i]))
end
done = false
while not done do
done = true
for i=#coroutines,1,-1 do
if coroutines[i]() then
table.remove(coroutines, i)
else
done = false
end
end
end
Either way, the output is the same:
- Output:
$ lua sleep_sort.lua 3 1 4 1 5 9 2 6 5 3 5 1 1 2 3 3 4 5 5 5 6 9
Mathematica/Wolfram Language
SleepSort = RunScheduledTask[Print@#, {#, 1}] & /@ # &;
SleepSort@{1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0};
- Output:
0 1 2 3 4 5 6 7 8 9
NetRexx
As implemented this sample goes beyond the scope of the task as defined; it will handle negative numbers.
/* NetRexx */
options replace format comments java crossref symbols nobinary
import java.util.concurrent.CountDownLatch
-- =============================================================================
class RSortingSleepsort
properties constant private
dflt = '-6 3 1 4 5 2 3 -7 1 6 001 3 -9 2 5 -009 -8 4 6 1 9 8 7 6 5 -7 3 4 5 2 0 -2 -1 -5 -4 -3 -0 000 0'
properties indirect
startLatch = CountDownLatch
doneLatch = CountDownLatch
floor = 0
sorted = ''
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method main(args = String[]) public static
arg = Rexx(args)
if arg = '' then arg = dflt
say ' unsorted:' arg
say ' sorted:' (RSortingSleepsort()).sleepSort(arg)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method sleepSort(iArg) public
setStartLatch(CountDownLatch(1)) -- used to put all threads on hold until we're ready to run
setDoneLatch(CountDownLatch(iArg.words())) -- used to indicate all work is done
loop mn = 1 to iArg.words()
setFloor(getFloor().min(iArg.word(mn))) -- save smallest -ve number so we can use it as a scale for sleep
Thread(SortThread(iArg.word(mn))).start() -- loop through input and create a thread for each element
end mn
getStartLatch().countDown() -- cry 'Havoc', and let slip the dogs of war.
do
getDoneLatch().await() -- wait for worker threads to complete
catch ix = InterruptedException
ix.printStackTrace()
end
return getSorted()
-- =============================================================================
class RSortingSleepsort.SortThread dependent implements Runnable
properties indirect
num
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method SortThread(nm)
setNum(nm)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method run() public
do
parent.getStartLatch().await() -- wait until all threads are constructed
sleepTime = getNum() + parent.getFloor().abs() -- shifted by value of smallest number (permits numbers < 0)
sleepTime = sleepTime * 250 -- scale up; milliseconds are not granular enough
Thread.sleep(sleepTime) -- wait for this number's turn to run
catch ie = InterruptedException
ie.printStackTrace()
end
do protect parent -- lock the parent to prevent collisions
parent.setSorted((parent.getSorted() num).strip()) -- stow the number in the results List
end
parent.getDoneLatch().countDown() -- this one's done; decrement the latch
return
Output:
unsorted: -6 3 1 4 5 2 3 -7 1 6 001 3 -9 2 5 -009 -8 4 6 1 9 8 7 6 5 -7 3 4 5 2 0 -2 -1 -5 -4 -3 -0 000 0 sorted: -9 -009 -8 -7 -7 -6 -5 -4 -3 -2 -1 000 0 0 -0 1 1 001 1 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 6 7 8 9
Nim
Compile with nim --threads:on c sleepsort
:
import os, strutils
proc single(n: int) =
sleep n
echo n
proc main =
var thr = newSeq[TThread[int]](paramCount())
for i,c in commandLineParams():
thr[i].createThread(single, c.parseInt)
thr.joinThreads
main()
Usage:
$ ./sleepsort 5 1 3 2 11 6 4 1 2 3 4 5 6 11
Objeck
use System.Concurrency;
use Collection;
bundle Default {
class Item from Thread {
@value : Int;
New(value : Int) {
Parent();
@value := value;
}
method : public : Run(param : System.Base) ~ Nil {
Sleep(1000 * @value);
@value->PrintLine();
}
}
class SleepSort {
function : Main(args : String[]) ~ Nil {
items := Vector->New();
each(i : args) {
items->AddBack(Item->New(args[i]->ToInt()));
};
each(i : items) {
items->Get(i)->As(Item)->Execute(Nil);
};
}
}
}
Objective-C
#import <Foundation/Foundation.h>
int main(int argc, char **argv)
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
while (--argc) {
int i = atoi(argv[argc]);
[queue addOperationWithBlock: ^{
sleep(i);
NSLog(@"%d\n", i);
}];
}
[queue waitUntilAllOperationsAreFinished];
}
Rather than having multiple operations that sleep, we could also dispatch the tasks after a delay:
#import <Foundation/Foundation.h>
int main(int argc, char **argv)
{
while (--argc) {
int i = atoi(argv[argc]);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, i * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{ NSLog(@"%d\n", i); });
}
}
Oforth
Instead of printing numbers, each task sends its integer into a channel (after sleeping 20 * n milliseconds). This allows the main task to create a new sorted list with those integers.
20 milliseconds is used to (try to) handle scheduler tick on Windows systems (around 15 ms). On Linux systems (after kernel 2.6.8), this value can be smaller.
import: parallel
: sleepSort(l)
| ch n |
Channel new ->ch
l forEach: n [ #[ n dup 20 * sleep ch send drop ] & ]
ListBuffer newSize(l size) #[ ch receive over add ] times(l size) ;
- Output:
100 seq 100 seq + sleepSort println [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 2 5, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 4 8, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 7 0, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 9 3, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100]
Ol
(define (sleep-sort lst)
(for-each (lambda (timeout)
(async (lambda ()
(sleep timeout)
(print timeout))))
lst))
(sleep-sort '(5 8 2 7 9 10 5))
- Output:
2 5 5 7 8 9 10
Pascal
my limit under linux was 4000 threads nearly 2 GB.
program sleepsort;
{$IFDEF FPC}
{$MODE DELPHI} {$Optimization ON,ALL}
{$ElSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
SysUtils;
const
HiLimit = 40;
type
tCombineForOneThread = record
cft_count : Uint64;
cft_ThreadID: NativeUint;
cft_ThreadHandle: NativeUint;
end;
pThreadBlock = ^tCombineForOneThread;
var
SortIdx : array of INteger;
ThreadBlocks : array of tCombineForOneThread;
gblThreadCount,
Finished: Uint32;
procedure PrepareThreads(thdCount:NativeInt);
var
i : NativeInt;
Begin
For i := 0 to thdCount-1 do
ThreadBlocks[i].cft_count:= random(2*HiLimit);
end;
procedure TestRunThd(parameter: pointer);
var
pThdBlk: pThreadBlock;
fi: NativeInt;
begin
pThdBlk := @ThreadBlocks[NativeUint(parameter)];
with pThdBlk^ do
begin
sleep(40*cft_count+1);
fi := Finished-1;
//write(fi:5,cft_count:8,#13);
InterLockedDecrement(Finished);
SortIdx[fi]:= NativeUint(parameter);
end;
EndThread(0);
end;
procedure Test;
var
j,UsedThreads: NativeInt;
begin
randomize;
UsedThreads:= GblThreadCount;
Finished :=UsedThreads;
PrepareThreads(UsedThreads);
j := 0;
while (j < UsedThreads) do
begin
with ThreadBlocks[j] do
begin
cft_ThreadHandle :=
BeginThread(@TestRunThd, Pointer(j), cft_ThreadID,16384 {stacksize} );
If cft_ThreadHandle = 0 then break;
end;
Inc(j);
end;
writeln(j);
UsedThreads := j;
Finished :=UsedThreads;
repeat
sleep(1);
until finished = 0;
For j := 0 to UsedThreads-1 do
CloseThread(ThreadBlocks[j].cft_ThreadID);
//output of sleep-sorted data
For j := UsedThreads-1 downto 1 do
write(ThreadBlocks[SortIdx[j]].cft_count,',');
writeln(ThreadBlocks[SortIdx[0]].cft_count);
end;
begin
randomize;
gblThreadCount := Hilimit;
Writeln('Testthreads : ',gblThreadCount);
setlength(ThreadBlocks,gblThreadCount);
setlength(SortIdx,gblThreadCount);
Test;
setlength(ThreadBlocks, 0);
{$IFDEF WINDOWS}
readln;
{$ENDIF}
end.
- Output:
time ./sleepsort Testthreads : 40 40 1,8,9,10,11,12,12,13,14,18,24,24,24,26,28,35,35,37,42,49,50,52,54,54,56,57,59,60,61,62,64,69,69,71,72,73,76,77,78,79 real 0m3,164s
Perl
Basically the C code.
1 while ($_ = shift and @ARGV and !fork);
sleep $_;
print "$_\n";
wait;
A more optimal solution makes use of Coro, a cooperative threading library. It has the added effect of being much faster, fully deterministic (sleep is not exact), and it allows you to easily collect the return value:
use Coro;
$ret = Coro::Channel->new;
@nums = qw(1 32 2 59 2 39 43 15 8 9 12 9 11);
for my $n (@nums){
async {
Coro::cede for 1..$n;
$ret->put($n);
}
}
print $ret->get,"\n" for 1..@nums;
Phix
Based on Euphoria
without js -- (multitasking) integer count procedure sleeper(integer key) ? key -- (or maybe res &= key) count -= 1 end procedure --sequence s = command_line()[3..$] sequence s = split("3 1 4 1 5 9 2 6 5") if length(s)=0 then puts(1,"Nothing to sort.\n") else count = 0 for i=1 to length(s) do object si = to_number(s[i]) if integer(si) then atom task = task_create(sleeper,{si}) task_schedule(task,{si/10,si/10}) count += 1 end if end for while count do task_yield() end while end if
PHP
A PHP implementation of sleep sort using process forking.
<?php
$buffer = 1;
$pids = [];
for ($i = 1; $i < $argc; $i++) {
$pid = pcntl_fork();
if ($pid < 0) {
die("failed to start child process");
}
if ($pid === 0) {
sleep($argv[$i] + $buffer);
echo $argv[$i] . "\n";
exit();
}
$pids[] = $pid;
}
foreach ($pids as $pid) {
pcntl_waitpid($pid, $status);
}
php ./sleepsort.php 35 21 11 1 2 27 32 7 42 20 50 42 25 41 43 14 46 20 30 8 1 2 7 8 11 14 20 20 21 25 27 30 32 35 41 42 42 43 46 50
PicoLisp
Sleeping in main process
(de sleepSort (Lst)
(make
(for (I . N) Lst
(task (- I) (* N 100) N N I I
(link N)
(pop 'Lst)
(task (- I)) ) )
(wait NIL (not Lst)) ) )
Sleeping in child processes
(de sleepSort (Lst)
(make
(for N Lst
(task (pipe (wait (* N 100))) N N
(link N)
(pop 'Lst)
(task (close @)) ) )
(wait NIL (not Lst)) ) )
Output in both cases:
: (sleepSort (3 1 4 1 5 9 2 6 5)) -> (1 1 2 3 4 5 5 6 9)
Just printing (no sorted result list)
Basically the C code.
(for N (3 1 4 1 5 9 2 6 5)
(unless (fork)
(call 'sleep N)
(msg N)
(bye) ) )
Output:
1 1 2 3 4 5 5 6 9
Pike
#!/usr/bin/env pike
int main(int argc, array(string) argv)
{
foreach(argv[1..], string value)
{
int v = (int)value;
if(v<0)
continue;
call_out(print, v, value);
}
return -1;
}
void print(string value)
{
write("%s\n", value);
if(find_call_out(print)==-1)
exit(0);
return;
}
Output :
$ ./sleep-sort.pike 4 5 -3 1 2 7 6 1 2 4 5 6 7
Prolog
Works with SWI-Prolog.
sleep_sort(L) :-
thread_pool_create(rosetta, 1024, []) ,
maplist(initsort, L, LID),
maplist(thread_join, LID, _LStatus),
thread_pool_destroy(rosetta).
initsort(V, Id) :-
thread_create_in_pool(rosetta, (sleep(V), writeln(V)), Id, []).
Output :
sleep_sort([5, 1, 3, 2, 11, 6, 3, 4]). 1 2 3 3 4 5 6 11 true.
PureBasic
NewMap threads()
Procedure Foo(n)
Delay(n)
PrintN(Str(n))
EndProcedure
If OpenConsole()
For i=1 To CountProgramParameters()
threads(Str(i)) = CreateThread(@Foo(), Val(ProgramParameter()))
Next
ForEach threads()
WaitThread(threads())
Next
Print("Press ENTER to exit"): Input()
EndIf
Sleep_sort.exe 3 1 4 1 5 9 1 1 3 4 5 9 Press ENTER to exit
Python
Python: Using threading.Timer
from time import sleep
from threading import Timer
def sleepsort(values):
sleepsort.result = []
def add1(x):
sleepsort.result.append(x)
mx = values[0]
for v in values:
if mx < v: mx = v
Timer(v, add1, [v]).start()
sleep(mx+1)
return sleepsort.result
if __name__ == '__main__':
x = [3,2,4,7,3,6,9,1]
if sleepsort(x) == sorted(x):
print('sleep sort worked for:',x)
else:
print('sleep sort FAILED for:',x)
- Sample output
sleep sort worked for: [3, 2, 4, 7, 3, 6, 9, 1]
Python v3.5+: Using asyncio
Since the introduction of async/await syntax, the implementation could be a sole translation from the original version in Bash:
#!/usr/bin/env python3
from asyncio import run, sleep, wait
from sys import argv
async def f(n):
await sleep(n)
print(n)
if __name__ == '__main__':
run(wait(map(f, map(int, argv[1:]))))
Example usage:
$ ./sleepsort.py 5 3 6 3 6 3 1 4 7 1 3 3 3 4 5 6 6 7
Racket
#lang racket
;; accepts a list to sort
(define (sleep-sort lst)
(define done (make-channel))
(for ([elem lst])
(thread
(λ ()
(sleep elem)
(channel-put done elem))))
(for/list ([_ (length lst)])
(channel-get done)))
;; outputs '(2 5 5 7 8 9 10)
(sleep-sort '(5 8 2 7 9 10 5))
Raku
(formerly Perl 6)
await map -> $delay { start { sleep $delay ; say $delay } },
<6 8 1 12 2 14 5 2 1 0>;
- Output:
0 1 1 2 2 5 6 8 12 14
This can also be written using reactive programming:
#!/usr/bin/env raku
use v6;
react whenever Supply.from-list(@*ARGS).start({ .&sleep // +$_ }).flat { .say }
- Output:
$ ./sleep-sort 1 3 5 6 2 4 1 2 3 4 5 6
REXX
This sort will accept any manner of numbers, or for that matter, any character string as well.
REXX isn't particular what is being sorted.
/*REXX program implements a sleep sort (with numbers entered from the command line (CL).*/
numeric digits 300 /*over the top, but what the hey! */
/* (above) ··· from vaudeville. */
@.= /*placeholder for the array of numbers.*/
stuff= 1e9 50 5 40 4 1 100 30 3 12 2 8 9 7 6 6 10 20 0 /*alphabetically ··· so far.*/
parse arg numbers /*obtain optional arguments from the CL*/
if numbers='' then numbers= stuff /*Not specified? Then use the default.*/
N= words(numbers) /*N is the number of numbers in list. */
w= length(N) /*width of N (used for nice output). */
parse upper version !ver . /*obtain which REXX we're running under*/
!regina= ('REXX-REGINA'==left(!ver, 11) ) /*indicate (or not) if this is Regina. */
say N 'numbers to be sorted:' numbers /*informative informational information*/
/*from department of redundancy depart.*/
do j=1 for N /*let's start to boogie─woogie da sort.*/
@.j= word(numbers, j) /*plug in a single number at a time. */
if datatype(@.j, 'N') then @.j= @.j / 1 /*normalize it if it's a numeric number*/
if !regina then call fork /*only REGINA REXX supports FORK BIF.*/
call sortItem j /*start a sort for an array number. */
end /*j*/
do forever while \inOrder(N) /*wait for the sorts to complete. */
call delay 1 /*one second is minimum effective time.*/
end /*forever while*/ /*well heck, other than zero seconds. */
m= max(length(@.1), length(@.N) ) /*width of smallest or largest number. */
say; say 'after sort:' /*display a blank line and a title. */
do k=1 for N /*list the (sorted) array's elements.*/
say left('', 20) 'array element' right(k, w) '───►' right(@.k, m)
end /*k*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sortItem: procedure expose @.; parse arg ? /*sorts a single (numeric) item. */
do Asort=1 until \switched /*sort unsorted array until it's sorted*/
switched= 0 /*it's all hunky─dorey, happy─dappy ···*/
do i=1 while @.i\=='' & \switched
if @.? >= @.i then iterate /*item is in order. */
parse value @.? @.i with @.i @.?
switched= 1 /* [↑] swapped one.*/
end /*i*/
if Asort//?==0 then call delay switched /*sleep if last item*/
end /*Asort*/
return /*Sleeping Beauty awakes. Not to worry: (c)=circa 1697.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
inOrder: procedure expose @.; parse arg howMany /*is the array in numerical order? */
do m=1 for howMany-1; next= m+1; if @.m>@.next then return 0 /*¬ in order*/
end /*m*/ /*keep looking for fountain of youth. */
return 1 /*yes, indicate with an indicator. */
Programming note: this REXX program makes use of DELAY BIF which delays (sleeps) for a specified amount of seconds.
Some REXXes don't have a DELAY BIF, so one is included here ──► DELAY.REX.
- output when using the internal default input:
19 numbers to be sorted: 1E9 50 5 40 4 1 100 30 3 12 2 8 9 7 6 6 10 20 0 after sort: array element 1 ───► 0 array element 2 ───► 1 array element 3 ───► 2 array element 4 ───► 3 array element 5 ───► 4 array element 6 ───► 5 array element 7 ───► 6 array element 8 ───► 6 array element 9 ───► 7 array element 10 ───► 8 array element 11 ───► 9 array element 12 ───► 10 array element 13 ───► 12 array element 14 ───► 20 array element 15 ───► 30 array element 16 ───► 40 array element 17 ───► 50 array element 18 ───► 100 array element 19 ───► 1000000000
Ruby
require 'thread'
nums = ARGV.collect(&:to_i)
sorted = []
mutex = Mutex.new
threads = nums.collect do |n|
Thread.new do
sleep 0.01 * n
mutex.synchronize {sorted << n}
end
end
threads.each {|t| t.join}
p sorted
Example
$ ruby sleepsort.rb 3 1 4 5 2 3 1 6 1 3 2 5 4 6 [1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6]
Rust
use std::thread;
fn sleepsort<I: Iterator<Item=u32>>(nums: I) {
let threads: Vec<_> = nums.map(|n|
thread::spawn(move || {
thread::sleep_ms(n);
println!("{}", n); })).collect();
for t in threads { t.join(); }
}
fn main() {
sleepsort(std::env::args().skip(1).map(|s| s.parse().unwrap()));
}
Output:
$ ./sleepsort 50 34 43 3 2 2 3 34 43 50
Scala
object SleepSort {
def main(args: Array[String]): Unit = {
val nums = args.map(_.toInt)
sort(nums)
Thread.sleep(nums.max * 21) // Keep the JVM alive for the example
}
def sort(nums: Seq[Int]): Unit =
nums.foreach(i => new Thread {
override def run() {
Thread.sleep(i * 20) // just `i` is unpredictable with small numbers
print(s"$i ")
}
}.start())
}
- Output:
$ scala SleepSort 1 3 6 0 9 7 4 2 5 8
0 1 2 3 4 5 5 6 7 8 9
Sidef
ARGV.map{.to_i}.map{ |i|
{Sys.sleep(i); say i}.fork;
}.each{.wait};
- Output:
% sidef test.sf 5 1 3 2 11 6 4 1 2 3 4 5 6 11
Simula
SIMULATION
BEGIN
PROCESS CLASS SORTITEM(N); INTEGER N;
BEGIN
HOLD(N);
OUTINT(N, 3);
END;
INTEGER I;
FOR I := 3, 2, 4, 7, 3, 6, 9, 1 DO
BEGIN
REF(SORTITEM) SI;
SI :- NEW SORTITEM(I);
ACTIVATE SI;
END;
HOLD(100000);
OUTIMAGE;
END;
- Output:
1 2 3 3 4 6 7 9
SNUSP
Bloated SNUSP is ideally suited to this task, since this the variant adds multithreading and an additional dimension of data space. Sleep time is simulated by the loop delay required to copy each cell value, thereby ensuring that smaller values are printed earlier than larger values. This program requires a Bloated SNUSP interpreter which returns zero on input end-of-file.
/$>\ input until eof
#/?<\?,/ foreach: fork
\ &/:+ copy and\
/:\?-; delay /
\.# print and exit thread
Legend:
- & - SPLIT creates a new thread. Like @ ENTER, it skips one cell of code space to start its continuation.
- : ; - UP and DOWN are equivalent to < > LEFT and RIGHT, but moves the data pointer in the second dimension.
- # - in Bloated SNUSP, LEAVE only terminates the current thread. The overall program only exits when all threads have quit.
Swift
import Foundation
for i in [5, 2, 4, 6, 1, 7, 20, 14] {
let time = dispatch_time(DISPATCH_TIME_NOW,
Int64(i * Int(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue()) {
print(i)
}
}
CFRunLoopRun()
- Output:
1 2 4 5 6 7 14 20
Tcl
Tcl 8.5
#!/bin/env tclsh
set count 0
proc process val {
puts $val
incr ::count
}
# Schedule the output of the values
foreach val $argv {
after [expr {$val * 10}] [list process $val]
}
# Run event loop until all values output...
while {$count < $argc} {
vwait count
}
Demo:
bash$ sleepsort.tcl 3 1 4 5 2 3 1 6 1 3 2 5 4 6 1 1 1 2 2 3 3 3 4 4 5 5 6 6
Tcl 8.6
set sorted {}
lmap x $argv {after $x [list lappend sorted $x]}
while {[llength $sorted] != $argc} {
vwait sorted
}
puts $sorted
- Output:
$ echo 'puts [lmap _ [lrepeat 30 {}] {expr {int(rand() * 100)}}]' | tclsh | tee /dev/tty | xargs tclsh sleepsort.tcl 5 8 70 27 15 80 49 2 69 93 29 1 14 84 43 2 81 44 60 62 8 75 23 61 42 68 79 46 72 65 1 2 2 5 8 8 14 15 23 27 29 42 43 44 46 49 60 61 62 65 68 69 70 72 75 79 80 81 84 93
Tcl 8.6: coroutine
#! /usr/bin/env tclsh
package require Tcl 8.6
# By aspect (https://wiki.tcl-lang.org/page/aspect). Modified slightly.
# 1. Schedule N delayed calls to our own coroutine.
# 2. Yield N times to grab the scheduled values. Print each.
# 3. Store the sorted list in $varName.
proc sleep-sort {ls varName} {
foreach x $ls {
after $x [info coroutine] $x
}
set $varName [lmap x $ls {
set newX [yield]
puts $newX
lindex $newX
}]
}
# Ensure the list is suitable for use with [sleep-sort].
proc validate ls {
if {[llength $ls] == 0} {
error {list is empty}
}
foreach x $ls {
if {![string is integer -strict $x] || $x < 0} {
error [list invalid value: $x]
}
}
return $ls
}
coroutine c sleep-sort [validate $argv] ::sorted
vwait sorted
Demo:
$ ./sleepsort.tcl 1 2 100 40 76 0 0 0 200 199 0 0 0 1 2 40 76 100 199 200
UNIX Shell
f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
f "$1" &
shift
done
wait
Usage and output:
sh sleepsort.sh 3 1 4 1 5 9 1 1 3 4 5 9
Visual Basic .NET
Imports System.Threading
Module Module1
Sub SleepSort(items As IEnumerable(Of Integer))
For Each item In items
Task.Factory.StartNew(Sub()
Thread.Sleep(1000 * item)
Console.WriteLine(item)
End Sub)
Next
End Sub
Sub Main()
SleepSort({1, 5, 2, 1, 8, 10, 3})
Console.ReadKey()
End Sub
End Module
- Output:
1 1 2 3 5 8 10
V (Vlang)
import time
import sync
fn main() {
mut wg := sync.new_waitgroup()
test_arr := [3, 2, 1, 4, 1, 7]
wg.add(test_arr.len)
for i, value in test_arr {
go sort(i, value, mut wg)
}
wg.wait()
println('Printed sorted array')
}
fn sort(id int, value int, mut wg sync.WaitGroup) {
time.sleep(value * time.millisecond) // can change duration to second or others
println(value)
wg.done()
}
- Output:
1 1 2 3 4 7 Printed sorted array
Wren
More of a simulation than a 'true' sleep sort.
import "timer" for Timer
import "io" for Stdout
import "os" for Process
var args = Process.arguments
var n = args.count
if (n < 2) Fiber.abort("There must be at least two arguments passed.")
var list = args.map{ |a| Num.fromString(a) }.toList
if (list.any { |i| i == null || !i.isInteger || i < 0 } ) {
Fiber.abort("All arguments must be non-negative integers.")
}
var max = list.reduce { |acc, i| acc = (i > acc) ? i : acc }
var fibers = List.filled(max+1, null)
System.print("Before: %(list.join(" "))")
for (i in list) {
var sleepSort = Fiber.new { |i|
Timer.sleep(1000)
Fiber.yield(i)
}
fibers[i] = sleepSort
}
System.write("After : ")
for (i in 0..max) {
var fib = fibers[i]
if (fib) {
System.write("%(fib.call(i)) ")
Stdout.flush()
}
}
System.print()
- Output:
Sample run:
$ wren Sorting_algorithms_Sleep_sort.wren 1 8 3 7 4 6 Before: 1 8 3 7 4 6 After : 1 3 4 6 7 8
zkl
vm.arglist.apply(fcn(n){ Atomic.sleep(n); print(n) }.launch);
Atomic.waitFor(fcn{ vm.numThreads == 1 }); Atomic.sleep(2); println();
- Output:
$ zkl bbb 7 6 9 2 4 8 1 3 5 123456789 $
- Programming Tasks
- Sorting Algorithms
- Sorting
- Ada
- APL
- Assembly
- AutoHotkey
- Bash
- BBC BASIC
- Brainf***
- C
- C sharp
- C++
- Clojure
- CoffeeScript
- Common Lisp
- D
- Dart
- Delphi
- Elena
- Elixir
- Emacs Lisp
- Erlang
- Euphoria
- F Sharp
- Factor
- Fortran
- FreeBASIC
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- Kotlin
- Lua
- Mathematica
- Wolfram Language
- NetRexx
- Nim
- Objeck
- Objective-C
- Oforth
- Ol
- Pascal
- Perl
- Phix
- PHP
- PicoLisp
- Pike
- Prolog
- PureBasic
- Python
- Racket
- Raku
- REXX
- Ruby
- Rust
- Scala
- Sidef
- Simula
- SNUSP
- Swift
- Tcl
- UNIX Shell
- Visual Basic .NET
- V (Vlang)
- Wren
- Zkl
- GUISS/Omit
- Axe/Omit