RosettaCode Monty Hall: Difference between revisions

From EiffelStudio: an EiffelSoftware project
Jump to navigation Jump to search
Bmeyer (talk | contribs)
Marco2357 (talk | contribs)
No edit summary
 
(9 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[Category:Rosetta Code]]
[[Category:Rosetta Code]]
[[Category:Flash Code ]]
'''-> [[RosettaCode]] Overview'''


==Reference==
==Reference==
Statement of the Monty Hall problem on RosettaCode: [http://rosettacode.org/wiki/Monty_Hall_problem here].
Statement of the Monty Hall problem on RosettaCode: [http://rosettacode.org/wiki/Monty_Hall_problem here].
Deadline for adding to RosettaCode page: 31 Aug 2012; submitter:
<br>Deadline for adding to RosettaCode page: 31 Aug 2012; submitter:


==Eiffel code==
==Eiffel code==
Here's a candidate implementation. This compiles and runs, producing output similar to this:
Staying wins 333504 times.
Switching wins 666496 times.
<e>
class
MONTY_HALL
create
make
feature {NONE} -- Initialization
make
local
games_count: INTEGER
do
create random_generator.make
games_count := 1000000
across 1 |..| games_count as game loop
play
end
print ("Staying wins " + staying_wins.out + " times.%N")
print ("Switching wins " + (games_count - staying_wins).out + " times.%N")
end
feature -- Commands
play
local
doors: ARRAYED_LIST [BOOLEAN]
chosen, shown: INTEGER
do
create doors.make_filled (Door_count) -- False is a goat, True is a car
doors [next_random_door] := True -- Put a car behind a random door
chosen := next_random_door -- Pick a door, any door
-- Monty selects a door which is neither the winner nor the choice
from
shown := next_random_door
until
shown /= chosen and not doors [shown]
loop
shown := next_random_door
end
if doors [chosen] then -- If you would have won by staying, count it
staying_wins := staying_wins + 1
end
ensure
staying_wins_valid: staying_wins = old staying_wins or staying_wins = old staying_wins + 1
end
feature {NONE} -- Implementation
Door_count: INTEGER = 3
-- The total number of doors.
staying_wins: INTEGER
-- The number of times that the strategy of staying would win.
random_generator: RANDOM
-- A random number generator for selecting doors.
next_random_door: INTEGER
-- A door chosen at random.
do
random_generator.forth
Result := random_generator.item \\ Door_count + 1
ensure
valid_door: Result >= 1 and Result <= Door_count
end
end
</e>
==Comments==
==Comments==
Note that the implementations in many other languages maintain a separate variable to count the number of switch wins. They calculate whether switching wins at each step via some funky logic that relies on zero-based array indexing, which would be inconvenient in Eiffel. But we don't need to do that at all anyway, because calculating it at each step is completely redundant: we can just do a final subtraction at the end, right?

Latest revision as of 08:27, 3 October 2012


-> RosettaCode Overview

Reference

Statement of the Monty Hall problem on RosettaCode: here.
Deadline for adding to RosettaCode page: 31 Aug 2012; submitter:

Eiffel code

Here's a candidate implementation. This compiles and runs, producing output similar to this:

Staying wins 333504 times.

Switching wins 666496 times.

class
	MONTY_HALL
 
create
	make
 
feature {NONE} -- Initialization
 
	make
		local
			games_count: INTEGER
		do
			create random_generator.make
			games_count := 1000000
 
			across 1 |..| games_count as game loop
				play
			end
 
			print ("Staying wins " + staying_wins.out + " times.%N")
			print ("Switching wins " + (games_count - staying_wins).out + " times.%N")
		end
 
feature -- Commands
 
	play
		local
			doors: ARRAYED_LIST [BOOLEAN]
			chosen, shown: INTEGER
		do
			create doors.make_filled (Door_count)	-- False is a goat, True is a car
			doors [next_random_door] := True	-- Put a car behind a random door
 			chosen := next_random_door	-- Pick a door, any door
 
			-- Monty selects a door which is neither the winner nor the choice
			from
				shown := next_random_door
			until
				shown /= chosen and not doors [shown]
			loop
				shown := next_random_door
			end
 
			if doors [chosen] then	-- If you would have won by staying, count it
				staying_wins := staying_wins + 1
			end
		ensure
			staying_wins_valid: staying_wins = old staying_wins or staying_wins = old staying_wins + 1
		end
 
feature {NONE} -- Implementation
 
	Door_count: INTEGER = 3
			-- The total number of doors.
 
	staying_wins: INTEGER
			-- The number of times that the strategy of staying would win.
 
	random_generator: RANDOM
			-- A random number generator for selecting doors.
 
	next_random_door: INTEGER
			-- A door chosen at random.
		do
			random_generator.forth
			Result := random_generator.item \\ Door_count + 1
		ensure
			valid_door: Result >= 1 and Result <= Door_count
		end
 
end

Comments

Note that the implementations in many other languages maintain a separate variable to count the number of switch wins. They calculate whether switching wins at each step via some funky logic that relies on zero-based array indexing, which would be inconvenient in Eiffel. But we don't need to do that at all anyway, because calculating it at each step is completely redundant: we can just do a final subtraction at the end, right?