I'm trying to figure out what's going on in this Perl Script. The Comments are me thinking, thank you, if you devote your time helping me. I have very little experience with Perl but have some knowledge in shell scripting.
I think @_
is a list of parameters passed down in a subroutine and $_
a global variable, I struggle to make sense of their actual purpose in this script.
#!/bin/perl
sub quick_sort {
# exit condition, when subset contains less than 2 elements
return @_ if @_ < 2;
# choosing pivot element, using subset as input, rand as random offset, no idea what the 1 is for, man says "int fd_out"
my $p = splice @_, int rand @_, 1;
# actual recursion and the main source of my confusion
# calling quicksort(smaller pivot, pivot, quicksort(greater pivot))
quick_sort(grep $_ < $p, @_), $p, quick_sort(grep $_ >= $p, @_);
}
# running the damn thing, no greater secrets here, i guess
my @a = (4, 65, 2, -31, 0, 99, 83, 782, 1);
@a = quick_sort @a;
print "@a\n";
quick_sort(grep $_ < $p, @_), $p, quick_sort(grep $_ >= $p, @_);
Let's break this down:
@_
is the array of function arguments.
$_
is a temporary scalar variable used as a placeholder in some contexts.
grep $_ < $p, @_
This is an expression which uses the grep
builtin function to create a list consisting of all the elements from @_
which satisfy the condition $_ < $p
-- that is, all the elements which are numerically less than the pivot.
The resulting list is passed to quick_sort
, so the result is a sorted list of all the elements less than the pivot.
The same thing happens on the other side:
quick_sort(grep $_ >= $p, @_);
This takes all the elements of @_
which are greater than the pivot and sorts those.
Finally:
quick_sort(grep $_ < $p, @_), $p, quick_sort(grep $_ >= $p, @_);
The comma expression creates a list consisting of:
A sorted list of all the arguments less than the pivot element.
The pivot element.
A sorted list of all the arguments greater than the pivot element.
And when you put those all together, you end up with a sorted list of all the arguments to the function.
But this is all silly. Perl has a builtin sort
function; you could express the same thing much more concisely as @a = sort { $a <=> $b } @a
, and it'd actually be much faster.