Monty Hall problem: Difference between revisions

(268 intermediate revisions by more than 100 users not shown)
Line 1:
{{task|Discrete math}}[[Category:Games]][[Category:Probability and statistics]]
[[Category:Games]]
Run random simulations of the [[wp:Monty_Hall_problem|Monty Hall]] game. Show the effects of a strategy of the contestant always keeping his first guess so it can be contrasted with the strategy of the contestant always switching his guess.
[[Category:Probability and statistics]]
[[File:Monte_Hall_problem.jpg|600px||right]]
 
Suppose you're on a game show and you're given the choice of three doors.
:Suppose you're on a game show and you're given the choice of three doors. Behind one door is a car; behind the others, goats. The car and the goats were placed randomly behind the doors before the show. The rules of the game show are as follows: After you have chosen a door, the door remains closed for the time being. The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it. If both remaining doors have goats behind them, he chooses one randomly. After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door. Imagine that you chose Door 1 and the host opens Door 3, which has a goat. He then asks you "Do you want to switch to Door Number 2?" Is it to your advantage to change your choice? ([http://www.usd.edu/~xtwang/Papers/MontyHallPaper.pdf Krauss and Wang 2003:10])
 
Behind one door is a car; behind the others, goats.
Note that the player may initially choose any of the three doors (not just Door 1), that the host opens a different door revealing a goat (not necessarily Door 3), and that he gives the player a second choice between the two remaining unopened doors.
 
The car and the goats were placed randomly behind the doors before the show.
 
 
;Rules of the game:
After you have chosen a door, the door remains closed for the time being.
 
The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it.
 
If both remaining doors have goats behind them, he chooses one randomly.
 
After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door.
 
Imagine that you chose Door 1 and the host opens Door 3, which has a goat.
 
He then asks you "Do you want to switch to Door Number 2?"
 
 
;The question:
Is it to your advantage to change your choice?
 
 
;Note:
The player may initially choose any of the three doors (not just Door 1), that the host opens a different door revealing a goat (not necessarily Door 3), and that he gives the player a second choice between the two remaining unopened doors.
 
 
;Task:
Run random simulations of the [[wp:Monty_Hall_problem|Monty Hall]] game. Show the effects of a strategy of the contestant always keeping his first guess so it can be contrasted with the strategy of the contestant always switching his guess.
 
Simulate at least a thousand games using three doors for each strategy <u>and show the results</u> in such a way as to make it easy to compare the effects of each strategy.
 
 
;References:
:* Stefan Krauss, X. T. Wang, "The psychology of the Monty Hall problem: Discovering psychological mechanisms for solving a tenacious brain teaser.", Journal of Experimental Psychology: General, Vol 132(1), Mar 2003, 3-22 [https://doi.org/10.1037/0096-3445.132.1.3 DOI: 10.1037/0096-3445.132.1.3]
:* A YouTube video: &nbsp; [https://www.youtube.com/watch?v=4Lb-6rxZxx0 Monty Hall Problem - Numberphile].
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V stay = 0
V sw = 0
 
L 1000
V lst = [1, 0, 0]
random:shuffle(&lst)
V ran = random:(3)
V user = lst[ran]
lst.pop(ran)
 
V huh = 0
L(i) lst
I i == 0
lst.pop(huh)
L.break
huh++
 
I user == 1
stay++
 
I lst[0] == 1
sw++
 
print(‘Stay = ’stay)
print(‘Switch = ’sw)</syntaxhighlight>
 
=={{header|8086 Assembly}}==
 
<syntaxhighlight lang="asm">time: equ 2Ch ; MS-DOS syscall to get current time
puts: equ 9 ; MS-DOS syscall to print a string
cpu 8086
bits 16
org 100h
section .text
;;; Initialize the RNG with the current time
mov ah,time
int 21h
mov di,cx ; RNG state is kept in DI and BP
mov bp,dx
mov dx,sw ; While switching doors,
mov bl,1
call simrsl ; run simulations,
mov dx,nsw ; While not switching doors,
xor bl,bl ; run simulations.
;;; Print string in DX, run 65536 simulations (according to BL),
;;; then print the amount of cars won.
simrsl: mov ah,puts ; Print the string
int 21h
xor cx,cx ; Run 65536 simulations
call simul
mov ax,si ; Print amount of cars
mov bx,number ; String pointer
mov cx,10 ; Divisor
.dgt: xor dx,dx ; Divide AX by ten
div cx
add dl,'0' ; Add ASCII '0' to the remainder
dec bx ; Move string pointer backwards
mov [bx],dl ; Store digit in string
test ax,ax ; If quotient not zero,
jnz .dgt ; calculate next digit.
mov dx,bx ; Print string starting at first digit
mov ah,puts
int 21h
ret
;;; Run CX simulations.
;;; If BL = 0, don't switch doors, otherwise, always switch
simul: xor si,si ; SI is the amount of cars won
.loop: call door ; Behind which door is the car?
xchg dl,al ; DL = car door
call door ; Which door does the contestant choose?
xchg ah,al ; AH = contestant door
.monty: call door ; Which door does Monty open?
cmp al,dl ; It can't be the door with the car,
je .monty
cmp al,ah ; or the door the contestant picked.
je .monty
test bl,bl ; Will the contestant switch doors?
jz .nosw
xor ah,al ; If so, he switches
.nosw: cmp ah,dl ; Did he get the car?
jne .next
inc si ; If so, add a car
.next: loop .loop
ret
;;; Generate a pseudorandom byte in AL using "X ABC" method
;;; Use it to select a door (1,2,3).
door: xchg bx,bp ; Load RNG state into byte-addressable
xchg cx,di ; registers.
.loop: inc bl ; X++
xor bh,ch ; A ^= C
xor bh,bl ; A ^= X
add cl,bh ; B += A
mov al,cl ; C' = B
shr al,1 ; C' >>= 1
add al,ch ; C' += C
xor al,bh ; C' ^= A
mov ch,al ; C = C'
and al,3 ; ...but we only want the last two bits,
jz .loop ; and if it was 0, get a new random number.
xchg bx,bp ; Restore the registers
xchg cx,di
ret
section .data
sw: db 'When switching doors: $'
nsw: db 'When not switching doors: $'
db '*****'
number: db 13,10,'$'</syntaxhighlight>
 
{{out}}
 
<pre>When switching doors: 42841
When not switching doors: 22395</pre>
 
=={{header|ActionScript}}==
<langsyntaxhighlight lang="actionscript">package {
import flash.display.Sprite;
 
Line 40 ⟶ 192:
}
}
}</langsyntaxhighlight>
Output:
<pre>Switching wins 18788 times. (62.626666666666665%)
Line 46 ⟶ 198:
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">-- Monty Hall Game
 
with Ada.Text_Io; use Ada.Text_Io;
Line 121 ⟶ 273:
Put_Line("%");
 
end Monty_Stats;</langsyntaxhighlight>
Results
<pre>Stay : count 34308 = 34.31%
Line 132 ⟶ 284:
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}}
<langsyntaxhighlight lang="algol68">INT trials=100 000;
 
PROC brand = (INT n)INT: 1 + ENTIER (n * random);
Line 185 ⟶ 337:
print(("Changing: ", percent(change winning), new line ));
print(("New random choice: ", percent(random winning), new line ))
)</langsyntaxhighlight>
Sample output:
<pre>
Line 192 ⟶ 344:
New random choice: 50.17%
</pre>
 
=={{header|APL}}==
<syntaxhighlight lang="apl"> ∇ Run runs;doors;i;chosen;cars;goats;swap;stay;ix;prices
[1] ⍝0: Monthy Hall problem
[2] ⍝1: http://rosettacode.org/wiki/Monty_Hall_problem
[3]
[4] (⎕IO ⎕ML)←0 1
[5] prices←0 0 1 ⍝ 0=Goat, 1=Car
[6]
[7] ix←⊃,/{3?3}¨⍳runs ⍝ random indexes of doors (placement of car)
[8] doors←(runs 3)⍴prices[ix] ⍝ matrix of doors
[9] stay←+⌿doors[;?3] ⍝ chose randomly one door - is it a car?
[10] swap←runs-stay ⍝ If not, then the other one is!
[11]
[12] ⎕←'Swap: ',(2⍕100×(swap÷runs)),'% it''s a car'
[13] ⎕←'Stay: ',(2⍕100×(stay÷runs)),'% it''s a car'
∇</syntaxhighlight>
<pre>
Run 100000
Swap: 66.54% it's a car
Stay: 33.46% it's a car
</pre>
 
=={{header|Arturo}}==
 
{{trans|Nim}}
 
<syntaxhighlight lang="rebol">stay: 0
swit: 0
 
loop 1..1000 'i [
lst: shuffle new [1 0 0]
rand: random 0 2
user: lst\[rand]
remove 'lst rand
huh: 0
loop lst 'i [
if zero? i [
remove 'lst huh
break
]
huh: huh + 1
]
 
if user=1 -> stay: stay+1
if and? [0 < size lst] [1 = first lst] -> swit: swit+1
]
 
print ["Stay:" stay]
print ["Switch:" swit]</syntaxhighlight>
 
{{out}}
 
<pre>Stay: 297
Switch: 549</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="ahk">#SingleInstance, Force
<lang ahk>
#NoTrayIcon
#SingleInstance, OFF
#Persistent
SetBatchLines, -1
Iterations = 1000
Loop, %Iterations%
Line 215 ⟶ 419:
Incorrect_Stay++
}
Percent_Change := floorround(Correct_Change / Iterations * 100)
Percent_RandomPercent_Stay := floorround(Correct_RandomCorrect_Stay / Iterations * 100)
Percent_StayPercent_Random := floorround(Correct_StayCorrect_Random / Iterations * 100)
 
