Peter
Peter Campbell Smith

Last digit sleeps

Weekly challenge 142 — 6 December 2021

Week 142 - 6 Dec 2021

Task 2

Task — Sleep sort

You are given a list of numbers. Write a script to implement Sleep Sort. For more information, please checkout this post.

The essence of the method is to start a new thread for each item in the list, and for those threads to pause for a period proportional to the value of the item, and then print the value.

Examples


Example 1:
Input:  5, 4, 3, 2, 1
Output: 1, 2, 3, 4, 5
The thread for 1 delays 1 second before printing '1',
that for 2 delays 2 seconds, and so on. As they are all
started at (approximately) the same time, the printing
will come out in numerical order.

Analysis

This is of course a joke, but you can do everything in Perl. I found that delaying $n seconds worked, but much less, for example $n / 2 seconds did not: the Linux scheduler clearly doesn't work that way.

It won't work, of course, for negative numbers and will take a long time for very large numbers. It will accept non-integers but I found it unreliable unless all the numbers differ from each other by at least 1. I recommend sticking with quicksort, or just use Perl's built-in sort (which probably uses quicksort).

Try it 

Try running the script with any input:



example: 10, 9, 8, 7, 6 - positive integers <= 30, please

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2021-12-06
# PWC 142 task 2

use v5.20;
use warnings;
use strict;

use Parallel::ForkManager;

my @array = (4, 6, 42, 3, 38, 54, 1, 17);
say qq[Sleep sort of: ] . join(' ', @array);

my $pm = Parallel::ForkManager->new(scalar @array); # number of parallel processes
for my $a (@array) {
    my $pid = $pm->start;   # if this is the parent create a child
    next if $pid;           # ... and don't do the rest of the loop
    sleep $a;               # if this is a child, sleep for $a seconds
    say $a;                 # ... and print $a
    $pm->finish;            # ... and stop
}

$pm->wait_all_children;

Output

Sleep sort of: 4 6 42 3 38 54 1 17
1
3
4
6
17
38
42
54