Very nice! I had a pretty good idea what algorithm was being used, but it took some reformatting and extra prints before I figured out how it was happening.
Here's the reformatted version behind the spoiler protection.
# This is a quicksort, using the first line as the pivot, then feeding
# all values less than the pivot to the first forked copy of this scri
+pt,
# and the values above the pivot to the 2nd forked copy.
#
# Variables:
# $v : pivot
# @c : child processes, $c[0] for values less than pivot, and $c[1]
+ for those above
# $c : count of extra occurrences of pivot, which must be printed w
+ith correct count
{
my $tracing = $ENV{TRACE};
my $pid = $$;
my $ppid = getppid();
sub trace
{
printf STDERR "\tPID %8x PPID %8x @_",
$pid,
$ppid if $tracing;
print "\n" unless $_[-1]=~/\n/;
}
}
defined(my $v = <>) or exit;
trace("PIVOT", $v);
# $c is the count of times to print the pivot, while @c is an array of
# filehandles into identical child processes which will handle values
+below the
# pivot (in $c[0]), and above the pivot (in $c[1]).
my ($c,@c) = 1;
open($_, "|-", "$^X $0") for @c[0,1];
while (<>) {
if ($_ eq $v) {
# Need to print pivot multiple times.
++$c;
}
else {
if ($_ lt $v) {
print {$c[1]} $_;
trace("sending to CHILD 1:", $_);
}
else {
print {$c[0]} $_;
trace("sending to CHILD 0:", $_);
}
}
}
trace("Printing values below pivot",$v);
pop @c; # This closes the left ($c[0]) child, printing all the values
+less than
# the pivot, in sorted order.
trace("Printing",$c,"copy(ies) of pivot",$v);
print $v x $c;
trace("Printing values above pivot",$v);
# The right (originally $c[1]) child gets closed and flushed at proces
+s exit,
# printing all the values greater than the pivot, in sorted order.
| [reply] [d/l] |