Data update
This commit is contained in:
parent
5150844a7d
commit
4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions
|
|
@ -5,7 +5,7 @@ Behind one door is a car; behind the others, goats.
|
|||
The car and the goats were placed randomly behind the doors before the show.
|
||||
|
||||
|
||||
;Rules of the game:
|
||||
;Rules of the game<nowiki>:</nowiki>
|
||||
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.
|
||||
|
|
@ -19,21 +19,21 @@ 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:
|
||||
;The question<nowiki>:</nowiki>
|
||||
Is it to your advantage to change your choice?
|
||||
|
||||
|
||||
;Note:
|
||||
;Note<nowiki>:</nowiki>
|
||||
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:
|
||||
;Task<nowiki>:</nowiki>
|
||||
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:
|
||||
;References<nowiki>:</nowiki>
|
||||
:* 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: [https://www.youtube.com/watch?v=4Lb-6rxZxx0 Monty Hall Problem - Numberphile].
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
110 DEF NGames = 10000
|
||||
120 RANDOMIZE
|
||||
130 LET NWins = 0
|
||||
140 FOR Game = 0 TO NGames
|
||||
140 FOR Game = 1 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
|
||||
210 FOR Game = 1 TO NGames
|
||||
220 IF IsGameWon(1) <> 0 THEN LET NWins = NWins + 1
|
||||
230 NEXT Game
|
||||
240 PRINT "But switching doors wins car in ";
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
-- Monty Hall Game
|
||||
|
||||
with Ada.Text_Io; use Ada.Text_Io;
|
||||
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
|
||||
with ada.Numerics.Discrete_Random;
|
||||
|
||||
procedure Monty_Stats is
|
||||
Num_Iterations : Positive := 100000;
|
||||
type Action_Type is (Stay, Switch);
|
||||
type Prize_Type is (Goat, Pig, Car);
|
||||
type Door_Index is range 1..3;
|
||||
package Random_Prize is new Ada.Numerics.Discrete_Random(Door_Index);
|
||||
use Random_Prize;
|
||||
Seed : Generator;
|
||||
Doors : array(Door_Index) of Prize_Type;
|
||||
|
||||
procedure Set_Prizes is
|
||||
Prize_Index : Door_Index;
|
||||
Booby_Prize : Prize_Type := Goat;
|
||||
begin
|
||||
Reset(Seed);
|
||||
Prize_Index := Random(Seed);
|
||||
Doors(Prize_Index) := Car;
|
||||
for I in Doors'range loop
|
||||
if I /= Prize_Index then
|
||||
Doors(I) := Booby_Prize;
|
||||
Booby_Prize := Prize_Type'Succ(Booby_Prize);
|
||||
end if;
|
||||
end loop;
|
||||
end Set_Prizes;
|
||||
|
||||
function Play(Action : Action_Type) return Prize_Type is
|
||||
Chosen : Door_Index := Random(Seed);
|
||||
Monty : Door_Index;
|
||||
begin
|
||||
Set_Prizes;
|
||||
for I in Doors'range loop
|
||||
if I /= Chosen and Doors(I) /= Car then
|
||||
Monty := I;
|
||||
end if;
|
||||
end loop;
|
||||
if Action = Switch then
|
||||
for I in Doors'range loop
|
||||
if I /= Monty and I /= Chosen then
|
||||
Chosen := I;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
return Doors(Chosen);
|
||||
end Play;
|
||||
Winners : Natural;
|
||||
Pct : Float;
|
||||
begin
|
||||
Winners := 0;
|
||||
for I in 1..Num_Iterations loop
|
||||
if Play(Stay) = Car then
|
||||
Winners := Winners + 1;
|
||||
end if;
|
||||
end loop;
|
||||
Put("Stay : count" & Natural'Image(Winners) & " = ");
|
||||
Pct := Float(Winners * 100) / Float(Num_Iterations);
|
||||
Put(Item => Pct, Aft => 2, Exp => 0);
|
||||
Put_Line("%");
|
||||
Winners := 0;
|
||||
for I in 1..Num_Iterations loop
|
||||
if Play(Switch) = Car then
|
||||
Winners := Winners + 1;
|
||||
end if;
|
||||
end loop;
|
||||
Put("Switch : count" & Natural'Image(Winners) & " = ");
|
||||
Pct := Float(Winners * 100) / Float(Num_Iterations);
|
||||
Put(Item => Pct, Aft => 2, Exp => 0);
|
||||
Put_Line("%");
|
||||
|
||||
end Monty_Stats;
|
||||
|
|
@ -2,7 +2,7 @@ stay: 0
|
|||
swit: 0
|
||||
|
||||
loop 1..1000 'i [
|
||||
lst: shuffle new [1 0 0]
|
||||
lst: shuffle [1 0 0]
|
||||
rand: random 0 2
|
||||
user: lst\[rand]
|
||||
remove 'lst rand
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
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.
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
use Random;
|
||||
|
||||
param doors: int = 3;
|
||||
config const games: int = 1000;
|
||||
|
||||
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 {
|
||||
for game in 1..#remaining_games {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var total_by_stay = + reduce wins_by_stay;
|
||||
|
||||
var total_by_switch = games - total_by_stay;
|
||||
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." );
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
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");
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
(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)))
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
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)
|
||||
|
|
@ -40,17 +40,17 @@ _NGames = 10000
|
|||
float NWins = 0
|
||||
short Game
|
||||
|
||||
FOR Game = 0 TO _NGames
|
||||
FOR Game = 1 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 USING "##.##" ; NWins / _NGames * 100 ;
|
||||
PRINT " % of games."
|
||||
|
||||
NWins = 0
|
||||
FOR Game = 0 TO _NGames
|
||||
FOR Game = 1 TO _NGames
|
||||
IF fn IsGameWon(1) <> 0 THEN NWins = NWins + 1
|
||||
NEXT Game
|
||||
PRINT "But switching doors wins car in ";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
20 LET N = 10000
|
||||
30 RANDOMIZE
|
||||
40 LET W = 0
|
||||
50 FOR G = 0 TO N
|
||||
50 FOR G = 1 TO N
|
||||
60 LET S = 0
|
||||
70 GOSUB 230
|
||||
80 IF V = 0 THEN 100
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
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
|
||||
140 FOR G = 1 TO N
|
||||
150 LET S = 1
|
||||
160 GOSUB 230
|
||||
170 IF V = 0 THEN 190
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ END IsGameWon;
|
|||
BEGIN
|
||||
Randomize(0);
|
||||
NWins := 0;
|
||||
FOR Game := 0 TO NGames DO
|
||||
FOR Game := 1 TO NGames DO
|
||||
IF IsGameWon(FALSE) THEN
|
||||
NWins := NWins + 1
|
||||
END
|
||||
|
|
@ -46,7 +46,7 @@ BEGIN
|
|||
WriteString('% of games.');
|
||||
WriteLn;
|
||||
NWins := 0;
|
||||
FOR Game := 0 TO NGames DO
|
||||
FOR Game := 1 TO NGames DO
|
||||
IF IsGameWon(TRUE) THEN
|
||||
NWins := NWins + 1
|
||||
END
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
#Declaring variables
|
||||
$intIterations = 10000
|
||||
$intKept = 0
|
||||
$intSwitched = 0
|
||||
|
||||
#Creating a function
|
||||
Function Play-MontyHall()
|
||||
{
|
||||
#Using a .NET object for randomization
|
||||
$objRandom = New-Object -TypeName System.Random
|
||||
|
||||
#Generating the winning door number
|
||||
$intWin = $objRandom.Next(1,4)
|
||||
|
||||
#Generating the chosen door
|
||||
$intChoice = $objRandom.Next(1,4)
|
||||
|
||||
#Generating the excluded number
|
||||
#Because there is no method to exclude a number from a range,
|
||||
#I let it re-generate in case it equals the winning number or
|
||||
#in case it equals the chosen door.
|
||||
$intLose = $objRandom.Next(1,4)
|
||||
While (($intLose -EQ $intWin) -OR ($intLose -EQ $intChoice))
|
||||
{$intLose = $objRandom.Next(1,4)}
|
||||
|
||||
#Generating the 'other' door
|
||||
#Same logic applies as for the chosen door: it cannot be equal
|
||||
#to the winning door nor to the chosen door.
|
||||
$intSwitch = $objRandom.Next(1,4)
|
||||
While (($intSwitch -EQ $intLose) -OR ($intSwitch -EQ $intChoice))
|
||||
{$intSwitch = $objRandom.Next(1,4)}
|
||||
|
||||
#Simple counters per win for both categories
|
||||
#Because a child scope cannot change variables in the parent
|
||||
#scope, the scope of the counters is expanded script-wide.
|
||||
If ($intChoice -EQ $intWin)
|
||||
{$script:intKept++}
|
||||
If ($intSwitch -EQ $intWin)
|
||||
{$script:intSwitched++}
|
||||
|
||||
}
|
||||
|
||||
#Looping the Monty Hall function for $intIterations times
|
||||
While ($intIterationCount -LT $intIterations)
|
||||
{
|
||||
Play-MontyHall
|
||||
$intIterationCount++
|
||||
}
|
||||
|
||||
#Output
|
||||
Write-Host "Results through $intIterations iterations:"
|
||||
Write-Host "Keep : $intKept ($($intKept/$intIterations*100)%)"
|
||||
Write-Host "Switch: $intSwitched ($($intSwitched/$intIterations*100)%)"
|
||||
Write-Host ""
|
||||
Loading…
Add table
Add a link
Reference in a new issue