The 16 Game
October 29, 2013
This is a trick question. There is no need to write a program; the solution is easy to work out just by reasoning. The numbers 4 through 16 don’t contribute to the solution, and can be ignored. There are 3! = 6 permutations of the numbers 1 through 3; two of them, (1 2 3) and (2 1 3), are winners, and the other four are losers. Thus, the average winning percentage is one-third. But if you really want to write a program, here it is:
(define (play xs)
(let loop ((xs xs) (one #f) (two #f))
(cond ((= (car xs) 1) (if two #t (loop (cdr xs) #t #f)))
((= (car xs) 2) (if one #t (loop (cdr xs) #f #t)))
((= (car xs) 3) #f)
(else (loop (cdr xs) one two))))))
(define (plays n)
(let loop ((n n) (wins 0))
(if (zero? n) wins
(if (play (shuffle (range 1 17)))
(loop (- n 1) (+ wins 1))
(loop (- n 1) wins)))))
Play
plays a single card; plays
plays n cards. The return value of (plays n)
ought to be about one-third of n:
> (plays 3000)
1010
> (plays 3000)
978
> (plays 3000)
989
It looks like our random number generator is properly uniform. We used range
, randint
and shuffle
from the Standard Prelude. You can run the program at http://programmingpraxis.codepad.org/OQTymiiW.
The only thing that matters is the relative order of 1, 2, and 3 in a permutation. Since 1/3 of the permutations have 1 and 2 before 3, the classical probability of winning is 1/3 and the expected percentage of winning cards in a pack is a little above 33. I didn’t write a program.
Solution in Racket.
Oops! The winning-% function had a bug in the second for*/sum clause.
Trying Nimrod:
A slightly different approach, which recursively calculate the probability. It is “generalized” to take any N >= 3, but that doesn’t matter :-)