Difference between revisions of "RosettaCode Monty Hall"
| (10 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]. | ||
| + | <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 00: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?


