Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Genius sorting algorithm: Sleep sort

Name: Anonymous 2011-01-20 12:22

Man, am I a genius. Check out this sorting algorithm I just invented.


#!/bin/bash
function f() {
    sleep "$1"
    echo "$1"
}
while [ -n "$1" ]
do
    f "$1" &
    shift
done
wait


example usage:
./sleepsort.bash 5 3 6 3 6 3 1 4 7

Name: Anonymous 2011-01-20 12:27

>>1
Oh god, it works.

But I don't like to wait 218382 seconds to sort '(0 218382)

Name: Anonymous 2011-01-20 12:31

>>2
yes the worst case is very big

Name: Anonymous 2011-01-20 12:45

What's the complexity?

Name: Anonymous 2011-01-20 12:56

#!/bin/bash
function f() {
    sleep $(echo "$1 / 10" |bc -l)
    echo "$1"
}
while [ -n "$1" ]
do
    f "$1" &
    shift
done
wait


OMG OPTIMISED
Make sure you have an implementation of sleep that accepts floating-point arguments.

Name: Anonymous 2011-01-20 13:10

>>4
Well i'm not sure how you define it. Basically O(highest_value_in_input)

Name: Anonymous 2011-01-20 14:16

O(highest_value_in_input + n) there is a linear time for creating each thread (it is a thread right?)

congrats OP, it is awesome

Name: Anonymous 2011-01-20 14:31

okay, so basically it sleeps longer depending on the number so the smaller numbers wake up sooner?

Name: Anonymous 2011-01-20 14:35

dicksort() {
    while [ -n "$1" ]
    do
       (sleep "$1"; echo "$1") &
       shift
    done
    wait
}

dicksort 2 1 4 3 2 1 99999999

Name: Anonymous 2011-01-20 14:41

Standard value based sort if you ask me.

Name: Anonymous 2011-01-20 15:25

f() {
    if test -n "$1"
        then ( sleep $1; echo $1 ) &
        shift
        f $*
        wait
    fi
}

Name: Anonymous 2011-01-20 15:41

>>10
What else would you sort them based on? IHBT

Name: Anonymous 2011-01-20 15:57

I highly enjoyed this.

Name: Anonymous 2011-01-20 16:03

>>11
Not tail recursive.

Name: Anonymous 2011-01-20 16:08

>>14
Recurse my tail!

Name: Anonymous 2011-01-20 16:24

