I think
ikegami's solution is fine; but I thought it would be nice if one could use the exact same comparison function that one would pass to
sort. So that if you'd say
sort { length($a) <=> length($b) or $a cmp $b } @data;
to get the entire data set in the desired order, you could simply s/sort/minima/ to get only the minima from that set:
minima { length($a) <=> length($b) or $a cmp $b } @data;
Here's how:
sub minima(&@)
{
my $comp = shift;
@_ <= 1 and return(@_);
my @cur = ( $_[0] );
for my $i ( 1 .. $#_ )
{
local( $a, $b ) = ( $cur[0], $_[$i] );
my $r = &$comp;
if ( $r > 0 )
{
@cur = ($_[$i]);
}
elsif ( $r == 0 )
{
push @cur, $_[$i];
}
# else keep current best.
}
@cur
}
However, this doesn't address the third requirement,
- Identify a random value from the resulting list
I'm not really sure what is wanted there.
Does it need to be truly random? Or is it that we simply don't care which one we get?
If the latter, then one can simply take the first from the resulting list.
If the former, then one could apply F-Y to the resulting list. Either way,
it's outside the scope of concern of this function, I think.