use List::Util;
sub unique_random_list {
my ($from, $to, $count) = @_;
$count = List::Util::min ($count, $to - $from);
my @result;
my @queue = [ $from, $to - $from, $count ];
while (my $job = shift @queue) {
my ($from, $length, $count) = @$job;
if ($count == $length) {
push @result, $from .. $from + $length;
} elsif ($count == 1) {
push @result, $from + int rand $length;
} else {
my $split_length = int ($length / 2);
my $split_count = List::Util::min (int rand $count, $spli
+t_length);
my $pad_length = $length - $split_length;
my $pad_count = $count - $split_count;
$split_count += $pad_count - $pad_length
if $pad_count > $pad_length;
unshift @queue, grep $_->[2],
[ $from, $split_length, $split_count ],
[ $from + $split_length, $length - $split_length, $count
+ - $split_count ];
}
}
@result;
}
my @list = unique_random_list (10, 100, 30);
|