sub pick {
my( $total, @weights ) = @_;
my $rand = rand $total;
( $rand -= $weights[ $_ ] ) < 0
and return $_
for 0 .. $#weights;
}
####
#! perl -slw
use strict;
use List::Util qw[ sum ];
our $SHIPS ||= 10;
our $REPS ||= 1e5;
sub pick {
my( $total, @weights ) = @_;
my $rand = rand $total;
( $rand -= $weights[ $_ ] ) < 0
and return $_ for 0 .. $#weights;
}
my @weights = map rand( 16 ), 1 .. $SHIPS;
my $total = sum @weights;
my @stats;
for ( 1 .. $REPS ) {
++$stats[ pick( $total, @weights ) ];
}
for ( 0 .. $#stats ) {
printf "%2d: Expected: %6.3f%% Actual: %6.3f%%\n",
$_,
$weights[ $_ ] *100 / $total,
$stats[ $_ ] *100 / $REPS;
}
print sum( @stats ) *100 / $REPS, '%' ;
####
C:\test>junk6 -SHIPS=4 -REPS=1e5
0: Expected: 16.519% Actual: 16.604%
1: Expected: 14.400% Actual: 14.466%
2: Expected: 51.934% Actual: 51.844%
3: Expected: 17.147% Actual: 17.086%
100%
C:\test>junk6 -SHIPS=20 -REPS=1e5
0: Expected: 2.126% Actual: 2.103%
1: Expected: 6.746% Actual: 6.834%
2: Expected: 0.847% Actual: 0.825%
3: Expected: 4.063% Actual: 4.133%
4: Expected: 4.473% Actual: 4.412%
5: Expected: 6.020% Actual: 6.079%
6: Expected: 2.758% Actual: 2.727%
7: Expected: 5.133% Actual: 5.055%
8: Expected: 4.221% Actual: 4.215%
9: Expected: 0.189% Actual: 0.191%
10: Expected: 2.151% Actual: 2.171%
11: Expected: 9.417% Actual: 9.511%
12: Expected: 5.079% Actual: 5.148%
13: Expected: 6.905% Actual: 7.080%
14: Expected: 9.644% Actual: 9.539%
15: Expected: 6.291% Actual: 6.266%
16: Expected: 1.084% Actual: 1.073%
17: Expected: 7.653% Actual: 7.578%
18: Expected: 9.065% Actual: 9.043%
19: Expected: 6.133% Actual: 6.017%
C:\test>junk6 -SHIPS=2 -REPS=1e2
0: Expected: 92.414% Actual: 96.000%
1: Expected: 7.586% Actual: 4.000%
100%
C:\test>junk6 -SHIPS=2 -REPS=1e2
0: Expected: 56.789% Actual: 55.000%
1: Expected: 43.211% Actual: 45.000%
100%