Skip to content

Instantly share code, notes, and snippets.

@koba04
Created December 1, 2012 16:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koba04/4183087 to your computer and use it in GitHub Desktop.
Save koba04/4183087 to your computer and use it in GitHub Desktop.
Sample of Sub::Rate and Data::WeightedRoundRobin.
#!perl
use strict;
use warnings;
use 5.010;
use Data::Dumper;
use Sub::Rate;
use Sub::Rate::NoMaxRate;
use Data::WeightedRoundRobin;
sub dump_total {
my ($cb) = @_;
my $total;
for (1..1000) {
my $menu = $cb->();
if ( !exists $total->{$menu} ) {
$total->{$menu} = 0;
}
++$total->{$menu};
}
say Dumper $total;
}
{
say "rand";
my $rate = [
{ rate => 40, value => "寿司" },
{ rate => 20, value => "ラーメン" },
{ rate => 20, value => "焼肉" },
{ rate => 15, value => "パスタ" },
{ rate => 5, value => "コンビニ" },
];
my $from = 0;
my $total = 0;
my $targets = [];
for my $menu ( @$rate ) {
my $to = $from + $menu->{rate};
push @$targets, { from => $from, to => $to, value => $menu->{value} };
$from += $menu->{rate};
$total += $menu->{rate};
}
my $pick = sub {
my $num = int( rand($total) + 1 );
for my $target ( @$targets ) {
if ( $target->{from} < $num && $target->{to} >= $num ) {
return $target->{value};
}
}
};
say $pick->();
dump_total($pick);
}
{
say "Sub::Rate";
# default max_rate == 100
my $rate = Sub::Rate->new;
$rate->add( 40 => sub { "寿司" });
$rate->add( 20 => sub { "ラーメン" });
$rate->add( 20 => sub { "焼肉" });
$rate->add( 15 => sub { "パスタ" });
$rate->add( default => sub { "コンビニ" });
my $func = $rate->generate;
say $func->();
dump_total($func);
}
{
say "YocchanIka";
my $rate = Sub::Rate->new;
$rate->add( 5 => sub { "よっちゃんイカアタリ" });
$rate->add( default => sub { "ハズレ" });
my $func = $rate->generate;
say $func->();
dump_total($func);
}
{
say "Data::WeightedRoundRobin";
my $dwr = Data::WeightedRoundRobin->new([
{ weight => 4, value => "寿司" },
{ weight => 2, value => "ラーメン" },
{ weight => 2, value => "焼肉" },
{ weight => 1.5, value => "パスタ" },
{ weight => 0.5, value => "コンビニ" },
]);
say $dwr->next;
dump_total(sub { $dwr->next });
}
{
say "Sub::Rate::NoMaxRate";
# default max_rate == 100
my $rate = Sub::Rate::NoMaxRate->new;
$rate->add( 4000 => sub { "寿司" });
$rate->add( 200 => sub { "ラーメン" });
$rate->add( 20 => sub { "焼肉" });
$rate->add( 10 => sub { "パスタ" });
$rate->add( 1 => sub { "コンビニ" });
my $func = $rate->generate;
say $func->();
dump_total($func);
}
{
say "Sub::Rate (rand_func)";
my $rate = Sub::Rate->new(rand_func => sub {
my ($max_rate) = @_;
# no sushi!!!!
return 40 + rand($max_rate);
});
$rate->add( 40 => sub { "寿司" });
$rate->add( 20 => sub { "ラーメン" });
$rate->add( 20 => sub { "焼肉" });
$rate->add( 15 => sub { "パスタ" });
$rate->add( default => sub { "コンビニ" });
my $func = $rate->generate;
say $func->();
dump_total($func);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment