Monty Hall problem: Difference between revisions

m
(40 intermediate revisions by 15 users not shown)
Line 517:
 
=={{header|BASIC}}==
==={{header|ANSI BASIC}}===
{{works with|QuickBasic|4.5}}
{{trans|JavaXPL0}}
{{works with|Decimal BASIC}}
<syntaxhighlight lang="qbasic">RANDOMIZE TIMER
<syntaxhighlight lang="basic">
DIM doors(3) '0 is a goat, 1 is a car
100 PROGRAM MontyHallProblem
CLS
110 DEF NGames = 10000
switchWins = 0
120 RANDOMIZE
stayWins = 0
130 LET NWins = 0
FOR plays = 0 TO 32767
140 FOR Game = 0 TO NGames
winner = INT(RND * 3) + 1
150 IF IsGameWon(0) <> 0 THEN LET NWins = NWins + 1
doors(winner) = 1'put a winner in a random door
160 NEXT Game
choice = INT(RND * 3) + 1'pick a door, any door
170 PRINT "NOT switching doors wins car in ";
DO
180 PRINT USING "##.#": NWins / NGames * 100;
shown = INT(RND * 3) + 1
190 PRINT "% of games."
'don't show the winner or the choice
200 LET NWins = 0
LOOP WHILE doors(shown) = 1 OR shown = choice
210 FOR Game = 0 TO NGames
stayWins = stayWins + doors(choice) 'if you won by staying, count it
220 IF IsGameWon(1) <> 0 THEN LET NWins = NWins + 1
switchWins = switchWins + doors(3 - choice - shown) 'could have switched to win
230 NEXT Game
doors(winner) = 0 'clear the doors for the next test
240 PRINT "But switching doors wins car in ";
NEXT plays
250 PRINT USING "##.#": NWins / NGames * 100;
PRINT "Switching wins"; switchWins; "times."
260 PRINT "% of games."
PRINT "Staying wins"; stayWins; "times."</syntaxhighlight>
270 END
Output:
280 REM ***
<pre>Switching wins 21805 times.
290 EXTERNAL FUNCTION IsGameWon(Sw)
Staying wins 10963 times.</pre>
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}}===
Line 569 ⟶ 595:
end
</syntaxhighlight>
 
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> total% = 10000
FOR trial% = 1 TO total%
prize_door% = RND(3) : REM. The prize is behind this door
guess_door% = RND(3) : REM. The contestant guesses this door
IF prize_door% = guess_door% THEN
REM. The contestant guessed right, reveal either of the others
reveal_door% = RND(2)
IF prize_door% = 1 reveal_door% += 1
IF prize_door% = 2 AND reveal_door% = 2 reveal_door% = 3
ELSE
REM. The contestant guessed wrong, so reveal the non-prize door
reveal_door% = prize_door% EOR guess_door%
ENDIF
stick_door% = guess_door% : REM. The sticker doesn't change his mind
swap_door% = guess_door% EOR reveal_door% : REM. but the swapper does
IF stick_door% = prize_door% sticker% += 1
IF swap_door% = prize_door% swapper% += 1
NEXT trial%
PRINT "After a total of ";total%;" trials,"
PRINT "The 'sticker' won ";sticker%;" times (";INT(sticker%/total%*100);"%)"
PRINT "The 'swapper' won ";swapper%;" times (";INT(swapper%/total%*100);"%)"</syntaxhighlight>
Output:
<pre>
After a total of 10000 trials,
The 'sticker' won 3379 times (33%)
The 'swapper' won 6621 times (66%)
</pre>
 
==={{header|Euphoria}}===
<syntaxhighlight lang="euphoria">integer switchWins, stayWins
switchWins = 0
stayWins = 0
 
integer winner, choice, shown
 
for plays = 1 to 10000 do
winner = rand(3)
choice = rand(3)
while 1 do
shown = rand(3)
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.
Staying wins 3303 times.
</pre>
 
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">
' version 19-01-2019
' compile with: fbc -s console
 
Const As Integer max = 1000000
Randomize Timer
 
Dim As UInteger i, car_door, chosen_door, montys_door, stay, switch
 
For i = 1 To max
car_door = Fix(Rnd * 3) + 1
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" _
+ " chance to win"; stay / max * 100
Print Using "If you switched, you have a ##.## percent chance to win"; _
switch / max * 100
 
' empty keyboard buffer
While InKey <> "" : Wend
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|IS-BASIC}}===
Line 586 ⟶ 713:
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}}
<syntaxhighlight lang="qbasic">RANDOMIZE TIMER
DIM doors(3) '0 is a goat, 1 is a car
CLS
switchWins = 0
stayWins = 0
FOR plays = 0 TO 32767
winner = INT(RND * 3) + 1
doors(winner) = 1'put a winner in a random door
choice = INT(RND * 3) + 1'pick a door, any door
DO
shown = INT(RND * 3) + 1
'don't show the winner or the choice
LOOP WHILE doors(shown) = 1 OR shown = choice
stayWins = stayWins + doors(choice) 'if you won by staying, count it
switchWins = switchWins + doors(3 - choice - shown) 'could have switched to win
doors(winner) = 0 'clear the doors for the next test
NEXT plays
PRINT "Switching wins"; switchWins; "times."
PRINT "Staying wins"; stayWins; "times."</syntaxhighlight>
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}}===
Line 616 ⟶ 923:
341 659</pre>
 
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">OPTION BASE 0
DIM puertas(3)
 
