Monty Hall problem: Difference between revisions

Reverted to an older version in order to restore Python and R
(Reverted to an older version in order to restore Python and R)
Line 2,424:
Wins when redeciding: 666459 (66.65% chance)
Wins when sticking: 333541 (33.35% chance)</pre>
 
=={{header|Python}}==
<lang python>'''
I could understand the explanation of the Monty Hall problem
but needed some more evidence
 
References:
http://www.bbc.co.uk/dna/h2g2/A1054306
http://en.wikipedia.org/wiki/Monty_Hall_problem especially:
http://en.wikipedia.org/wiki/Monty_Hall_problem#Increasing_the_number_of_doors
'''
from random import randrange
 
doors, iterations = 3,100000 # could try 100,1000
 
def monty_hall(choice, switch=False, doorCount=doors):
# Set up doors
door = [False]*doorCount
# One door with prize
door[randrange(doorCount)] = True
 
chosen = door[choice]
 
unpicked = door
del unpicked[choice]
 
# Out of those unpicked, the alternative is either:
# the prize door, or
# an empty door if the initial choice is actually the prize.
alternative = True in unpicked
 
if switch:
return alternative
else:
return chosen
 
print "\nMonty Hall problem simulation:"
print doors, "doors,", iterations, "iterations.\n"
 
print "Not switching allows you to win",
print sum(monty_hall(randrange(3), switch=False)
for x in range(iterations)),
print "out of", iterations, "times."
print "Switching allows you to win",
print sum(monty_hall(randrange(3), switch=True)
for x in range(iterations)),
print "out of", iterations, "times.\n"</lang>
Sample output:
<pre>Monty Hall problem simulation:
3 doors, 100000 iterations.
 
Not switching allows you to win 33337 out of 100000 times.
Switching allows you to win 66529 out of 100000 times.</pre>
 
 
 
===Python 3 version: ===
Another (simpler in my opinion), way to do this is below, also in python 3:
<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</lang>
 
=={{header|R}}==
 
<lang rsplus># 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).
 
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)
 
# We can assme that the contestant always choose door 1 without any loss of
# generality, by equivalence. That is, we can always relabel the doors
# to make the user-chosen door into door 1.
# Thus, the host opens door '2' unless door 2 has the prize, in which case
# the host opens door 3.
 
host_opens <- 2 + (true_answers == 2)
other_door <- 2 + (true_answers != 2)
 
## if always switch
summary( other_door == true_answers )
## if we never switch
summary( true_answers == 1)
## if we randomly switch
random_switch <- other_door
random_switch[runif(N) >= .5] <- 1
summary(random_switch == true_answers)
 
 
 
## To go with the exact parameters of the Rosetta challenge, complicating matters....
## 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.
 
N <- 10000 #trials
true_answers <- sample(1:3, N, replace=TRUE)
user_choice <- sample(1:3, N, replace=TRUE)
## the host_choice is more complicated
host_chooser <- function(user_prize) {
# this could be cleaner
bad_choices <- unique(user_prize)
# in R, the x[-vector] form implies, choose the indices in x not in vector
choices <- c(1:3)[-bad_choices]
# if the first arg to sample is an int, it treats it as the number of choices
if (length(choices) == 1) { return(choices)}
else { return(sample(choices,1))}
}
 
host_choice <- apply( X=cbind(true_answers,user_choice), FUN=host_chooser,MARGIN=1)
not_door <- function(x){ return( (1:3)[-x]) } # we could also define this
# directly at the FUN argument following
other_door <- apply( X = cbind(user_choice,host_choice), FUN=not_door, MARGIN=1)
 
 
## if always switch
summary( other_door == true_answers )
## if we never switch
summary( true_answers == user_choice)
## if we randomly switch
random_switch <- user_choice
change <- runif(N) >= .5
random_switch[change] <- other_door[change]
summary(random_switch == true_answers)</lang>
 
 
<pre>Results:
 
> ## if always switch
> summary( other_door == true_answers )
Mode FALSE TRUE
logical 3298 6702
> ## if we never switch
> summary( true_answers == 1)
Mode FALSE TRUE
logical 6702 3298
> ## if we randomly switch
> summary(random_switch == true_answers)
Mode FALSE TRUE
logical 5028 4972
 
 
> ## if always switch
> summary( other_door == true_answers )
Mode FALSE TRUE
logical 3295 6705
> ## if we never switch
> summary( true_answers == user_choice)
Mode FALSE TRUE
logical 6705 3295
> ## if we randomly switch
> summary(random_switch == true_answers)
Mode FALSE TRUE
logical 4986 5014 </pre>
 
<pre># As above, but generalized to K number of doors
 
K = 4 # number of doors
N = 1e4 # number of simulation trials
 
chooser <- function(x) { i <- (1:K)[-x]; if (length(i)>1) sample(i,1) else i }
 
p100 <- function(...) { cat("\nNumber of doors:", K,
"\nSimulation yields % winning probability:",
" (2nd choice after host reveal)\n");
print(c(...) * 100, digits=3) }
 
prize_door <- sample(1:K, N, replace=TRUE)
first_choice <- sample(1:K, N, replace=TRUE)
 
host_opens <- apply(cbind(prize_door, first_choice), 1, chooser)
second_choice <- apply(cbind(host_opens, first_choice), 1, chooser)
 
p100("By first choice" = (Pr.first_win <- mean(first_choice == prize_door)),
"By second choice" = (Pr.second_win <- mean(second_choice == prize_door)),
" Change gain" = Pr.second_win / Pr.first_win - 1)
 
#-------
#
# Sample output:
 
Number of doors: 4
Simulation yields % winning probability: (2nd choice after host reveal)
By first choice By second choice Change gain
24.7 36.5 48.0
</pre>
 
=={{header|Racket}}==