use List::Util 'sum'; sub fact { my $n = shift; my $f = 1; $f *= $_ for 1 .. $n; $f; } sub prob { my ($sizes, $sample) = @_; my $n = @$sizes; ## number of types of items my $S = sum @$sizes; ## total number of items my @sampled = (0) x $n; $sampled[$_]++ for @$sample; ## $sampled[x] = how many of type x ## are in this sample? my $total = fact(scalar @$sample); $total *= ( ($sizes->[$_] / $S) ** $sampled[$_] ) / fact($sampled[$_]) for 0 .. $n-1; $total; } ## how many ways to get 2 of type 8, 1 of type 3, etc.. ? print prob( [35000,41000,16000,18000,21000,45000,27000,10000,16000], [8,8,3,1,5,0,0] ); ## output: 0.000397344401565931