==={{header|True BASIC}}===
<syntaxhighlight lang="basic">
LET numTiradas = 1000000
 
FOR i = 10 TO numTiradas
LET pta_coche = INT(RND * 3) + 1
LET puertas(pta_coche) = 1
LET pta_elegida = INT(RND * 3) + 1
DO
IF pta_coche <> pta_elegida THEN
LET pta_montys = 6INT(RND -* pta_coche3) -+ pta_elegida1
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
DO
LET pta_montys = INT(RND * 3) + 1
LOOP UNTIL pta_montys <> pta_coche
END IF
LET puertas(pta_coche) = 0
! mantener elección
IF pta_coche = pta_elegida THEN LET permanece = permanece + 1
! cambiar elección
IF pta_coche = 6 - pta_montys - pta_elegida THEN LET cambia = cambia + 1
NEXT i
 
PRINT "Cambiar gana el"; permanece / numTiradas * 100; "% de las veces."
PRINT "Mantenerse gana el"; cambia / numTiradas * 100; "% de las veces."
END</syntaxhighlight>
END
</syntaxhighlight>
 
==={{header|Yabasic}}===
<syntaxhighlight lang="yabasic">
numTiradas = 1000000
 
for i = 1 to numTiradas
=={{header|BBC BASIC}}==
pta_coche = int(ran(3)) + 1
<syntaxhighlight lang="bbcbasic"> total% = 10000
pta_elegida = int(ran(3)) + 1
FOR trial% = 1 TO total%
if pta_coche <> pta_elegida then
prize_door% = RND(3) : REM. The prize is behind this door
pta_montys = 6 - pta_coche - pta_elegida
guess_door% = RND(3) : REM. The contestant guesses this door
else
IF prize_door% = guess_door% THEN
repeat
REM. The contestant guessed right, reveal either of the others
pta_montys = int(ran(3)) + 1
reveal_door% = RND(2)
until pta_montys <> pta_coche
IF prize_door% = 1 reveal_door% += 1
end if
IF prize_door% = 2 AND reveal_door% = 2 reveal_door% = 3
// manteenr elección
ELSE
if pta_coche = pta_elegida then permanece = permanece + 1 : fi
REM. The contestant guessed wrong, so reveal the non-prize door
// cambiar elección
reveal_door% = prize_door% EOR guess_door%
if pta_coche = 6 - pta_montys - pta_elegida then cambia = cambia + 1 : fi
ENDIF
next i
stick_door% = guess_door% : REM. The sticker doesn't change his mind
swap_door% = guess_door% EOR reveal_door% : REM. but the swapper does
IF stick_door% = prize_door% sticker% += 1
IF swap_door% = prize_door% swapper% += 1
NEXT trial%
PRINT "After a total of ";total%;" trials,"
PRINT "The 'sticker' won ";sticker%;" times (";INT(sticker%/total%*100);"%)"
PRINT "The 'swapper' won ";swapper%;" times (";INT(swapper%/total%*100);"%)"</syntaxhighlight>
Output:
<pre>
After a total of 10000 trials,
The 'sticker' won 3379 times (33%)
The 'swapper' won 6621 times (66%)
</pre>
 
print "Si mantiene su eleccion, tiene un ", permanece / numTiradas * 100, "% de probabilidades de ganar."
=={{header|C}}==
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.
<syntaxhighlight lang="c">//Evidence of the Monty Hall solution of marquinho1986 in C [github.com/marquinho1986]
 
#include <stdlib.h>
Line 681 ⟶ 981:
#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]
#define NumSim 10000000
 
void main() {
Line 709 ⟶ 1,009:
Output of one run:
 
<pre> After 100000001000000000 games, I won 3330728333332381 by staying. That is 33.307277333238%. Andand I won by switching 6669272666667619 That is 66.692723666762% </pre>
 
=={{header|C sharp|C#}}==
Line 817 ⟶ 1,117:
 
=={{header|Chapel}}==
 
<syntaxhighlight lang="chapel">use Random;
'''Version 1''' : using task parallelism.
 
<syntaxhighlight lang="chapel">
use Random;
 
param doors: int = 3;
Line 869 ⟶ 1,173:
}
</syntaxhighlight>
 
Sample output:
<pre>
Line 874 ⟶ 1,179:
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>
 
Line 1,309 ⟶ 1,648:
<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
If you switched, you have a 66.64 percent chance to win
</pre>
 
=={{header|Eiffel}}==
Line 1,697 ⟶ 2,067:
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}}==
Line 1,730 ⟶ 2,152:
<pre>Switching wins 66595 times.
Staying wins 33405 times.</pre>
 
=={{header|Euphoria}}==
<syntaxhighlight lang="euphoria">integer switchWins, stayWins
switchWins = 0
stayWins = 0
 
integer winner, choice, shown
 