MsgBox,, Monty Hall Problem, These are the results:`r`n`r`nWhen I changed my guess, I got %Correct_Change% of %Iterations% (that's %Incorrect_Change% incorrect). Thats %Percent_Change%`% correct.`r`nWhen I randomly changed my guess, I got %Correct_Random% of %Iterations% (that's %Incorrect_Random% incorrect). Thats %Percent_Random%`% correct.`r`nWhen I stayed with my first guess, I got %Correct_Stay% of %Iterations% (that's %Incorrect_Stay% incorrect). Thats %Percent_Stay%`% correct.
MsgBox,, Monty Hall Problem, These are the results:`r`n`r`nWhen I changed my guess, I got %Correct_Change% of %Iterations% (that's %Incorrect_Change% incorrect). That's %Percent_Change%`% correct.`r`n`r`nWhen I randomly changed my guess, I got %Correct_Random% of %Iterations% (that's %Incorrect_Random% incorrect). That's %Percent_Random%`% correct.`r`n`r`nWhen I stayed with my first guess, I got %Correct_Stay% of %Iterations% (that's %Incorrect_Stay% incorrect). That's %Percent_Stay%`% correct.
ExitApp
 
Monty_Hall(Mode) ;Mode is 1 for change, 2 for random, or 3 for stay
{
Random, prizeguess, 1, 3
Random, guessactual, 1, 3
Random, rand, 1, 2
If (prize = guess && Mode != 3)
While show != 0 && show != guess
Random, show, 1, 3
Else
show := 6 - prize - guess
Random, change_guess, 0, 1
If (Mode = 1 || (change_guess && Mode = 2))
Return, (6 - show - guess) = prize
Else If (Mode = 3 || (!change_guess && Mode = 2))
Return, guess = prize
Else
Return
}
</lang>
 
show := guess = actual ? guess = 3 ? guess - rand : guess = 1 ? guess+rand : guess + 2*rand - 3 : 6 - guess - actual
Mode := Mode = 2 ? 2*rand - 1: Mode
Return, Mode = 1 ? 6 - guess - show = actual : guess = actual
}</syntaxhighlight>
Sample output:
<pre>
These are the results:
 
When I changed my guess, I got 762659 of 1000 (that's 238341 incorrect). ThatsThat's 7666% correct.
 
When I randomly changed my guess, I got 572 of 1000 (that's 428 incorrect). Thats 57% correct.
When I stayedrandomly withchanged my first guess, I got 329505 of 1000 (that's 671495 incorrect). ThatsThat's 3251% correct.
 
When I stayed with my first guess, I got 329 of 1000 (that's 671 incorrect). That's 32% correct.
</pre>
 
=={{header|AWK}}==
<langsyntaxhighlight lang="awk">#!/bin/gawk -f
 
# Monty Hall problem
Line 305 ⟶ 504:
simulate(RAND)
}</langsyntaxhighlight>
Sample output:
<langsyntaxhighlight lang="awk">bash$ ./monty_hall.awk
 
Monty Hall problem simulation:
Line 315 ⟶ 514:
Algorithm switch: prize count = 6655, = 66.55%
Algorithm random: prize count = 4991, = 49.91%
bash$</langsyntaxhighlight>
 
=={{header|bashBASIC}}==
==={{header|ANSI BASIC}}===
{{works with|bash|2.x| and most bash-compatible unix shells}}
{{trans|XPL0}}
<lang bash>
{{works with|Decimal BASIC}}
#!/bin/bash
<syntaxhighlight lang="basic">
# Simulates the "monty hall" probability paradox and shows results.
100 PROGRAM MontyHallProblem
# http://en.wikipedia.org/wiki/Monty_Hall_problem
110 DEF NGames = 10000
# (should rewrite this in C for faster calculating of huge number of rounds)
120 RANDOMIZE
# (Hacked up by Éric Tremblay, 07.dec.2010)
130 LET NWins = 0
140 FOR Game = 0 TO NGames
150 IF IsGameWon(0) <> 0 THEN LET NWins = NWins + 1
160 NEXT Game
170 PRINT "NOT switching doors wins car in ";
180 PRINT USING "##.#": NWins / NGames * 100;
190 PRINT "% of games."
200 LET NWins = 0
210 FOR Game = 0 TO NGames
220 IF IsGameWon(1) <> 0 THEN LET NWins = NWins + 1
230 NEXT Game
240 PRINT "But switching doors wins car in ";
250 PRINT USING "##.#": NWins / NGames * 100;
260 PRINT "% of games."
270 END
280 REM ***
290 EXTERNAL FUNCTION IsGameWon(Sw)
300 REM Play one game.
310 REM Switching if and only if Sw <> 0.
320 REM Returns 1 if the game is won, 0 otherwise.
330 LET Car = INT(RND * 3) ! Randomly place car behind a door.
340 LET Player0 = INT(RND * 3) ! Player randomly chooses a door.
350 DO
360 LET Monty = INT(RND * 3) ! Monty opens door revealing a goat.
370 LOOP UNTIL (Monty <> Car) AND (Monty <> Player0)
380 IF Sw <> 0 THEN ! Player switches TO remaining door.
390 DO
400 LET Player = INT(RND * 3)
410 LOOP UNTIL (Player <> Player0) AND (Player <> Monty)
420 ELSE
430 LET Player = Player0 ! Player sticks with original door.
440 END IF
450 IF Player = Car THEN
460 LET IsGameWon = 1
470 ELSE
480 LET IsGameWon = 0
490 END IF
500 END FUNCTION
</syntaxhighlight>
{{out}}(example)
<pre>
NOT switching doors wins car in 32.3% of games.
But switching doors wins car in 67.3% of games.
</pre>
 
==={{header|BASIC256}}===
num_doors=3 # default number of doors
<syntaxhighlight lang="basic256">
num_rounds=10 #default number of rounds
numTiradas = 1000000
[ "$1" = "" ] || num_doors=$[$1+0]
permanece = 0
[ "$2" = "" ] || num_rounds=$[$2+0]
cambia = 0
 
for i = 1 to numTiradas
nbase=1 # or 0 if we want to see door numbers zero-based
pta_coche = int(rand * 3) + 1
num_win=0; num_lose=0
pta_elegida = int(rand * 3) + 1
if pta_coche <> pta_elegida then
pta_montys = 6 - pta_coche - pta_elegida
else
do
pta_montys = int(Rand * 3) + 1
until pta_montys <> pta_coche
end if
# manteenr elección
if pta_coche = pta_elegida then permanece += 1
# cambiar elección
if pta_coche = 6 - pta_montys - pta_elegida then cambia +=1
next i
 
print "Si mantiene su elección, tiene un "; permanece / numTiradas * 100 ;"% de probabilidades de ganar."
echo "$num_doors doors, playing $num_rounds times."
print "Si cambia, tiene un "; cambia / numTiradas * 100; "% de probabilidades de ganar."
[ "$num_doors" -lt 3 ] && {
end
echo "Hey, there has to be at least 3 doors!!"
</syntaxhighlight>
exit 1
}
echo
 
==={{header|BBC BASIC}}===
function one_round() {
<syntaxhighlight lang="bbcbasic"> total% = 10000
winning_door=$[$RANDOM % $num_doors ]
FOR trial% = 1 TO total%
player_picks_door=$[$RANDOM % $num_doors ]
prize_door% = RND(3) : REM. The prize is behind this door
guess_door% = RND(3) : REM. The contestant guesses this door
# This WILL loop forever if there are less than 3 doors
IF prize_door% = guess_door% THEN
host_leaves_door=$winning_door
REM. The contestant guessed right, reveal either of the others
while [ "$host_leaves_door" = "$player_picks_door" ]; do
reveal_door% = RND(2)
#echo -n "(Host looks at door $host_leaves_door...) "
IF prize_door% = 1 reveal_door% += 1
host_leaves_door=$[$RANDOM % $num_doors]
IF prize_door% = 2 AND reveal_door% = 2 reveal_door% = 3
done
ELSE
REM. The contestant guessed wrong, so reveal the non-prize door
# Output the result of this round
reveal_door% = prize_door% EOR guess_door%
#echo "Round $[$nbase+current_round]: "
ENDIF
echo -n "Player chooses #$[$nbase+$player_picks_door]. "
stick_door% = guess_door% : REM. The sticker doesn't change his mind
[ "$num_doors" -ge 10 ] &&
swap_door% = guess_door% EOR reveal_door% : REM. but the swapper does
# listing too many door numbers (10 or more) will just clutter the output
IF stick_door% = prize_door% sticker% += 1
echo -n "Host opens all except #$[$nbase+$host_leaves_door] and #$[$nbase+$player_picks_door]. " \
IF swap_door% = prize_door% swapper% += 1
|| {
NEXT trial%
# less than 10 doors, we list them one by one instead of "all except ?? and ??"
PRINT "After a total of ";total%;" trials,"
echo -n "Host opens"
PRINT "The 'sticker' won ";sticker%;" times (";INT(sticker%/total%*100);"%)"
host_opens=0
PRINT "The 'swapper' won ";swapper%;" times (";INT(swapper%/total%*100);"%)"</syntaxhighlight>
while [ "$host_opens" -lt "$num_doors" ]; do
Output:
[ "$host_opens" != "$host_leaves_door" ] && [ "$host_opens" != "$player_picks_door" ] && \
<pre>
echo -n " #$[$nbase+$host_opens]"
After a total of 10000 trials,
host_opens=$[$host_opens+1]
The 'sticker' won 3379 times (33%)
done
The 'swapper' won 6621 times (66%)
echo -n " "
</pre>
}
echo -n "(prize is behind #$[$nbase+$winning_door]) "
echo -n "Switch from $[$nbase+$player_picks_door] to $[$nbase+$host_leaves_door]: "
[ "$winning_door" = "$host_leaves_door" ] && {
echo "WIN."
num_win=$[num_win+1]
} || {
echo "LOSE."
num_lose=$[num_lose+1]
}
} # end of function one_round
 
==={{header|Euphoria}}===
# ok, let's go
<syntaxhighlight lang="euphoria">integer switchWins, stayWins
current_round=0
switchWins = 0
while [ "$num_rounds" -gt "$current_round" ]; do
stayWins = 0
one_round
current_round=$[$current_round+1]
done
 
integer winner, choice, shown
# (08.dec.2010) Changed this summary message to indicate "always stay" vs. "always switch"
 
echo
for plays = 1 to 10000 do
echo "Wins (switch to remaining door): $num_win"
winner = rand(3)
echo "Losses (stick to first choice): $num_lose"
choice = rand(3)
exit 0
while 1 do
</lang>
shown = rand(3)
Output of a few runs:
if shown != winner and shown != choice then
exit
end if
end while
stayWins += choice = winner
switchWins += 6-choice-shown = winner
end for
printf(1, "Switching wins %d times.\n", switchWins)
printf(1, "Staying wins %d times.\n", stayWins)
</syntaxhighlight>
{{out}} (sample)
<pre>
Switching wins 6697 times.
$ ./monty_hall_problem.sh
3Staying doors,wins playing 103303 times.
</pre>
 
==={{header|FreeBASIC}}===
Player chooses #2. Host opens #1 (prize is behind #3) Switch from 2 to 3: WIN.
<syntaxhighlight lang="freebasic">
Player chooses #2. Host opens #3 (prize is behind #1) Switch from 2 to 1: WIN.
' version 19-01-2019
Player chooses #2. Host opens #1 (prize is behind #3) Switch from 2 to 3: WIN.
' compile with: fbc -s console
Player chooses #2. Host opens #1 (prize is behind #2) Switch from 2 to 3: LOSE.
Player chooses #2. Host opens #1 (prize is behind #3) Switch from 2 to 3: WIN.
Player chooses #3. Host opens #2 (prize is behind #1) Switch from 3 to 1: WIN.
Player chooses #3. Host opens #2 (prize is behind #3) Switch from 3 to 1: LOSE.
Player chooses #2. Host opens #3 (prize is behind #2) Switch from 2 to 1: LOSE.
Player chooses #3. Host opens #1 (prize is behind #3) Switch from 3 to 2: LOSE.
Player chooses #2. Host opens #3 (prize is behind #1) Switch from 2 to 1: WIN.
 
Const As Integer max = 1000000
Wins (switch to remaining door): 6
Randomize Timer
Losses (stick to first choice): 4
 
Dim As UInteger i, car_door, chosen_door, montys_door, stay, switch
 
For i = 1 To max
$ ./monty_hall_problem.sh 10 5
car_door = Fix(Rnd * 3) + 1
10 doors, playing 5 times.
chosen_door = Fix(Rnd * 3) + 1
If car_door <> chosen_door Then
montys_door = 6 - car_door - chosen_door
Else
Do
montys_door = Fix(Rnd * 3) + 1
Loop Until montys_door <> car_door
End If
'Print car_door,chosen_door,montys_door
' stay
If car_door = chosen_door Then stay += 1
' switch
If car_door = 6 - montys_door - chosen_door Then switch +=1
Next
 
Print Using "If you stick to your choice, you have a ##.## percent" _
Player chooses #8. Host opens all except #1 and #8. (prize is behind #8) Switch from 8 to 1: LOSE.
+ " chance to win"; stay / max * 100
Player chooses #2. Host opens all except #3 and #2. (prize is behind #3) Switch from 2 to 3: WIN.
Print Using "If you switched, you have a ##.## percent chance to win"; _
Player chooses #9. Host opens all except #2 and #9. (prize is behind #2) Switch from 9 to 2: WIN.
switch / max * 100
Player chooses #6. Host opens all except #8 and #6. (prize is behind #8) Switch from 6 to 8: WIN.
Player chooses #5. Host opens all except #7 and #5. (prize is behind #7) Switch from 5 to 7: WIN.
 
' empty keyboard buffer
Wins (switch to remaining door): 4
While InKey <> "" : Wend
Losses (stick to first choice): 1
Print : Print "hit any key to end program"
Sleep
End
</syntaxhighlight>
{{out}}
<pre>
If you stick to your choice, you have a 33.32 percent chance to win
If you switched, you have a 66.68 percent chance to win
</pre>
 
 
=={{header|FutureBasic}}==
$ ./monty_hall_problem.sh 3 1000
Translated from ANSI BASIC
3 doors, playing 1000 times.
<syntaxhighlight lang="futurebasic">
// Monty Hall problem
// May 2024 - Rich Love
 
local fn IsGameWon(Sw as int) as bool
Player chooses #3. Host opens #2 (prize is behind #3) Switch from 3 to 1: LOSE.
REM Play one game.
Player chooses #3. Host opens #2 (prize is behind #1) Switch from 3 to 1: WIN.
REM Switching if and only if Sw <> 0.
Player chooses #2. Host opens #3 (prize is behind #1) Switch from 2 to 1: WIN.
REM Returns 1 if the game is won, 0 otherwise.
short Car = INT(RND(3)) //Randomly place car behind a door.
short Player0 = INT(RND(3)) // Player randomly chooses a door.
short Monty
short IsGameWon
short Player
DO
Monty = INT(RND(3)) // Monty opens door revealing a goat.
UNTIL (Monty <> Car) AND (Monty <> Player0)
380
IF Sw <> 0 // Player switches TO remaining door.
DO
Player = INT(RND(3))
UNTIL (Player <> Player0) AND (Player <> Monty)
Monty = INT(RND(3))
 
ELSE
[ ... ]
Player = Player0 // Player sticks with original door.
END IF
IF Player = Car
IsGameWon = 1
ELSE
IsGameWon = 0
END IF
END fn = IsgameWon
 
Player chooses #1. Host opens #3 (prize is behind #2) Switch from 1 to 2: WIN.
Player chooses #3. Host opens #1 (prize is behind #3) Switch from 3 to 2: LOSE.
Player chooses #3. Host opens #1 (prize is behind #2) Switch from 3 to 2: WIN.
 
_NGames = 10000
Wins (switch to remaining door): 655
 
Losses (stick to first choice): 345
float NWins = 0
short Game
 
FOR Game = 0 TO _NGames
IF fn IsGameWon(0) <> 0 THEN NWins = NWins + 1
NEXT Game
 
 
PRINT "NOT switching doors wins car in ";
PRINT USING "##.##" ; NWins / 100 ;
PRINT " % of games."
 
NWins = 0
FOR Game = 0 TO _NGames
IF fn IsGameWon(1) <> 0 THEN NWins = NWins + 1
NEXT Game
PRINT "But switching doors wins car in ";
PRINT USING "##.##" ; NWins / _NGames * 100;
PRINT " % of games."
 
handleevents
</syntaxhighlight>
{{output}}
<pre>
NOT switching doors wins car in 33.48% of games.
But switching doors wins car in 67.15% of games.
</pre>
 
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "MontyH.bas"
110 RANDOMIZE
120 LET NUMGAMES=1000
130 LET CHANGING,NOTCHANGING=0
140 FOR I=0 TO NUMGAMES-1
150 LET PRIZEDOOR=RND(3)+1:LET CHOSENDOOR=RND(3)+1
160 IF CHOSENDOOR=PRIZEDOOR THEN
170 LET NOTCHANGING=NOTCHANGING+1
180 ELSE
190 LET CHANGING=CHANGING+1
200 END IF
210 NEXT
220 PRINT "Num of games:";NUMGAMES
230 PRINT "Wins not changing doors:";NOTCHANGING,NOTCHANGING/NUMGAMES*100;"% of total."
240 PRINT "Wins changing doors:",CHANGING,CHANGING/NUMGAMES*100;"% of total."</syntaxhighlight>
 
==={{header|Liberty BASIC}}===
{{trans|Quick BASIC}}
{{works with|Just BASIC}}
<syntaxhighlight lang="lb">
DIM doors(3) '0 is a goat, 1 is a car
 
total = 10000 'set desired number of iterations
switchWins = 0
stayWins = 0
 
FOR plays = 1 TO total
winner = INT(RND(1) * 3) + 1
doors(winner) = 1'put a winner in a random door
choice = INT(RND(1) * 3) + 1'pick a door, any door
DO
shown = INT(RND(1) * 3) + 1
'don't show the winner or the choice
LOOP WHILE doors(shown) = 1 OR shown = choice
if doors(choice) = 1 then
stayWins = stayWins + 1 'if you won by staying, count it
else
switchWins = switchWins + 1'could have switched to win
end if
doors(winner) = 0 'clear the doors for the next test
NEXT
PRINT "Result for ";total;" games."
PRINT "Switching wins "; switchWins; " times."
PRINT "Staying wins "; stayWins; " times."
</syntaxhighlight>
{{out}} (example)
<pre>
Result for 10000 games.
Switching wins 6634 times.
Staying wins 3366 times.</pre>
 
==={{header|Minimal BASIC}}===
{{trans|ANSI BASIC}}
{{works with|BASICA}}
<syntaxhighlight lang="basic">
10 REM Monty Hall problem
20 LET N = 10000
30 RANDOMIZE
40 LET W = 0
50 FOR G = 0 TO N
60 LET S = 0
70 GOSUB 230
80 IF V = 0 THEN 100
90 LET W = W+1
100 NEXT G
110 PRINT "NOT switching doors wins car in";
120 PRINT W/N*100; "per cent of games."
130 LET W = 0
140 FOR G = 0 TO N
150 LET S = 1
160 GOSUB 230
170 IF V = 0 THEN 190
180 LET W = W+1
190 NEXT G
200 PRINT "But switching doors wins car in";
210 PRINT W/N*100; "per cent of games."
220 END
230 REM ** Is game won?
240 REM Play one game.
250 REM Switching if and only if S <> 0.
260 REM Randomly place car behind a door.
270 LET C = INT(RND*3)
280 REM Player randomly chooses a door.
290 LET P0 = INT(RND*3)
300 REM Monty opens door revealing a goat.
310 LET M = INT(RND*3)
320 IF M = C THEN 310
330 IF M = P0 THEN 310
340 IF S = 0 THEN 410
350 REM Player switches to remaining door.
360 LET P = INT(RND*3)
370 IF P = P0 THEN 360
380 IF P = M THEN 360
390 GOTO 430
400 REM Player sticks with original door.
410 LET P = P0
420 REM Victory?
430 IF P <> C THEN 460
440 LET V = 1
450 RETURN
460 LET V = 0
470 RETURN
</syntaxhighlight>
 
==={{header|PureBasic}}===
<syntaxhighlight lang="purebasic">Structure wins
stay.i
redecide.i
EndStructure
 
#goat = 0
#car = 1
Procedure MontyHall(*results.wins)
Dim Doors(2)
Doors(Random(2)) = #car
 
player = Random(2)
Select Doors(player)
Case #car
*results\redecide + #goat
*results\stay + #car
Case #goat
*results\redecide + #car
*results\stay + #goat
EndSelect
EndProcedure
OpenConsole()
#Tries = 1000000
Define results.wins
 
For i = 1 To #Tries
MontyHall(@results)
Next
PrintN("Trial runs for each option: " + Str(#Tries))
PrintN("Wins when redeciding: " + Str(results\redecide) + " (" + StrD(results\redecide / #Tries * 100, 2) + "% chance)")
PrintN("Wins when sticking: " + Str(results\stay) + " (" + StrD(results\stay / #Tries * 100, 2) + "% chance)")
Input()</syntaxhighlight>
 
Output:<pre>Trial runs for each option: 1000000
Wins when redeciding: 666459 (66.65% chance)
Wins when sticking: 333541 (33.35% chance)</pre>
 
==={{header|QuickBASIC}}===
{{works with|QuickBasic|4.5}}
{{trans|Java}}
<langsyntaxhighlight lang="qbasic">RANDOMIZE TIMER
DIM doors(3) '0 is a goat, 1 is a car
CLS
Line 464 ⟶ 935:
NEXT plays
PRINT "Switching wins"; switchWins; "times."
PRINT "Staying wins"; stayWins; "times."</langsyntaxhighlight>
Output:
<pre>Switching wins 21805 times.
Staying wins 10963 times.</pre>
 
==={{header|Run BASIC}}===
{{trans|Quick BASIC}}
{{works with|Just BASIC}}
<syntaxhighlight lang="runbasic">
input "Number of tries;";tries ' gimme the number of iterations
FOR plays = 1 TO tries
winner = INT(RND(1) * 3) + 1
doors(winner) = 1 'put a winner in a random door
choice = INT(RND(1) * 3) + 1 'pick a door please
[DO] shown = INT(RND(1) * 3) + 1
' ------------------------------------------
' don't show the winner or the choice
if doors(shown) = 1 then goto [DO]
if shown = choice then goto [DO]
if doors(choice) = 1 then
stayWins = stayWins + 1 ' if you won by staying, count it
else
switchWins = switchWins + 1 ' could have switched to win
end if
doors(winner) = 0 'clear the doors for the next test
NEXT
PRINT " Result for ";tries;" games."
PRINT "Switching wins ";switchWins; " times."
PRINT " Staying wins ";stayWins; " times."</syntaxhighlight>
 
==={{header|Sinclair ZX81 BASIC}}===
Works with 1k of RAM.
 
This program could certainly be made more efficient. What is really going on, after all, is
<pre>if initial guess = car then
sticker wins
else
switcher wins;</pre>
but I take it that the point is to demonstrate the outcome to people who may <i>not</i> see that that's what is going on. I have therefore written the program in a deliberately naïve style, not assuming anything.
<syntaxhighlight lang="basic"> 10 PRINT " WINS IF YOU"
20 PRINT "STICK","SWITCH"
30 LET STICK=0
40 LET SWITCH=0
50 FOR I=1 TO 1000
60 LET CAR=INT (RND*3)
70 LET GUESS=INT (RND*3)
80 LET SHOW=INT (RND*3)
90 IF SHOW=GUESS OR SHOW=CAR THEN GOTO 80
100 LET NEWGUESS=INT (RND*3)
110 IF NEWGUESS=GUESS OR NEWGUESS=SHOW THEN GOTO 100
120 IF GUESS=CAR THEN LET STICK=STICK+1
130 IF NEWGUESS=CAR THEN LET SWITCH=SWITCH+1
140 NEXT I
150 PRINT AT 2,0;STICK,SWITCH</syntaxhighlight>
{{out}}
<pre> WINS IF YOU
STICK SWITCH
341 659</pre>
 
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">OPTION BASE 0
DIM puertas(3)
 
LET numTiradas = 1000000
 
FOR i = 0 TO numTiradas
LET pta_coche = INT(RND * 3) + 1
LET puertas(pta_coche) = 1
LET pta_elegida = INT(RND * 3) + 1
DO
LET pta_montys = INT(RND * 3) + 1
LOOP WHILE puertas(pta_montys) = 1 OR pta_montys = pta_elegida
IF puertas(pta_elegida) = 1 THEN
LET cambia = cambia + 1
ELSE
LET permanece = permanece + 1
END IF
LET puertas(pta_coche) = 0
NEXT i
 
PRINT "Cambiar gana el"; permanece / numTiradas * 100; "% de las veces."
PRINT "Mantenerse gana el"; cambia / numTiradas * 100; "% de las veces."
END</syntaxhighlight>
 
==={{header|Yabasic}}===
<syntaxhighlight lang="yabasic">
numTiradas = 1000000
 
for i = 1 to numTiradas
pta_coche = int(ran(3)) + 1
pta_elegida = int(ran(3)) + 1
if pta_coche <> pta_elegida then
pta_montys = 6 - pta_coche - pta_elegida
else
repeat
pta_montys = int(ran(3)) + 1
until pta_montys <> pta_coche
end if
// manteenr elección
if pta_coche = pta_elegida then permanece = permanece + 1 : fi
// cambiar elección
if pta_coche = 6 - pta_montys - pta_elegida then cambia = cambia + 1 : fi
next i
 
print "Si mantiene su eleccion, tiene un ", permanece / numTiradas * 100, "% de probabilidades de ganar."
print "Si cambia, tiene un ", cambia / numTiradas * 100, "% de probabilidades de ganar."
end
</syntaxhighlight>
 
=={{header|C}}==
<syntaxhighlight lang="c">//Evidence of the Monty Hall solution of marquinho1986 in C [github.com/marquinho1986]
 
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <math.h>
#define NumSim 1000000000 // one billion of simulations! using the Law of large numbers concept [https://en.wikipedia.org/wiki/Law_of_large_numbers]
 
void main() {
#define TRIALS 10000
unsigned long int i,stay=0;
int ChosenDoor,WinningDoor;
bool door[3]={0,0,0};
srand(time(NULL)); //initialize random seed.
for(i=0;i<=NumSim;i++){
WinningDoor=rand() % 3; // choosing winning door.
ChosenDoor=rand() % 3; // selected door.
if(door[WinningDoor]=true,door[ChosenDoor])stay++;
door[WinningDoor]=false;
}
printf("\nAfter %lu games, I won %u by staying. That is %f%%. and I won by switching %lu That is %f%%",NumSim, stay, (float)stay*100.0/(float)i,abs(NumSim-stay),100-(float)stay*100.0/(float)i);
}
</syntaxhighlight>
 
Output of one run:
 
<pre>After 1000000000 games, I won 333332381 by staying. That is 33.333238%. and I won by switching 666667619 That is 66.666762% </pre>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
 
class Program
int brand(int n)
{
static void Main(string[] args)
return ( n * ((double)rand()/((double)RAND_MAX + (double)1.0 ) ) );
{
int switchWins = 0;
int stayWins = 0;
 
Random gen = new Random();
for(int plays = 0; plays < 1000000; plays++ )
{
int[] doors = {0,0,0};//0 is a goat, 1 is a car
 
var winner = gen.Next(3);
doors[winner] = 1; //put a winner in a random door
int choice = gen.Next(3); //pick a door, any door
int shown; //the shown door
do
{
shown = gen.Next(3);
}
while (doors[shown] == 1 || shown == choice); //don't show the winner or the choice
stayWins += doors[choice]; //if you won by staying, count it
//the switched (last remaining) door is (3 - choice - shown), because 0+1+2=3
switchWins += doors[3 - choice - shown];
}
 
Console.Out.WriteLine("Staying wins " + stayWins + " times.");
Console.Out.WriteLine("Switching wins " + switchWins + " times.");
}
}</syntaxhighlight>
Sample output:
<pre>
Staying wins: 333830
Switching wins: 666170
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <iostream>
#include <cstdlib>
#include <ctime>
int randint(int n)
{
return (1.0*n*std::rand())/(1.0+RAND_MAX);
}
 
int other(int doorA, int doorB)
#define PERCENT(X) ( 100.0*((float)(X))/((float)TRIALS) )
{
int doorC;
if (doorA == doorB)
{
doorC = randint(2);
if (doorC >= doorA)
++doorC;
}
else
{
for (doorC = 0; doorC == doorA || doorC == doorB; ++doorC)
{
// empty
}
}
return doorC;
}
 
int check(int games, bool change)
int main()
{
int win_count = 0;
int prize, choice, show, notshown, newchoice;
for (int game = 0; game < games; ++game)
int staywinning=0, changewinning=0, randomwinning=0;
int odoor[2];
int i,j,k;
for(i=0; i < TRIALS; i++)
{
int const winning_door = randint(3);
/* put the prize somewhere */
int prizeconst original_choice = brandrandint(3);
int open_door = other(original_choice, winning_door);
/* let the user choose a door */
 
choice = brand(3);
int const selected_door = change?
/* let us take a list of unchoosen doors */
other(open_door, original_choice)
for (j=0, k=0; j<3; j++)
: original_choice;
{
 
if (j!=choice) odoor[k++] = j;
if (selected_door == winning_door)
}
/* Monty opens one... */++win_count;
}
if ( choice == prize )
{ /* staying the user will win... Monty opens a random
return win_count;
port*/
}
show = odoor[ brand(2) ];
notshown = odoor[ (show+1)%2 ];
int main()
} else { /* no random, Monty can open just one door... */
{
if ( odoor[0] == prize )
std::srand(std::time(0));
{
 
show = odoor[1];
int notshowngames = odoor[0]10000;
int wins_stay = check(games, false);
} else {
int wins_change = check(games, true);
show = odoor[0];
std::cout << "staying: " << 100.0*wins_stay/games << "%, changing: " << 100.0*wins_change/games << "%\n";
notshown = odoor[1];
}</syntaxhighlight>
}
Sample output:
}
staying: 33.73%, changing: 66.9%
 
/* the user randomly choose one of the two closed doors
=={{header|Chapel}}==
(one is his/her previous choice, the second is the
 
one notshown */
'''Version 1''' : using task parallelism.
odoor[0] = choice;
 
odoor[1] = notshown;
<syntaxhighlight lang="chapel">
newchoice = odoor[ brand(2) ];
use Random;
/* now let us count if it takes it or not */
 
if ( choice == prize ) staywinning++;
param doors: int = 3;
if ( notshown == prize ) changewinning++;
config const games: int = 1000;
if ( newchoice == prize ) randomwinning++;
 
config const maxTasks = 32;
var numTasks = 1;
while( games / numTasks > 1000000 && numTasks < maxTasks ) do numTasks += 1;
const tasks = 1..#numTasks;
const games_per_task = games / numTasks ;
const remaining_games = games % numTasks ;
 
var wins_by_stay: [tasks] int;
 
coforall task in tasks {
 
var rand = new RandomStream();
 
for game in 1..#games_per_task {
var player_door = (rand.getNext() * 1000): int % doors ;
var winning_door = (rand.getNext() * 1000): int % doors ;
if player_door == winning_door then
wins_by_stay[ task ] += 1;
}
if task == tasks.last then {
printf("Staying: %.2f\n", PERCENT(staywinning) );
for game in 1..#remaining_games {
printf("Changing: %.2f\n", PERCENT(changewinning) );
var player_door = (rand.getNext() * 1000): int % doors ;
printf("New random choice: %.2f\n", PERCENT(randomwinning) );
var winning_door = (rand.getNext() * 1000): int % doors ;
}</lang>
if player_door == winning_door then
wins_by_stay[ task ] += 1;
}
}
 
}
Output of one run:
 
var total_by_stay = + reduce wins_by_stay;
<pre>Staying: 33.41
 
Changing: 66.59
var total_by_switch = games - total_by_stay;
New random choice: 49.67</pre>
var percent_by_stay = ((total_by_stay: real) / games) * 100;
var percent_by_switch = ((total_by_switch: real) / games) * 100;
 
writeln( "Wins by staying: ", total_by_stay, " or ", percent_by_stay, "%" );
writeln( "Wins by switching: ", total_by_switch, " or ", percent_by_switch, "%" );
if ( total_by_stay > total_by_switch ){
writeln( "Staying is the superior method." );
} else if( total_by_stay < total_by_switch ){
writeln( "Switching is the superior method." );
} else {
writeln( "Both methods are equal." );
}
</syntaxhighlight>
 
Sample output:
<pre>
Wins by staying: 354 or 35.4%
Wins by switching: 646 or 64.6%
Switching is the superior method.
</pre>
 
'''Version 2''' : using data parallelism.
 
<syntaxhighlight lang="chapel">
use Random;
 
config const numGames = 100_000_000;
 
var switch, stick: uint;
 
// have a separate RNG for each task; add together the results at the end
forall i in 1..numGames
with (var rand = new RandomStream(uint, parSafe = false), + reduce stick)
{
var chosen_door = rand.getNext() % 3;
var winner_door = rand.getNext() % 3;
if chosen_door == winner_door then
stick += 1;
}
 
// if you lost by sticking it means you would have won by switching
switch = numGames - stick;
writeln("Over ", numGames, " games:\n - switching wins ",
100.0*switch / numGames, "% of the time and\n - sticking wins ",
100.0*stick / numGames, "% of the time");
 
</syntaxhighlight>
 
Sample output:
<pre>
Over 1000000 games:
- switching wins 66.6937% of the time and
- sticking wins 33.3063% of the time
</pre>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(ns monty-hall-problem
(:use [clojure.contrib.seq :only (shuffle)]))
 
Line 557 ⟶ 1,302:
(range times))]
(str "wins " wins " times out of " times)))
</syntaxhighlight>
</lang>
<langsyntaxhighlight lang="clojure">monty-hall-problem> (println "staying:" (simulate true 1000))
staying: wins 337 times out of 1000
nil
Line 564 ⟶ 1,309:
switching: wins 638 times out of 1000
nil
</syntaxhighlight>
</lang>
 
=={{header|COBOL}}==
{{works with|OpenCOBOL}}
<syntaxhighlight lang="cobol"> IDENTIFICATION DIVISION.
PROGRAM-ID. monty-hall.
 
DATA DIVISION.
WORKING-STORAGE SECTION.
78 Num-Games VALUE 1000000.
 
*> These are needed so the values are passed to
*> get-rand-int correctly.
01 One PIC 9 VALUE 1.
01 Three PIC 9 VALUE 3.
 
01 doors-area.
03 doors PIC 9 OCCURS 3 TIMES.
 
01 choice PIC 9.
01 shown PIC 9.
01 winner PIC 9.
 
01 switch-wins PIC 9(7).
01 stay-wins PIC 9(7).
 
01 stay-wins-percent PIC Z9.99.
01 switch-wins-percent PIC Z9.99.
 
PROCEDURE DIVISION.
PERFORM Num-Games TIMES
MOVE 0 TO doors (winner)
 
CALL "get-rand-int" USING CONTENT One, Three,
REFERENCE winner
MOVE 1 TO doors (winner)
CALL "get-rand-int" USING CONTENT One, Three,
REFERENCE choice
PERFORM WITH TEST AFTER
UNTIL NOT(shown = winner OR choice)
CALL "get-rand-int" USING CONTENT One, Three,
REFERENCE shown
END-PERFORM
ADD doors (choice) TO stay-wins
ADD doors (6 - choice - shown) TO switch-wins
END-PERFORM
COMPUTE stay-wins-percent ROUNDED =
stay-wins / Num-Games * 100
COMPUTE switch-wins-percent ROUNDED =
switch-wins / Num-Games * 100
 
DISPLAY "Staying wins " stay-wins " times ("
stay-wins-percent "%)."
DISPLAY "Switching wins " switch-wins " times ("
switch-wins-percent "%)."
.
 
IDENTIFICATION DIVISION.
PROGRAM-ID. get-rand-int.
 
DATA DIVISION.
WORKING-STORAGE SECTION.
01 call-flag PIC X VALUE "Y".
88 first-call VALUE "Y", FALSE "N".
 
01 num-range PIC 9.
 
LINKAGE SECTION.
01 min-num PIC 9.
01 max-num PIC 9.
 
01 ret PIC 9.
 
PROCEDURE DIVISION USING min-num, max-num, ret.
*> Seed RANDOM once.
IF first-call
MOVE FUNCTION RANDOM(FUNCTION CURRENT-DATE (9:8))
TO num-range
SET first-call TO FALSE
END-IF
 
COMPUTE num-range = max-num - min-num + 1
COMPUTE ret =
FUNCTION MOD(FUNCTION RANDOM * 100000, num-range)
+ min-num
.
END PROGRAM get-rand-int.
 
END PROGRAM monty-hall.</syntaxhighlight>
 
{{out}}
<pre>
Staying wins 0333396 times (33.34%).
Switching wins 0666604 times (66.66%).
</pre>
 
=={{header|ColdFusion}}==
<syntaxhighlight lang="cfm"><cfscript>
<lang cfm>
function runmontyhall(num_tests) {
<cfscript>
// number of wins when player switches after original selection
function runmontyhall(num_tests) {
switch_wins = 0;
// number of wins when player switches after original selection
// number of wins when players "sticks" with original selection
switch_wins = 0;
stick_wins = 0;
// number of wins when players "sticks" with original selection
// run all the tests
stick_wins = 0;
for(i=1;i<=num_tests;i++) {
// run all the tests
// unconditioned potential for selection of each door
for(i=1;i<=num_tests;i++) {
doors = [0,0,0];
// unconditioned potential for selection of each door
// winning door is randomly assigned...
doors = [0,0,0];
winner = randrange(1,3);
// winning door is randomly assigned...
// ...and actualized in the array of real doors
winner = randrange(1,3);
doors[winner] = 1;
// ...and actualized in the array of real doors
// player chooses one of three doors
doors[winner] = 1;
choice = randrange(1,3);
// player chooses one of three doors
do {
choice = randrange(1,3);
// monty randomly reveals a door...
do {
shown = randrange(1,3);
// monty randomly reveals a door...
}
shown = randrange(1,3);
// ...but monty only reveals empty doors;
}
// he will not reveal the door that the player has choosen
// ...but monty only reveals empty doors;
// henor will nothe reveal the winning door that the player has choosen
while(shown==choice || doors[shown]==1);
// nor will he reveal the winning door
// when the door the player originally selected is the winner, the "stick" option gains a point
while(shown==choice || doors[shown]==1);
stick_wins += doors[choice];
// when the door the player originally selected is the winner, the "stick" option gains a point
// to calculate the number of times the player would have won with a "switch", subtract the
stick_wins += doors[choice];
// to calculate the number of times the player would have won with a "switch", subtract the// "value" of the chosen, "stuck-to" door from 1, the possible number of wins if the player
// if the player // chose and stuck with the winning door (1), the player would not have won by switching, so the value is 1-1=0
// the value is 1-1=0 if the player chose and stuck with a losing door (0), the player would have won by switching, so the value is 1-0=1
// have won by switching, so the value is 1-0=1
switch_wins += 1-doors[choice];
switch_wins += 1-doors[choice];
}
// finally, simply run the percentages for each outcome
stick_percentage = (stick_wins/num_tests)*100;
switch_percentage = (switch_wins/num_tests)*100;
writeoutput('Number of Tests: ' & num_tests);
writeoutput('<br />Stick Wins: ' & stick_wins & ' ['& stick_percentage &'%]');
writeoutput('<br />Switch Wins: ' & switch_wins & ' ['& switch_percentage &'%]');
}
// finally, simply run the percentages for each outcome
runmontyhall(10000);
stick_percentage = (stick_wins/num_tests)*100;
</cfscript>
switch_percentage = (switch_wins/num_tests)*100;
</lang>
writeoutput('Number of Tests: ' & num_tests);
writeoutput('<br />Stick Wins: ' & stick_wins & ' ['& stick_percentage &'%]');
writeoutput('<br />Switch Wins: ' & switch_wins & ' ['& switch_percentage &'%]');
}
runmontyhall(10000);
</cfscript></syntaxhighlight>
Output:
<pre>
Line 615 ⟶ 1,458:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun make-round ()
(let ((array (make-array 3
:element-type 'bit
Line 629 ⟶ 1,472:
 
(defun won? (array i)
(= 1 (bit array i)))</langsyntaxhighlight>
<langsyntaxhighlight lang="lisp">CL-USER> (progn (loop repeat #1=(expt 10 6)
for round = (make-round)
for initial = (random 3)
Line 647 ⟶ 1,490:
#1# 1/100))))))
Stay: 33.2716%
Switch: 66.6593%</langsyntaxhighlight>
 
<syntaxhighlight lang="lisp">
=={{header|C++}}==
;Find out how often we win if we always switch
<lang cpp>#include <iostream>
(defun rand-elt (s)
#include <cstdlib>
(elt s (random (length s))))
#include <ctime>
int randint(int n)
{
return (1.0*n*std::rand())/(1.0+RAND_MAX);
}
 
(defun monty ()
int other(int doorA, int doorB)
(let* ((doors '(0 1 2))
{
(prize (random 3));possible values: 0, 1, 2
int doorC;
if(pick (doorA ==random doorB3))
(opened (rand-elt (remove pick (remove prize doors))));monty opens a door which is not your pick and not the prize
{
(other (car (remove pick (remove opened doors))))) ;you decide to switch to the one other door that is not your pick and not opened
doorC = randint(2);
(= prize other))) ; did you switch to the prize?
if (doorC >= doorA)
 
++doorC;
(defun monty-trials (n)
(count t (loop for x from 1 to n collect (monty))))
</syntaxhighlight>
 
=={{header|D}}==
<syntaxhighlight lang="d">import std.stdio, std.random;
 
void main() {
int switchWins, stayWins;
 
while (switchWins + stayWins < 100_000) {
immutable carPos = uniform(0, 3); // Which door is car behind?
immutable pickPos = uniform(0, 3); // Contestant's initial pick.
int openPos; // Which door is opened by Monty Hall?
 
// Monty can't open the door you picked or the one with the car
// behind it.
do {
openPos = uniform(0, 3);
} while(openPos == pickPos || openPos == carPos);
 
int switchPos;
// Find position that's not currently picked by contestant and
// was not opened by Monty already.
for (; pickPos==switchPos || openPos==switchPos; switchPos++) {}
 
if (pickPos == carPos)
stayWins++;
else if (switchPos == carPos)
switchWins++;
else
assert(0); // Can't happen.
}
 
else
writefln("Switching/Staying wins: %d %d", switchWins, stayWins);
{
}</syntaxhighlight>
for (doorC = 0; doorC == doorA || doorC == doorB; ++doorC)
{{out}}
{
<pre>Switching/Staying wins: 66609 33391</pre>
// empty
 
=={{header|Dart}}==
The class Game attempts to hide the implementation as much as possible, the play() function does not use any specifics of the implementation.
<syntaxhighlight lang="dart">int rand(int max) => (Math.random()*max).toInt();
 
class Game {
int _prize;
int _open;
int _chosen;
 
Game() {
_prize=rand(3);
_open=null;
_chosen=null;
}
 
void choose(int door) {
_chosen=door;
}
 
void reveal() {
if(_prize==_chosen) {
int toopen=rand(2);
if (toopen>=_prize)
toopen++;
_open=toopen;
} else {
for(int i=0;i<3;i++)
if(_prize!=i && _chosen!=i) {
_open=i;
break;
}
}
}
 
return doorC;
void change() {
for(int i=0;i<3;i++)
if(_chosen!=i && _open!=i) {
_chosen=i;
break;
}
}
 
bool hasWon() => _prize==_chosen;
 
String toString() {
String res="Prize is behind door $_prize";
if(_chosen!=null) res+=", player has chosen door $_chosen";
if(_open!=null) res+=", door $_open is open";
return res;
}
}
 
intvoid checkplay(int gamescount, bool changeswap) {
int wins=0;
{
int win_count = 0;
for (int game = 0; game < games; ++game)
{
int const winning_door = randint(3);
int const original_choice = randint(3);
int open_door = other(original_choice, winning_door);
 
for(int i=0;i<count;i++) {
int const selected_door = change?
Game game=new Game();
other(open_door, original_choice)
game.choose(rand(3));
: original_choice;
game.reveal();
if(swap)
game.change();
if(game.hasWon())
wins++;
}
String withWithout=swap?"with":"without";
double percent=(wins*100.0)/count;
print("playing $withWithout switching won $percent%");
}
 
test() {
if (selected_door == winning_door)
for(int i=0;i<5;i++) {
++win_count;
Game g=new Game();
g.choose(i%3);
g.reveal();
print(g);
g.change();
print(g);
print("win==${g.hasWon()}");
}
return win_count;
}
int main()
{
std::srand(std::time(0));
 
main() {
int games = 10000;
int wins_stay = checkplay(games10000, false);
int wins_change = checkplay(games10000, true);
}</syntaxhighlight>
std::cout << "staying: " << 100.0*wins_stay/games << "%, changing: " << 100.0*wins_change/games << "%\n";
<pre>playing without switching won 33.32%
}</lang>
playing with switching won 67.63%</pre>
Sample output:
staying: 33.73%, changing: 66.9%
 
=={{header|C sharp|C#Delphi}}==
{{trans|JavaC#}}
{{works with|Delphi|XE10}}
{{libheader| System.SysUtils}}
<syntaxhighlight lang="delphi">program MontyHall;
 
{$APPTYPE CONSOLE}
<lang C sharp>
using System;
 
{$R *.res}
namespace MontyHallProblem
{
class Program
{
static void Main(string[] args)
{
int switchWins = 0;
int stayWins = 0;
 
uses
Random gen = new Random();
System.SysUtils;
for(int plays = 0; plays < 1000000; plays++ )
{
int[] doors = {0,0,0};//0 is a goat, 1 is a car
 
const
var winner = gen.Next(3);
numGames = 1000000; // Number of games to run
doors[winner] = 1; //put a winner in a random door
int choice = gen.Next(3); //pick a door, any door
int shown; //the shown door
do
{
shown = gen.Next(3);
}
while(doors[shown] == 1 || shown == choice); //don't show the winner or the choice
stayWins += doors[choice];//if you won by staying, count it
//the switched (last remaining) door is (3 - choice - shown), because 0+1+2=3
switchWins += doors[3 - choice - shown];
}
 
var
System.Console.Out.Write("Switching wins " + switchWins + " times.");
switchWins, stayWins, plays: Int64;
System.Console.Out.Write("Staying wins " + stayWins + " times.");
doors: array[0..2] of Integer;
}
i, winner, choice, shown: Integer;
begin
switchWins := 0;
stayWins := 0;
 
for plays := 1 to numGames do
begin
 
//0 is a goat, 1 is a car
for i := 0 to 2 do
doors[i] := 0;
 
//put a winner in a random door
winner := Random(3);
doors[winner] := 1;
 
//pick a door, any door
choice := Random(3);
 
//don't show the winner or the choice
repeat
shown := Random(3);
until (doors[shown] <> 1) and (shown <> choice);
 
//if you won by staying, count it
stayWins := stayWins + doors[choice];
 
//the switched (last remaining) door is (3 - choice - shown), because 0+1+2=3
switchWins := switchWins + doors[3 - choice - shown];
end;
 
WriteLn('Staying wins ' + IntToStr(stayWins) + ' times.');
WriteLn('Switching wins ' + IntToStr(switchWins) + ' times.');
end.
</syntaxhighlight>
{{out}}
<pre>Staying wins 333253 times.
Switching wins 666747 times.</pre>
 
=={{header|Dyalect}}==
 
{{trans|C#}}
 
<syntaxhighlight lang="dyalect">var switchWins = 0
var stayWins = 0
for plays in 0..1000000 {
var doors = [0 ,0, 0]
var winner = rnd(max: 3)
doors[winner] = 1
var choice = rnd(max: 3)
var shown = rnd(max: 3)
while doors[shown] == 1 || shown == choice {
shown = rnd(max: 3)
}
stayWins += doors[choice]
switchWins += doors[3 - choice - shown]
}
</lang>
print("Staying wins \(stayWins) times.")
print("Switching wins \(switchWins) times.")</syntaxhighlight>
 
{{out}}
Sample output:
 
<pre>Staying wins 286889 times.
Switching wins 713112 times.</pre>
 
=={{header|EasyLang}}==
{{trans|FreeBASIC}}
<syntaxhighlight>
max = 1000000
for i = 1 to max
car_door = randint 3
chosen_door = randint 3
if car_door <> chosen_door
montys_door = 6 - car_door - chosen_door
else
repeat
montys_door = randint 3
until montys_door <> car_door
.
.
if car_door = chosen_door
stay += 1
.
if car_door = 6 - montys_door - chosen_door
switch += 1
.
.
print "If you stick to your choice, you have a " & stay / max * 100 & " percent chance to win"
print "If you switched, you have a " & switch / max * 100 & " percent chance to win"
</syntaxhighlight>
{{out}}
<pre>
If you stick to your choice, you have a 33.36 percent chance to win
Staying winns: 333830
If you switched, you have a 66.64 percent chance to win
Switching winns: 666170
</pre>
 
=={{header|DEiffel}}==
<syntaxhighlight lang="eiffel">
<lang d>import std.stdio, std.random;
note
description: "[
Monty Hall Problem as an Eiffel Solution
1. Set the stage: Randomly place car and two goats behind doors 1, 2 and 3.
2. Monty offers choice of doors --> Contestant will choose a random door or always one door.
2a. Door has Goat - door remains closed
2b. Door has Car - door remains closed
3. Monty offers cash --> Contestant takes or refuses cash.
3a. Takes cash: Contestant is Cash winner and door is revealed. Car Loser if car door revealed.
3b. Refuses cash: Leads to offer to switch doors.
4. Monty offers door switch --> Contestant chooses to stay or change.
5. Door reveal: Contestant refused cash and did or did not door switch. Either way: Reveal!
6. Winner and Loser based on door reveal of prize.
Car Winner: Chooses car door
Cash Winner: Chooses cash over any door
Goat Loser: Chooses goat door
Car Loser: Chooses cash over car door or switches from car door to goat door
]"
date: "$Date$"
revision: "$Revision$"
 
class
void main() {
MH_APPLICATION
Random gen = Random(unpredictableSeed);
uint switchWins = 0, stayWins = 0;
 
create
while(switchWins + stayWins < 100_000) {
make
uint carPos = dice(gen, 1, 1, 1); // Which door is car behind?
uint pickPos = dice(gen, 1, 1, 1); // Contestant's initial pick.
uint openPos; // Which door is opened by Monty Hall?
 
feature {NONE} -- Initialization
// Monty can't open the door you picked or the one with the car
// behind it.
do {
openPos = dice(gen, 1, 1, 1);
} while(openPos == pickPos || openPos == carPos);
 
make
uint switchPos = 0;
-- Initialize Current.
// Find position that's not currently picked by contestant and was
do
// not opened by Monty already.
play_lets_make_a_deal
for(; pickPos == switchPos || openPos == switchPos; switchPos++) {}
ensure
played_1000_games: game_count = times_to_play
end
 
feature {NONE} -- Implementation: Access
if(pickPos == carPos) {
stayWins++;
} else if(switchPos == carPos) {
switchWins++;
} else {
assert(0); // Can't happen.
}
}
 
live_contestant: attached like contestant
writefln("Switching wins: %d Staying wins: %d", switchWins, stayWins);
-- Attached version of `contestant'
}</lang>
do
if attached contestant as al_contestant then
Result := al_contestant
else
create Result
check not_attached_contestant: False end
end
end
 
contestant: detachable TUPLE [first_door_choice, second_door_choice: like door_number_anchor; takes_cash, switches_door: BOOLEAN]
Output:
-- Contestant for Current.
 
active_stage_door (a_door: like door_anchor): attached like door_anchor
-- Attached version of `a_door'.
do
if attached a_door as al_door then
Result := al_door
else
create Result
check not_attached_door: False end
end
end
 
door_1, door_2, door_3: like door_anchor
-- Doors with prize names and flags for goat and open (revealed).
 
feature {NONE} -- Implementation: Status
 
game_count, car_win_count, cash_win_count, car_loss_count, goat_loss_count, goat_avoidance_count: like counter_anchor
switch_count, switch_win_count: like counter_anchor
no_switch_count, no_switch_win_count: like counter_anchor
-- Counts of games played, wins and losses based on car, cash or goat.
 
feature {NONE} -- Implementation: Basic Operations
 
prepare_stage
-- Prepare the stage in terms of what doors have what prizes.
do
inspect new_random_of (3)
when 1 then
door_1 := door_with_car
door_2 := door_with_goat
door_3 := door_with_goat
when 2 then
door_1 := door_with_goat
door_2 := door_with_car
door_3 := door_with_goat
when 3 then
door_1 := door_with_goat
door_2 := door_with_goat
door_3 := door_with_car
end
active_stage_door (door_1).number := 1
active_stage_door (door_2).number := 2
active_stage_door (door_3).number := 3
ensure
door_has_prize: not active_stage_door (door_1).is_goat or
not active_stage_door (door_2).is_goat or
not active_stage_door (door_3).is_goat
consistent_door_numbers: active_stage_door (door_1).number = 1 and
active_stage_door (door_2).number = 2 and
active_stage_door (door_3).number = 3
end
 
door_number_having_prize: like door_number_anchor
-- What door number has the car?
do
if not active_stage_door (door_1).is_goat then
Result := 1
elseif not active_stage_door (door_2).is_goat then
Result := 2
elseif not active_stage_door (door_3).is_goat then
Result := 3
else
check prize_not_set: False end
end
ensure
one_to_three: between_1_and_x_inclusive (3, Result)
end
 
door_with_car: attached like door_anchor
-- Create a door with a car.
do
create Result
Result.name := prize
ensure
not_empty: not Result.name.is_empty
name_is_prize: Result.name.same_string (prize)
end
 
door_with_goat: attached like door_anchor
-- Create a door with a goat
do
create Result
Result.name := gag_gift
Result.is_goat := True
ensure
not_empty: not Result.name.is_empty
name_is_prize: Result.name.same_string (gag_gift)
is_gag_gift: Result.is_goat
end
 
next_contestant: attached like live_contestant
-- The next contestant on Let's Make a Deal!
do
create Result
Result.first_door_choice := new_random_of (3)
Result.second_door_choice := choose_another_door (Result.first_door_choice)
Result.takes_cash := random_true_or_false
if not Result.takes_cash then
Result.switches_door := random_true_or_false
end
ensure
choices_one_to_three: Result.first_door_choice <= 3 and Result.second_door_choice <= 3
switch_door_implies_no_cash_taken: Result.switches_door implies not Result.takes_cash
end
 
choose_another_door (a_first_choice: like door_number_anchor): like door_number_anchor
-- Make a choice from the remaining doors
require
one_to_three: between_1_and_x_inclusive (3, a_first_choice)
do
Result := new_random_of (3)
from until Result /= a_first_choice
loop
Result := new_random_of (3)
end
ensure
first_choice_not_second: a_first_choice /= Result
result_one_to_three: between_1_and_x_inclusive (3, Result)
end
 
play_lets_make_a_deal
-- Play the game 1000 times
local
l_car_win, l_car_loss, l_cash_win, l_goat_loss, l_goat_avoided: BOOLEAN
do
from
game_count := 0
invariant
consistent_win_loss_counts: (game_count = (car_win_count + cash_win_count + goat_loss_count))
consistent_loss_avoidance_counts: (game_count = (car_loss_count + goat_avoidance_count))
until
game_count >= times_to_play
loop
prepare_stage
contestant := next_contestant
l_cash_win := (live_contestant.takes_cash)
 
l_car_win := (not l_cash_win and
(not live_contestant.switches_door and live_contestant.first_door_choice = door_number_having_prize) or
(live_contestant.switches_door and live_contestant.second_door_choice = door_number_having_prize))
 
l_car_loss := (not live_contestant.switches_door and live_contestant.first_door_choice /= door_number_having_prize) or
(live_contestant.switches_door and live_contestant.second_door_choice /= door_number_having_prize)
 
l_goat_loss := (not l_car_win and not l_cash_win)
 
l_goat_avoided := (not live_contestant.switches_door and live_contestant.first_door_choice = door_number_having_prize) or
(live_contestant.switches_door and live_contestant.second_door_choice = door_number_having_prize)
 
check consistent_goats: l_goat_loss implies not l_goat_avoided end
check consistent_car_win: l_car_win implies not l_car_loss and not l_cash_win and not l_goat_loss end
check consistent_cash_win: l_cash_win implies not l_car_win and not l_goat_loss end
check consistent_goat_avoidance: l_goat_avoided implies (l_car_win or l_cash_win) and not l_goat_loss end
check consistent_car_loss: l_car_loss implies l_cash_win or l_goat_loss end
 
if l_car_win then car_win_count := car_win_count + 1 end
if l_cash_win then cash_win_count := cash_win_count + 1 end
if l_goat_loss then goat_loss_count := goat_loss_count + 1 end
if l_car_loss then car_loss_count := car_loss_count + 1 end
if l_goat_avoided then goat_avoidance_count := goat_avoidance_count + 1 end
 
if live_contestant.switches_door then
switch_count := switch_count + 1
if l_car_win then
switch_win_count := switch_win_count + 1
end
else -- if not live_contestant.takes_cash and not live_contestant.switches_door then
no_switch_count := no_switch_count + 1
if l_car_win or l_cash_win then
no_switch_win_count := no_switch_win_count + 1
end
end
 
 
game_count := game_count + 1
end
print ("%NCar Wins:%T%T " + car_win_count.out +
"%NCash Wins:%T%T " + cash_win_count.out +
"%NGoat Losses:%T%T " + goat_loss_count.out +
"%N-----------------------------" +
"%NTotal Win/Loss:%T%T" + (car_win_count + cash_win_count + goat_loss_count).out +
"%N%N" +
"%NCar Losses:%T%T " + car_loss_count.out +
"%NGoats Avoided:%T%T " + goat_avoidance_count.out +
"%N-----------------------------" +
"%NTotal Loss/Avoid:%T" + (car_loss_count + goat_avoidance_count).out +
"%N-----------------------------" +
"%NStaying Count/Win:%T" + no_switch_count.out + "/" + no_switch_win_count.out + " = " + (no_switch_win_count / no_switch_count * 100).out + " %%" +
"%NSwitch Count/Win:%T" + switch_count.out + "/" + switch_win_count.out + " = " + (switch_win_count / switch_count * 100).out + " %%"
)
end
 
feature {NONE} -- Implementation: Random Numbers
 
last_random: like random_number_anchor
-- The last random number chosen.
 
random_true_or_false: BOOLEAN
-- A randome True or False
do
Result := new_random_of (2) = 2
end
 
new_random_of (a_number: like random_number_anchor): like door_number_anchor
-- A random number from 1 to `a_number'.
do
Result := (new_random \\ a_number + 1).as_natural_8
end
 
new_random: like random_number_anchor
-- Random integer
-- Each call returns another random number.
do
random_sequence.forth
Result := random_sequence.item
last_random := Result
ensure
old_random_not_new: old last_random /= last_random
end
 
random_sequence: RANDOM
-- Random sequence seeded from clock when called.
attribute
create Result.set_seed ((create {TIME}.make_now).milli_second)
end
 
feature {NONE} -- Implementation: Constants
 
times_to_play: NATURAL_16 = 1000
-- Times to play the game.
 
prize: STRING = "Car"
-- Name of the prize
 
gag_gift: STRING = "Goat"
-- Name of the gag gift
 
door_anchor: detachable TUPLE [number: like door_number_anchor; name: STRING; is_goat, is_open: BOOLEAN]
-- Type anchor for door tuples.
 
door_number_anchor: NATURAL_8
-- Type anchor for door numbers.
 
random_number_anchor: INTEGER
-- Type anchor for random numbers.
 
counter_anchor: NATURAL_16
-- Type anchor for counters.
 
feature {NONE} -- Implementation: Contract Support
 
between_1_and_x_inclusive (a_number, a_value: like door_number_anchor): BOOLEAN
-- Is `a_value' between 1 and `a_number'?
do
Result := (a_value > 0) and (a_value <= a_number)
end
 
end
</syntaxhighlight>
{{out}}
<pre>
Car Wins: 177
Switching wins: 66673 Staying wins: 33327
Cash Wins: 486
Goat Losses: 337
-----------------------------
Total Win/Loss: 1000
 
 
Car Losses: 657
Goats Avoided: 343
-----------------------------
Total Loss/Avoid: 1000
-----------------------------
Staying Count/Win: 742/573 = 77.223719676549862 %
Switch Count/Win: 258/90 = 34.883720930232556 %
</pre>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule MontyHall do
def simulate(n) do
{stay, switch} = simulate(n, 0, 0)
:io.format "Staying wins ~w times (~.3f%)~n", [stay, 100 * stay / n]
:io.format "Switching wins ~w times (~.3f%)~n", [switch, 100 * switch / n]
end
defp simulate(0, stay, switch), do: {stay, switch}
defp simulate(n, stay, switch) do
doors = Enum.shuffle([:goat, :goat, :car])
guess = :rand.uniform(3) - 1
[choice] = [0,1,2] -- [guess, shown(doors, guess)]
if Enum.at(doors, choice) == :car, do: simulate(n-1, stay, switch+1),
else: simulate(n-1, stay+1, switch)
end
defp shown(doors, guess) do
[i, j] = Enum.shuffle([0,1,2] -- [guess])
if Enum.at(doors, i) == :goat, do: i, else: j
end
end
 
MontyHall.simulate(10000)</syntaxhighlight>
 
{{out}}
<pre>
Staying wins 3397 times (33.970%)
Switching wins 6603 times (66.030%)
</pre>
 
=={{header|Emacs Lisp}}==
{{trans|Picolisp}}
<syntaxhighlight lang="lisp">(defun montyhall (keep)
(let ((prize (random 3))
(choice (random 3)))
(if keep (= prize choice)
(/= prize choice))))
 
(let ((cnt 0))
(dotimes (i 10000)
(and (montyhall t) (setq cnt (1+ cnt))))
(message "Strategy keep: %.3f%%" (/ cnt 100.0)))
 
(let ((cnt 0))
(dotimes (i 10000)
(and (montyhall nil) (setq cnt (1+ cnt))))
(message "Strategy switch: %.3f%%" (/ cnt 100.0)))</syntaxhighlight>
 
{{out}}
 
Strategy keep: 34.410%
Strategy switch: 66.430%
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
type Prize
enum do int GOAT, CAR end
type Door
model
int id
Prize prize
new by int =id, Prize =prize do end
fun asText = text by block do return "(id:" + me.id + ", prize:" + me.prize.value + ")" end
end
type Player
model
Door choice
fun choose = void by List doors
me.choice = doors[random(3)]
end
end
type Monty
model
fun setPrize = void by List doors, Prize prize
doors[random(3)].prize = prize
end
end
type MontyHallProblem
int ITERATIONS = 1000000
Map counter = text%int[ "keep" => 0, "switch" => 0 ]
writeLine("Simulating " + ITERATIONS + " games:")
for int i = 0; i < ITERATIONS; i++
if i % 100000 == 0 do write(".") end
^|three numbered doors with no cars for now|^
List doors = Door[Door(1, Prize.GOAT), Door(2, Prize.GOAT), Door(3, Prize.GOAT)]
Monty monty = Monty() # set up Monty
monty.setPrize(doors, Prize.CAR) # Monty randomly sets the car behind one door
Player player = Player() # set up the player
player.choose(doors) # the player makes a choice
^|here Monty opens a door with a goat;
|behind the ones that are still closed there is a car and a goat,
|so that the player *always* wins by keeping or switching.
|^
counter[when(player.choice.prize == Prize.CAR, "keep", "switch")]++
end
writeLine()
writeLine(counter)
</syntaxhighlight>
{{out}}
<pre>
Simulating 1000000 games:
..........
[keep:332376,switch:667624]
</pre>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">-module(monty_hall).
 
-export([main/0]).
 
main() ->
random:seed(now()),
{WinStay, WinSwitch} = experiment(100000, 0, 0),
io:format("Switching wins ~p times.\n", [WinSwitch]),
io:format("Staying wins ~p times.\n", [WinStay]).
 
experiment(0, WinStay, WinSwitch) ->
{WinStay, WinSwitch};
experiment(N, WinStay, WinSwitch) ->
Doors = setelement(random:uniform(3), {0,0,0}, 1),
SelectedDoor = random:uniform(3),
OpenDoor = open_door(Doors, SelectedDoor),
experiment(
N - 1,
WinStay + element(SelectedDoor, Doors),
WinSwitch + element(6 - (SelectedDoor + OpenDoor), Doors) ).
 
open_door(Doors,SelectedDoor) ->
OpenDoor = random:uniform(3),
case (element(OpenDoor, Doors) =:= 1) or (OpenDoor =:= SelectedDoor) of
true -> open_door(Doors, SelectedDoor);
false -> OpenDoor
end.
</syntaxhighlight>
Sample Output:
<pre>Switching wins 66595 times.
Staying wins 33405 times.</pre>
 
=={{header|F_Sharp|F#}}==
I don't bother with having Monty "pick" a door, since you only win if you initially pick a loser in the switch strategy and you only win if you initially pick a winner in the stay strategy so there doesn't seem to be much sense in playing around the background having Monty "pick" doors. Makes it pretty simple to see why it's always good to switch.
<syntaxhighlight lang="fsharp">open System
let monty nSims =
let rnd = new Random()
let SwitchGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
if winner <> pick then 1 else 0
 
let StayGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
if winner = pick then 1 else 0
 
let Wins (f:unit -> int) = seq {for i in [1..nSims] -> f()} |> Seq.sum
printfn "Stay: %d wins out of %d - Switch: %d wins out of %d" (Wins StayGame) nSims (Wins SwitchGame) nSims</syntaxhighlight>
Sample Output:
<pre>Stay: 332874 wins out of 1000000 - Switch: 667369 wins out of 1000000</pre>
 
I had a very polite suggestion that I simulate Monty's "pick" so I'm putting in a version that does that. I compare the outcome with my original outcome and, unsurprisingly, show that this is essentially a noop that has no bearing on the output, but I (kind of) get where the request is coming from so here's that version...
<syntaxhighlight lang="fsharp">let montySlower nSims =
let rnd = new Random()
let MontyPick winner pick =
if pick = winner then
[0..2] |> Seq.filter (fun i -> i <> pick) |> Seq.nth (rnd.Next(0,2))
else
3 - pick - winner
let SwitchGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
let monty = MontyPick winner pick
let pickFinal = 3 - monty - pick
 
// Show that Monty's pick has no effect...
 
if (winner <> pick) <> (pickFinal = winner) then
printfn "Monty's selection actually had an effect!"
if pickFinal = winner then 1 else 0
 
let StayGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
let monty = MontyPick winner pick
 
// This one's even more obvious than the above since pickFinal
// is precisely the same as pick
 
let pickFinal = pick
if (winner = pick) <> (winner = pickFinal) then
printfn "Monty's selection actually had an effect!"
if winner = pickFinal then 1 else 0
 
let Wins (f:unit -> int) = seq {for i in [1..nSims] -> f()} |> Seq.sum
printfn "Stay: %d wins out of %d - Switch: %d wins out of %d" (Wins StayGame) nSims (Wins SwitchGame) nSims</syntaxhighlight>
 
=={{header|Forth}}==
 
<lang forth>include random.fs
===version 1===
<syntaxhighlight lang="forth">include random.fs
 
variable stay-wins
Line 818 ⟶ 2,295:
cr switch-wins @ . [char] / emit . ." switching wins" ;
 
1000 trials</langsyntaxhighlight>
 
or in iForth:
 
<langsyntaxhighlight lang="forth">0 value stay-wins
0 value switch-wins
 
Line 835 ⟶ 2,312:
dup 0 ?DO trial LOOP
CR stay-wins DEC. ." / " dup DEC. ." staying wins,"
CR switch-wins DEC. ." / " DEC. ." switching wins." ;</langsyntaxhighlight>
 
With output:
Line 842 ⟶ 2,319:
33336877 / 100000000 staying wins,
66663123 / 100000000 switching wins. ok</pre>
 
===version 2===
{{works with|GNU Forth}}
While Forthers are known (and regarded) for always simplifying the problem, I think version 1 is missing the point here. The optimization can only be done if one already understands the game. For what it's worth, here is a simulation that takes all the turns of the game.
<syntaxhighlight lang="forth">require random.fs
here seed !
 
1000000 constant rounds
variable wins
variable car
variable firstPick
variable revealed
defer applyStrategy
 
: isCar ( u - f ) car @ = ;
: remaining ( u u - u ) 3 swap - swap - ;
: setup 3 random car ! ;
: choose 3 random firstPick ! ;
: otherGoat ( - u ) car @ firstPick @ remaining ;
: randomGoat ( - u ) car @ 1+ 2 random + 3 mod ;
: reveal firstPick @ isCar IF randomGoat ELSE otherGoat THEN revealed ! ;
: keep ( - u ) firstPick @ ;
: switch ( - u ) firstPick @ revealed @ remaining ;
: open ( u - f ) isCar ;
: play ( - f ) setup choose reveal applyStrategy open ;
: record ( f ) 1 and wins +! ;
: run 0 wins ! rounds 0 ?DO play record LOOP ;
: result wins @ 0 d>f rounds 0 d>f f/ 100e f* ;
: .result result f. '%' emit ;
 
' keep IS applyStrategy run ." Keep door => " .result cr
' switch IS applyStrategy run ." Switch door => " .result cr
bye</syntaxhighlight>
 
{{out}}
<pre>
Keep door => 33.2922 %
Switch door => 66.7207 %
</pre>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">PROGRAM MONTYHALL
IMPLICIT NONE
Line 890 ⟶ 2,406:
WRITE(*, "(A,F6.2,A)") "Chance of winning by switching is", real(switchcount)/trials*100, "%"
 
END PROGRAM MONTYHALL</langsyntaxhighlight>
Sample Output
Chance of winning by not switching is 32.82%
Chance of winning by switching is 67.18%
 
=={{header|F_Sharp|F#Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Monty_Hall_problem}}
I don't bother with having Monty "pick" a door, since you only win if you initially pick a loser in the switch strategy and you only win if you initially pick a winner in the stay strategy so there doesn't seem to be much sense in playing around the background having Monty "pick" doors. Makes it pretty simple to see why it's always good to switch.
<lang fsharp>open System
let monty nSims =
let rnd = new Random()
let SwitchGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
if winner <> pick then 1 else 0
 
'''Solution'''
let StayGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
if winner = pick then 1 else 0
 
The following program makes a given number of simulations. On each, three options are evaluated:
let Wins (f:unit -> int) = seq {for i in [1..nSims] -> f()} |> Seq.sum
printfn "Stay: %d wins out of %d - Switch: %d wins out of %d" (Wins StayGame) nSims (Wins SwitchGame) nSims</lang>
I had a very polite suggestion that I simulate Monty's "pick" so I'm putting in a version that does that. I compare the outcome with my original outcome and, unsurprisingly, show that this is essentially a noop that has no bearing on the output, but I (kind of) get where the request is coming from so here's that version...
<lang fsharp>let montySlower nSims =
let rnd = new Random()
let MontyPick winner pick =
if pick = winner then
[0..2] |> Seq.filter (fun i -> i <> pick) |> Seq.nth (rnd.Next(0,2))
else
3 - pick - winner
let SwitchGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
let monty = MontyPick winner pick
let pickFinal = 3 - monty - pick
 
* If the player keeps his/her selection
// Show that Monty's pick has no effect...
* If the player randomly chooses between hs/her selection and the other (closed) door.
* If the player switches his/her selection
 
Finally, it shows the number of wins for each case.
if (winner <> pick) <> (pickFinal = winner) then
printfn "Monty's selection actually had an effect!"
if pickFinal = winner then 1 else 0
 
[[File:Fōrmulæ - Monty Hall problem 01.png]]
let StayGame() =
let winner, pick = rnd.Next(0,3), rnd.Next(0,3)
let monty = MontyPick winner pick
 
[[File:Fōrmulæ - Monty Hall problem 02.png]]
// This one's even more obvious than the above since pickFinal
// is precisely the same as pick
 
[[File:Fōrmulæ - Monty Hall problem 03.png]]
let pickFinal = pick
if (winner = pick) <> (winner = pickFinal) then
printfn "Monty's selection actually had an effect!"
if winner = pickFinal then 1 else 0
 
It can be seen that:
let Wins (f:unit -> int) = seq {for i in [1..nSims] -> f()} |> Seq.sum
 
printfn "Stay: %d wins out of %d - Switch: %d wins out of %d" (Wins StayGame) nSims (Wins SwitchGame) nSims</lang>
* If the player keeps his/her selection, he/she wins around 1/3 of times
* If the player randomly chooses between his/her selection and the other (closed) door, he/she wins around 1/2 of times
* If the player switches his/her selection, he/she wins around 2/3 of times
 
The following variation shows the evolution of the probabilities for each case:
 
[[File:Fōrmulæ - Monty Hall problem 04.png]]
 
[[File:Fōrmulæ - Monty Hall problem 05.png]]
 
[[File:Fōrmulæ - Monty Hall problem 06.png]]
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"math/rand"
"time"
)
 
func main() {
games := 100000
r := rand.New(rand.NewSource(time.Now().UnixNano()))
 
var switcherWins, keeperWins, shown int
for i := 0; i < games; i++ {
doors := []int{0, 0, 0}
doors[r.Intn(3)] = 1 // Set which one has the car
choice := r.Intn(3) // Choose a door
for shown = r.Intn(3); shown == choice || doors[shown] == 1; shown = r.Intn(3) {}
switcherWins += doors[3 - choice - shown]
keeperWins += doors[choice]
}
floatGames := float32(games)
fmt.Printf("Switcher Wins: %d (%3.2f%%)\n",
switcherWins, (float32(switcherWins) / floatGames * 100))
fmt.Printf("Keeper Wins: %d (%3.2f%%)",
keeperWins, (float32(keeperWins) / floatGames * 100))
}</syntaxhighlight>
Output:
<pre>
Switcher Wins: 66542 (66.54%)
Keeper Wins: 33458 (33.46%)
</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import System.Random (StdGen, getStdGen, randomR)
 
trials :: Int
Line 978 ⟶ 2,512:
percent n ++ "% of the time."
percent n = show $ round $
100 * (fromIntegral n) / (fromIntegral trials)</langsyntaxhighlight>
 
{{libheader|mtl}}
With a <tt>State</tt> monad, we can avoid having to explicitly pass around the <tt>StdGen</tt> so often. <tt>play</tt> and <tt>cars</tt> can be rewritten as follows:
 
<langsyntaxhighlight lang="haskell">import Control.Monad.State
 
play :: Bool -> State StdGen Door
Line 1,003 ⟶ 2,537:
cars n switch g = (numcars, new_g)
where numcars = length $ filter (== Car) prize_list
(prize_list, new_g) = runState (replicateM n (play switch)) g</langsyntaxhighlight>
 
Sample output (for either implementation):
<langsyntaxhighlight lang="haskell">The switch strategy succeeds 67% of the time.
The stay strategy succeeds 34% of the time.</langsyntaxhighlight>
 
=={{header|HicEst}}==
<langsyntaxhighlight lang="hicest">REAL :: ndoors=3, doors(ndoors), plays=1E4
 
DLG(NameEdit = plays, DNum=1, Button='Go')
Line 1,041 ⟶ 2,575:
WRITE(ClipBoard, Name) plays, switchWins, stayWins
 
END</langsyntaxhighlight>
<langsyntaxhighlight lang="hicest">! plays=1E3; switchWins=695; stayWins=305;
! plays=1E4; switchWins=6673; stayWins=3327;
! plays=1E5; switchWins=66811; stayWins=33189;
! plays=1E6; switchWins=667167; stayWins=332833;</langsyntaxhighlight>
 
== {{header|Icon}} and {{header|Unicon }}==
<syntaxhighlight lang="icon">procedure main(arglist)
==={{header|Icon}}===
<lang Icon>procedure main(arglist)
 
rounds := integer(arglist[1]) | 10000
Line 1,067 ⟶ 2,600:
write("Strategy 2 'Switching' won ", real(strategy2) / rounds )
 
end</langsyntaxhighlight>
 
Sample Output:<pre>Monty Hall simulation for 10000 rounds.
Line 1,073 ⟶ 2,606:
Strategy 2 'Switching' won 0.6734</pre>
 
==={{header|UniconIo}}===
<syntaxhighlight lang="io">keepWins := 0
This Icon solution works in Unicon.
switchWins := 0
doors := 3
times := 100000
pickDoor := method(excludeA, excludeB,
door := excludeA
while(door == excludeA or door == excludeB,
door = (Random value() * doors) floor
)
door
)
times repeat(
playerChoice := pickDoor()
carDoor := pickDoor()
shownDoor := pickDoor(carDoor, playerChoice)
switchDoor := pickDoor(playerChoice, shownDoor)
(playerChoice == carDoor) ifTrue(keepWins = keepWins + 1)
(switchDoor == carDoor) ifTrue(switchWins = switchWins + 1)
)
("Switching to the other door won #{switchWins} times.\n"\
.. "Keeping the same door won #{keepWins} times.\n"\
.. "Game played #{times} times with #{doors} doors.") interpolate println
</syntaxhighlight>
Sample output:<pre>Switching to the other door won 66935 times.
Keeping the same door won 33065 times.
Game played 100000 times with 3 doors.</pre>
 
=={{header|J}}==
Line 1,080 ⟶ 2,638:
The core of this simulation is picking a random item from a set
 
<langsyntaxhighlight lang="j">pick=: {~ ?@#</langsyntaxhighlight>
 
And, of course, we will be picking from one ofdoor from three doors
 
<langsyntaxhighlight lang="j">DOORS=:1 2 3</langsyntaxhighlight>
 
But note that the simulation code should work just as well with more doors.
Line 1,090 ⟶ 2,648:
Anyways the scenario where the contestant's switch or stay strategy makes a difference is where Monty has picked from the doors which are neither the user's door nor the car's door.
 
<langsyntaxhighlight lang="j">scenario=: ((pick@-.,])pick,pick) bind DOORS</langsyntaxhighlight>
 
(Here, I have decided that the result will be a list of three door numbers. The first number in that list is the number Monty picks, the second number represents the door the user picked, and the third number represents the door where the car is hidden.)
Line 1,096 ⟶ 2,654:
Once we have our simulation test results for the scenario, we need to test if staying would win. In other words we need to test if the user's first choice matches where the car was hidden:
 
<langsyntaxhighlight lang="j">stayWin=: =/@}.</langsyntaxhighlight>
 
In other words: drop the first element from the list representing our test results -- this leaves us with the user's choice and the door where the car was hidden -- and then insert the verb <code>=</code> between those two values.
 
We also need to test if switching would win. In other words, we need to test if the user would pick the car from the doors other than the one Monty picked and the one the user originally picked:
 
<langsyntaxhighlight lang="j">switchWin=: pick@(DOORS -. }:) = {:</langsyntaxhighlight>
 
In other words, start with our list of all doors and then remove the door the monty picked and the door the user picked, and then pick one of the remaining doors at random (the pick at random part is only significant if there were originally more than 3 doors) and see if that matches the door where the car is.
 
Finally, we need to run the simulation a thousand times and count how many times each strategy wins:
 
<langsyntaxhighlight lang="j"> +/ (stayWin,switchWin)@scenario"0 i.1000
320 680</langsyntaxhighlight>
 
Or, we could bundle this all up as a defined word. Here, the (optional) left argument "names" the doors and the right argument says how many simulations to run:
 
<langsyntaxhighlight lang="j">simulate=:3 :0
1 2 3 simulate y
:
Line 1,116 ⟶ 2,678:
stayWin=. =/@}.
switchWin=. pick@(x -. }:) = {:
r=.(stayWin,switchWin)@scenario"0 i.1000y
labels=. ];.2 'limit stay switch '
smoutput labels,.":"0 y,+/r
)</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight lang="j"> simulate 1000
limit 1000
stay 304
switch 696 </langsyntaxhighlight>
 
