#! perl -slw
use strict;
use Data::Dump qw[ pp ];
sub genPicker {
my $fh = shift;
my( @vals, @odds ); ( $vals[ @vals ], $odds[ @odds ] ) = split( '
+' ) for <$fh>;
## Sort if not sorted
my @order = sort{ $odds[ $a ] <=> $odds[ $b ] } 0 .. $#odds;
@odds = @odds[ @order ];
@vals = @vals[ @order ];
## Calculate and accumulate break points
my $t = 0; $t += $_ for @odds;
$_ /= $t for @odds;
$odds[ $_ + 1 ] += $odds[ $_ ] for 0 .. $#odds - 1;
## Generate a subroutine to do the picking
return sub {
my $r = rand();
$r < $odds[ $_ ] and return $vals[ $_ ] for 0 .. $#odds;
};
}
my $pick = genPicker( *DATA );
## run a quick test
my %tally; ++$tally{ $pick->() } for 1 .. 10e6;
pp \%tally;
__DATA__
A 1e-7
B 20e-7
C 10e-5
Produces: C:\test>1127420
{ A => 9949, B => 195307, C => 9794744 }
C:\test>1127420
{ A => 10077, B => 196613, C => 9793310 }
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
|