A Rebol Challenge. The Monty Hall Puzzle
[1/22] from: reichart::prolific::com at: 15-Dec-2001 23:47
We Reboler have been challenged.
I was posing some puzzles with some friends on another mailing list I belong
to, the enjoyment of which is provided here first should you want to try and
solve this for yourself. However, one of the people responding was a
programmer, and he wrote a program to try to solve the problem. First he
wrote this in Pearl (183 characters), then in Matlab (136 characters). I
put it to you--smarter people than I--to put this man to shame! Give me
your best Rebolette, and I will make him see the error of his ways :-)
OK, no looking this up on the web. This is a real fun one if you have not
seen it before, or better stated, worked through it.
The scenario is such: you are given the opportunity to select one closed
door of three, behind one of which there is a prize. The other two doors
hide "goats" (or some other such "non-prize"), or nothing at all. Once you
have made your selection, Monty Hall will open one of the remaining doors,
revealing that it does not contain the prize. He then asks you if you would
like to switch your selection to the other unopened door, or stay with your
original choice. Here is the problem:
Does it matter if you switch?
P.S. this problem was presented to two of my engineers and myself many many
years ago. We were told that the "staff" scientist at the company of the
presenter all got it wrong. So the three of us worked on it together for
about 25 minutes. Came to our conclusion, then wrote a computer program to
prove it.
I then wrote a layman's description of "why." Which I found was
needed because SO MANY PEOPLE CAN NOT ACCEPT THE ANSWER. Especially
statisticians! Too funny. If anyone wants a copy, I will dig it up.
Now for the Email from my friend:
He writes...
Nah, matlab is the way to go for this:
b=sum(floor(3*rand(100,100))==0);y=floor(3*rand(100,100));
o=(floor(2*rand(100,100))+1).*(y==0)+(3-y).*(y>0);c=sum(y.*o>0);
d=sum(c>b-c<b); [b;c]
if (d>90) fprintf(1,"Switching is better (95%%+ confidence)\n"); end
But maybe you can do better in Rebol. I don't see a way to off the top of
my head. Note that if we're just comparing the core computation, the matlab
is barely three lines. (The "o" variable is not strictly needed, but I am
including it anyway to explicitly construct the
door-picked-by-Monty.)
Perl is 183 characters, not counting invocation from the command line or
comments. Matlab is 136.
/usr/bin/perl -e 'print "St Sw (%win)\n";$d=0;for($i=0;$i<100;$i++){
$b=0;$c=0;for($a=0;$a<100;$a++){$b+=int(rand(3))==0};
for($a=0;$a<100;$a++){$y=int(rand(3));$o=$y?(3-$y):(int(rand(2))+1);
$c+=$o*$y>0;};$d+=($c>=$b)-($c<=$b);print "$b $c\n"};print "St Sw (%win)";
if ($d>90) { print "\nSwitching is better (95%+ confidence)" };print "\n"'
Reichart...
[Reichart--Prolific--com]
Be useful.
[2/22] from: carl:cybercraft at: 17-Dec-2001 0:15
On 16-Dec-01, Reichart wrote:
> We Reboler have been challenged.
> I was posing some puzzles with some friends on another mailing list
<<quoted lines omitted: 44>>
> (%win)"; if ($d>90) { print "\nSwitching is better (95%+
> confidence)" };print "\n"'
Not being a statistician, (or having a clue what the above code
does:), my approach to such problems is to simulate them many times
and see if there's a noticable difference in the results. So here's
my code to do that, but it may be bugged as it wasn't giving the
results I was expecting. But then, what's expected is not what we're
supposed to get, right? (:
rebol[]k: s: 0 r: func[n][random n]a: does[p: r 3 c: r 3 p = c]
loop 10000 [if a[k: k + 1]if if not a[r 2 = 1][s: s + 1]]print
["Kept" k "Switched" s]
I especially like the "if if" as it sounds like an accurate
description of my code. (: Anyway, it's 151 bytes long for what it's
worth.
--
Carl Read
[3/22] from: sunandadh:aol at: 16-Dec-2001 6:52
Hi Reichart.
> But maybe you can do better in Rebol. I don't see a way to off the top of
> my head. Note that if we're just comparing the core computation, the
matlab
> is barely three lines. (The "o" variable is not strictly needed, but I am
> including it anyway to explicitly construct the
> door-picked-by-Monty.)
Here's my attempt. It runs a simulated Monty 500 times.
I get a "length" of 142 (length? mold load %doors.r), but I don't have the
same text message as you and the "external" length could be shorter by
one-lining it all and reducing the variables to W and N.
The core calculation is just one line, but I'm using a different algorithm.
rebol []
Win: 0 n: 0
loop 500 [
n: n + 1
win: win + last sort next random [0 0 1]
]
Print ["Win%" win * 100 / n]
In slow motion and with intermediate variables this is:
Three doors: one has a 1 behind it (thats the car) the other two have a big
zero.
Doors: random [0 0 1]
whichever door I pick is modelled by
MyDoor: first Doors
Monty then shows me a zero door:
MontyDoor: mimimum Door/2 Door/3
I then select the other of Monty's doors:
MySwappedDoor: Maximim Door/2 Door/3
which is the same as
MySwappedDoor: last sort next Doors
so if MySwappedDoor is a 1, I'm a winner!
Sunanda
[4/22] from: rotenca:telvia:it at: 16-Dec-2001 14:11
----- Original Message -----
From: <[SunandaDH--aol--com]>
To: <[rebol-list--rebol--com]>
Sent: Sunday, December 16, 2001 12:52 PM
Subject: [REBOL] Re: A Rebol Challenge. The Monty Hall Puzzle
> Hi Reichart.
> >
> > But maybe you can do better in Rebol. I don't see a way to off the top
of
> > my head. Note that if we're just comparing the core computation, the
> matlab
> > is barely three lines. (The "o" variable is not strictly needed, but I
am
> > including it anyway to explicitly construct the
> > door-picked-by-Monty.)
<<quoted lines omitted: 10>>
> ]
> Print ["Win%" win * 100 / n]
Beautiful! You can remove the n + 1:
Win: 0 n: 500 print ["Win%" 100 / n * loop n [win: win + last sort next random
[0 0 1]]]
---
Ciao
Romano
[5/22] from: brett:codeconscious at: 17-Dec-2001 0:33
Hi Reichart,
The one is not as wonderous as Sunanda's solution but is interesting because
you can use whatever symbols you like
to represent the boxes :)
The code below simulates the always switch strategy - returns rough
probability of winning:
REBOL[]
d: {123}w: 0 loop n: 500 [
p: func[s][copy/part random s 1]
b: p d c: p d if b = p union b c [w: w + 1]]
w / n
d: represents the choices - could have been any series of 3 elements e.g
[box1 box2 box3]
p: makes a random selection from a series
b: the winning box
c: the first choice
(union b c) is equivalent to the two closed boxes after monty has opened one
empty box
That is it is equivalent too
box-to-remove: exclude d union b c
choices: exclude d box-to-remove
An anxious person would probably figure out they'd more than likely goofed
first go :)
Cheers
Brett.
[6/22] from: rebol:optushome:au at: 16-Dec-2001 23:58
> REBOL[]
> d: {123}w: 0 loop n: 500 [
<<quoted lines omitted: 4>>
> [box1 box2 box3]
> p: makes a random selection from a series
Hi Brett,
Just to point out a lesser known refinement of random
p: func[s][copy/part random s 1]
I think could be replaced by
p: func[s][random/only s]
Cheers,
Allen K
[7/22] from: andreas:bolka:gmx at: 16-Dec-2001 15:17
16 Dec 2001, 08:47:34, Reichart wrote:
> P.S. this problem was presented to two of my engineers and myself
> many many years ago. We were told that the "staff" scientist at the
<<quoted lines omitted: 4>>
> PEOPLE CAN NOT ACCEPT THE ANSWER. Especially statisticians! Too
> funny. If anyone wants a copy, I will dig it up.
I'd like to have a copy ;)
--
Best regards,
Andreas mailto:[andreas--bolka--gmx--net]
[8/22] from: sunandadh:aol at: 16-Dec-2001 10:19
Hi Romano,
> Beautiful! You can remove the n + 1:
>
> Win: 0 n: 500 print ["Win%" 100 / n * loop n [win: win + last sort next
> random
> [0 0 1]]]
>
Thanks. I thought I'd minimised it completely, but it's amazing what teamwork
can do.
If we just want to print the winning percentage, and we shorten the variable
names we get:
W: 0 n: 500 100 / n * loop n [w: w + last sort next random [0 0 1]]
which is just
length? {W: 0 n: 500 100 / n * loop n [w: w + last sort next random [0 0 1]]}
67 bytes. Which--spookily enough--equals our win percentage for swapping.
Sunanda.
[9/22] from: doncox:enterprise at: 16-Dec-2001 17:01
On 16-Dec-01, Andreas Bolka wrote:
> 16 Dec 2001, 08:47:34, Reichart wrote:
>> P.S. this problem was presented to two of my engineers and myself
<<quoted lines omitted: 6>>
>> funny. If anyone wants a copy, I will dig it up.
> I'd like to have a copy ;)
If it's not too long, post it.
Regards
--
Don Cox
[doncox--enterprise--net]
[10/22] from: rotenca:telvia:it at: 16-Dec-2001 17:33
Hi Sunanda,
> Thanks. I thought I'd minimised it completely, but it's amazing what
teamwork
> can do.
Nothing in front of your wonderful:
last sort next random
P.S.
Are you from India?
---
Ciao
Romano
[11/22] from: rebol665:ifrance at: 16-Dec-2001 17:37
Hi Romano and Sunanda,
Your work is brilliant ! It helps me to get to the problem, and finally my
17 years'old son explained it to me. If you consider that each time I loose
I did not win, the answer can be shorten a bit.
rebol[]
win: 100 print ["Win% = " loop win [ win: win - first random [0 0 1]]]
It is a beat cheatting considering that your version iterate 500 times so I
give also my 1000 iterations version.
rebol[]
win: 1000 print ["Win% = " (loop win [ win: win - first random [0 0 1]]) /
10]
These are respectively 43 and 51 bytes long.
Patrick
[12/22] from: g:santilli:tiscalinet:it at: 16-Dec-2001 15:27
Hello Reichart!
On 16-Dic-01, you wrote:
R> Does it matter if you switch?
Readable version:
random/seed now
no-switch-wins: 0
switch-wins: 0
loop 1000 [
winning: random 3
your-choice: random 3
either your-choice = winning [
no-switch-wins: no-switch-wins + 1
] [
switch-wins: switch-wins + 1
]
]
print [
"If you switch, you win" switch-wins "times" newline
"If you don't switch, you win" no-switch-wins "times"
]
Compact version:
r: does[random 3]n: s: 0 loop 1000[either r = r[n: n + 1][s: s + 1]]
print [
"If you switch, you win" s "times" newline
"If you don't switch, you win" n "times"
]
I presume the code you show is doing something different, but I
don't speak perl or matlab... :)
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[13/22] from: sunandadh:aol at: 16-Dec-2001 14:18
Hi Patrick,
> Your work is brilliant ! It helps me to get to the problem, and finally my
> 17 years'old son explained it to me. If you consider that each time I loose
> I did not win, the answer can be shorten a bit.
Thanks,
> rebol[]
> win: 100 print ["Win% = " loop win [ win: win - first random [0 0 1]]]
<<quoted lines omitted: 4>>
> 10]
> These are respectively 43 and 51 bytes long.
Good stuff!
Your solutions embody the logic that
:
1. If I stick with what I've got, I've a 1/3rd chance of winning
2. Therefore Monty has a 2/3 chance of having the car
3. But Monty has shown me an empty door, So, if Monty has the car it MUST
be behind the door he didn't open.
4. Therefore I'll take that unopened door and win 2/3s of the time
Given we all accept that logic, that, we could shorten the puzzle even more:
Print ["Win% " 200 / 3]
<g!>
The problem being that not everyone does accept that logic at first view. So,
to be
fair, we need code that runs a fair emulation of making a choice.
Sunanda
[14/22] from: sunandadh:aol at: 16-Dec-2001 16:43
Hi Romano,
P.S.
> Are you from India?
Sorry No. Irish descent, living in Birmingham, England.
Sunanda.
[15/22] from: rebol665:ifrance at: 16-Dec-2001 22:54
Hi, Sunanda
Print ["Win% " 200 / 3]
I came to the same conclusion thanks to your "slow motion" explanation but I
did not dare to put that. Indeed the 2/3 emerges from your explanation.
>so if MySwappedDoor is a 1, I'm a winner!
Actually this already points to "how can that happens if the 1 comes first
in the block?". However it was not my aim to "stole your thunder" (as would
Monica Geller say*).
>The problem being that not everyone does accept that logic at first view.
My version could have come without any assumption, even without knowing what
it was all about. Your program was counting how many times a random block
including two zero and only one one could either be [0 0 1] or [0 1 0]. My
version said that it suffice to count how many times it would not be [1 0
0].
I must confess that I too prefer your version that not only gives the
answers but also "explains" it. That was a very very clever piece of code !
Patrick
ps: * comes from the serie FRIENDS, episode 701
[16/22] from: brett:codeconscious at: 17-Dec-2001 11:34
Hi Allen,
You're right. I didn't know about that refinement.
I would have used "first random s" instead of "random/only".
But here though, I used copy/part because I needed a series to work in the
union operation. Otherwise I'll need to
add "to-string" before the "random/only" and d will need to be restricted to
being a string only. Doing this yields,
REBOL[]
d: {123}w: 0 loop n: 500 [
p: func[s][to-string random/only s]
b: p d c: p d if b = p union b c [w: w + 1]]
w / n
Which is about 3 characters longer than the original :)
Cheers
Brett.
[17/22] from: joel:neely:fedex at: 16-Dec-2001 16:20
Hi, Sunanda, et al,
It seems to me that the problem in the original post was persuasion
and not just computation. That being the case, the text of the
program itself (or its derivation) should be a compelling argument
for the right answer.
IOW, if I had trouble understanding/accepting an answer, I would
not be very persuaded simply by the output of a highly compact
program that seemed to contain assumptions about the very answer
I was having trouble with.
That said, let me offer two lines of reasoning (starting with the
same assumptions -- one argument based on verbal reasoning and one
based on code refactoring) which might be of some persuasive value
(but YMMV).
****************
* ASSUMPTIONS: *
****************
0) There are three doors.
1) The prize door is chosen at random.
2) The contestant chooses a door at random.
3) Monty chooses and opens a door at random that is neither the
prize door nor the contestant's door.
********************
* VERBAL ARGUMENT: *
********************
Imagine that there are two contestants playing as a team. They
agree on an initial guess (randomly chosen, remember), but then
one (A) always keeps the initial guess, while the other (B) always
switches after Monty opens a door.
Since Monty always opens a non-prize door (leaving two doors
unopened) exactly one of them must win on every round.
Since Monty opens the non-prize door after the initial guess is
chosen, his choice of which door to open changes neither the
initial guess nor the door behind which the prize has already
been placed. Therefore, A's chances of winning are unaffected
by what Monty does.
Since A is choosing randomly to find the winning one door out of
three, his odds of winning are 1/3, and his odds of losing are 2/3.
Therefore, B's odds of winning are 2/3 (B wins whenever A loses).
*************************
* REFACTORING ARGUMENT: *
*************************
Implementing the assumptions (using RANDOM) and trying a bunch of
rounds, we get something like this (in my best commented-to-death
style -- remember that we're explaining to a skeptic ;-) :
8<------------------------------------------------------------
pickadoor: function [
rounds [integer!]
][
prizedoor guessdoor montydoor keepwins switchwins
][
;
; neither strategy has won anything before we start
;
keepwins: switchwins: 0
;
; simulate the specified number of rounds
;
loop rounds [
;
; prize is behind a randomly-chosen door
;
prizedoor: random 3
;
; contestant (or team) randomly guesses a door
;
guessdoor: random 3
;
; Monty opens a non-prize, non-guessed door
;
until [
montydoor: random 3
all [montydoor <> prizedoor montydoor <> guessdoor]
]
;
; which strategy won on this round?
;
either guessdoor = prizedoor [
keepwins: keepwins + 1
][
switchwins: switchwins + 1
]
]
print [
"Keep won" keepwins "rounds,"
"switch won" switchwins "rounds"
]
]
8<------------------------------------------------------------
Having started with a painfully explicit (but obviously valid --
I hope!) function, let't start compacting and refactoring. I'll
save my typing time and your bandwidth and reading time by
omitting the comments from here on...
Step 1: Since KEEPWINS + SWITCHWINS is always equal to rounds
played thus far, we don't need both variables. Let's
eliminate SWITCHWINS throughout the code.
8<------------------------------------------------------------
pickadoor: function [
rounds [integer!]
][
prizedoor guessdoor montydoor keepwins
][
keepwins: 0
loop rounds [
prizedoor: random 3
guessdoor: random 3
until [
montydoor: random 3
all [montydoor <> prizedoor montydoor <> guessdoor]
]
if guessdoor = prizedoor [
keepwins: keepwins + 1
]
]
print [
"Keep won" keepwins "rounds,"
"switch won" rounds - keepwins "rounds"
]
]
8<------------------------------------------------------------
Step 2: Since KEEPWINS only depends on the values of GUESSDOOR
and PRIZEDOOR (but *not* on MONTYDOOR), we can eliminate
MONTYDOOR from the code.
8<------------------------------------------------------------
pickadoor: function [
rounds [integer!]
][
prizedoor guessdoor keepwins
][
keepwins: 0
loop rounds [
prizedoor: random 3
guessdoor: random 3
if guessdoor = prizedoor [
keepwins: keepwins + 1
]
]
print [
"Keep won" keepwins "rounds,"
"switch won" rounds - keepwins "rounds"
]
]
8<------------------------------------------------------------
Step 3: The variables PRIZEDOOR and GUESSDOOR are set to a new
value once per loop, and then examined exactly once per
loop; therefore, we can eliminate the variables by using their
defining expressions instead of their (single) usage.
8<------------------------------------------------------------
pickadoor: function [
rounds [integer!]
][
keepwins
][
keepwins: 0
loop rounds [
if (random 3) = random 3 [
keepwins: keepwins + 1
]
]
print [
"Keep won" keepwins "rounds,"
"switch won" rounds - keepwins "rounds"
]
]
8<------------------------------------------------------------
At this point, a symmetry argument should suffice to persuade
that the output converges to 1/3 and 2/3 (assuming that the
PRNG is valid).
Step 4: Apply symmetry; the choice of 3 is irrelevant.
8<------------------------------------------------------------
pickadoor: function [
rounds [integer!]
][
keepwins
][
keepwins: 0
loop rounds [
if 3 = random 3 [
keepwins: keepwins + 1
]
]
print [
"Keep won" keepwins "rounds,"
"switch won" rounds - keepwins "rounds"
]
]
8<------------------------------------------------------------
Step 5: Just for fun, let's get dense! Compacting words to
one-letter names, pruning constant output strings, and
eschewing layout whitespace...
8<------------------------------------------------------------
REBOL []p: function [n][k r][k: 0
loop n[if 3 = r 3[k: k + 1]]print[k n - k]]
8<------------------------------------------------------------
Step 6: If we're willing to pollute the global namespace,
forego the function, and type the one-liner into the
interactive console each time...
8<------------------------------------------------------------
n: 10000 k: 0 loop n[if 3 = random 3[k: k + 1]]print[k n - k]
8<------------------------------------------------------------
But, IMHO, the persuasion is in the process by which we arrived
at the last version (or maybe a version or two before that... ;-)
and not in its raw output.
-jn-
PS: As I've mentioned before, I have a random process that picks
the sigs on this box. The resonance between topic and the
randomly chosen sig per message has been *really* freaky today!
--
If you think big enough, you'll never have to do it.
-- Reisner's Rule of Conceptual Intertia
joel:FIX:PUNCTUATION:dot:neely:at:fedex:dot:com
[18/22] from: carl:cybercraft at: 17-Dec-2001 21:13
On 17-Dec-01, Carl Read wrote:
> Not being a statistician, (or having a clue what the above code
> does:), my approach to such problems is to simulate them many times
<<quoted lines omitted: 8>>
> description of my code. (: Anyway, it's 151 bytes long for what it's
> worth.
I thought the above was bugged, and it was. Here's a fixed version...
rebol[]k: s: 0 r: func[n][random n]m: does[p: r 3 c: r 3 p = c] loop
10000 [if m[k: k + 1]if not m[s: s + 1]]print ["Kept" k "Switched" s]
Nowhere near as short as some of the other posts, but anyway, here's
my reasoning behind it...
The prize is placed behind one of 3 doors...
prize: random 3
You choose one of the doors...
chosen: random 3
Now, Monty can see if they're a match - ie, if you've picked a
winner...
matched?: prize = chosen
Which returns true if you've chosen the prize. If you decide to keep
this then it's obvious (I hope:) that you had 1 chance in 3 of
picking the prize.
But what if you accept Monty's offer to switch? Well, there's only
two posibilities:
1) You'd chosen the prize, so switching from that means you lose
regardless of what Monty does.
2) You hadn't chosen the prize, Monty exposes the other losing door,
and so you switch to the winning door.
So a switch always means a reversal of your original choice - a
winning choice becoming a losing one and vice-versa. So...
matched?: not matched?
But what happens to the "1 chance in 3 of picking the prize."? Well
that also means you had 2 chances in 3 of losing, right? And the
switch makes an original loss a win, so switching gives you 2 chances
in 3 of winning, thus doubling your chances of a win.
Note that I originally (though vaguely) thought switching would
improve your chances from 1 in 3 to 1 in 2, but this result is much
more fun. (:
--
Carl Read
[19/22] from: sunandadh:aol at: 17-Dec-2001 9:39
Hi Joel,
> It seems to me that the problem in the original post was persuasion
> and not just computation. That being the case, the text of the
<<quoted lines omitted: 4>>
> program that seemed to contain assumptions about the very answer
> I was having trouble with.
I completely agree that a highly compressed program isn't often a great way
to win an argument. But (just to defend myself for a moment) my attempt
embodied all the "rules": I picked a door; Monty picked an empty one of the
other two; I swap to his unopened one. No built-in assumptions there.
i also agree with an earlier post of yours (about Perl and parlor games). The
best test of a programming language isn't how compact a program it can write,
but (I would claim) how easy it is to write maintainable programs in it. But
even that tests mainly the design skills and long-term vision of the
programmer.
A good test of all of our (and Perl and Matlab) solutions is how easily can
they be modified as various "real world" changes are required. Almost by
definition, we can't know what our programs will face over there lifetimes,
but here are a few of the sort of things that might beset a Monty simulator:
-- Not three doors, but 10
-- Not 10 but 25 million doors (challenging many language implementations to
handle this as in-store arrays)
-- Monty opens more than one door
--there is more than one door with a car behind it
-- I get to pick more than one originally, but can only open ONE of mine, OR
one of his once Monty has opened the ones on his side
-- I get to pick more than one door, and Monty opens N of mine and M of his.
-- There are several prizes (a Saab and a Mercedes) including some booby
prizes (A tribe and a yugo maybe). Monty will open up to N doors at random; I
can't win the prize behind an opened door; but I can tell him to stop at any
moment, and then make my choice.
-- The program running as a CGI is so overwhelming popular that it is
swamping the server: rewrite it to use half the cpu cycles.
-- The government will buy 3,000,000 copies but only after the simulation is
run not 500 times but 500,000,000 times. (Rebol can handle this number, but
for most languages
Wins + 1 = Wins
for a sufficiently large value of Wins. If you exceed that, you need extra
special code).
I can see how my solution will naturally extend for some of these; can be
bodged into shape for others; and would be scrapped and rewritten for the
rest. And that's programming!
Sunanda.
[20/22] from: joel:neely:fedex at: 17-Dec-2001 12:27
Hi, Sunanda,
[SunandaDH--aol--com] wrote:
> I completely agree that a highly compressed program isn't often a
> great way to win an argument. But (just to defend myself for a
> moment) ...
>
No defense necessary (except perhaps on my part for poor choice of
wording -- perhaps I should have said "inferences" or "conclusions"
instead of "assumptions")! All I meant was that several of the very
compact solutions were the *result* of reasoning about the problem,
rather than a *record* of the reasoning process itself. In such a
situation, a skeptical audience simply shifts its skepticism to the
program itself, rather than having its skepticism relieved.
> The best test of a programming language isn't how compact a program
> it can write, but (I would claim) how easy it is to write maintain-
> able programs in it. But even that tests mainly the design skills
> and long-term vision of the programmer.
>
Per your following discussion, I believe we'd agree that "ability to
guess -- most of the time -- what is likely to change in the future"
is an important part of "long-term vision".
> A good test of all of our (and Perl and Matlab) solutions is how
> easily can they be modified as various "real world" changes are
> required. Almost by definition, we can't know what our programs
> will face over there lifetimes, but here are a few of the sort of
> things that might beset a Monty simulator:
>
...
> I can see how my solution will naturally extend for some of these;
> can be bodged into shape for others; and would be scrapped and
> rewritten for the rest. And that's programming!
>
A *VERY* interesting and thought-provoking list! Thanks!
-jn-
[21/22] from: carl:cybercraft at: 18-Dec-2001 11:57
On 17-Dec-01, Carl Read wrote:
> Here's a fixed version...
> rebol[]k: s: 0 r: func[n][random n]m: does[p: r 3 c: r 3 p = c] loop
<<quoted lines omitted: 25>>
> switch makes an original loss a win, so switching gives you 2
> chances in 3 of winning, thus doubling your chances of a win.
After showing the above explaination to someone (not on this list)
they still didn't believe it, so I've written a graphical version in
the hope that pictures will win out where words fail... (Not a View
version though - run it from the Console.)
rebol []
doors: func [n c][
d: copy/deep ["[ ]" "[ ]" "[ ]"]
d/:n/2: c
return d
]
game: does [
print " Switching Keeping"
prize: random 3
print ["Prize: " doors prize #"P" " " doors prize #"P"]
guess: random 3
print ["Guess: " doors guess #"G" " " doors guess #"G"]
opened: first random difference [1 2 3] reduce [prize guess]
prin ["Opened:" doors opened #"X"]
prin " "
print either prize = guess [kept: kept + 1 "Win"]["Loss"]
sw: first difference [1 2 3] reduce [guess opened]
print ["Switch:" doors sw #"S"]
prin " "
print either prize = sw [switched: switched + 1 "Win"]["Loss"]
played: played + 1
print [
"Wins: " switched " "
kept
" Played:" played
]
]
played: 0
kept: 0
switched: 0
quit?: false
print ""
while [not quit?][
game
print ""
print "Enter to continue - Esc to quit."
inp: input
quit?: inp = "q"
]
Enough! (:
--
Carl Read
[22/22] from: nitsch-lists:netcologne at: 18-Dec-2001 0:41
RE: [REBOL] Re: A Rebol Challenge. The Monty Hall Puzzle
[carl--cybercraft--co--nz] wrote:
> On 17-Dec-01, Carl Read wrote:
> > Here's a fixed version...
<<quoted lines omitted: 30>>
> the hope that pictures will win out where words fail... (Not a View
> version though - run it from the Console.)
well, thats to complicated to me, i give up.
i have a 2/3 choice to get a priceless door, this chances are
better, and so i want to be priceless.
hey, and if i hit, Monty will show me the other priceless door!
so i have two :)
happy without a price
-Volker ;-)
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted