After typing this up, I see
Zaxo already posted the same idea. Ah well, here it is anyway.
#!/usr/bin/perl
use strict;
# Assign a weight to each item. In this example
# pigs get twice the weight of dogs or cows
my %weight = (
"dog" => 1,
"cow" => 1,
"pig" => 2
);
# Create an array with a number of elements
# equal to the weights of the items
my @bucket;
foreach my $animal (keys %weight)
{
push @bucket, ($animal) x $weight{$animal};
}
# @bucket now looks like this:
#
# $bucket[0] = "dog"
# $bucket[1] = "cow"
# $bucket[2] = "pig"
# $bucket[3] = "pig"
#
# "pig" has twice as many slots as "dog" or "cow"
# The choose_weighted() subroutine now just has to
# pick a random element from the array.
sub choose_weighted
{
my $bucket = shift;
return $bucket->[rand(@$bucket)];
}
# Test code to demonstrate it works
my %count;
for (1..1000)
{
my $animal = &choose_weighted(\@bucket);
$count{$animal}++;
}
foreach my $animal (keys %count)
{
print "$animal: $count{$animal}\n";
}
-Matt