Or, with more doors (and assuming this does not require new behaviorsrules fromabout how Monty behaves or how the player behaves):
 
<langsyntaxhighlight lang="j"> 1 2 3 4 simulate 1000
limit 1000
stay 233
switch 388 </langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.util.Random;
public class Monty{
public static void main(String[] args){
Line 1,160 ⟶ 2,722:
System.out.println("Staying wins " + stayWins + " times.");
}
}</langsyntaxhighlight>
Output:
<pre>Switching wins 21924 times.
Staying wins 10844 times.</pre>
 
=={{header|JavaScript}}==
 
===Extensive Solution===
 
This solution can test with n doors, the difference in probability for switching is shown to diminish as the number of doors increases*.
 
<syntaxhighlight lang="javascript">
function montyhall(tests, doors) {
'use strict';
tests = tests ? tests : 1000;
doors = doors ? doors : 3;
var prizeDoor, chosenDoor, shownDoor, switchDoor, chosenWins = 0, switchWins = 0;
// randomly pick a door excluding input doors
function pick(excludeA, excludeB) {
var door;
do {
door = Math.floor(Math.random() * doors);
} while (door === excludeA || door === excludeB);
return door;
}
// run tests
for (var i = 0; i < tests; i ++) {
// pick set of doors
prizeDoor = pick();
chosenDoor = pick();
shownDoor = pick(prizeDoor, chosenDoor);
switchDoor = pick(chosenDoor, shownDoor);
 
// test set for both choices
if (chosenDoor === prizeDoor) {
chosenWins ++;
} else if (switchDoor === prizeDoor) {
switchWins ++;
}
}
// results
return {
stayWins: chosenWins + ' ' + (100 * chosenWins / tests) + '%',
switchWins: switchWins + ' ' + (100 * switchWins / tests) + '%'
};
}
</syntaxhighlight>
 
