Skip to content

Instantly share code, notes, and snippets.

@quad
Created December 29, 2010 01:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quad/758007 to your computer and use it in GitHub Desktop.
Save quad/758007 to your computer and use it in GitHub Desktop.
My friend, Dan Coffman, posed a game on his Facebook...
#
# My friend, Dan Coffman, posed a game on his Facebook. Some people answered. I
# didn't believe that one of them was wrong.
#
# A game (reworded to remove misleading 'i.e.'):
#
# The dealer shuffles a deck of cards and reveals them face up one at a time.
# At any time, you can interrupt the dealer and bet that the next card will be
# red. If the card is red, you win. If it is black, you lose. Is there a
# strategy that will allow you to win more than half your games?
#
# Can you explain why/why not?
#
import random
# I don't know shit about statistics, so I don't actually know how many runs is statistically valid.
RUNS = 1000
class Card:
def __init__(self, value):
self.value = value
def is_red(self):
return (self.value % 2) == 0
class Deck(list):
def __init__(self):
self.extend([Card(v) for v in range(52)])
random.shuffle(self)
def test(guess):
seen = []
won, lost = 0, 0
for c in Deck():
if guess(seen):
if c.is_red():
won += 1
else:
lost += 1
seen.append(c)
if (won + lost) > 0:
return won / float(won + lost)
else:
return None
def guess_bias(seen):
number_reds = len(filter(lambda c: c.is_red(), seen))
number_blacks = len(seen) - number_reds
return number_blacks > number_reds
def guess_when_certain(seen):
number_blacks = len(filter(lambda c: not c.is_red(), seen))
return number_blacks == 26
def main():
guessers = [('Always guess red', lambda seen: True),
('Guess when biased', guess_bias),
('Guess when certain', guess_when_certain)]
for title, guess in guessers:
# I'm dropping runs in which a guess is never taken. But they could
# also be 100% wins or 100% loses?
tests = filter(None, [test(guess) for x in xrange(RUNS)])
print "%s: %.4f" % (title, sum(tests) / len(tests))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment