#!/usr/local/bin/perl use strict; use warnings; sub make_random_picker { my $picks = shift; my @choices = sort { $b->[1] <=> $a->[1] } @$picks; my $t; $t += $_->[1] for @choices; $_->[1] /= $t for @choices; return sub { my ( $p, $r ) = ( 0, rand() ); for my $choice (@choices) { $p += $choice->[1]; return $choice->[0] if $r < $p; } return $choices[-1][0]; } } my $pick = make_random_picker([ [ foo => 20 ], [ bar => 10 ], [ baz => 10 ], [ hoge => 30 ], [ moge => 30 ], ]); print $pick->(), "\n" for ( 1 .. 20 );