for plays = 1 to 10000 do
winner = rand(3)
choice = rand(3)
while 1 do
shown = rand(3)
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>
Sample Output:<br />
:Switching wins 6697 times<br />
:Staying wins 3303 times
 
=={{header|F_Sharp|F#}}==
Line 1,944 ⟶ 2,340:
Chance of winning by switching is 67.18%
 
=={{header|FreeBASICFōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Monty_Hall_problem}}
<syntaxhighlight lang="freebasic">' version 19-01-2019
' compile with: fbc -s console
 
'''Solution'''
Const As Integer max = 1000000
Randomize Timer
 
The following program makes a given number of simulations. On each, three options are evaluated:
Dim As UInteger i, car_door, chosen_door, montys_door, stay, switch
 
* If the player keeps his/her selection
For i = 1 To max
* If the player randomly chooses between hs/her selection and the other (closed) door.
car_door = Fix(Rnd * 3) + 1
* If the player switches his/her selection
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
 
Finally, it shows the number of wins for each case.
Print Using "If you stick to your choice, you have a ##.## percent" _
+ " chance to win"; stay / max * 100
Print Using "If you switched, you have a ##.## percent chance to win"; _
switch / max * 100
 
[[File:Fōrmulæ - Monty Hall problem 01.png]]
' empty keyboard buffer
While InKey <> "" : Wend
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>
 
[[File:Fōrmulæ - Monty Hall problem 02.png]]
=={{header|Fōrmulæ}}==
 
[[File:Fōrmulæ - Monty Hall problem 03.png]]
 
It can be seen that:
 
* 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]]
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
[[File:Fōrmulæ - Monty Hall problem 05.png]]
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - Monty Hall problem 06.png]]
In '''[https://formulae.org/?example=Monty_Hall_problem this]''' page you can see the program(s) related to this task and their results.
 
=={{header|Go}}==
Line 2,279 ⟶ 2,660:
===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">
Line 2,331 ⟶ 2,712:
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.
Line 2,682 ⟶ 3,065:
(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}}==
Line 2,720 ⟶ 3,109:
Switching wins 666330 times
</pre>
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
'adapted from BASIC solution
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>
Output:
<pre>
Result for 10000 games.
Switching wins 6634 times.
Staying wins 3366 times.</pre>
 
=={{header|Lua}}==
Line 2,881 ⟶ 3,236:
 
=={{header|MATLAB}}==
<syntaxhighlight 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 2,972 ⟶ 3,341:
<syntaxhighlight lang="maxscript">Stay strategy:33.77%
Switch strategy:66.84%</syntaxhighlight>
 
 
=={{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}}==
Line 3,539 ⟶ 3,978:
Staying wins 332 out of 1000.
</pre>
 
=={{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|Python}}==
Line 4,079 ⟶ 4,477:
<pre>Staying wins 33.84% of the time.
Switching wins 66.16% of the time.</pre>
 
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">' adapted from BASIC solution
 
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|Rust}}==
Line 4,331 ⟶ 4,705:
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}}==
Line 4,388 ⟶ 4,797:
(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>
 
Line 4,729 ⟶ 5,254:
 
=={{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).
Line 4,771 ⟶ 5,296:
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="ecmascriptwren">import "random" for Random
 
var montyHall = Fn.new { |games|
Line 4,849 ⟶ 5,406:
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">def GamesNGames = 10000; \number of games simulated
int Game, WinsNWins;
include c:\cxpl\codes;
 
procfunc Playint IsGameWon(Switch); \Play one game
int Switch;
int Car, Player, Player0, Monty;
Line 4,864 ⟶ 5,421:
until Player # Player0 and Player # Monty
else Player:= Player0; \player sticks with original door
ifreturn Player = Car then Wins:= Wins+1;
];
 
[Format(2,1);
NWins:= 0;
Text(0, "Not switching doors wins car in ");
for Game:= 0 to NGames-1 do
Wins:= 0;
if IsGameWon(false) then NWins:= NWins+1;
for Game:= 0 to Games-1 do Play(false);
Text(0, "NOT switching doors wins car in ");
RlOut(0, float(Wins)/float(Games)*100.0);
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);
Wins:= 0;
for Game:= 0 to Games-1 do Play(true);
RlOut(0, float(Wins)/float(Games)*100.0);
Text(0, "% of games.^M^J");
]</syntaxhighlight>
Line 4,883 ⟶ 5,442:
Example output:
<pre>
NotNOT 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;
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">
numTiradas = 1000000
 
pub fn main() !void {
for i = 1 to numTiradas
var stick_wins: u32 = 0;
pta_coche = int(ran(3)) + 1
var switch_wins: u32 = 0;
pta_elegida = int(ran(3)) + 1
var doors = [3]bool{ true, false, false };
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
 
var t = std.rand.DefaultPrng.init(42);
print "Si mantiene su eleccion, tiene un ", permanece / numTiradas * 100, "% de probabilidades de ganar."
const r = t.random();
print "Si cambia, tiene un ", cambia / numTiradas * 100, "% de probabilidades de ganar."
 
end
var guess: u8 = undefined;
</syntaxhighlight>
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>
 
 
2,122

edits