Peter’s blog ✴ Week 142 ✴ 6 December 2021

THE WEEKLY CHALLENGE
Last digit sleeps

The Perl Camel

Task 2

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

Perl Weekly’s review

from PW issue 542

A very unique style of blogging, focussed on task analysis. Keep it up. Great work.

This review may cover either or both challenges for this week.

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;

14 lines of code

Output from script

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

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain