Skip to content

Instantly share code, notes, and snippets.

@Ovid
Created January 25, 2023 09:52
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 Ovid/68a6b1e3c4b49fd42e9070bcc84e1742 to your computer and use it in GitHub Desktop.
Save Ovid/68a6b1e3c4b49fd42e9070bcc84e1742 to your computer and use it in GitHub Desktop.
Monty Carlo Problem
#!/usr/bin/env perl
# See also: https://fosstodon.org/@ovid/109745522656272671
# See also: https://priceonomics.com/the-time-everyone-corrected-the-worlds-smartest/
use Less::Boilerplate;
# $does_switch = 0 means they don't switch doors
# $does_switch = 1 means they do switch doors
my $does_switch = 0;
my ( $win, $lose ) = ( 0, 0 );
my $trials = 10_000;
for ( 1 .. $trials ) {
my $prize = int( rand(3) );
my $choice = int( rand(3) );
my @other_doors = grep { $_ != $choice } 0 .. 2;
my $revealed
= $prize == $other_doors[0] ? pop @other_doors
: $prize == $other_doors[1] ? shift @other_doors
: rand > .5 ? shift @other_doors
: pop @other_doors;
my $new_choice = $does_switch ? shift @other_doors : $choice;
( $new_choice == $prize ) ? $win++ : $lose++;
}
say sprintf "Win %% if you %s switch: %.1f%%." =>
( $does_switch ? 'do' : 'do not' ), ( $win * 100 ) / $trials;
@tobyink
Copy link

tobyink commented Jan 25, 2023

On lines 17-21, where the host decides which door to reveal, the script uses the $prize variable to pick the door. It has knowledge of where the prize is.

In the Mastodon thread, I was talking about a zero-knowledge host, so something like:

    use List::Util qw( shuffle );
    ( my $revealed, @other_doors ) = shuffle( @other_doors );

In that case, the win % is always about 33.3%, whether $does_switch is 0 or 1.

@Ovid
Copy link
Author

Ovid commented Jan 25, 2023

From the original post:

You choose a door and the host opens a door you didn't choose and shows there's no prize.

@tobyink
Copy link

tobyink commented Jan 25, 2023

Okay then, if you prefer...

    use List::Util qw( shuffle );
    ( my $revealed, @other_doors ) = shuffle( @other_doors );
    next if $revealed == $prize; # invalid situation, so next iteration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment