After game night the other day at RC there was a small discussion on sorting algorithms and the “sleep sort” algorithm came up. I’ve never heard of this algorithm before so after being told how it works, I went home and coded it for myself (seeing is believing).

The idea is if you have an array of numbers, for each number in the array, you can spin up a thread and sleep the number of seconds. Because Threads run in parallel, each thread will print the right number at the right time. Here’s what this looks like in python code,

import threading
import time


def sleep_and_print(i):
    time.sleep(i)
    print(i)


x = [1, 4, 5, 2, 3]

for i in x:
    t = threading.Thread(target=sleep_and_print, args=(i,))
    t.start()

Technically python threads don’t run in parallel but that won’t hurt us here…

When you run the above program it should print,

1
2
3
4
5

(over a period of 5 seconds).

But then I got bored and wanted to see if I can compress this little script into as few lines of harder-to-read-six-months-later lines of code and got this,

import threading
import time

from functools import partial


def sleep_and_print(i):
    time.sleep(i)
    print(i)


x = [1, 4, 5, 2, 3]

sleep_funcs = map(lambda i: partial(sleep_and_print, i), x)

[threading.Thread(target=i).start() for i in sleep_funcs]

(Thanks to Tom @ RC for correcting a typo I had in this script)

My friend Kamal noted that this variation also works,

import threading
import time

from functools import partial


def sleep_and_print(i):
    time.sleep(i)
    print(i)


x = [1, 4, 5, 2, 3]

sleep_funcs = map(partial(partial, sleep_and_print), x)

[threading.Thread(target=i).start() for i in sleep_funcs]

Now go get some sleep, who knows, maybe it’ll sort the issues in your life!

P.S.1. this is all in python 3

P.S.2. here’s what this looks like in Go (note I don’t know if this is idiomatic Go)

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	x := []int{1, 4, 5, 2, 3}
	var wg sync.WaitGroup

	for _, num := range x {
		wg.Add(1)
		go func(num time.Duration) {
			defer wg.Done()
			time.Sleep(time.Second * num)
			fmt.Printf("%d\n", num)
		}(time.Duration(num))
	}
	wg.Wait()
}