Powershell - 168 131 125 115
Golfed code:
nal g Random;1..1e4|%{$C=g 3;$P=g 3;$T+=$C-eq(0..2|?{$_-ne$P-and$_-ne(0..2|?{$_-ne$P-and$_-ne$C}|g)})};"$($T/100)%"
Changes from Original:
Trimmed 53 characters off the original script with some modifications.
- Removed spaces and parenthesis where PowerShell is forgiving of it.
- Used a
ForEach-Object
loop, via the %
alias, instead of while
.
- Used number ranges (e.g.:
0..2
) instead of explicitly defined arrays.
- Removed
write
from the last command - turns out I don't need it after all.
- Flipped the expression for the host's choice around to use the shorter pipelining syntax.
- Replaced 10000 with 1e4.
- Took Joey's suggestion and omitted
Get-
from Get-Random
. (Note: This modification significantly bloats the run time. On my system it jumped from about 20 seconds to nearly a half-hour per run!)
- Used Rynant's trick of doing
$T+=...
instead of if(...){$T++}
.
Some notes:
This script is intended to be as concise as possible, while also being as thorough a simulation of the Monty Hall scenario as possible. It makes no assumptions as to where the car will be, or which door the player will choose first. Assumptions are not even made for which specific door the host will choose in any given scenario. The only remaining assumptions are those which are actually stated in the Monty Hall problem:
- The host will choose a door that the player did not pick first, which does not contain the car.
- If the player picked the door with the car first, that means there are two possible choices for the host.
- The player's final choice will be neither his initial choice nor the host's choice.
Ungolfed, with comments:
# Setup a single-character alias for Random, to save characters later.
# Note: Script will run a lot (about 500 times) faster if you use Get-Random here.
# Seriously, as it currently is, this script will take about a half-hour or more to run.
# With Get-Random, it'll take less than a minute.
nal g Random;
# Run a Monty Hall simulation for each number from 1 to 10,000 (1e4).
1..1e4|%{
# Set car location ($C) and player's first pick ($P) to random picks from a pool of 3.
# Used in this way, Random chooses from 0..2.
$C=g 3;$P=g 3;
# Increment win total ($T) if the car is behind the door the player finally chooses.
# (Player's final choice represented by nested script.)
$T+=$C-eq(
# Filter the doors (0..2) to determine player's final choice.
0..2|?{
# Player's final choice will be neither their original choice, nor the host's pick.
# (Host's pick represented by nested script.)
$_-ne$P-and$_-ne(
# Filter the doors to determine host's pick.
0..2|?{
# Host picks from door(s) which do not contain the car and were not originally picked by the player.
$_-ne$P-and$_-ne$C
# Send filtered doors to Random for host's pick.
}|g
)
}
)
};
# After all simulations are complete, output overall win percentage.
"$($T/100)%"
# Variable & alias cleanup. Not included in golfed script.
rv C,P,T;ri alias:g
I've run this script several times and it consistently outputs results very near to two-thirds probability. Some samples:
(As above)
(Using Get-Random
as the alias definition, instead of just Random
)
- 66.92%
- 67.71%
- 66.6%
- 66.88%
- 66.68%
- 66.16%
- 66.96%
- 66.7%
- 65.96%
- 66.87%