RosettaCodeData/Task/100-prisoners/Perl/100-prisoners.pl
2023-07-01 13:44:08 -04:00

51 lines
1.7 KiB
Perl

use strict;
use warnings;
use feature 'say';
use List::Util 'shuffle';
sub simulation {
my($population,$trials,$strategy) = @_;
my $optimal = $strategy =~ /^o/i ? 1 : 0;
my @prisoners = 0..$population-1;
my $half = int $population / 2;
my $pardoned = 0;
for (1..$trials) {
my @drawers = shuffle @prisoners;
my $total = 0;
for my $prisoner (@prisoners) {
my $found = 0;
if ($optimal) {
my $card = $drawers[$prisoner];
if ($card == $prisoner) {
$found = 1;
} else {
for (1..$half-1) {
$card = $drawers[$card];
($found = 1, last) if $card == $prisoner
}
}
} else {
for my $card ( (shuffle @drawers)[0..$half]) {
($found = 1, last) if $card == $prisoner
}
}
last unless $found;
$total++;
}
$pardoned++ if $total == $population;
}
$pardoned / $trials * 100
}
my $population = 100;
my $trials = 10000;
say " Simulation count: $trials\n" .
(sprintf " Random strategy pardons: %6.3f%% of simulations\n", simulation $population, $trials, 'random' ) .
(sprintf "Optimal strategy pardons: %6.3f%% of simulations\n", simulation $population, $trials, 'optimal');
$population = 10;
$trials = 100000;
say " Simulation count: $trials\n" .
(sprintf " Random strategy pardons: %6.3f%% of simulations\n", simulation $population, $trials, 'random' ) .
(sprintf "Optimal strategy pardons: %6.3f%% of simulations\n", simulation $population, $trials, 'optimal');