{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
Peter Norvig
May 2020
\n", "\n", "# Flipping Cards: A Guessing Game\n", "\n", "The [538 Riddler for Aug. 17, 2018](\n", "https://fivethirtyeight.com/features/step-1-game-theory-step-2-step-3-profit/) poses this problem:\n", "\n", "> Take a standard deck of cards, and pull out the numbered cards from one suit (the nine cards 2 through 10). Shuffle them, and then lay them face down in a row. Flip over the first card so it is face up. Now guess whether the next card in the row (the first down card) is higher or lower. If you’re right, keep going. If you play this game optimally, what’s the probability that you can get to the end without making any mistakes?

\n", "> *Extra credit:* What if there were more cards β€” 2 through 20, or 2 through 100? How do your chances of getting to the end change?\n", " \n", "First, let's define \"*play this game optimally.*\" The optimal policy is to look at the current flipped-up card and, remembering what cards have already been flipped and thus knowing what cards remain face-down, guess that the first down card will be \"higher\" if the majority of the down cards are higher than the up card, otherwise guess that it will be \"lower\". (*Details*: In case of a tie in the counts, guessing either \"higher\" or \"lower\" is equally optimal. When there are only two cards left (one up, one down) you know for sure what the down card is, so you can always guess right.)\n", " \n", "# Brute Force Algorithm\n", " \n", "We can solve the problem with brute force: for every permutation of the cards, call `guess_all` to determine if the optimal policy guesses right on that sequence of cards. Assuming every permutation is equally likely (that is, the cards were shuffled fairly), the overall probability of guessing right is the proportion of `True` results.\n", " \n", "> *Python Trivia*: `True` is equal to `1` and `False` is equal to `0`, so `sum([True, False, True])` is 2; `mean([True, False, True])` is 2/3, and when `b` is a Boolean and `x` is a number, the expression `(b and x)` is equivalent to `(x if b else 0)` and the expression `(x - b)` is equivalent to `((x - 1) if b else x)`. In other languages you would be required (or at least encouraged) to explicitly cast Booleans to integers, but in Python `bool` is a subclass of `int` and it is considered good style to do without casts.\n", " \n", "I can implement `guess_all` as follows:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "from matplotlib import pyplot as plt\n", "from itertools import permutations\n", "from statistics import mean\n", "from functools import lru_cache" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def guess_all(cards) -> bool: \n", " \"\"\"You guess all the cards right if you guess the first right and the rest right.\"\"\"\n", " return len(cards) <= 2 or guess_first(cards) and guess_all(cards[1:])\n", "\n", "def guess_first(cards) -> bool:\n", " \"\"\"Guess that the first down card will be \"higher\" or \"lower\" according to majority \n", " counts of the down cards; return True if the guess is correct.\"\"\"\n", " up, *down = cards\n", " higher = sum(d > up for d in down)\n", " lower = sum(d < up for d in down)\n", " return (higher > lower) == (down[0] > up)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some simple examples:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# On this sequence, the optimal policy always guesses \"higher\"; \n", "# and it turns out that's always right. \n", "guess_all((2, 3, 4, 5, 6))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# On this sequence, the optimal policy guesses \"higher\" first; that's wrong.\n", "# There is a 3/4 chance that a down card is higher than 3, but it turns\n", "# out that the first down card, 2, is the one lower card.\n", "guess_all((3, 2, 4, 5, 6)) " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "guess_first((3, 2, 4, 5, 6))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# The Answer\n", "\n", "The probability that we can guess all nine cards right is the average over all possible permutations of the cards:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.17085537918871252" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cards = \"πŸƒ‚πŸƒƒπŸƒ„πŸƒ…πŸƒ†πŸƒ‡πŸƒˆπŸƒ‰πŸƒŠ\" # Use Unicode cards instead of boring ints; why not?\n", "answer = mean(map(guess_all, permutations(cards)))\n", "answer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's the correct answer ([per 538](https://fivethirtyeight.com/features/how-many-hoops-will-kids-jump-through-to-play-rock-paper-scissors/)): about 17% chance of guessing all nine cards right.\n", "____\n", "\n", "\n", "# Extra Credit: Efficient Algorithm\n", "\n", "The extra credit problem asks about 19 and 99 cards. But there are $19! \\approx 10^{17}$ permutations of 19 cards and a whopping $99! \\approx 10^{156}$ permutations of 99 cards. So my brute force algorithm won't work. \n", "\n", "(*Note*: since we are now dealing with the general case of $n$ cards, I'll represent them as `range(n)`, that is, starting at `0` rather than `2`.)\n", "\n", "# Efficient Algorithm: Analysis\n", "\n", "We will need a more efficient way of representing cards, so that we don't need to consider $n!$ possibilities. I see two ideas that will help. Consider what happens when we are deciding whether to guess \"higher\" or \"lower\" in `guess_first(cards)`: \n", "\n", "**First**, the **order** of the `down` cards doesn't matter. The optimal policy makes the same guess whether `down` is `(2, 3, 4, 5)` or a permutation such as `(4, 2, 5, 3)`. So we could represent cards as a set: `{2, 3, 4, 5}`. As we discard flipped cards, we must consider subsets. Since there are $n!$ permutations but only $2^n$ subsets of $n$ cards, this is a nice improvement, good enough to handle $n=19$ (but not good enough for $n=99$).\n", "\n", "**Second**, the **identity** of the `down` cards doesn't matter. What does matter is how many down cards are higher or lower than the up card. For example, when the up card is `3` it doesn't matter if the remaining cards are `{2, 3, 6}` or `{1, 3, 4}` or `{0, 3, 5}` or any other set of three cards in which the `3` is the middle card. For any such set, there is one card higher and one card lower than the up card, so the chance of guessing right is 50%. Note that I can't represent all these situations as \"*there are 3 cards remaining and the up card is 3*\" but I can represent them as \"*there are 3 cards remaining and the up card is the second lowest*\". \n", "\n", "In other words, I can describe the up card by **renumbering** it to be its index into the sorted list of remaining cards (up and down). For each of the three sets described here, the index of the `3` card is `1`; it is the second element of the sorted list of cards:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "for cards in ({2, 3, 6}, {1, 3, 4}, {0, 3, 5}):\n", " assert sorted(cards).index(3) == 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some further examples of renumbering:\n", "\n", " - [Cards: `{2, 3, 6}` Up: `3`] *renumbered to* [Cards: `range(3)` Up: `1`] (i.e., second lowest)\n", " - [Cards: `{1, 3, 4}` Up: `3`] *renumbered to* [Cards: `range(3)` Up: `1`] (i.e., second lowest)\n", " - [Cards: `{0, 3, 5}` Up: `3`] *renumbered to* [Cards: `range(3)` Up: `1`] (i.e., second lowest)\n", " - [Cards: `{3, 5, 7}` Up: `3`] *renumbered to* [Cards: `range(3)` Up: `0`] (i.e., lowest)\n", " - [Cards: `{0, 1, 3}` Up: `3`] *renumbered to* [Cards: `range(3)` Up: `2`] (i.e., third lowest)\n", "\n", " \n", "Now I can describe any situation with just two integers, the number of cards and the index of the up card. That means there are only $n^2$ possible situations to describe, which should be good enough to handle $n=99$ and beyond. \n", "\n", "What I have done is gone from a **concrete** representation of the cards as explicit permutations to an **abstract** representation that says how many cards remain and what the index number of the up card is, but doesn't say exactly what the cards are nor what order they are in. This kind of abstraction is often a good way to fight against combinatorial explosion.\n", "\n", "\n", "\n", "\n", "# Efficient Algorithm: First Try\n", "\n", "I wanted to define a function, `P_all(n)`, that tells me the probability of guessing all `n` cards right. I wrote down a first try at a definition:\n", "\n", " def P_all(n) -> float:\n", " return 1 if n <= 2 else P_first(n) * P_all(n - 1)\n", " \n", "Could it really be as simple as that? All I have to do is define `P_first(n)` (the probability of guessing the first of `n` cards right) and I'm done? My immediate reaction was that this feels *too* easy. I was suspicious of this definition for three reasons:\n", "\n", "1. It is rare (but not unheard of) for an efficient algorithm to be simpler than the brute force algorithm.\n", "- I said there should be renumbering, but this code doesn't do any renumbering.\n", "- This code says the joint probability of getting the first card right and then getting the rest right is the product of their probabilities. But that's true *only when the two events are independent*. And in flipping cards, the two events are *not* independent, because both events depend on the card that is the first down card in `P_first(n)` and becomes the up card in `P_all(n - 1)`. \n", "\n", "My suspicions were well-founded: this code won't work.\n", "\n", "# Efficient Algorithm: Second Try\n", "\n", "I need to capture the fact that the card that is the first down card for the current guess becomes the up card for the next guess. One way to do that is to define `P_all_given(up, n)` to be the probability of guessing all the cards right given that the flipped-up card has index `up` in the sorted list of `n` remaining cards (including the `up` card).\n", "\n", "Now `P_all(n)` is defined to call `P_all_given(up, n)` for each possible `up` card and average the results:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def P_all(n) -> float:\n", " \"\"\"Probability of guessing all n cards right.\"\"\"\n", " return mean(P_all_given(up, n) for up in range(n))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`P_all_given(up, n)` works by considering each possible first down card (`down1`), computing if we would guess the first down card right given the up card (`guess_first_given(up, down1, n)`), and if right, calling `P_all_given` recursively with the old first down card (renumbered) being the new up card, and the deck size, `n`, being one card smaller. \n", "When this is all done, we take the average probability value over all the down cards. We also arrange for `P_all_given` to cache its values so that we don't repeat computations; this is crucial for efficiency." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "@lru_cache(None)\n", "def P_all_given(up, n) -> float:\n", " \"\"\"Probability of guessing all n cards right, given the index of the up card.\"\"\"\n", " return (1 if n <= 2 else\n", " mean(guess_first_given(up, down1, n) and P_all_given(renumber(down1, up), n - 1)\n", " for down1 in range(n) if down1 != up))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function `guess_first_given(up, down1, n)`, defined below, returns true if we would correctly guess the first down card given the up card. The optimal policy is to guess that the first down card will be higher than the renumbered up card when the up card is in the lower half of `range(n)`. \n", "\n", "And finally, `renumber` renumbers a card by decrementing it by one if the card we are discarding (the up card) is lower (meaning that the card we are keeping becomes one closer to the lowest possible card). Otherwise the card's number is unchanged." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def guess_first_given(up, down1, n) -> bool:\n", " \"\"\"Do we guess the first down card right given the up card, \n", " when the set of cards (including up and down) is range(n)?\"\"\"\n", " return (up < n / 2) == (down1 > up)\n", "\n", "def renumber(card, discard) -> int: return card - (discard < card)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that `P_all(n)` agrees with the brute-force answer (except for round-off in the 17th decimal place):" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.17085537918871255\n", "0.17085537918871252\n" ] } ], "source": [ "print(P_all(9))\n", "print(answer)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# The Extra Credit Answers\n", "\n", "We can now efficiently answer the extra credit questions:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.008419397002884993" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P_all(19)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6.67213407124781e-14" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P_all(99)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The moral is: give yourself at least about 100 tries to guess 19 cards right, and don't expect to *ever* guess 99 cards right.\n", "\n", "# Closed Form Formula?\n", "\n", "I would like to come up with a closed-form formula for `P_all(n)` as a function of $n$. I don't see how to define an *exact* formula, but I can see that:\n", "- When the up card is the very middle of the remaining cards, we have a 50% chance of guessing the next card right.\n", "- When the up card is the very highest or very lowest of the remaining cards, we have a 100% chance of guessing the next card right.\n", "- So on average (very roughly speaking), we should have about a 75% chance of guessing right on each card.\n", "- In a full deck we make $n - 2$ guesses (we don't have to guess the first card, and we will know the last card for sure).\n", "- Therefore, the chance of guessing all the cards right is roughly $0.75^{(n-2)}$\n", "\n", "If the exponential formula $0.75^{(n-2)}$ were correct, then it would be true that `P_all(n + 1) / P_all(n) = 0.75` for all `n`. Let's sample some values of `n` and see:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{2: 0.8333333333333334,\n", " 3: 0.8,\n", " 4: 0.775,\n", " 5: 0.7688172043010753,\n", " 6: 0.7587412587412588,\n", " 7: 0.7557603686635944,\n", " 8: 0.7500967866821525,\n", " 9: 0.7483290322580645,\n", " 19: 0.7343228066190575,\n", " 39: 0.7277139939871775,\n", " 59: 0.7255656153885536,\n", " 79: 0.7245013548920631,\n", " 99: 0.7238659386192225,\n", " 199: 0.7226021071682432,\n", " 299: 0.7221828896968574,\n", " 399: 0.7219736649122889}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Ns = [*range(2, 10), *range(19, 99, 20), *range(99, 400, 100)]\n", "\n", "{n: P_all(n + 1) / P_all(n) \n", " for n in Ns}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see that the ratio starts higher than 0.75 and becomes lower. That means that `P_all(n)` is not exactly an exponential function.\n", "\n", "How close is it? Let's draw a plot to see. We'll use a log scale, on which an exponential is a straight (blue) line. I use 0.725 as the base for the exponential, which nicely highlights that the `P_all(n)` data points (red) start out and end up on the blue exponential line, but rise slightly above it in the middle. Still the points are a very good fit to the line, considering that they span 56 orders of magnitude. I also show the line for `0.75 ** (n - 2)`; all the data points except the first few are well below that." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "

" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "base = 0.725\n", "\n", "X = range(2, 400, 4)\n", "P = [P_all(n) for n in X]\n", "E = [base ** (n - 2) for n in X]\n", "G = [0.75 ** (n - 2) for n in X]\n", "\n", "plt.figure(figsize=(9, 9))\n", "plt.yscale('log')\n", "plt.xlabel(\"Number of Cards, n\")\n", "plt.ylabel(\"Probability of Guessing All Right (log scale)\")\n", "plt.plot(X, G, 'g:', label='0.750 ** (n-2)')\n", "plt.plot(X, E, 'b-', lw=2, label=f'{base} ** (n-2)')\n", "plt.plot(X, P, 'r.', label='P_all(n)')\n", "plt.legend();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Computational Complexity: O(n) Notation \n", "\n", "The brute force algorithm, with `guess_all(n)`, requires $O(n!)$ computation time because it considers every permutation of $n$ cards.\n", "\n", "In the efficient algorithm, `P_all(n)` makes $n$ calls to `P_all_given`, and each call to `P_all_given` considers $n$ down cards and makes recursive calls only when `guess_first_given(up, down1, n)` returns true. Some of those calls have already been computed and are cached. It seems complicated to do an exact analysis. \n", "\n", "However, if we assume that the majority of the work done by `P_all` is inside a call to `P_all_given`, and note that both of `P_all_given`'s arguments are restricted to $n$ possible values, then we can conclude that only $O(n^2)$ unique calls can be made. Repeated calls will fetch results from the cache in constant time. Therefore `P_all` is $O(n^2)$.\n", "\n", "Experimental evidence shows that for every value of `n` tested so far, a call to `P_all(n)` does *exactly* $n \\times (n + 1) / 2 - 1$ unique calls to `P_all_given`. We can determine this by looking at the number of elements in the function's cache.\n", "\n", "In the table below, `n` is the number of cards, `s` is the size of the cache, and we see that `s` is always equal to $c = n \\times (n + 1) / 2 - 1$. \n", "\n", "The last four columns of the table don't deal with computational complexity. They give the value of `P_all(n)`, the ratio `P_all(n + 1) / P_all(n)`, the approximation `base ** (n - 2)`, and the percentage difference between the true value and the approximation." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " n | s | s==c ||P_all(n) |P(n+1)/P(n)|base**(n-2)| Ξ”(P, 0.725**(n-2))\n", "β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”||β€”β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”\n", " 2 | 2 | True || 1.0e+00 | 0.8333 | 1.0e+00 | 0%\n", " 3 | 5 | True || 8.3e-01 | 0.8000 | 7.2e-01 | 13%\n", " 4 | 9 | True || 6.7e-01 | 0.7750 | 5.3e-01 | 21%\n", " 5 | 14 | True || 5.2e-01 | 0.7688 | 3.8e-01 | 26%\n", " 6 | 20 | True || 4.0e-01 | 0.7587 | 2.8e-01 | 30%\n", " 7 | 27 | True || 3.0e-01 | 0.7558 | 2.0e-01 | 34%\n", " 8 | 35 | True || 2.3e-01 | 0.7501 | 1.5e-01 | 36%\n", " 9 | 44 | True || 1.7e-01 | 0.7483 | 1.1e-01 | 38%\n", " 19 | 189 | True || 8.4e-03 | 0.7343 | 4.2e-03 | 50%\n", " 39 | 779 | True || 1.6e-05 | 0.7277 | 6.8e-06 | 57%\n", " 59 | 1,769 | True || 2.6e-08 | 0.7256 | 1.1e-08 | 58%\n", " 79 | 3,159 | True || 4.2e-11 | 0.7245 | 1.8e-11 | 58%\n", " 99 | 4,949 | True || 6.7e-14 | 0.7239 | 2.8e-14 | 57%\n", " 199 | 19,899 | True || 5.5e-28 | 0.7226 | 3.1e-28 | 45%\n", " 299 | 44,849 | True || 4.2e-42 | 0.7222 | 3.3e-42 | 20%\n", " 399 | 79,799 | True || 3.0e-56 | 0.7220 | 3.6e-56 | -19%\n" ] } ], "source": [ "P_all_given.cache_clear()\n", "\n", "print(f' n | s | s==c ||P_all(n) |P(n+1)/P(n)|base**(n-2)| Ξ”(P, {base}**(n-2))')\n", "print(f'β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”||β€”β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”|β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”')\n", "for n in Ns:\n", " p = P_all(n)\n", " s = P_all_given.cache_info().currsize\n", " c = n * (n + 1) / 2 - 1\n", " e = base ** (n - 2)\n", " r = P_all(n + 1) / P_all(n)\n", " Ξ” = (p - e) / p\n", " print(f'{n:4d} | {s:6,d} | {s == c} ||{p:8.1e} | {r:6.4f} | {e:8.1e} | {Ξ”:3.0%}')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 2 }