>>15
(tail (anus! 'my))

Name: Anonymous 2011-01-20 16:26

>>15
Intercourse under my tail!

Name: Anonymous 2011-01-20 16:28

If the difference between any two of the numbers is too small, race conditions will fuck you up the ass.

Name: Anonymous 2011-01-20 16:30

>>18
Luckily, 1 second should be enough for anyone.

Name: >>18 2011-01-20 16:32

like perhaps in:
./sleepsort 0.000002 0.000003 0.000001

Name: Anonymous 2011-01-20 16:38

What about
./sleepsort -1 -2 -3 ?

If you slept exp(n) instead of n it could easily include negative integers too!

Name: Anonymous 2011-01-20 17:12

This is sort of like a simple bucket/radix sort but instead of using a space-based array, it's effectivly using a time-based "array"

Name: Anonymous 2011-01-20 17:13

>>21
obviously the correct solution is to divide every input by two and add MAXINT/2.

Name: Anonymous 2011-01-20 17:16

>>23
OMG OPTIMIS-Oh, wait.

Name: Anonymous 2011-01-20 17:28

This thread is entertaining.  My gratitude goes to all participators.

Name: Anonymous 2011-01-20 18:19

>>21,23-24
For optimal results, use a logistic functioneg. 0.5+9.5/((1+0.5e^(-1.5(t-10)))^(2)) to normalize the inputs. You can bound the sleep time arbitrarily this way. I'm not writing that in bash.

Name: Anonymous 2011-01-20 18:43

>>26
Still doesn't solve the race condition problem. Over here it happens with values with mutual differences as high as those in:
./sleepsort 0.02 0.03 0.01

Name: Anonymous 2011-01-20 19:47

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;

namespace SleepSort
{
    public class SleepSort
    {
        static void Main(string[] args)
        {
            var xs = new[] { 11, 215, 12, 1985, 12, 1203, 12, 152 };
            var sorted = Sort(xs, x => x);
            Console.Write("Sorted:");
            foreach (var x in sorted)
                Console.Write(" {0}", x);
            Console.WriteLine();
            Console.ReadKey(true);
        }

        public static IEnumerable<T> Sort<T>(IEnumerable<T> xs, Func<T, int> conv)
        {
            const int WEIGHT = 40000;
            var ev = new EventWaitHandle(false, EventResetMode.ManualReset);
            var q = new Queue<T>();
            ParameterizedThreadStart f = x => { ev.WaitOne(); Thread.SpinWait(conv((T)x) * WEIGHT); lock (q) { q.Enqueue((T)x); } };
            var ts = xs.Select(x => { var t = new Thread(f); t.Start(x); return t; }).ToArray();
            ev.Set();
            foreach (var t in ts)
                t.Join();
            return q;
        }
    }
}

It's still a bit of a stochastic sort.

Name: Anonymous 2011-01-20 20:21

>>28
Lol I just tried to compile this in java, but I assume now that it's C#

Name: Anonymous 2011-01-20 20:30

>>27
Well no, in fact it makes the race condition worse. Many of the differences are going to be quite small indeed after coming out of that function.

I can think of a few enhancements:
First: tailor A and Khttp://en.wikipedia.org/wiki/Generalised_logistic_curve  to the range of inputs. This adds some complexity, but it is nearly canceled by the act of spawning the sleeps and calculating Y(t) anyway.

Second: keep track of deltas upon return. When the gap is large enough relative to previous gapsFeigenbaum constant? start a new partition, reiterate the process on each. (Note: multiple partitions can be sleep-sorted at the same time.) This will distribute the sleep times more evenly among elements, however: there is still no guarantee on most platforms that any kind of sleep sort will be free of race conditions, on any set of inputs, no matter the minimum range between elements.

Third, a meta-enhancement: make best-guesses at values for the range chosen in the first enhancement for the purposes of optimal calculations. Likewise establish a good terminal condition for the second, probably when all partitions have 1 element.

If you have a huge range in input with many clusters, I think these variations are optimal over anything less sophisticated. I've no idea how often that is the case (actually... does anyone have info on this?) but it seems like it's probably common enough. Even if the clustering isn't bad, the partitioning process deals with it automatically.

Name: Anonymous 2011-01-20 20:48

>>30
lolwut

Name: Anonymous 2011-01-20 21:22

Good thread.

Name: Anonymous 2011-01-20 21:56

Yeah, that's pretty cool but check my doubles.

Name: Anonymous 2011-01-21 5:34

>>33
sweet dubs bro

Name: Anonymous 2011-01-21 5:39

Block the threads until every single one is created, also you should probably attempt to indicate to the OS that every thread doesn't need a very large stack.

Name: Anonymous 2011-01-21 5:54

Thread was better than I expected, nh OP.

Name: Anonymous 2011-01-21 6:17

>>35
Yes I was thinking about whether this algorithm could have potential use for a huge amount (eg billions) of numbers in a small range.. but i'm not sure which OS would handle billions of processes/threads... so like I said before it's essential a radix sort but in the time dimension.. the way around as others have said would be to have radix style buckets to group the numbers, then sort each bucket etc..

Name: Anonymous 2011-01-21 7:10

Oh shit, we're busted, there's a REALISTICALLY THINKING PERSON in this thread!

Name: Anonymous 2011-01-21 7:30

>>29
lol'd, but does Java have lambda expressions and var and LINQ? Didn't think so.

>>35
My implementation (>>28) blocks them, but even after letting them continue they won't all start at the exact same time.

Name: Anonymous 2011-01-21 7:38

Someone email this to Knuth.

Name: Anonymous 2011-01-21 8:01

>>40
Knuth doesn't do email anymore

Name: Anonymous 2011-01-21 8:05

>>41
That's only because he's DED.

Name: >>28 2011-01-21 8:31

-module(sleepsort).
-export([sort/2, spawn_waiters/3, wait/4]).

sort(Xs, Conv) ->
    spawn(?MODULE, spawn_waiters, [Xs, Conv, self()]),
    receive
        {spawned, N} -> queue(N)
    end.

queue(N) -> queue(N, []).
queue(0, Xs) ->
    lists:reverse(Xs);
queue(N, Xs) ->
    receive
        {item, X} ->
            queue(N - 1, [X|Xs])
    end.

spawn_waiters(Xs, Conv, P) -> spawn_waiters(P, Conv, Xs, 0).
spawn_waiters(P, _, [], N) ->
    P ! {spawned, N};
spawn_waiters(P, Conv, [X|Xs], N) ->
    spawn(?MODULE, wait, [X, Conv(X), P, self()]),
    receive
        monitored -> ok
    end,
    spawn_waiters(P, Conv, Xs, N + 1).

wait(X, T, Q, P) ->
    Ref = erlang:monitor(process, P),
    P ! monitored,
    receive
        {'DOWN', Ref, process, P, _} -> ok
    end,
    timer:sleep(T),
    Q ! {item, X}.


Also this. I'm an EARLY ADOPTER.

Name: Anonymous 2011-01-21 8:37


(module sleepsort racket
   (provide sleepsort)
   (define (sleepsort x)
      (map (lambda (x) (thread (lambda () (sleep x) (display x)))) x)))

Name: Anonymous 2011-01-21 8:40

>>44
display
Are you also one of the people that define their square as IO ()?

Name: Anonymous 2011-01-21 8:44

History in the making, guys. Turns out /prog/ can do good things.

Name: Anonymous 2011-01-21 8:47

>>43
Holy fuck Erlang in /prog/?!?!?!?!

Props.

Name: Anonymous 2011-01-21 8:47

>>45
Yes.
void CalculateAndPrintSquareEx(DWORD dwOperand, HANDLE hOutputDevice, ...) { fprintf(hOutputDevice, "%d", dwOperand*dwOperand); }
int main (int argc, char *argv[]) {
   CalculateAndPrintSquareEx(2, stdout, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); }

Name: Anonymous 2011-01-21 8:54

>>48
That's :: Int -> IO ().
I was thinking more along the lines of ReadParseSquareAndOutput(...).

Name: Anonymous 2011-01-21 8:59

>>49
That's :: DoubleWord -> Handle -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> Nothing -> IO ().

Name: Anonymous 2011-01-21 9:12

>>50
More like :: Int32 -> IORef -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> Maybe a -> IO ()
(I counted.)

Name: Anonymous 2011-01-21 9:16

>>51
Maybe (Ptr a)

Name: Anonymous 2011-01-21 9:20

>>51
Wait, fuck. That should be:
CalculateAndPrintSquareEx :: Int32 -> IORef -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe e -> Maybe f -> Maybe g -> Maybe h -> Maybe i -> Maybe j -> Maybe k -> Maybe l -> Maybe m -> Maybe n -> Maybe o -> Maybe p -> Maybe q -> Maybe r -> Maybe s -> Maybe t -> Maybe u -> Maybe v -> Maybe w -> Maybe x -> Maybe y -> Maybe z -> Maybe a' -> Maybe b' -> Maybe c' -> Maybe d' -> Maybe e' -> Maybe f' -> Maybe g' -> Maybe h' -> Maybe i' -> Maybe j' -> Maybe k' -> Maybe l' -> Maybe m' -> Maybe n' -> Maybe o' -> Maybe p' -> Maybe q' -> Maybe r' -> Maybe s' -> Maybe t' -> Maybe u' -> Maybe v' -> Maybe w' -> Maybe x' -> Maybe y' -> Maybe z' -> Maybe a'' -> Maybe b'' -> Maybe c'' -> Maybe d'' -> Maybe e'' -> Maybe f'' -> Maybe g'' -> Maybe h'' -> Maybe i'' -> Maybe j'' -> Maybe k'' -> Maybe l'' -> Maybe m'' -> Maybe n'' -> Maybe o'' -> Maybe p'' -> Maybe q'' -> Maybe r'' -> Maybe s'' -> Maybe t'' -> Maybe u'' -> Maybe v'' -> Maybe w'' -> Maybe x'' -> Maybe y'' -> Maybe z'' -> Maybe a''' -> Maybe b''' -> Maybe c''' -> Maybe d''' -> Maybe e''' -> Maybe f''' -> Maybe g''' -> Maybe h''' -> Maybe i''' -> Maybe j''' -> Maybe k''' -> IO ()

Name: Anonymous 2011-01-21 12:23

oh thread is officially shit now. congrats /prog/

Name: Anonymous 2011-01-21 12:31

>>54
np faggot

Name: Anonymous 2011-01-21 12:46

>>55
nobody likes you and nobody would miss you

Name: Anonymous 2011-01-21 13:10

>>56
girls dont like you

Name: Anonymous 2011-01-21 13:16

>>57
Apostrophes and capital letters don't like you.

Name: Anonymous 2011-01-21 15:03

>>58
girl's Dont like you

Name: Anonymous 2011-01-21 15:17

your gay

Name: Anonymous 2011-01-21 15:23

The Autism Consortium frowns upon this thread.

Name: Anonymous 2011-01-21 15:24

To the person reading this in the future, >>54-60 are from something which we call an ``imageboard'', more specifically the imageboard called ``/g/'', this means that they enjoy making bad posts with little to no-content.

Name: Anonymous 2011-01-21 15:26

>>62
I lol'd!

Name: Anonymous 2011-01-21 16:11

>>62
nice.

Name: Anonymous 2011-01-21 16:52

>>63,64
NOOOOooooooOOOOOOOOoooooooooooOOOOOOOOoooo

Name: Anonymous 2011-01-21 16:54

>>65
nice.

Name: Anonymous 2011-01-21 17:21

>>65
I lol'd

Name: Anonymous 2011-01-21 18:00

>>65
I bet you miss ``HAX MY ANUS'' now, motherfucker.

Name: Anonymous 2011-01-21 18:00

>>1
Good job. Now try writing it in an actual language, like C.

Name: Anonymous 2011-01-21 18:08

Hax Anii everyday.
Anii MUST be haxxed.

Name: Anonymous 2011-01-21 18:47

>>69

My implementations of sleep and echo are written in C.

Name: Anonymous 2011-01-21 18:54

>>69
ooh no i'd have to use pipe() and fork() !

Name: Anonymous 2011-01-21 19:02

>>71
That's like saying you wrote a hardware implementation of sleepsort because it's run on hardware.

Name: Anonymous 2011-01-21 19:05

>>73

Well most of the time in that script is spent in those programs, if your intention was to optimize it by writing it in C it wouldn't work.

Name: Anonymous 2011-01-21 19:23

>>72
pipe()
What for?  Sounds like this would be an actual challenge to you.

Name: Anonymous 2011-01-21 20:29

>>74
>>69 is just being a turd. A big part of the novelty here is that it's a shell script.

Name: Anonymous 2011-01-22 5:38

>>75
to set up a signalling channel

Name: Anonymous 2011-02-02 13:39

I think thats brilliant :)
Would be fun to design a hardware sorter, based on this..
hmm, something to think about after my partials.

Name: Anonymous 2011-02-02 14:33

#include <assert.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        assert(argc >= 2);
        while (argc --> 2 && fork()) ;
        sleep(atoi(argv[argc]));
        puts(argv[argc]);
        while (wait(NULL) != -1) ;
}

Name: Anonymous 2011-02-02 14:49

>>79
+1 use of goes-to operator

Name: Anonymous 2011-03-30 16:47

THIS IS A MESSAGE FROM THE SUSSIX DEV TEAM (ME)

/*
 * Inspired by the valiant /prog/lodtyes
 * one of my personalities wrote an OMP
 * implementation.
 *
 * Since we are currently training SCC
 * (SCC Compiles C) we currently have to
 * use GCC to compile it.
 */

/*
 * @file sleepsort.c
 * @brief sorts numbers
 *
 * @compile gcc sleepsort.c -fopenmp -o sleepsort
 *
 * @author Gerald Jay Sussman (Massachvsetts Institvte of Technology)
 *
 * Copyright (C) 2011 Gerald Jay Sussman and the Massachvsetts
 * Institvte of Technology. All rights reserved.
 *
 * The new BSD License is applied to this software, see LICENSE.txt
 */

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int main(int argc, char **argv) {
  int i;

  omp_set_num_threads(argc);

#pragma omp parallel for
  for (i = 0; i < argc - 1; i++) {
    long int this = atol(argv[i+1]);

    sleep(this);

    printf("%ld\n", this);
    fflush(stdout);
  }

  return 0;
}


THIS HAS BEEN A MESSAGE FROM THE SUSSIX DEV TEAM (ME)

Name: Anonymous 2011-03-30 17:26

Is Quantum Sleepsort O(1)?

Name: Anonymous 2011-03-30 18:07

My shitty attempt in Haskell... first time I ever used Control.Concurrent

import Control.Concurrent
import System.Posix.Unistd (sleep)

sleepFunc :: MVar [Int] -> Int -> IO ()
sleepFunc arr n = do
    sleep n
    xs <- takeMVar arr
    putMVar arr (n:xs)
   
sleepSort_ :: [Int] -> IO [Int]
sleepSort_ xs = do
    res <- newMVar []
    let ts = map (sleepFunc res) xs
    mapM_ forkIO ts
    waitForIt res (length xs)
   
   
waitForIt m n = do
    arr <- takeMVar m
    if length arr == n
       then return $ reverse arr
       else do
           putMVar m arr
           sleep 1
           waitForIt m n

Name: Anonymous 2011-03-30 18:17

>>82
It's still O(n), but without the race condition problems.

Name: Anonymous 2011-03-30 22:22

>>48
wat, the function should return a BOOL

Name: Anonymous 2011-03-31 1:35

Just run an insertion sort over the output if you're worried about race conditions. This ensures that the numbers are relatively close to their ending points.

Name: Anonymous 2011-03-31 6:01

>>81
Is threading in C really this simple?

Name: Anonymous 2011-03-31 8:10

>>87
Only with that OMP thing

Name: Anonymous 2011-03-31 8:37

>>87
Only with #pragma omp everyline

Name: Anonymous 2011-03-31 9:00

Perl Legacy:

map {sleep $_; print "$_\n"} @ARGV;

Name: Anonymous 2011-03-31 9:01

>>90
Shorter than ``in Lisp'' DSL.

Name: Anonymous 2011-03-31 9:06

>>91
YHBT

Name: Anonymous 2011-03-31 9:08

>>90
Perl's map is parallel?

Name: Anonymous 2011-03-31 10:48

Actual Perl implementation. Forking in Perl is awkward to say the least.


#!/usr/bin/perl                                                                
sub f {
  sleep $_[0];
  print "$_[0]\n";
}

for (0..$#ARGV) {
  $pid = fork();
  if ($pid) {
    # parent                                                                   
  push(@childs, $pid);
}
  if ($pid == 0) {
    # child                                                                    
    &f(@ARGV[$_]);
    exit(0);
  }
}
foreach (@childs) {
waitpid($_, 0);
}



time perl sleepsort.pl 3 1 8 2 9 5 4
1
2
3
4
5
8
9

real    0m9.007s
user    0m0.008s
sys    0m0.000s

Terribly inaccurate with anything other than integers, but you can give arguments like 0.003 "sqrt(2)" 10e-3, for what it's worth.

Name: Anonymous 2011-03-31 20:49

Name: Anonymous 2011-03-31 20:58

way to ruin a good python thread

Name: Anonymous 2011-03-31 22:44

If you're sorting very large groups of numbers, unless your CPU can spawn the necessary number of threads, the accuracy will be compromised by shit like thread quantums.

Name: Anonymous 2011-03-31 22:50

svn checkout my://dubs

Name: Anonymous 2011-03-31 22:50

At revision 99.

Name: Anonymous 2011-03-31 22:51

one hundubs

Name: Anonymous 2011-03-31 23:22

>>98,99
That might surprise you, but your gay.

Newer Posts