RosettaCodeData/Task/Modified-random-distribution/Perl/modified-random-distributio...

36 lines
1.1 KiB
Perl

use strict;
use warnings;
use List::Util 'max';
sub distribution {
my %param = ( function => \&{scalar sub {return 1}}, sample_size => 1e5, @_);
my @values;
do {
my($r1, $r2) = (rand, rand);
push @values, $r1 if &{$param{function}}($r1) > $r2;
} until @values == $param{sample_size};
wantarray ? @values : \@values;
}
sub modifier_notch {
my($x) = @_;
return 2 * ( $x < 1/2 ? ( 1/2 - $x )
: ( $x - 1/2 ) );
}
sub print_histogram {
our %param = (n_bins => 10, width => 80, @_);
my %counts;
$counts{ int($_ * $param{n_bins}) / $param{n_bins} }++ for @{$param{data}};
our $max_value = max values %counts;
print "Bin Counts Histogram\n";
printf "%4.2f %6d: %s\n", $_, $counts{$_}, hist($counts{$_}) for sort keys %counts;
sub hist { scalar ('■') x ( $param{width} * $_[0] / $max_value ) }
}
print_histogram( data => \@{ distribution() } );
print "\n\n";
my @samples = distribution( function => \&modifier_notch, sample_size => 50_000);
print_histogram( data => \@samples, n_bins => 20, width => 64);