{{out}}
<syntaxhighlight lang="javascript">
montyhall(1000, 3)
Object {stayWins: "349 34.9%", switchWins: "651 65.1%"}
montyhall(1000, 4)
Object {stayWins: "253 25.3%", switchWins: "384 38.4%"}
montyhall(1000, 5)
Object {stayWins: "202 20.2%", switchWins: "265 26.5%"}
</syntaxhighlight>
 
In the above code/problem version with n doors, only one "losing" door is opened/shown by the show host before the possibility of switch. There is a generalization to the problem in which the show host progressively opens losing doors one by one until two remains. In this case, the win probability of switching increases as the number of door increases. This has been discussed in a [https://www.researchgate.net/publication/262373808_A_generalization_of_the_Monty_Hall_Problem] 2009 article.
 
Slight modification of the script above for modularity inside of HTML.
<syntaxhighlight lang="javascript"><html>
 
<body>
 
<input id="userInputMH" value="1000">
<input id="userInputDoor" value="3">
<br>
<button onclick="montyhall()">Calculate</button>
<p id="firstPickWins"></p>
<p id="switchPickWins"></p>
 
</body>
 
</html>
 
 
<script>
function montyhall() {
var tests = document.getElementById("userInputMH").value;
var doors = document.getElementById("userInputDoor").value;
var prizeDoor, chosenDoor, shownDoor, switchDoor, chosenWins = 0,switchWins = 0;
 
function pick(excludeA, excludeB) {
var door;
do {
door = Math.floor(Math.random() * doors);
} while (door === excludeA || door === excludeB);
return door;
}
 
 
for (var i = 0; i < tests; i++) {
 
prizeDoor = pick();
chosenDoor = pick();
shownDoor = pick(prizeDoor, chosenDoor);
switchDoor = pick(chosenDoor, shownDoor);
 
if (chosenDoor === prizeDoor) {
chosenWins++;
} else if (switchDoor === prizeDoor) {
switchWins++;
}
}
document.getElementById("firstPickWins").innerHTML = 'First Door Wins: ' + chosenWins + ' | ' + (100 * chosenWins / tests) + '%';
document.getElementById("switchPickWins").innerHTML = 'Switched Door Wins: ' + switchWins + ' | ' + (100 * switchWins / tests) + '%';
}
 
</script></syntaxhighlight>
'''Output:'''
<syntaxhighlight lang="javascript">(1000, 3)
First Door Wins: 346 | 34.6%
Switching Door Wins: 654 | 65.4%</syntaxhighlight>
 
===Basic Solution===
 
<!-- http://blog.dreasgrech.com/2011/09/simulating-monty-hall-problem.html -->
<syntaxhighlight lang="javascript">
var totalGames = 10000,
selectDoor = function () {
return Math.floor(Math.random() * 3); // Choose a number from 0, 1 and 2.
},
games = (function () {
var i = 0, games = [];
 
for (; i < totalGames; ++i) {
games.push(selectDoor()); // Pick a door which will hide the prize.
}
 
return games;
}()),
play = function (switchDoor) {
var i = 0, j = games.length, winningDoor, randomGuess, totalTimesWon = 0;
 
for (; i < j; ++i) {
winningDoor = games[i];
randomGuess = selectDoor();
if ((randomGuess === winningDoor && !switchDoor) ||
(randomGuess !== winningDoor && switchDoor))
{
/*
* If I initially guessed the winning door and didn't switch,
* or if I initially guessed a losing door but then switched,
* I've won.
*
* I lose when I initially guess the winning door and then switch,
* or initially guess a losing door and don't switch.
*/
 
totalTimesWon++;
}
}
return totalTimesWon;
};
 
/*
* Start the simulation
*/
 
console.log("Playing " + totalGames + " games");
console.log("Wins when not switching door", play(false));
console.log("Wins when switching door", play(true));
</syntaxhighlight>
 
{{out}}
<syntaxhighlight lang="javascript">
Playing 10000 games
Wins when not switching door 3326
Wins when switching door 6630
</syntaxhighlight>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
Neither the C nor the Go implementations of jq currently provides a PRN generator,
so this entry uses /dev/urandom as an external source of entropy as
follows:
 
<pre>
cat /dev/urandom | tr -cd '0-9' | fold -w 1 | jq -nrf monty-hall.jq
</pre>
 
where monty-hall.jq contains one of the following jq programs.
 
====Basic solution====
This solution is based on the observation: {{quote|If I initially guessed the winning door and didn't switch, or if I initially guessed a losing door but then switched, I've won.}}
 
<syntaxhighlight lang="jq">def rand:
input as $r
| if $r < . then $r else rand end;
 
def logical_montyHall:
. as $games
| {switchWins: 0, stayWins: 0}
| reduce range (0; $games) as $_ (.;
(3|rand) as $car # put car in a random door
| (3|rand) as $choice # choose a door at random
| if $choice == $car then .stayWins += 1
else .switchWins += 1
end )
| "Simulating \($games) games:",
"Staying wins \(.stayWins) times",
"Switching wins \(.switchWins) times\n" ;
 
1e3, 1e6 | logical_montyHall</syntaxhighlight>
 
====Simulation====
{{trans|Kotlin}}
<syntaxhighlight lang="jq">def rand:
input as $r
| if $r < . then $r else rand end;
 
def montyHall:
. as $games
| [range(0;3) | 0 ] as $doors0
| {switchWins: 0, stayWins: 0}
| reduce range (0; $games) as $_ (.;
($doors0 | .[3|rand] = 1) as $doors # put car in a random door
| (3|rand) as $choice # choose a door at random
| .stop = false
| until (.stop;
.shown = (3|rand) # the shown door
| if ($doors[.shown] != 1 and .shown != $choice)
then .stop=true
else .
end)
| .stayWins += $doors[$choice]
| .switchWins += $doors[3 - $choice - .shown]
)
| "Simulating \($games) games:",
"Staying wins \(.stayWins) times",
"Switching wins \(.switchWins) times\n" ;
1e3, 1e6 | montyHall</syntaxhighlight>
{{out}}
<pre>
Simulating 1000 games:
Staying wins 325 times
Switching wins 675 times
 
Simulating 1000000 games:
Staying wins 333253 times
Switching wins 666747 times
</pre>
 
=={{header|Julia}}==
To make things interesting, I decided to generalize the problem to <tt>ncur</tt> doors and <tt>ncar</tt> cars. To allow the MC to always show a goat behind a door after the contestant chooses, <math>ncur-ncar \ge 2</math>.
 
I was was of two minds on the type of simulation to provide, so I wrote two different simulators. The literal simulator mimics the mechanics of the game as literally as possible, shuffling the arrangement of cars behind doors and randomizes all choices. This avoids any feel of cheating but results in rather complex code. The clean simulator implements the game more elegantly but it might look like cheating.
 
'''The Literal Simulation Function'''
<syntaxhighlight lang="julia">using Printf
 
function play_mh_literal{T<:Integer}(ncur::T=3, ncar::T=1)
ncar < ncur || throw(DomainError())
curtains = shuffle(collect(1:ncur))
cars = curtains[1:ncar]
goats = curtains[(ncar+1):end]
pick = rand(1:ncur)
isstickwin = pick in cars
deleteat!(curtains, findin(curtains, pick))
if !isstickwin
deleteat!(goats, findin(goats, pick))
end
if length(goats) > 0 # reveal goat
deleteat!(curtains, findin(curtains, shuffle(goats)[1]))
else # no goats, so reveal car
deleteat!(curtains, rand(1:(ncur-1)))
end
pick = shuffle(curtains)[1]
isswitchwin = pick in cars
return (isstickwin, isswitchwin)
end
</syntaxhighlight>
 
'''The Clean Simulation Function'''
<syntaxhighlight lang="julia">
function play_mh_clean{T<:Integer}(ncur::T=3, ncar::T=1)
ncar < ncur || throw(DomainError())
pick = rand(1:ncur)
isstickwin = pick <= ncar
pick = rand(1:(ncur-2))
if isstickwin # remove initially picked car from consideration
pick += 1
end
isswitchwin = pick <= ncar
return (isstickwin, isswitchwin)
end
</syntaxhighlight>
 
'''Supporting Functions'''
<syntaxhighlight lang="julia">
function mh_results{T<:Integer}(ncur::T, ncar::T,
nruns::T, play_mh::Function)
stickwins = 0
switchwins = 0
for i in 1:nruns
(isstickwin, isswitchwin) = play_mh(ncur, ncar)
if isstickwin
stickwins += 1
end
if isswitchwin
switchwins += 1
end
end
return (stickwins/nruns, switchwins/nruns)
end
 
function mh_analytic{T<:Integer}(ncur::T, ncar::T)
stickodds = ncar/ncur
switchodds = (ncar - stickodds)/(ncur-2)
return (stickodds, switchodds)
end
 
function show_odds{T<:Real}(a::T, b::T)
@sprintf " %.1f %.1f %.2f" 100.0*a 100*b 1.0*b/a
end
 
function show_simulation{T<:Integer}(ncur::T, ncar::T, nruns::T)
println()
print("Simulating a ", ncur, " door, ", ncar, " car ")
println("Monty Hall problem with ", nruns, " runs.\n")
 
println(" Solution Stick Switch Improvement")
 
(a, b) = mh_results(ncur, ncar, nruns, play_mh_literal)
println(@sprintf("%10s: ", "Literal"), show_odds(a, b))
 
(a, b) = mh_results(ncur, ncar, nruns, play_mh_clean)
println(@sprintf("%10s: ", "Clean"), show_odds(a, b))
 
(a, b) = mh_analytic(ncur, ncar)
println(@sprintf("%10s: ", "Analytic"), show_odds(a, b))
println()
return nothing
end
</syntaxhighlight>
 
'''Main'''
<syntaxhighlight lang="julia">
for i in 3:5, j in 1:(i-2)
show_simulation(i, j, 10^5)
end
</syntaxhighlight>
 
This code shows, for a variety of configurations, the results for 3 solutions: literal simulation, clean simulation, analytic. Stick is the percentage of times that the player wins a car by sticking to an initial choice. Switch is the winning percentage the comes with switching one's selection following the goat reveal. Improvement is the ratio of switch to stick.
{{out}}
<pre>
Simulating a 3 door, 1 car Monty Hall problem with 100000 runs.
 
Solution Stick Switch Improvement
Literal: 33.2 66.8 2.02
Clean: 33.4 66.6 2.00
Analytic: 33.3 66.7 2.00
 
 
Simulating a 4 door, 1 car Monty Hall problem with 100000 runs.
 
Solution Stick Switch Improvement
Literal: 25.1 37.5 1.49
Clean: 24.7 37.6 1.52
Analytic: 25.0 37.5 1.50
 
 
Simulating a 4 door, 2 car Monty Hall problem with 100000 runs.
 
Solution Stick Switch Improvement
Literal: 49.7 75.3 1.51
Clean: 49.9 74.9 1.50
Analytic: 50.0 75.0 1.50
 
 
Simulating a 5 door, 1 car Monty Hall problem with 100000 runs.
 
Solution Stick Switch Improvement
Literal: 20.2 26.5 1.31
Clean: 20.0 26.8 1.34
Analytic: 20.0 26.7 1.33
 
 
Simulating a 5 door, 2 car Monty Hall problem with 100000 runs.
 
Solution Stick Switch Improvement
Literal: 40.0 53.5 1.34
Clean: 40.4 53.4 1.32
Analytic: 40.0 53.3 1.33
 
 
Simulating a 5 door, 3 car Monty Hall problem with 100000 runs.
 
Solution Stick Switch Improvement
Literal: 60.3 79.9 1.33
Clean: 59.9 80.1 1.34
Analytic: 60.0 80.0 1.33
</pre>
 
'''Literal versus Clean'''
 
The clean simulation runs significantly faster and uses less memory.
<pre>
julia> @time mh_results(3, 1, 10^5, play_mh_literal)
elapsed time: 0.346965522 seconds (183790752 bytes allocated, 27.56% gc time)
(0.33216,0.66784)
 
julia> @time mh_results(3, 1, 10^5, play_mh_clean)
elapsed time: 0.046481738 seconds (9600160 bytes allocated)
(0.33241,0.66759)
</pre>
=={{header|K}}==
<syntaxhighlight lang="k">
montyhall:{t:,/ 1_ x {`prng@`t[];ch:1?3;pr:1?3;sw:1?2;$[sw;a:ch=pr;a:~(ch=pr)];a}\0N;("KEEP %";(+/t)%x;"SWAP %";(+/~t)%x)}
 
montyhall 100000
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.1.2
 
import java.util.Random
 
fun montyHall(games: Int) {
var switchWins = 0
var stayWins = 0
val rnd = Random()
(1..games).forEach {
val doors = IntArray(3) // all zero (goats) by default
doors[rnd.nextInt(3)] = 1 // put car in a random door
val choice = rnd.nextInt(3) // choose a door at random
var shown: Int
do {
shown = rnd.nextInt(3) // the shown door
}
while (doors[shown] == 1 || shown == choice)
stayWins += doors[choice]
switchWins += doors[3 - choice - shown]
}
println("Simulating $games games:")
println("Staying wins $stayWins times")
println("Switching wins $switchWins times")
}
 
fun main(args: Array<String>) {
montyHall(1_000_000)
}</syntaxhighlight>
Sample output:
{{out}}
<pre>
Simulating 1000000 games:
Staying wins 333670 times
Switching wins 666330 times
</pre>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function playgame(player)
local car = math.random(3)
local pchoice = player.choice()
Line 1,182 ⟶ 3,198:
for i = 1, 20000 do playgame(player) end
print(player.wins)
end</langsyntaxhighlight>
 
=={{header|Lua/Torch}}==
<syntaxhighlight lang="lua">function montyHall(n)
local car = torch.LongTensor(n):random(3) -- door with car
local choice = torch.LongTensor(n):random(3) -- player's choice
local opens = torch.LongTensor(n):random(2):csub(1):mul(2):csub(1) -- -1 or +1
local iscarchoice = choice:eq(car)
local nocarchoice = 1-iscarchoice
opens[iscarchoice] = (((opens + choice - 1) % 3):abs() + 1)[iscarchoice]
opens[nocarchoice] = (6 - car - choice)[nocarchoice]
local change = torch.LongTensor(n):bernoulli() -- 0: stay, 1: change
local win = iscarchoice:long():cmul(1-change) + nocarchoice:long():cmul(change)
return car, choice, opens, change, win
end
 
function montyStats(n)
local car, pchoice, opens, change, win = montyHall(n)
local change_and_win = change [ win:byte()]:sum()/ change :sum()*100
local no_change_and_win = (1-change)[ win:byte()]:sum()/(1-change):sum()*100
local change_and_win_not = change [1-win:byte()]:sum()/ change :sum()*100
local no_change_and_win_not = (1-change)[1-win:byte()]:sum()/(1-change):sum()*100
 
print(string.format(" %9s %9s" , "no change", "change" ))
print(string.format("win %8.4f%% %8.4f%%", no_change_and_win , change_and_win ))
print(string.format("win not %8.4f%% %8.4f%%", no_change_and_win_not, change_and_win_not))
end
 
montyStats(1e7)</syntaxhighlight>
 
Output for 10 million samples:
<pre>
no change change
win 33.3008% 66.6487%
win not 66.6992% 33.3513%</pre>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module CheckIt {
Enum Strat {Stay, Random, Switch}
total=10000
Print $("0.00")
player_win_stay=0
player_win_switch=0
player_win_random=0
For i=1 to total {
Dim doors(1 to 3)=False
doors(Random(1,3))=True
guess=Random(1,3)
Inventory other
for k=1 to 3 {
If k <> guess Then Append other, k
}
If doors(guess) Then {
Mont_Hall_show=other(Random(0,1)!)
} Else {
If doors(other(0!)) Then {
Mont_Hall_show=other(1!)
} Else Mont_Hall_show=other(0!)
Delete Other, Mont_Hall_show
}
Strategy=Each(Strat)
While Strategy {
Select Case Eval(strategy)
Case Random
{
If Random(1,2)=1 Then {
If doors(guess) Then player_win_Random++
} else If doors(other(0!)) Then player_win_Random++
}
Case Switch
If doors(other(0!)) Then player_win_switch++
Else
If doors(guess) Then player_win_stay++
End Select
}
}
Print "Stay: ";player_win_stay/total*100;"%"
Print "Random: ";player_win_Random/total*100;"%"
Print "Switch: ";player_win_switch/total*100;"%"
}
CheckIt
</syntaxhighlight>
{{out}}
<pre>
Stay: 33.39%
Random: 51.00%
Switch: 66.61%
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica"> montyHall[nGames_] :=
Module[{r, winningDoors, firstChoices, nStayWins, nSwitchWins, s},
r := RandomInteger[{1, 3}, nGames];
winningDoors = r;
firstChoices = r;
nStayWins = Count[Transpose[{winningDoors, firstChoices}], {d_, d_}];
nSwitchWins = nGames - nStayWins;
Grid[{{"Strategy", "Wins", "Win %"}, {"Stay", Row[{nStayWins, "/", nGames}], s=N[100 nStayWins/nGames]},
{"Switch", Row[{nSwitchWins, "/", nGames}], 100 - s}}, Frame -> All]]</syntaxhighlight>
 
;Usage:
<syntaxhighlight lang="mathematica">montyHall[100000]</syntaxhighlight>
 
[[File:MontyHall.jpg]]
 
=={{header|MATLAB}}==
<syntaxhighlight lang="matlab">
<lang MATLAB>function montyHall(numDoors,numSimulations)
wins = ceil(3*rand(1e8,1)) - ceil(3*rand(1e8,1))
mprintf('chance to win for staying: %1.6f %%\nchance to win for changing: %1.6f %%', 100*length(wins(wins==0))/length(wins), 100*length(wins(wins<>0))/length(wins))
</syntaxhighlight>
 
OUTPUT:
 
<syntaxhighlight lang="matlab">
chance to win for staying: 33.334694 %
chance to win for changing: 66.665306 %
</syntaxhighlight>
 
<syntaxhighlight lang="matlab">
 
function montyHall(numDoors,numSimulations)
 
assert(numDoors > 2);
Line 1,240 ⟶ 3,376:
disp(sprintf('Switch win percentage: %f%%\nStay win percentage: %f%%\n', [switchedDoors(1)/sum(switchedDoors),stayed(1)/sum(stayed)] * 100));
end</langsyntaxhighlight>
 
Output:
<langsyntaxhighlight MATLABlang="matlab">>> montyHall(3,100000)
Switch win percentage: 66.705972%
Stay win percentage: 33.420062%</langsyntaxhighlight>
 
 
=={{header|MAXScript}}==
<langsyntaxhighlight lang="maxscript">fn montyHall choice switch =
(
doors = #(false, false, false)
Line 1,273 ⟶ 3,408:
iterations = 10000
format ("Stay strategy:%\%\n") (iterate iterations false)
format ("Switch strategy:%\%\n") (iterate iterations true)</langsyntaxhighlight>
Output:
<langsyntaxhighlight lang="maxscript">Stay strategy:33.77%
Switch strategy:66.84%</langsyntaxhighlight>
 
 
=={{header|Modula-2}}==
{{trans|XPL0|<code>CARDINAL</code> (unsigned integer) used instead of integer.}}
{{works with|ADW Modula-2|any (Compile with the linker option ''Console Application'').}}
<syntaxhighlight lang="modula2">
MODULE MontyHallProblem;
 
FROM STextIO IMPORT
WriteLn, WriteString;
FROM RandomNumbers IMPORT
Randomize, Rnd;
FROM SRealIO IMPORT
WriteFixed;
 
CONST
NGames = 10000; (* number of games simulated *)
VAR
NWins, Game: CARDINAL;
 
PROCEDURE IsGameWon(Sw: BOOLEAN): BOOLEAN;
(* Play one game. *)
VAR
Car, Player, Player0, Monty: CARDINAL;
BEGIN
Car := Rnd(3); (* Randomly place car behind a door. *)
Player0 := Rnd(3); (* Player randomly chooses a door. *)
REPEAT
Monty := Rnd(3); (* Monty opens door revealing a goat. *)
UNTIL (Monty <> Car) AND (Monty <> Player0);
IF Sw THEN
(* Player switches to remaining door. *)
REPEAT
Player := Rnd(3);
UNTIL (Player <> Player0) AND (Player <> Monty)
ELSE
Player := Player0 (* Player sticks with original door. *)
END;
RETURN (Player = Car);
END IsGameWon;
 
BEGIN
Randomize(0);
NWins := 0;
FOR Game := 0 TO NGames DO
IF IsGameWon(FALSE) THEN
NWins := NWins + 1
END
END;
WriteString('NOT switching doors wins car in ');
WriteFixed(FLOAT(NWins) / FLOAT(NGames) * 100.0, 1, 4);
WriteString('% of games.');
WriteLn;
NWins := 0;
FOR Game := 0 TO NGames DO
IF IsGameWon(TRUE) THEN
NWins := NWins + 1
END
END;
WriteString('But switching doors wins car in ');
WriteFixed(FLOAT(NWins) / FLOAT(NGames) * 100.0, 1, 4);
WriteString('% of games.');
WriteLn;
END MontyHallProblem.
</syntaxhighlight>
{{out}}(example)
<pre>
NOT switching doors wins car in 33.4% of games.
But switching doors wins car in 66.5% of games.
</pre>
 
=={{header|NetRexx}}==
{{trans|Java}}
{{trans|REXX}}
{{trans|PL/I}}
<syntaxhighlight lang="netrexx">/* NetRexx ************************************************************
* 30.08.2013 Walter Pachl translated from Java/REXX/PL/I
**********************************************************************/
options replace format comments java crossref savelog symbols nobinary
 
doors = create_doors
switchWins = 0
stayWins = 0
shown=0
Loop plays=1 To 1000000
doors=0
r=r3()
doors[r]=1
choice = r3()
loop Until shown<>choice & doors[shown]=0
shown = r3()
End
If doors[choice]=1 Then
stayWins=stayWins+1
Else
switchWins=switchWins+1
End
Say "Switching wins " switchWins " times."
Say "Staying wins " stayWins " times."
 
method create_doors static returns Rexx
doors = ''
doors[0] = 0
doors[1] = 0
doors[2] = 0
return doors
 
method r3 static
rand=random()
return rand.nextInt(3) + 1</syntaxhighlight>
Output
<pre>
Switching wins 667335 times.
Staying wins 332665 times.
</pre>
 
=={{header|Nim}}==
{{trans|Python}}
<syntaxhighlight lang="nim">import random
 
randomize()
 
proc shuffle[T](x: var seq[T]) =
for i in countdown(x.high, 0):
let j = rand(i)
swap(x[i], x[j])
 
# 1 represents a car
# 0 represent a goat
 
var
stay = 0 # amount won if stay in the same position
switch = 0 # amount won if you switch
 
for i in 1..1000:
var lst = @[1,0,0] # one car and two goats
shuffle(lst) # shuffles the list randomly
let ran = rand(2 ) # gets a random number for the random guess
let user = lst[ran] # storing the random guess
del lst, ran # deleting the random guess
 
var huh = 0
for i in lst: # getting a value 0 and deleting it
if i == 0:
del lst, huh # deletes a goat when it finds it
break
inc huh
 
if user == 1: # if the original choice is 1 then stay adds 1
inc stay
 
if lst[0] == 1: # if the switched value is 1 then switch adds 1
inc switch
 
echo "Stay = ",stay
echo "Switch = ",switch</syntaxhighlight>
Output:
<pre>Stay = 337
Switch = 663</pre>
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let trials = 10000
 
type door = Car | Goat
Line 1,307 ⟶ 3,601:
strat (100. *. (float n /. float trials)) in
msg "switch" switch;
msg "stay" stay</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<syntaxhighlight lang="parigp">test(trials)={
my(stay=0,change=0);
for(i=1,trials,
my(prize=random(3),initial=random(3),opened);
while((opened=random(3))==prize | opened==initial,);
if(prize == initial, stay++, change++)
);
print("Wins when staying: "stay);
print("Wins when changing: "change);
[stay, change]
};
 
test(1e4)</syntaxhighlight>
 
Output:
<pre>Wins when staying: 3433
Wins when changing: 6567
%1 = [3433, 6567]</pre>
 
=={{header|Pascal}}==
<syntaxhighlight lang="pascal">program MontyHall;
 
uses
sysutils;
 
const
NumGames = 1000;
 
 
{Randomly pick a door(a number between 0 and 2}
function PickDoor(): Integer;
begin
Exit(Trunc(Random * 3));
end;
 
var
i: Integer;
PrizeDoor: Integer;
ChosenDoor: Integer;
WinsChangingDoors: Integer = 0;
WinsNotChangingDoors: Integer = 0;
begin
Randomize;
for i := 0 to NumGames - 1 do
begin
//randomly picks the prize door
PrizeDoor := PickDoor;
//randomly chooses a door
ChosenDoor := PickDoor;
 
//if the strategy is not changing doors the only way to win is if the chosen
//door is the one with the prize
if ChosenDoor = PrizeDoor then
Inc(WinsNotChangingDoors);
 
//if the strategy is changing doors the only way to win is if we choose one
//of the two doors that hasn't the prize, because when we change we change to the prize door.
//The opened door doesn't have a prize
if ChosenDoor <> PrizeDoor then
Inc(WinsChangingDoors);
end;
 
Writeln('Num of games:' + IntToStr(NumGames));
Writeln('Wins not changing doors:' + IntToStr(WinsNotChangingDoors) + ', ' +
FloatToStr((WinsNotChangingDoors / NumGames) * 100) + '% of total.');
 
Writeln('Wins changing doors:' + IntToStr(WinsChangingDoors) + ', ' +
FloatToStr((WinsChangingDoors / NumGames) * 100) + '% of total.');
 
end.
</syntaxhighlight>
 
Output:
<pre>Num of games:1000
Wins not changing doors:359, 35,9% of total.
Wins changing doors:641, 64,1% of total.</pre>
 
=={{header|Perl}}==
 
<langsyntaxhighlight lang="perl">#! /usr/bin/perl
use strict;
my $trials = 10000;
Line 1,337 ⟶ 3,709:
 
print "Stay win ratio " . (100.0 * $stay/$trials) . "\n";
print "Switch win ratio " . (100.0 * $switch/$trials) . "\n";</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
Modified copy of [[Monty_Hall_problem#Euphoria|Euphoria]]
{{works with|Rakudo|#22 "Thousand Oaks"}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
 
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
This implementation is parametric over the number of doors. [[wp:Monty_Hall_problem#Increasing_the_number_of_doors|Increasing the number of doors in play makes the superiority of the switch strategy even more obvious]].
<span style="color: #004080;">integer</span> <span style="color: #000000;">swapWins</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">stayWins</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">winner</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">choice</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">reveal</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">other</span>
 
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<lang perl6>sub remove (@a is rw, Int $i) {
my $temp = @a[$i];
<span style="color: #008080;">for</span> <span style="color: #000000;">game</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1_000_000</span> <span style="color: #008080;">do</span>
@a = @a[0 ..^ $i], @a[$i ^..^ @a];
<span style="color: #000000;">winner</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
return $temp;
<span style="color: #000000;">choice</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
}
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
 
<span style="color: #000000;">reveal</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
enum Prize <Car Goat>;
<span style="color: #008080;">if</span> <span style="color: #000000;">reveal</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">winner</span> <span style="color: #008080;">and</span> <span style="color: #000000;">reveal</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">choice</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
enum Strategy <Stay Switch>;
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
 
<span style="color: #000000;">stayWins</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">choice</span><span style="color: #0000FF;">==</span><span style="color: #000000;">winner</span><span style="color: #0000FF;">)</span>
sub play (Strategy $strategy, Int :$doors = 3) returns Prize {
<span style="color: #000000;">other</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">-</span><span style="color: #000000;">choice</span><span style="color: #0000FF;">-</span><span style="color: #000000;">reveal</span> <span style="color: #000080;font-style:italic;">-- (as 1+2+3=6, and reveal!=choice)</span>
# Call the door with a car behind it door 0. Number the
<span style="color: #000000;">swapWins</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">other</span><span style="color: #0000FF;">==</span><span style="color: #000000;">winner</span><span style="color: #0000FF;">)</span>
# remaining doors starting from 1.
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
my Prize @doors = Car, Goat xx $doors - 1;
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Stay: %,d\nSwap: %,d\nTime: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">stayWins</span><span style="color: #0000FF;">,</span><span style="color: #000000;">swapWins</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)})</span>
# The player chooses a door.
<!--</syntaxhighlight>-->
my Prize $initial_pick = remove @doors, @doors.keys().pick;
{{out}}
# Of the n doors remaining, the host chooses n - 1 that have
<pre>
# goats behind them and opens them, removing them from play.
Stay: 333,292
remove @doors, $_
Swap: 666,708
for pick @doors.elems - 1, grep { @doors[$_] == Goat }, keys @doors;
Time: 0.2s
# If the player stays, they get their initial pick. Otherwise,
</pre>
# they get whatever's behind the remaining door.
return $strategy == Stay ?? $initial_pick !! @doors[0];
}
 
constant TRIALS = 100;
 
for 3, 10 -> $doors {
my %wins;
say "With $doors doors: ";
for Stay, 'Staying', Switch, 'Switching' -> $s, $name {
for ^TRIALS {
++%wins{$s} if play($s, doors => $doors) == Car;
}
say " $name wins ",
round(100*%wins{$s} / TRIALS),
'% of the time.'
}
}</lang>
 
Sample output:
<pre>With 3 doors:
Staying wins 34% of the time.
Switching wins 64% of the time.
With 10 doors:
Staying wins 14% of the time.
Switching wins 94% of the time.</pre>
 
A hundred trials generally isn't enough to get good numbers, but as of release #22, Rakudo is quite slow and may segfault while executing a long-running program.
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?php
function montyhall($iterations){
$switch_win = 0;
Line 1,420 ⟶ 3,765:
montyhall(10000);
?></langsyntaxhighlight>
Output:
<pre>Iterations: 10000 - Stayed wins: 3331 (33.31%) - Switched wins: 6669 (66.69%)</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">go =>
_ = random2(), % different seed
member(Rounds,[1000,10_000,100_000,1_000_000,10_000_000]),
println(rounds=Rounds),
SwitchWins = 0,
StayWins = 0,
NumDoors = 3,
foreach(_ in 1..Rounds)
Winner = choice(NumDoors),
Choice = choice(NumDoors),
% Shown is not needed for the simulation
% Shown = pick([Door : Door in 1..NumDoors, Door != Winner, Door != Choice]),
if Choice == Winner then
StayWins := StayWins + 1
else
SwitchWins := SwitchWins + 1
end
end,
 
printf("Switch win ratio %0.5f%%\n", 100.0 * SwitchWins/Rounds),
printf("Stay win ratio %0.5f%%\n", 100.0 * StayWins/Rounds),
nl,
fail,
nl.
 
% pick a number from 1..N
choice(N) = random(1,N).
 
pick(L) = L[random(1,L.len)].</syntaxhighlight>
 
{{out}}
<pre>rounds = 1000
Switch win ratio 68.80000%
Stay win ratio 31.20000%
 
rounds = 10000
Switch win ratio 67.25000%
Stay win ratio 32.75000%
 
rounds = 100000
Switch win ratio 66.69700%
Stay win ratio 33.30300%
 
rounds = 1000000
Switch win ratio 66.65520%
Stay win ratio 33.34480%
 
rounds = 10000000
Switch win ratio 66.66641%
Stay win ratio 33.33359%</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de montyHall (Keep)
(let (Prize (rand 1 3) Choice (rand 1 3))
(if Keep # Keeping the first choice?
Line 1,443 ⟶ 3,840:
(do 10000 (and (montyHall NIL) (inc 'Cnt)))
(format Cnt 2) )
" %" )</langsyntaxhighlight>
Output:
<pre>Strategy KEEP -> 33.01 %
Strategy SWITCH -> 67.73 %</pre>
 
=={{header|PL/I}}==
{{trans|Java}}
<syntaxhighlight lang="pli">*process source attributes xref;
ziegen: Proc Options(main);
/* REXX ***************************************************************
* 30.08.2013 Walter Pachl derived from Java
**********************************************************************/
Dcl (switchWins,stayWins) Bin Fixed(31) Init(0);
Dcl doors(3) Bin Fixed(31);
Dcl (plays,r,choice) Bin Fixed(31) Init(0);
Dcl c17 Char(17) Init((datetime()));
Dcl p9 Pic'(9)9' def(c17) pos(5);
i=random(p9);
Do plays=1 To 1000000;
doors=0;
r=r3();
doors(r)=1;
choice=r3();
Do Until(shown^=choice & doors(shown)=0);
shown=r3();
End;
If doors(choice)=1 Then
stayWins+=1;
Else
switchWins+=1;
End;
Put Edit("Switching wins ",switchWins," times.")(Skip,a,f(6),a);
Put Edit("Staying wins ",stayWins ," times.")(Skip,a,f(6),a);
 
r3: Procedure Returns(Bin Fixed(31));
/*********************************************************************
* Return a random integer: 1, 2, or 3
*********************************************************************/
Dcl r Bin Float(53);
Dcl res Bin Fixed(31);
r=random();
res=(r*3)+1;
Return(res);
End;
End;</syntaxhighlight>
Output:
<pre>
Switching wins 665908 times.
Staying wins 334092 times.
</pre>
 
=={{header|PostScript|Post Script}}==
Use ghostscript or print this to a postscript printer
 
<syntaxhighlight lang="postscript">%!PS
<lang PostScript>%!PS
/Courier % name the desired font
20 selectfont % choose the size in points and establish
Line 1,486 ⟶ 3,929:
 
 
showpage % print all on the page</langsyntaxhighlight>
 
Sample output:
Line 1,494 ⟶ 3,937:
</pre>
 
=={{header|PowershellPowerShell}}==
<langsyntaxhighlight Powershelllang="powershell">#Declaring variables
$intIterations = 10000
$intKept = 0
Line 1,548 ⟶ 3,991:
Write-Host "Keep : $intKept ($($intKept/$intIterations*100)%)"
Write-Host "Switch: $intSwitched ($($intSwitched/$intIterations*100)%)"
Write-Host ""</langsyntaxhighlight>
Output:
<pre>Results through 10000 iterations:
Line 1,554 ⟶ 3,997:
Switch: 6664 (66.64%)</pre>
 
=={{header|PureBasicProlog}}==
{{works with|GNU Prolog}}
<lang PureBasic>Structure wins
<syntaxhighlight lang="prolog">
stay.i
:- initialization(main).
redecide.i
EndStructure
 
% Simulate a play.
#goat = 0
play(Switch, Won) :-
#car = 1
% Random prize door
Procedure MontyHall(*results.wins)
Dim Doors random(21, 4, P),
Doors(Random(2)) = #car
 
player = % Random(2) contestant door
random(1, 4, C),
Select Doors(player)
Case #car
*results\redecide + #goat
*results\stay + #car
Case #goat
*results\redecide + #car
*results\stay + #goat
EndSelect
EndProcedure
OpenConsole()
#Tries = 1000000
Define results.wins
 
% Random reveal door, not prize or contestant door
For i = 1 To #Tries
repeat,
MontyHall(@results)
random(1, 4, R),
Next
R \= P,
R \= C,
PrintN("Trial runs for each option: " + Str(#Tries))
!,
PrintN("Wins when redeciding: " + Str(results\redecide) + " (" + StrD(results\redecide / #Tries * 100, 2) + "% chance)")
PrintN("Wins when sticking: " + Str(results\stay) + " (" + StrD(results\stay / #Tries * 100, 2) + "% chance)")
Input()</lang>
 
% Final door
Output:<pre>Trial runs for each option: 1000000
(
Wins when redeciding: 666459 (66.65% chance)
Switch, between(1, 3, F), F \= C, F \= R, !;
Wins when sticking: 333541 (33.35% chance)</pre>
\+ Switch, F = C
),
 
% Check result.
(F = P -> Won = true ; Won = false).
 
% Count wins.
win_count(0, _, Total, Total).
 
win_count(I, Switch, A, Total) :-
I > 0,
I1 is I - 1,
play(Switch, Won),
(Won, A1 is A + 1;
\+ Won, A1 is A),
win_count(I1, Switch, A1, Total).
 
main :-
randomize,
win_count(1000, true, 0, SwitchTotal),
format('Switching wins ~d out of 1000.\n', [SwitchTotal]),
win_count(1000, false, 0, StayTotal),
format('Staying wins ~d out of 1000.\n', [StayTotal]).
</syntaxhighlight>
{{out}}
<pre>
Switching wins 667 out of 1000.
Staying wins 332 out of 1000.
</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">'''
I could understand the explanation of the Monty Hall problem
but needed some more evidence
Line 1,640 ⟶ 4,095:
print sum(monty_hall(randrange(3), switch=True)
for x in range(iterations)),
print "out of", iterations, "times.\n"</langsyntaxhighlight>
Sample output:
<pre>Monty Hall problem simulation:
Line 1,648 ⟶ 4,103:
Switching allows you to win 66529 out of 100000 times.</pre>
 
=={{header|R}}==
 
<lang r># Since R is a vector based language that penalizes for loops, we will avoid
# for-loops, instead using "apply" statement variants (like "map" in other
# functional languages).
 
===Python 3 version: ===
set.seed(19771025) # set the seed to set the same results as this code
Another (simpler in my opinion), way to do this is below, also in python 3:
<syntaxhighlight lang="python">import random
#1 represents a car
#0 represent a goat
 
stay = 0 #amount won if stay in the same position
switch = 0 # amount won if you switch
 
for i in range(1000):
lst = [1,0,0] # one car and two goats
random.shuffle(lst) # shuffles the list randomly
ran = random.randrange(3) # gets a random number for the random guess
 
user = lst[ran] #storing the random guess
 
del(lst[ran]) # deleting the random guess
 
huh = 0
for i in lst: # getting a value 0 and deleting it
if i ==0:
del(lst[huh]) # deletes a goat when it finds it
break
huh+=1
if user ==1: # if the original choice is 1 then stay adds 1
stay+=1
if lst[0] == 1: # if the switched value is 1 then switch adds 1
switch+=1
 
print("Stay =",stay)
print("Switch = ",switch)
#Done by Sam Witton 09/04/2014</syntaxhighlight>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ $ "bigrat.qky" loadfile ] now!
[ 0 ( number of cars when not changing choice )
0 ( number of cars when changing choice )
rot times
[ 3 random ( door with goat )
3 random ( contestant's choice )
= ( If the two numbers are equal then the contestant
wins a car if they change their mind, and they win
a goat if they don't change their mind. The wins
are reversed if the numbers are not equal. )
if dip 1+ ] ( increment the relevant count )
say "Strategy A is that the contestant changes their mind." cr
say "Strategy B is that the contestant does not their mind." cr
say "Approximate ratio of car wins with strategy A over strategy B: "
swap 100 round
vulgar$ echo$ cr ] is trials ( n --> )</syntaxhighlight>
 
{{out}}
Running the simulation in the Quackery shell.
<pre>/O> 1000 trials
...
Strategy A is that the contestant changes their mind.
Strategy B is that the contestant does not their mind.
Approximate ratio of car wins with strategy A over strategy B: 15/8
 
Stack empty.
 
/O> 1000000 trials
...
Strategy A is that the contestant changes their mind.
Strategy B is that the contestant does not their mind.
Approximate ratio of car wins with strategy A over strategy B: 2/1
 
Stack empty.
</pre>
 
From this we can conclude that strategy B is preferable, as goats are the GOAT!
 
=={{header|R}}==
 
<syntaxhighlight lang="rsplus">set.seed(19771025) # set the seed to set the same results as this code
N <- 10000 # trials
true_answers <- sample(1:3, N, replace=TRUE)
Line 1,711 ⟶ 4,242:
change <- runif(N) >= .5
random_switch[change] <- other_door[change]
summary(random_switch == true_answers)</langsyntaxhighlight>
 
 
Line 1,775 ⟶ 4,306:
</pre>
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
#lang racket
 
(define (get-last-door a b) ; assumes a != b
(vector-ref '#(- 2 1
2 - 0
1 0 -)
(+ a (* 3 b))))
 
(define (run-game strategy)
(define car-door (random 3))
(define first-choice (random 3))
(define revealed-goat
(if (= car-door first-choice)
(let ([r (random 2)]) (if (<= car-door r) (add1 r) r)) ; random
(get-last-door car-door first-choice))) ; reveal goat
(define final-choice (strategy first-choice revealed-goat))
(define win? (eq? final-choice car-door))
;; (printf "car: ~s\nfirst: ~s\nreveal: ~s\nfinal: ~s\n => ~s\n\n"
;; car-door first-choice revealed-goat final-choice
;; (if win? 'win 'lose))
win?)
 
(define (keep-choice first-choice revealed-goat)
first-choice)
 
(define (change-choice first-choice revealed-goat)
(get-last-door first-choice revealed-goat))
 
(define (test-strategy strategy)
(define N 10000000)
(define wins (for/sum ([i (in-range N)]) (if (run-game strategy) 1 0)))
(printf "~a: ~a%\n"
(object-name strategy)
(exact->inexact (/ wins N 1/100))))
 
(for-each test-strategy (list keep-choice change-choice))
</syntaxhighlight>
 
Sample Output:
<pre>
keep-choice: 33.33054%
change-choice: 66.67613%
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.09}}
This implementation is parametric over the number of doors. [[wp:Monty_Hall_problem#Increasing_the_number_of_doors|Increasing the number of doors in play makes the superiority of the switch strategy even more obvious]].
 
<syntaxhighlight lang="raku" line>enum Prize <Car Goat>;
enum Strategy <Stay Switch>;
sub play (Strategy $strategy, Int :$doors = 3) returns Prize {
# Call the door with a car behind it door 0. Number the
# remaining doors starting from 1.
my Prize @doors = flat Car, Goat xx $doors - 1;
# The player chooses a door.
my Prize $initial_pick = @doors.splice(@doors.keys.pick,1)[0];
# Of the n doors remaining, the host chooses n - 1 that have
# goats behind them and opens them, removing them from play.
while @doors > 1 {
@doors.splice($_,1)
when Goat
given @doors.keys.pick;
}
# If the player stays, they get their initial pick. Otherwise,
# they get whatever's behind the remaining door.
return $strategy === Stay ?? $initial_pick !! @doors[0];
}
constant TRIALS = 10_000;
for 3, 10 -> $doors {
my atomicint @wins[2];
say "With $doors doors: ";
for Stay, 'Staying', Switch, 'Switching' -> $s, $name {
(^TRIALS).race.map: {
@wins[$s]⚛++ if play($s, doors => $doors) == Car;
}
say " $name wins ",
round(100*@wins[$s] / TRIALS),
'% of the time.'
}
}</syntaxhighlight>
{{out}}
<pre>With 3 doors:
Staying wins 34% of the time.
Switching wins 66% of the time.
With 10 doors:
Staying wins 10% of the time.
Switching wins 90% of the time.</pre>
 
=={{header|REXX}}==
===version 1===
{{trans|Java}}
<syntaxhighlight lang="rexx">/* REXX ***************************************************************
* 30.08.2013 Walter Pachl derived from Java
**********************************************************************/
Call time 'R'
switchWins = 0;
stayWins = 0
Do plays = 1 To 1000000
doors.=0
r=r3()
doors.r=1
choice = r3()
Do Until shown<>choice & doors.shown=0
shown = r3()
End
If doors.choice=1 Then
stayWins=stayWins+1
Else
switchWins=switchWins+1
End
Say "Switching wins " switchWins " times."
Say "Staying wins " stayWins " times."
Say 'REXX:' time('E') 'seconds'
Call time 'R'
'ziegen'
Say 'PL/I:' time('E') 'seconds'
Say ' '
Call time 'R'
'java ziegen'
Say 'NetRexx:' time('E') 'seconds'
Exit
r3: Return random(2)+1</syntaxhighlight>
Output for 1000000 samples:
<pre>
Switching wins 666442 times.
Staying wins 333558 times.
REXX: 4.321000 seconds
 
Switching wins 665908 times.
Staying wins 334092 times.
PL/I: 0.328000 seconds
 
Switching wins 667335 times.
Staying wins 332665 times.
NetRexx: 2.042000 seconds
</pre>
 
From the Rosetta Code:Village Pump/Run times on examples?
 
As per Michael Mol about showing timings for program execution times:
::* Discouraging timing comparisons between different languages.
::* Allowing detailed timings, if someone wants to, in the talk pages.
::* But generally - like now, leaving them out.
 
===version 2===
<syntaxhighlight lang="rexx">/*REXX program simulates any number of trials of the classic TV show Monty Hall problem.*/
parse arg # seed . /*obtain the optional args from the CL.*/
if #=='' | #=="," then #= 1000000 /*Not specified? Then 1 million trials*/
if datatype(seed, 'W') then call random ,, seed /*Specified? Use as a seed for RANDOM.*/
wins.= 0 /*wins.0 ≡ stay, wins.1 ≡ switching.*/
do #; door. = 0 /*initialize all doors to a value of 0.*/
car= random(1, 3); door.car= 1 /*the TV show hides a car randomly. */
?= random(1, 3); _= door.? /*the contestant picks a (random) door.*/
wins._ = wins._ + 1 /*bump count of type of win strategy.*/
end /*#*/ /* [↑] perform the loop # times. */
/* [↑] door values: 0≡goat 1≡car */
say 'switching wins ' format(wins.0 / # * 100, , 1)"% of the time."
say ' staying wins ' format(wins.1 / # * 100, , 1)"% of the time." ; say
say 'performed ' # " times with 3 doors." /*stick a fork in it, we're all done. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
switching wins 66.7% of the time.
staying wins 33.3% of the time.
 
performed 1000000 times with 3 doors.
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
total = 10000
swapper = 0
sticker = 0
revealdoor = 0
for trial = 1 to total
prizedoor = random(3) + 1
guessdoor = random(3) + 1
if prizedoor = guessdoor
revealdoor = random(2) + 1
if prizedoor = 1 revealdoor += 1 ok
if (prizedoor = 2 and revealdoor = 2) revealdoor = 3 ok
else
revealdoor = (prizedoor ^ guessdoor)
ok
stickdoor = guessdoor
swapdoor = (guessdoor ^ revealdoor)
if stickdoor = prizedoor sticker += 1 ok
if swapdoor = prizedoor swapper += 1 ok
next
see "after a total of " + total + " trials," + nl
see "the 'sticker' won " + sticker + " times (" + floor(sticker/total*100) + "%)" + nl
see "the 'swapper' won " + swapper + " times (" + floor(swapper/total*100) + "%)" + nl
</syntaxhighlight>
Output:
<pre>
after a total of 10000 trials,
the 'sticker' won 2461 times (24%)
the 'swapper' won 7539 times (75%)
</pre>
 
=={{header|Ruby}}==
 
<langsyntaxhighlight lang="ruby">n = 10_000 #number of times to play
 
stay = switch = 0 #sum of each strategy's wins
Line 1,785 ⟶ 4,525:
#the doors reveal 2 goats and a car
doors = [ :goat , :goat , :goatcar ].shuffle
doors[rand(3)] = :car
#random guess
Line 1,794 ⟶ 4,533:
begin shown = rand(3) end while shown == guess || doors[shown] == :car
#staying with the initial guess wins if the initial doors[guess] is the== :car
stay += 1#staying with the initial guess wins if doors[the initial guess] ==is the :car
stay += 1
else
#switching guesses wins if the unshown door is the car
#switching guesses wins if the unshown door is the car
switch += 1 if doors[3-guess-shown] == :car
switch += 1
end
end
 
puts "Staying wins %.2f%% of the time." % (100.0 * stay / n)
puts "Switching wins %.2f%% of the time." % (100.0 * switch / n)</langsyntaxhighlight>
Sample Output:
<pre>Staying wins 33.84% of the time.
Switching wins 66.16% of the time.</pre>
 
=={{header|Rust}}==
{{libheader|rand}}
<syntaxhighlight lang="rust">extern crate rand;
use rand::Rng;
use rand::seq::SliceRandom;
 
#[derive(Clone, Copy, PartialEq)]
enum Prize {Goat , Car}
 
const GAMES: usize = 3_000_000;
fn main() {
let mut switch_wins = 0;
let mut rng = rand::thread_rng();
for _ in 0..GAMES {
let mut doors = [Prize::Goat; 3];
*doors.choose_mut(&mut rng).unwrap() = Prize::Car;
 
// You only lose by switching if you pick the car the first time
if doors.choose(&mut rng).unwrap() != &Prize::Car {
switch_wins += 1;
}
}
println!("I played the game {total} times and won {wins} times ({percent}%).",
total = GAMES,
wins = switch_wins,
percent = switch_wins as f64 / GAMES as f64 * 100.0
);
}</syntaxhighlight>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">import scala.util.Random
 
object MontyHallSimulation {
Line 1,841 ⟶ 4,612:
switchStrategyWins, percent(switchStrategyWins)))
}
}</langsyntaxhighlight>
 
Sample:
Line 1,852 ⟶ 4,623:
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">(define (random-from-list list) (list-ref list (random (length list))))
(define (random-permutation list)
(if (null? list)
Line 1,921 ⟶ 4,692:
;; > (compare-strategies 1000000)
;; (stay-strategy won with probability 33.3638 %
;; and switch-strategy won with probability 66.716 %)</langsyntaxhighlight>
 
=={{header|Scilab}}==
{{incorrect|scilab|Several syntax and logical errors: switch is a keyword, the variable a is never used, and in the result the sum does not yield 100000 (which is logical since both result are taken from different random samples, but they should not). Also some useless complexity: the nested if can be simplified with logical operators.}}
 
<syntaxhighlight lang="text">// How it works:
// MontyHall() is a function with argument switch:
// it will be called 100000 times with switch=%T,
// and another 100000 times with switch=%F
 
function win=MontyHall(switch) //If switch==%T the player will switch
doors=zeros(1,3) //All goats
car=grand(1,1,'uin',1,3)
a(car)=1 //Place a car somewher
pick=grand(1,1,'uin',1,3) //The player picks...
if pick==car then //If the player picks right...
if switch==%T then //...and switches he will be wrong
win=%F
else //...but if he doesn't, he will be right
win=%T
end
else //If the player picks a goat...
if switch==%T then //...and switches: the other door with the goat shall be
win=%T // opened: the player will switch to the car and win
else //...but if he doesn't, he will remain by his goat
win=%F
end
end
endfunction
 
wins_switch=0
wins_stay=0
games=100000
for i=1:games
if MontyHall(%T)==%T then
wins_switch=wins_switch+1
end
if MontyHall(%F)==%T then
wins_stay=wins_stay+1
end
end
disp("Switching, one wins"+ascii(10)+string(wins_switch)+" games out of "+string(games))
disp("Staying, one wins"+ascii(10)+string(wins_stay)+" games out of "+string(games))</syntaxhighlight>
 
Output:
 
<pre>
Switching, one wins
66649 games out of 100000
Staying, one wins
33403 games out of 100000
</pre>
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const proc: main is func
local
var integer: switchWins is 0;
var integer: stayWins is 0;
var integer: winner is 0;
var integer: choice is 0;
var integer: shown is 0;
var integer: plays is 0;
begin
for plays range 1 to 10000 do
winner := rand(1, 3);
choice := rand(1, 3);
repeat
shown := rand(1, 3)
until shown <> winner and shown <> choice;
stayWins +:= ord(choice = winner);
switchWins +:= ord(6 - choice - shown = winner);
end for;
writeln("Switching wins " <& switchWins <& " times");
writeln("Staying wins " <& stayWins <& " times");
end func;</syntaxhighlight>
 
Output:
<pre>
Switching wins 6654 times
Staying wins 3346 times
</pre>
 
=={{header|SETL}}==
<syntaxhighlight lang="setl">program monty_hall;
setrandom(0);
 
n_simulations := 100000;
print('Chance to win:');
print('When switching doors:', win_chance(true, n_simulations) * 100, '%');
print('When not switching doors:', win_chance(false, n_simulations) * 100, '%');
 
proc win_chance(switch, n_simulations);
wins := 0;
loop for i in [1..n_simulations] do
wins +:= if simulate(switch) then 1 else 0 end;
end loop;
return wins / n_simulations;
end proc;
 
proc simulate(switch);
doors := {1, 2, 3};
car := random doors;
goats := doors less car;
choice := random doors;
opened := random (goats less choice);
 
if switch then
choice := arb (doors less choice less opened);
end if;
return choice = car;
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>Chance to win:
When switching doors: 66.584 %
When not switching doors: 33.093 %</pre>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">var n = 1000 # number of times to play
var switchWins = (var stayWins = 0) # sum of each strategy's wins
 
n.times { # play the game n times
var prize = pick(^3)
var chosen = pick(^3)
 
var show;
do {
show = pick(^3)
} while (show ~~ [chosen, prize])
 
given(chosen) {
when (prize) { stayWins += 1 }
when ([3 - show - prize]) { switchWins += 1 }
default { die "~ error ~" }
}
}
 
say ("Staying wins %.2f%% of the time." % (100.0 * stayWins / n))
say ("Switching wins %.2f%% of the time." % (100.0 * switchWins / n))</syntaxhighlight>
{{out}}
<pre>
Staying wins 31.20% of the time.
Switching wins 68.80% of the time.
</pre>
 
=={{header|SPAD}}==
{{works with|FriCAS, OpenAxiom, Axiom}}
<syntaxhighlight lang="spad">
montyHall(n) ==
wd:=[1+random(3) for j in 1..n]
fc:=[1+random(3) for j in 1..n]
st:=reduce(_+,[1 for j in 1..n | wd.j=fc.j])
p:=(st/n)::DoubleFloat
FORMAT(nil,"stay: ~A, switch: ~A",p,1-p)$Lisp
</syntaxhighlight>
Domain:[http://fricas.github.io/api/Integer.html?highlight=random Integer]
 
{{out}}
<pre>
(1) -> montyHall(1000)
Compiling function montyHall with type PositiveInteger ->
SExpression
 
(1) stay: 0.319, switch: 0.681
Type: SExpression
(2) -> montyHall(10000)
 
(2) stay: 0.3286, switch: 0.6714
Type: SExpression
(3) -> montyHall(100000)
 
(3) stay: 0.33526, switch: 0.66474
Type: SExpression
</pre>
 
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "monty" )
@( description, "Run random simulations of the Monty Hall game. Show the" )
@( description, "effects of a strategy of the contestant always keeping" )
@( description, "his first guess so it can be contrasted with the" )
@( description, "strategy of the contestant always switching his guess." )
@( description, "Simulate at least a thousand games using three doors" )
@( description, "for each strategy and show the results in such a way as" )
@( description, "to make it easy to compare the effects of each strategy." )
@( see_also, "http://rosettacode.org/wiki/Monty_Hall_problem" )
@( author, "Ken O. Burtch" );
pragma license( unrestricted );
 
pragma restriction( no_external_commands );
 
procedure monty is
num_iterations : constant positive := 100_000;
type action_type is (stay, switch);
type prize_type is (goat, pig, car);
doors : array(1..3) of prize_type;
type door_index is new positive;
 
-- place the prizes behind random doors
 
procedure set_prizes is
begin
doors( 1 ) := goat;
doors( 2 ) := pig;
doors( 3 ) := car;
arrays.shuffle( doors );
end set_prizes;
 
-- determine if the prize was chosen based on strategy
 
function play( action : action_type ) return prize_type is
chosen : door_index := door_index( numerics.rnd(3) );
monty : door_index;
begin
set_prizes;
for i in arrays.first(doors)..arrays.last(doors) loop
if i /= chosen and doors(i) /= car then
monty := i;
end if;
end loop;
if action = switch then
for i in arrays.first(doors)..arrays.last(doors) loop
if i /= monty and i /= chosen then
chosen := i;
exit;
end if;
end loop;
end if;
return doors( chosen );
end play;
 
winners : natural; -- times won
pct : float; -- percentage won
 
begin
winners := 0;
for i in 1..num_iterations loop
if play( stay ) = car then
winners := @+1;
end if;
end loop;
pct := float( winners * 100 ) / float( num_iterations );
put( "Stay: count" ) @ ( winners ) @ ( " = " ) @ ( pct ) @ ( "%" );
new_line;
winners := 0;
for i in 1..num_iterations loop
if play( switch ) = car then
winners := @+1;
end if;
end loop;
pct := float( winners * 100 ) / float( num_iterations );
put( "Switch: count" ) @ ( winners ) @ ( " = " ) @ ( pct ) @ ( "%" );
new_line;
end monty;</syntaxhighlight>
 
=={{header|Standard ML}}==
Works with SML/NJ or with MLton using the SML/NJ Util library.
 
<syntaxhighlight lang="standard ml">
val pidint = Word64.toInt(Posix.Process.pidToWord(Posix.ProcEnv.getpid()));
val rand = Random.rand(LargeInt.toInt(Time.toSeconds(Time.now())), pidint);
 
fun stick_win 0 wins = wins
| stick_win trial wins =
let
val winner_door = (Random.randNat rand) mod 3;
val chosen_door = (Random.randNat rand) mod 3;
in
if winner_door = chosen_door then
stick_win (trial-1) (wins+1)
else
stick_win (trial-1) wins
end
 
val trials = 1000000;
val sticks = stick_win trials 0;
val stick_winrate = 100.0 * Real.fromInt(sticks) / Real.fromInt(trials);
(* if you lost by sticking you would have won by swapping *)
val swap_winrate = 100.0 - stick_winrate;
 
(print ("sticking = " ^ Real.toString(stick_winrate) ^ "% win rate\n");
print ("swapping = " ^ Real.toString(swap_winrate) ^ "% win rate\n"));
</syntaxhighlight>
 
'''Output'''
<pre>
sticking = 33.3449% win rate
swapping = 66.6551% win rate
</pre>
 
=={{header|Stata}}==
 
<syntaxhighlight lang="stata">clear
set obs 1000000
gen car=runiformint(1,3)
gen choice1=runiformint(1,3)
gen succ1=car==choice1
gen shown=cond(succ1,runiformint(1,2),6-car-choice1)
replace shown=shown+1 if succ1 & (car==1 | car==shown)
gen choice2=6-shown-choice1
gen succ2=car==choice2
tabstat succ1 succ2, s(mean)</syntaxhighlight>
 
'''Output'''
 
<pre> stats | succ1 succ2
---------+--------------------
mean | .333632 .666368
------------------------------</pre>
 
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
func montyHall(doors: Int = 3, guess: Int, switch: Bool) -> Bool {
guard doors > 2, guess > 0, guess <= doors else { fatalError() }
 
let winningDoor = Int.random(in: 1...doors)
 
return winningDoor == guess ? !`switch` : `switch`
}
 
var switchResults = [Bool]()
 
for _ in 0..<1_000 {
let guess = Int.random(in: 1...3)
let wasRight = montyHall(guess: guess, switch: true)
 
switchResults.append(wasRight)
}
 
let switchWins = switchResults.filter({ $0 }).count
 
print("Switching would've won \((Double(switchWins) / Double(switchResults.count)) * 100)% of games")
print("Not switching would've won \(((Double(switchResults.count - switchWins)) / Double(switchResults.count)) * 100)% of games")</syntaxhighlight>
 
{{out}}
<pre>Switching would've won 66.8% of games
Not switching would've won 33.2% of games</pre>
 
=={{header|Tcl}}==
A simple way of dealing with this one, based on knowledge of the underlying probabilistic system, is to use code like this:
<langsyntaxhighlight lang="tcl">set stay 0; set change 0; set total 10000
for {set i 0} {$i<$total} {incr i} {
if {int(rand()*3) == int(rand()*3)} {
Line 1,934 ⟶ 5,047:
}
puts "Estimate: $stay/$total wins for staying strategy"
puts "Estimate: $change/$total wins for changing strategy"</langsyntaxhighlight>
But that's not really the point of this challenge; it should add the concealing factors too so that we're simulating not just the solution to the game, but also the game itself. (Note that we are using Tcl's lists here to simulate sets.)
 
We include a third strategy that is proposed by some people (who haven't thought much about it) for this game: just picking at random between all the doors offered by Monty the second time round.
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Utility: pick a random item from a list
Line 2,003 ⟶ 5,116:
puts "Estimate: $stay/$total wins for 'staying' strategy"
puts "Estimate: $change/$total wins for 'changing' strategy"
puts "Estimate: $anew/$total wins for 'picking anew' strategy"</langsyntaxhighlight>
This might then produce output like
Estimate: 3340/10000 wins for 'staying' strategy
Line 2,009 ⟶ 5,122:
Estimate: 4960/10000 wins for 'picking anew' strategy
Of course, this challenge could also be tackled by putting up a GUI and letting the user be the source of the randomness. But that's moving away from the letter of the challenge and takes a lot of effort anyway...
 
=={{header|Transact SQL}}==
T-SQL for general case:
<syntaxhighlight lang="transact sql">
---- BEGIN ------------
create table MONTY_HALL(
NOE int,
CAR int,
ALTERNATIVE int,
ORIGIN int,
[KEEP] int,
[CHANGE] int,
[RANDOM] int
)
 
-- INIT
truncate table MONTY_HALL
 
declare @N int , @i int -- No of Experiments and their counter
declare @rooms int , -- number of rooms
@origin int, -- original choice
@car int , -- room with car
@alternative int -- alternative room
 
select @rooms = 3, @N = 100000 , @i = 0
 
-- EXPERIMENTS LOOP
while @i < @N begin
select @car = FLOOR(rand()*@rooms)+1 , @origin = FLOOR(rand()*@rooms)+1
select @alternative = FLOOR(rand()*(@rooms-1))+1
select @alternative = case when @alternative < @origin then @alternative else @alternative + 1 end
select @alternative = case when @origin = @car then @alternative else @car end
 
insert MONTY_HALL
select @i,@car,@alternative,@origin,@origin,@alternative,case when rand() < 5e-1 then @origin else @alternative end
 
select @i = @i + 1
end
 
-- RESULTS
select avg (case when [KEEP] = CAR then 1e0 else 0e0 end )*1e2 as [% OF WINS FOR KEEP],
avg (case when [CHANGE] = CAR then 1e0 else 0e0 end )*1e2 as [% OF WINS FOR CHANGE],
avg (case when [RANDOM] = CAR then 1e0 else 0e0 end )*1e2 as [% OF WINS FOR RANDOM]
from MONTY_HALL
---- END ------------
</syntaxhighlight>
<pre>
% OF WINS FOR KEEP % OF WINS FOR CHANGE % OF WINS FOR RANDOM
---------------------- ---------------------- ----------------------
33.607 66.393 49.938
</pre>
 
=={{header|UNIX Shell}}==
{{works with|bash|2.x| and most bash-compatible unix shells}}
<syntaxhighlight lang="bash">#!/bin/bash
# Simulates the "monty hall" probability paradox and shows results.
# http://en.wikipedia.org/wiki/Monty_Hall_problem
# (should rewrite this in C for faster calculating of huge number of rounds)
# (Hacked up by Éric Tremblay, 07.dec.2010)
 
num_rounds=10 #default number of rounds
num_doors=3 # default number of doors
[ "$1" = "" ] || num_rounds=$[$1+0]
[ "$2" = "" ] || num_doors=$[$2+0]
 
nbase=1 # or 0 if we want to see door numbers zero-based
num_win=0; num_lose=0
 
echo "Playing $num_rounds times, with $num_doors doors."
[ "$num_doors" -lt 3 ] && {
echo "Hey, there has to be at least 3 doors!!"
exit 1
}
echo
 
function one_round() {
winning_door=$[$RANDOM % $num_doors ]
player_picks_door=$[$RANDOM % $num_doors ]
 
# Host leaves this door AND the player's first choice closed, opens all others
# (this WILL loop forever if there is only 1 door)
host_skips_door=$winning_door
while [ "$host_skips_door" = "$player_picks_door" ]; do
#echo -n "(Host looks at door $host_skips_door...) "
host_skips_door=$[$RANDOM % $num_doors]
done
# Output the result of this round
#echo "Round $[$nbase+current_round]: "
echo -n "Player chooses #$[$nbase+$player_picks_door]. "
[ "$num_doors" -ge 10 ] &&
# listing too many door numbers (10 or more) will just clutter the output
echo -n "Host opens all except #$[$nbase+$host_skips_door] and #$[$nbase+$player_picks_door]. " \
|| {
# less than 10 doors, we list them one by one instead of "all except ?? and ??"
echo -n "Host opens"
host_opens=0
while [ "$host_opens" -lt "$num_doors" ]; do
[ "$host_opens" != "$host_skips_door" ] && [ "$host_opens" != "$player_picks_door" ] && \
echo -n " #$[$nbase+$host_opens]"
host_opens=$[$host_opens+1]
done
echo -n " "
}
echo -n "(prize is behind #$[$nbase+$winning_door]) "
echo -n "Switch from $[$nbase+$player_picks_door] to $[$nbase+$host_skips_door]: "
[ "$winning_door" = "$host_skips_door" ] && {
echo "WIN."
num_win=$[num_win+1]
} || {
echo "LOSE."
num_lose=$[num_lose+1]
}
} # end of function one_round
 
# ok, let's go
current_round=0
while [ "$num_rounds" -gt "$current_round" ]; do
one_round
current_round=$[$current_round+1]
done
 
echo
echo "Wins (switch to remaining door): $num_win"
echo "Losses (first guess was correct): $num_lose"
exit 0</syntaxhighlight>
Output of a few runs:
<pre>
$ ./monty_hall_problem.sh
Playing 10 times, with 3 doors.
 
Player chooses #2. Host opens #3 (prize is behind #1) Switch from 2 to 1: WIN.
Player chooses #1. Host opens #3 (prize is behind #2) Switch from 1 to 2: WIN.
Player chooses #2. Host opens #3 (prize is behind #2) Switch from 2 to 1: LOSE.
Player chooses #1. Host opens #2 (prize is behind #1) Switch from 1 to 3: LOSE.
Player chooses #2. Host opens #3 (prize is behind #1) Switch from 2 to 1: WIN.
Player chooses #2. Host opens #1 (prize is behind #2) Switch from 2 to 3: LOSE.
Player chooses #3. Host opens #1 (prize is behind #2) Switch from 3 to 2: WIN.
Player chooses #2. Host opens #1 (prize is behind #3) Switch from 2 to 3: WIN.
Player chooses #1. Host opens #3 (prize is behind #1) Switch from 1 to 2: LOSE.
Player chooses #1. Host opens #2 (prize is behind #3) Switch from 1 to 3: WIN.
 
Wins (switch to remaining door): 6
Losses (first guess was correct): 4
 
 
$ ./monty_hall_problem.sh 5 10
Playing 5 times, with 10 doors.
 
Player chooses #1. Host opens all except #10 and #1. (prize is behind #10) Switch from 1 to 10: WIN.
Player chooses #7. Host opens all except #8 and #7. (prize is behind #8) Switch from 7 to 8: WIN.
Player chooses #6. Host opens all except #1 and #6. (prize is behind #1) Switch from 6 to 1: WIN.
Player chooses #8. Host opens all except #3 and #8. (prize is behind #8) Switch from 8 to 3: LOSE.
Player chooses #6. Host opens all except #5 and #6. (prize is behind #5) Switch from 6 to 5: WIN.
 
Wins (switch to remaining door): 4
Losses (first guess was correct): 1
 
 
$ ./monty_hall_problem.sh 1000
Playing 1000 times, with 3 doors.
 
Player chooses #2. Host opens #1 (prize is behind #2) Switch from 2 to 3: LOSE.
Player chooses #3. Host opens #1 (prize is behind #2) Switch from 3 to 2: WIN.
[ ... ]
Player chooses #1. Host opens #3 (prize is behind #2) Switch from 1 to 2: WIN.
Player chooses #3. Host opens #2 (prize is behind #1) Switch from 3 to 1: WIN.
 
Wins (switch to remaining door): 655
Losses (first guess was correct): 345
</pre>
 
=={{header|Ursala}}==
Line 2,017 ⟶ 5,301:
for the switching strategy.
 
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import flo
Line 2,033 ⟶ 5,317:
#show+
 
main = ~&plrTS/<'stay: ','switch: '> format* <staying_wins,switching_wins></langsyntaxhighlight>
Output will vary slightly for each run due to randomness.
<pre>
Line 2,041 ⟶ 5,325:
 
=={{header|Vedit macro language}}==
{{trans|BASICQuickBASIC}}
 
Vedit macro language does not have random number generator, so one is implemented in subroutine RANDOM (the algorithm was taken from ANSI C library).
<langsyntaxhighlight lang="vedit">#90 = Time_Tick // seed for random number generator
#91 = 3 // random numbers in range 0 to 2
#1 = 0 // wins for "always stay" strategy
Line 2,077 ⟶ 5,361:
#93 = 0x7fffffff % 48271
#90 = (48271 * (#90 % #92) - #93 * (#90 / #92)) & 0x7fffffff
return ((#90 & 0xffff) * #91 / 0x10000)</langsyntaxhighlight>
 
Sample output:
Line 2,083 ⟶ 5,367:
Staying winns: 3354
Switching winns: 6646
</pre>
 
=={{header|V (Vlang)}}==
{{trans|Java}}
<syntaxhighlight lang="v (vlang)">
import rand
 
fn main() {
games := 1_000_000
mut doors := [3]int{}
mut switch_wins, mut stay_wins, mut shown, mut guess := 0, 0, 0, 0
for _ in 1..games + 1 {
doors[rand.int_in_range(0, 3) or {exit(1)}] = 1 // Set which one has the car
guess = rand.int_in_range(0, 3) or {exit(1)} // Choose a door
for doors[shown] == 1 || shown == guess {
shown = rand.int_in_range(0, 3) or {exit(1)} // Shown door
}
stay_wins += doors[guess]
switch_wins += doors[3 - guess - shown]
for clear in 0..3 {if doors[clear] != 0 {doors[clear] = 0}}
}
println("Simulating ${games} games:")
println("Staying wins ${stay_wins} times at ${(f32(stay_wins) / f32(games) * 100):.2}% of games")
println("Switching wins ${switch_wins} times at ${(f32(switch_wins) / f32(games) * 100):.2}% of games")
}
</syntaxhighlight>
 
{{out}}
<pre>
Simulating 1000000 games:
Staying wins 332518 times at 33.25% of games
Switching wins 667482 times at 66.75% of games
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="wren">import "random" for Random
 
var montyHall = Fn.new { |games|
var rand = Random.new()
var switchWins = 0
var stayWins = 0
for (i in 1..games) {
var doors = [0] * 3 // all zero (goats) by default
doors[rand.int(3)] = 1 // put car in a random door
var choice = rand.int(3) // choose a door at random
var shown = 0
while (true) {
shown = rand.int(3) // the shown door
if (doors[shown] != 1 && shown != choice) break
}
stayWins = stayWins + doors[choice]
switchWins = switchWins + doors[3-choice-shown]
}
System.print("Simulating %(games) games:")
System.print("Staying wins %(stayWins) times")
System.print("Switching wins %(switchWins) times")
}
 
montyHall.call(1e6)</syntaxhighlight>
 
{{out}}
Sample output:
<pre>
Simulating 1000000 games:
Staying wins 333970 times
Switching wins 666030 times
</pre>
 
=={{header|X++}}==
<syntaxhighlight lang="x++">//Evidence of the Monty Hall solution in Dynamics AX (by Wessel du Plooy - HiGH Software).
 
int changeWins = 0;
int noChangeWins = 0;
int attempts;
int picked;
int reveal;
int switchdoor;
int doors[];
 
for (attempts = 0; attempts < 32768; attempts++)
{
doors[1] = 0; //0 is a goat, 1 is a car
doors[2] = 0;
doors[3] = 0;
doors[(xGlobal::randomPositiveInt32() mod 3) + 1] = 1; //put a winner in a random door
picked = (xGlobal::randomPositiveInt32() mod 3) + 1; //pick a door, any door
 
do
{
reveal = (xGlobal::randomPositiveInt32() mod 3) + 1;
}
while (doors[reveal] == 1 || reveal == picked); //don't show the winner or the choice
 
if (doors[picked] == 1)
noChangeWins++;
else
changeWins++;
}
 
print strFmt("Switching wins %1 times.", changeWins);
print strFmt("Staying wins %1 times.", noChangeWins);
pause;
</syntaxhighlight>
 
Output:
<pre>Switching wins 21699 times.
Staying wins 11069 times.</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">def NGames = 10000; \number of games simulated
int Game, NWins;
include c:\cxpl\codes;
 
func int IsGameWon(Switch); \Play one game
int Switch;
int Car, Player, Player0, Monty;
[Car:= Ran(3); \randomly place car behind a door
Player0:= Ran(3); \player randomly chooses a door
repeat Monty:= Ran(3); \Monty opens door revealing a goat
until Monty # Car and Monty # Player0;
if Switch then \player switches to remaining door
repeat Player:= Ran(3);
until Player # Player0 and Player # Monty
else Player:= Player0; \player sticks with original door
return Player = Car;
];
 
[Format(2,1);
NWins:= 0;
for Game:= 0 to NGames-1 do
if IsGameWon(false) then NWins:= NWins+1;
Text(0, "NOT switching doors wins car in ");
RlOut(0, float(NWins)/float(NGames)*100.0);
Text(0, "% of games.^M^J");
 
NWins:= 0;
for Game:= 0 to NGames-1 do
if IsGameWon(true) then NWins:= NWins+1;
Text(0, "But switching doors wins car in ");
RlOut(0, float(NWins)/float(NGames)*100.0);
Text(0, "% of games.^M^J");
]</syntaxhighlight>
 
Example output:
<pre>
NOT switching doors wins car in 33.7% of games.
But switching doors wins car in 66.7% of games.
</pre>
 
=={{header|Zig}}==
<syntaxhighlight lang="zig">const std = @import("std");
 
const number_of_simulations: u32 = 10_000_000;
 
pub fn main() !void {
var stick_wins: u32 = 0;
var switch_wins: u32 = 0;
var doors = [3]bool{ true, false, false };
 
var t = std.rand.DefaultPrng.init(42);
const r = t.random();
 
var guess: u8 = undefined;
var door_shown: u8 = undefined;
 
for (0..number_of_simulations) |_| {
std.rand.Random.shuffle(r, bool, &doors);
guess = r.intRangeAtMost(u8, 0, 2);
door_shown = r.intRangeAtMost(u8, 0, 2);
while (!doors[door_shown] and door_shown != guess) door_shown = r.intRangeAtMost(u8, 0, 2);
if (doors[guess]) {
stick_wins += 1;
} else {
switch_wins += 1;
}
}
 
std.debug.print("After {} simulations:\nStick wins: {}\nSwitch wins: {}\n", .{ number_of_simulations, stick_wins, switch_wins });
}</syntaxhighlight>
 
 
=={{header|zkl}}==
{{trans|Go}}
<syntaxhighlight lang="zkl">const games=0d100_000;
 
reg switcherWins=0, keeperWins=0, shown=0;
do(games){
doors := L(0,0,0);
doors[(0).random(3)] = 1; // Set which one has the car
choice := (0).random(3); // Choose a door
while(1){ shown = (0).random(3);
if (not (shown == choice or doors[shown] == 1)) break; }
switcherWins += doors[3 - choice - shown];
keeperWins += doors[choice];
}
 
"Switcher Wins: %,d (%3.2f%%)".fmt(
switcherWins, switcherWins.toFloat() / games * 100).println();
"Keeper Wins: %,d (%3.2f%%)".fmt(
keeperWins, keeperWins.toFloat() / games * 100).println();</syntaxhighlight>
{{out}}
<pre>
Switcher Wins: 66,730 (66.73%)
Keeper Wins: 33,270 (33.27%)
</pre>
44

edits