diff --git a/ipynb/Coin Flip.ipynb b/ipynb/Coin Flip.ipynb index 4409ee5..afae6da 100644 --- a/ipynb/Coin Flip.ipynb +++ b/ipynb/Coin Flip.ipynb @@ -24,26 +24,29 @@ "\n", "- We're looking for a \"shortest sequence of moves\" that reaches a goal. That's a [shortest path search problem](https://en.wikipedia.org/wiki/Shortest_path_problem). I've done that before.\n", "- Since the Devil gets to make moves too, you might think that this is a [minimax](https://en.wikipedia.org/wiki/Minimax) problem: that we should choose the move that leads to the shortest path, given that the Devil has the option of making moves that lead to the longest path.\n", - "- But minimax only works when you know what moves the opponent is making: he did *that*, so I'll do *this*. In this problem the player is blinfolded; that makes it a [partially observable problem](https://en.wikipedia.org/wiki/Partially_observable_system) (in this case, not observable at all, but we still say \"partially\").\n", + "- But minimax only works when you know what moves the opponent is making: he did *that*, so I'll do *this*. In this problem the player is blinfolded; that makes it a [partially observable problem](https://en.wikipedia.org/wiki/Partially_observable_system) (in this case, not observable at all, but it is traditional to say \"partially\").\n", "- In such problems, we don't know for sure the true state of the world before or after any move. So we should represent what *is* known: *the set of states that we believe to be possible*. We call this a *belief state*. At the start of the game, each of the four coins could be either heads or tails, so that's 24 = 16 possibilities in the initial belief state:\n", " {HHHH, HHHT, HHTH, HHTT, HTHH, HTHT, HTTH, HTTT, \n", " THHH, THHT, THTH, THTT, TTHH, TTHT, TTTH, TTTT}\n", - "- So we have a single-agent shortest path search in the space of belief states (not the space of physical states of the coins). We search for a path from the inital belief state to the goal belief state, which is `{HHHH}`.\n", + "- So we have a single-agent shortest-path search in the space of belief states (not the space of physical states of the coins). We search for a path from the inital belief state to the goal belief state, which is `{HHHH}` (meaning that 4 heads is the only possibility).\n", "- A move updates the belief state as follows: for every four-coin sequence in the current belief state, rotate it in every possible way, and then flip the coins specified by the position(s) in the move. Collect all these results together to form the new belief state. The search space is small (just 216 possible belief states), so run time will be fast. \n", - "- I'll Keep It Simple, and not worry about rotational symmetry (although we'll come back to that later).\n", + "- I'll [Keep It Simple](https://en.wikipedia.org/wiki/KISS_principle), and not worry about rotational symmetry (although we'll come back to that later).\n", "\n", "\n", "# Basic Data Structures and Functions\n", "\n", "What data structures will I be dealing with?\n", "\n", + "\n", + "\n", "- `Coins`: a *coin sequence* (four coins, in order, on the table) is represented as a `str` of four characters, such as `'HTTT'`. \n", "- `Belief`: a *belief state* is a `frozenset` of `Coins` (frozen so it can be hashed), like `{'HHHT', 'TTTH'}`.\n", - "- `Position`: an integer index into the coin sequence; position `0` selects the `H` in `'HTTT'`\n", - "and corresponds to the 12 o'clock position; position 1 corresponds to 3 o'clock, and so on.\n", + "- `Position`: an integer index into the coin sequence; position `0` selects the `H` in `'HTTT'`.\n", "- `Move`: a set of positions to flip, such as `{0, 2}`. \n", "- `Strategy`: an ordered list of moves. A\n", - "blindfolded player has no feedback, there thus no decision points in the strategy. " + "blindfolded player has no feedback, thus there are no decision points in the strategy. \n", + "\n", + "I take the coin sequence `'HTTT'` to mean there is an `'H'` at the 12 o'clock position, then 3, , 6, and 9 o'clock in that order are `'T'`." ] }, { @@ -60,7 +63,7 @@ "Belief = frozenset # A set of possible coin sequences: {'HHHT', 'TTTH'}.\n", "Position = int # An index into a coin sequence.\n", "Move = set # A set of positions to flip: {0, 2}\n", - "Strategy = list # A list of Moves: [{0, 1, 2, 3}, {0, 2}, ...]" + "Strategy = tuple # A sequence of Moves: ({0, 1, 2, 3}, {0, 2}, ...)" ] }, { @@ -83,9 +86,9 @@ "metadata": {}, "outputs": [], "source": [ - "def all_moves() -> [Move]: \n", + "def all_moves() -> (Move,): \n", " \"List of all possible moves.\"\n", - " return [set(m) for m in powerset(range(4))]\n", + " return tuple(map(Move, powerset(range(4))))\n", "\n", "def all_coins() -> Belief:\n", " \"The belief set consisting of all possible coin sequences.\"\n", @@ -129,33 +132,7 @@ "cell_type": "code", "execution_count": 3, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[set(),\n", - " {0},\n", - " {1},\n", - " {2},\n", - " {3},\n", - " {0, 1},\n", - " {0, 2},\n", - " {0, 3},\n", - " {1, 2},\n", - " {1, 3},\n", - " {2, 3},\n", - " {0, 1, 2},\n", - " {0, 1, 3},\n", - " {0, 2, 3},\n", - " {1, 2, 3},\n", - " {0, 1, 2, 3}]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "all_moves()" ] @@ -164,33 +141,7 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "frozenset({'HHHH',\n", - " 'HHHT',\n", - " 'HHTH',\n", - " 'HHTT',\n", - " 'HTHH',\n", - " 'HTHT',\n", - " 'HTTH',\n", - " 'HTTT',\n", - " 'THHH',\n", - " 'THHT',\n", - " 'THTH',\n", - " 'THTT',\n", - " 'TTHH',\n", - " 'TTHT',\n", - " 'TTTH',\n", - " 'TTTT'})" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "all_coins()" ] @@ -324,14 +275,14 @@ " \"Breadth-first search from start state to goal; return strategy to get to goal.\"\n", " explored = set()\n", " queue = deque([(Strategy(), start)])\n", - " while queue:\n", + " while queue: # Entries in queue are (move_sequence, end_state) pairs\n", " (strategy, state) = queue.popleft()\n", " if state == goal:\n", " return strategy\n", " for action in actions:\n", " state2 = result(state, action)\n", " if state2 not in explored:\n", - " queue.append((strategy + [action], state2))\n", + " queue.append((strategy + (action,), state2))\n", " explored.add(state2)" ] }, @@ -352,7 +303,7 @@ { "data": { "text/plain": [ - "[{0, 1, 2, 3},\n", + "({0, 1, 2, 3},\n", " {0, 2},\n", " {0, 1, 2, 3},\n", " {0, 1},\n", @@ -366,7 +317,7 @@ " {0, 1},\n", " {0, 1, 2, 3},\n", " {0, 2},\n", - " {0, 1, 2, 3}]" + " {0, 1, 2, 3})" ] }, "execution_count": 10, @@ -394,12 +345,12 @@ "\n", "# Verifying the Winning Strategy\n", "\n", - "I don't have a proof, but I have some evidence that this strategy works:\n", + "I don't have a proof, but I have some evidence that this strategy is the answer:\n", "- Exploring with paper and pencil, it looks good. \n", "- A colleague did the puzzle and got the same answer. \n", - "- It passes the `winning` test below.\n", + "- It passes the `probably_wins` test below.\n", "\n", - "The call `winning(strategy, k)` plays the strategy *k* times against a Devil that chooses starting positions and rotations at random. Note this is dealing with concrete, individual states of the world, like `HTHH`, not belief states. If `winning` returns `False`, then the strategy is *definitely* flawed. If it returns `True`, then the strategy is *probably* good—it won *k* times in a row—but that does not prove it will win every time (and either way `winning` makes no claims about being a *shortest* strategy)." + "The call `probably_wins(strategy, k)` plays the strategy * k* times against each possible starting position, assuming a Devil that chooses rotations at random. Note this is dealing with concrete, individual states of the world, like `HTHH`, not belief states. If `probably_wins` returns `False`, then the strategy is *definitely* flawed. If it returns `True`, then the strategy is *probably* good, but that does not prove it will win every time (and either way `probably_wins` makes no claims about being a *shortest* strategy)." ] }, { @@ -419,32 +370,30 @@ } ], "source": [ - "def winning(strategy, k=100000) -> bool:\n", + "def probably_wins(strategy, k=1000) -> bool:\n", " \"Is this a winning strategy? A probabilistic algorithm.\"\n", - " return all(play(strategy) == 'HHHH'\n", + " return all('T' not in play(strategy, coins)\n", + " for coins in all_coins() \n", " for _ in range(k))\n", "\n", - "def play(strategy, starting_coins=list(all_coins())) -> Coins:\n", - " \"Play strategy for one game against a random Devil; return final state of coins.\"\n", - " coins = random.choice(starting_coins)\n", + "def play(strategy, coins) -> Coins:\n", + " \"Play strategy for one game against a random Devil, starting with coins; return final state of coins.\"\n", " for move in strategy:\n", " if 'T' not in coins: return coins\n", " coins = random.choice(list(rotations(coins)))\n", " coins = flip(coins, move)\n", " return coins\n", "\n", - "winning(strategy=coin_search())" + "probably_wins(strategy=coin_search())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "# Canonical Coin Sequences and Moves\n", "\n", - "\n", - "# Canonical Coin Sequences\n", - "\n", - "Consider these coin sequences: `{'HHHT', 'HHTH', 'HTHH', 'THHH'}`. In a sense, these are all the same: they all denote the same sequence of coins with the table rotated to different degrees. Since the devil is free to rotate the table any amount at any time, we could be justified in treating all four of these as equivalent, and collapsing them into one representative member. I will **redefine** `Coins` so that is stil takes an iterable of `'H'` or `'T'` characters and joins them into a `str`, but I will make it consider all possible rotations of the string and (arbitraily) choose the one that comes first in alphabetical order (which would be `'HHHT'` for the four coin sequences mentioned here)." + "Consider these coin sequences: `{'HHHT', 'HHTH', 'HTHH', 'THHH'}`. In a sense, these are all the same: they all denote the same sequence of coins with the table rotated to different degrees. Since the devil is free to rotate the table any amount at any time, we could be justified in treating all four of these as equivalent, and collapsing them into one representative member. I will **redefine** `Coins` so that is still takes an iterable of `'H'` or `'T'` characters and joins them into a `str`, but I will make it consider all possible rotations of the resulting string and (arbitraily) choose the one that comes first in alphabetical order (which would be `'HHHT'` for the four coin sequences mentioned here)." ] }, { @@ -498,37 +447,78 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The starting belief set is down from 16 to 6, namely 4 heads, 3 heads, 2 adjacent heads, 2 opposite heads, 1 head, and no heads, respectively. \n", + "The starting belief set is down from 16 to 6, namely: {4 heads, 3 heads, 2 adjacent heads, 2 opposite heads, 1 head, and no heads}, respectively. \n", "\n", - "Let's make sure we didn't break anything and that we get the same 15-step solution:" + "Now for canonical moves. The moves `{0}` and `{1}` should be considered the same, since they both say \"flip one coin.\" To get that, look at the canonicalized set of `all_coins(N)`, and for each one pull out the set of positions that have an `H` in them and flip those positions. (The positions with a `T` should be symmetric, so we don't need them as well.)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, + "outputs": [], + "source": [ + "def all_moves() -> [Move]:\n", + " \"All canonical moves.\"\n", + " return [Move(i for i in range(4) if coins[i] == 'H')\n", + " for coins in sorted(all_coins())]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[{0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3},\n", - " {0, 1},\n", - " {0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3},\n", - " {0},\n", - " {0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3},\n", - " {0, 1},\n", - " {0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3}]" + "[{0, 1, 2, 3}, {0, 1, 2}, {0, 1}, {0, 2}, {0}, set()]" ] }, - "execution_count": 15, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_moves()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So again we've gone down from 16 to 6.\n", + "\n", + "Let's make sure we didn't break anything and that we still get the same 15-step solution:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3})" + ] + }, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -541,22 +531,20 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Winning Strategies for *N* Coins\n", + "# Winning Strategies for N Coins\n", "\n", - "What if there are 3 coins on the table arranged in a triangle? Or 6 coins in a hexagon? To answer that, I'll generalize all the functions that have a \"4\" in them: `all_moves, all_coins`, `rotations` and `coin_search`.\n", - "\n", - "Computing `all_coins(N)` is easy; just take the product, and canonicalize each one with the new definition of `Coins`. For `all_moves(N)` I want canonicalized moves: the moves `{0}` and `{1}` should be considered the same, since they both say \"flip one coin.\" To get that, look at the canonicalized set of `all_coins(N)`, and for each one pull out the set of positions that have an `H` in them and flip those positions. (The positions with a `T` should be symmetric, so we don't need them as well.)" + "What if there are 3 coins on the table arranged in a triangle? Or 6 coins in a hexagon? To answer that, I'll generalize all the functions that have a \"4\" in them: `all_moves, all_coins`, `rotations` and `coin_search`, as well as `probably_wins`. In each case the chage is trivial." ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "def all_moves(N=4) -> [Move]:\n", " \"All canonical moves for a sequence of N coins.\"\n", - " return [set(i for i in range(N) if coins[i] == 'H')\n", + " return [Move(i for i in range(N) if coins[i] == 'H')\n", " for coins in sorted(all_coins(N))]\n", "\n", "def all_coins(N=4) -> Belief:\n", @@ -569,7 +557,13 @@ "\n", "def coin_search(N=4) -> Strategy: \n", " \"Use the generic `search` function to solve the Coin Flip problem.\"\n", - " return search(start=all_coins(N), goal={'H' * N}, actions=all_moves(N), result=update)" + " return search(start=all_coins(N), goal={'H' * N}, actions=all_moves(N), result=update)\n", + "\n", + "def probably_wins(strategy, N=4, k=1000) -> bool:\n", + " \"Is this a winning strategy? A probabilistic algorithm.\"\n", + " return all('T' not in play(strategy, coins)\n", + " for coins in all_coins(N) \n", + " for _ in range(k))" ] }, { @@ -581,7 +575,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -594,24 +588,41 @@ "assert rotations('HHHHHT') == {'HHHHHT', 'HHHHTH', 'HHHTHH', 'HHTHHH', 'HTHHHH', 'THHHHH'}\n", "assert update({'TTTTTTT'}, {3}) == {'HTTTTTT'}\n", "assert (update(rotations('HHHHHT'), {0}) == update({'HHTHHH'}, {1}) == update({'THHHHH'}, {2})\n", - " == {'HHHHHH', 'HHHHTT', 'HHHTHT', 'HHTHHT'})\n", - "\n", - "assert coin_search(4) == [\n", - " {0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3},\n", - " {0, 1},\n", - " {0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3},\n", - " {0, 1, 2},\n", - " {0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3},\n", - " {0, 1},\n", - " {0, 1, 2, 3},\n", - " {0, 2},\n", - " {0, 1, 2, 3}]" + " == {'HHHHHH', 'HHHHTT', 'HHHTHT', 'HHTHHT'})" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3})" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "coin_search(4)" ] }, { @@ -623,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -643,7 +654,7 @@ " 12: 352}" ] }, - "execution_count": 18, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -657,23 +668,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "On the one hand this is encouraging; there are only 352 canonical coin sequences of length 12, far less than the 4,096 non-canonical squences. On the other hand, it is discouraging; since we are searching over belief states, that would be 2352 belief states, which is nore than a googol. However, we should be able to easily handle up to N=7, because 220 is only a million.\n", + "On the one hand this is encouraging; there are only 352 canonical coin sequences of length 12, far less than the 4,096 non-canonical squences. On the other hand, it is discouraging; since we are searching over belief states, that would be 2352 belief states, which is more than a googol. However, we should be able to easily handle up to N=7, because 220 is only a million.\n", "\n", - "# Winning Strategies for 1 to 7 Coins" + "# Winning Strategies for N = 1 to 7 Coins" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{1: [{0}],\n", - " 2: [{0, 1}, {0}, {0, 1}],\n", + "{1: ({0},),\n", + " 2: ({0, 1}, {0}, {0, 1}),\n", " 3: None,\n", - " 4: [{0, 1, 2, 3},\n", + " 4: ({0, 1, 2, 3},\n", " {0, 2},\n", " {0, 1, 2, 3},\n", " {0, 1},\n", @@ -687,13 +698,13 @@ " {0, 1},\n", " {0, 1, 2, 3},\n", " {0, 2},\n", - " {0, 1, 2, 3}],\n", + " {0, 1, 2, 3}),\n", " 5: None,\n", " 6: None,\n", " 7: None}" ] }, - "execution_count": 19, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -708,7 +719,7 @@ "source": [ "Too bad; there are no winning strategies for N = 3, 5, 6, or 7. \n", "\n", - "There *are* winning strategies for N = 1, 2, 4; they have lengths 1, 3, 15, respectively. Hmm. That suggests ...\n", + "There *are* winning strategies for N = 1, 2, 4; they have lengths 1, 3, 15, respectively. Hmmm. That suggests ...\n", "\n", "# A Conjecture\n", "\n", @@ -722,25 +733,45 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 1min 10s, sys: 119 ms, total: 1min 11s\n", - "Wall time: 1min 11s\n" + "CPU times: user 1min 13s, sys: 208 ms, total: 1min 13s\n", + "Wall time: 1min 13s\n" ] } ], "source": [ - "%time strategy = coin_search(8)" + "%time strategy8 = coin_search(8)" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "probably_wins(strategy8, N=8, k=100)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -749,13 +780,13 @@ "255" ] }, - "execution_count": 21, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "len(strategy)" + "len(strategy8)" ] }, { @@ -763,7 +794,8 @@ "metadata": {}, "source": [ "**Eureka!** That's evidence in favor of the conjecture. But not proof. And it leaves many questions unanswered:\n", - "- Can you show there are no winning strategies for *N* = 9, 10, 11, ...?\n", + "- Can you show there are no winning strategies for *N* = 9? Currently, `coin_search(9)` should take about 20 million minutes.\n", + "- Can you show there are no winning strategies for *N* = 10, 11, ...?\n", "- Can you prove there are no winning strategies for any *N* that is not a power of 2?\n", "- Can you find a winning strategy of length 65,535 for *N* = 16 and verify that it works?\n", "- Can you generate a winning strategy for any power of 2 (without proving it is shortest)?\n", @@ -784,7 +816,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -792,8 +824,10 @@ " \"For each move, print the move number, move, and belief state.\"\n", " belief = all_coins(N)\n", " order = sorted(belief)\n", + " print('Move| Flips | Belief State')\n", + " print('----+----------+-------------')\n", " def show(i, move, order=sorted(belief)):\n", - " print('{:3} | {:8} | {}'.format(i, movestr(move, N), beliefstr(belief, order)))\n", + " print(f'{i:3} | {movestr(move, N):8} | {beliefstr(belief, order)}')\n", " show(0, set())\n", " for (i, move) in enumerate(moves, 1):\n", " belief = update(belief, move)\n", @@ -820,13 +854,15 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "Move| Flips | Belief State\n", + "----+----------+-------------\n", " 0 | | HH HT TT\n", " 1 | 01 | HH HT \n", " 2 | 0 | HH TT\n", @@ -840,13 +876,15 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "Move| Flips | Belief State\n", + "----+----------+-------------\n", " 0 | | HHHH HHHT HHTT HTHT HTTT TTTT\n", " 1 | 0123 | HHHH HHHT HHTT HTHT HTTT \n", " 2 | 0 2 | HHHH HHHT HHTT HTTT TTTT\n", @@ -881,22 +919,23 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - " 1: HHTH rot: HTHH flip: 0123 => HTTT\n", - " 2: HTTT rot: TTTH flip: 0 2 => HHHT\n", - " 3: HHHT rot: HHTH flip: 0123 => HTTT\n", - " 4: HTTT rot: THTT flip: 01 => HTTT\n", - " 5: HTTT rot: TTHT flip: 0123 => HHHT\n", - " 6: HHHT rot: HTHH flip: 0 2 => HTTT\n", - " 7: HTTT rot: HTTT flip: 0123 => HHHT\n", - " 8: HHHT rot: HHHT flip: 012 => TTTT\n", - " 9: TTTT rot: TTTT flip: 0123 => HHHH\n" + " 1: HHTH | rot: THHH | flip: 0123 HTTT\n", + " 2: HTTT | rot: HTTT | flip: 0 2 HTTT\n", + " 3: HTTT | rot: THTT | flip: 0123 HHHT\n", + " 4: HHHT | rot: HHTH | flip: 01 HTTT\n", + " 5: HTTT | rot: HTTT | flip: 0123 HHHT\n", + " 6: HHHT | rot: HHHT | flip: 0 2 HTTT\n", + " 7: HTTT | rot: HTTT | flip: 0123 HHHT\n", + " 8: HHHT | rot: HTHH | flip: 012 HTHT\n", + " 9: HTHT | rot: THTH | flip: 0123 HTHT\n", + " 10: HTHT | rot: THTH | flip: 0 2 HHHH\n" ] }, { @@ -905,14 +944,14 @@ "'HHHH'" ] }, - "execution_count": 25, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "def play(coins, strategy, verbose=False):\n", - " \"Play strategy against a random Devil; return final state of coins.\"\n", + "def play(strategy, coins, verbose=False):\n", + " \"Play strategy for one game against a random Devil, starting with coins; return final state of coins.\"\n", " N = len(coins)\n", " for i, move in enumerate(strategy, 1):\n", " if 'T' not in coins: return coins\n", @@ -920,174 +959,276 @@ " coins1 = random.choice(list(rotations(coins)))\n", " coins = flip(coins1, move)\n", " if verbose: \n", - " print('{:4d}: {} rot: {} flip: {} => {}'.format(\n", - " i, coins0, coins1, movestr(move, N), coins))\n", + " print(f'{i:4d}: {coins0} | rot: {coins1} | flip: {movestr(move, N)} {coins}')\n", " return coins\n", "\n", - "play('HHTH', coin_search(4), True)" + "play(coin_search(4), 'HHTH', True)" ] }, { "cell_type": "code", - "execution_count": 26, - "metadata": {}, + "execution_count": 30, + "metadata": { + "scrolled": false + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - " 1: HTTHTTHT rot: HTTHTHTT flip: 01234567 => HHTHHTHT\n", - " 2: HHTHHTHT rot: HTHHTHHT flip: 0 2 4 6 => HHHTTTTT\n", - " 3: HHHTTTTT rot: TTHHHTTT flip: 01234567 => HHHHHTTT\n", - " 4: HHHHHTTT rot: THHHHHTT flip: 01 45 => HHTTTTHT\n", - " 5: HHTTTTHT rot: THTHHTTT flip: 01234567 => HHHHTHTT\n", - " 6: HHHHTHTT rot: HHTHTTHH flip: 0 2 4 6 => HHHHTTHT\n", - " 7: HHHHTTHT rot: HHHTTHTH flip: 01234567 => HHTHTTTT\n", - " 8: HHTHTTTT rot: HTTTTHHT flip: 012 456 => HHTHTTTT\n", - " 9: HHTHTTTT rot: THHTHTTT flip: 01234567 => HHHHTTHT\n", - " 10: HHHHTTHT rot: HTHHHHTT flip: 0 2 4 6 => HHTTTTHT\n", - " 11: HHTTTTHT rot: THHTTTTH flip: 01234567 => HHHHTHTT\n", - " 12: HHHHTHTT rot: THHHHTHT flip: 01 45 => HHTHHTHT\n", - " 13: HHTHHTHT rot: THHTHTHH flip: 01234567 => HTHTTHTT\n", - " 14: HTHTTHTT rot: THTTHTHT flip: 0 2 4 6 => HHHTTTTT\n", - " 15: HHHTTTTT rot: TTTHHHTT flip: 01234567 => HHHHHTTT\n", - " 16: HHHHHTTT rot: THHHHHTT flip: 0123 => HHTTHTTT\n", - " 17: HHTTHTTT rot: TTHHTTHT flip: 01234567 => HHHTTHHT\n", - " 18: HHHTTHHT rot: THHTHHHT flip: 0 2 4 6 => HHTTTHTT\n", - " 19: HHTTTHTT rot: TTHTTHHT flip: 01234567 => HHHTHHTT\n", - " 20: HHHTHHTT rot: THHTTHHH flip: 01 45 => HHHTHTHT\n", - " 21: HHHTHTHT rot: THTHHHTH flip: 01234567 => HTHTHTTT\n", - " 22: HTHTHTTT rot: THTTTHTH flip: 0 2 4 6 => HHHHHHHT\n", - " 23: HHHHHHHT rot: THHHHHHH flip: 01234567 => HTTTTTTT\n", - " 24: HTTTTTTT rot: TTTTTTHT flip: 012 456 => HHHTHHTT\n", - " 25: HHHTHHTT rot: HHTTHHHT flip: 01234567 => HHTTTHTT\n", - " 26: HHTTTHTT rot: TTHHTTTH flip: 0 2 4 6 => HHHTTHHT\n", - " 27: HHHTTHHT rot: HTTHHTHH flip: 01234567 => HHTTHTTT\n", - " 28: HHTTHTTT rot: TTTHHTTH flip: 01 45 => HHHTHTHT\n", - " 29: HHHTHTHT rot: THTHHHTH flip: 01234567 => HTHTHTTT\n", - " 30: HTHTHTTT rot: THTTTHTH flip: 0 2 4 6 => HHHHHHHT\n", - " 31: HHHHHHHT rot: HHHHTHHH flip: 01234567 => HTTTTTTT\n", - " 32: HTTTTTTT rot: THTTTTTT flip: 01234 6 => HHHTHTHT\n", - " 33: HHHTHTHT rot: HTHHHTHT flip: 01234567 => HTHTHTTT\n", - " 34: HTHTHTTT rot: TTHTHTHT flip: 0 2 4 6 => HTTTTTTT\n", - " 35: HTTTTTTT rot: TTTTTHTT flip: 01234567 => HHHHHHHT\n", - " 36: HHHHHHHT rot: HTHHHHHH flip: 01 45 => HHHTTHHT\n", - " 37: HHHTTHHT rot: HHTTHHTH flip: 01234567 => HHTTHTTT\n", - " 38: HHTTHTTT rot: HHTTHTTT flip: 0 2 4 6 => HHTTTHTT\n", - " 39: HHTTTHTT rot: TTHTTHHT flip: 01234567 => HHHTHHTT\n", - " 40: HHHTHHTT rot: HHHTHHTT flip: 012 456 => HTTTTTTT\n", - " 41: HTTTTTTT rot: THTTTTTT flip: 01234567 => HHHHHHHT\n", - " 42: HHHHHHHT rot: HHHHHHTH flip: 0 2 4 6 => HHHTHTHT\n", - " 43: HHHTHTHT rot: HTHTHHHT flip: 01234567 => HTHTHTTT\n", - " 44: HTHTHTTT rot: TTHTHTHT flip: 01 45 => HHHTTHHT\n", - " 45: HHHTTHHT rot: HTTHHTHH flip: 01234567 => HHTTHTTT\n", - " 46: HHTTHTTT rot: TTHHTTHT flip: 0 2 4 6 => HHTTTHTT\n", - " 47: HHTTTHTT rot: HTTTHTTH flip: 01234567 => HHHTHHTT\n", - " 48: HHHTHHTT rot: THHHTHHT flip: 0123 => HHTHTTTT\n", - " 49: HHTHTTTT rot: TTTHHTHT flip: 01234567 => HHHHTTHT\n", - " 50: HHHHTTHT rot: TTHTHHHH flip: 0 2 4 6 => HHTTTTHT\n", - " 51: HHTTTTHT rot: HTHHTTTT flip: 01234567 => HHHHTHTT\n", - " 52: HHHHTHTT rot: HHHTHTTH flip: 01 45 => HTHTTHTT\n", - " 53: HTHTTHTT rot: THTTHTHT flip: 01234567 => HHTHHTHT\n", - " 54: HHTHHTHT rot: THHTHTHH flip: 0 2 4 6 => HHHTTTTT\n", - " 55: HHHTTTTT rot: TTTTTHHH flip: 01234567 => HHHHHTTT\n", - " 56: HHHHHTTT rot: HTTTHHHH flip: 012 456 => HHTTTTHT\n", - " 57: HHTTTTHT rot: TTTHTHHT flip: 01234567 => HHHHTHTT\n", - " 58: HHHHTHTT rot: HHTHTTHH flip: 0 2 4 6 => HHHHTTHT\n", - " 59: HHHHTTHT rot: THHHHTTH flip: 01234567 => HHTHTTTT\n", - " 60: HHTHTTTT rot: HTTTTHHT flip: 01 45 => HTHTTHTT\n", - " 61: HTHTTHTT rot: TTHTHTTH flip: 01234567 => HHTHHTHT\n", - " 62: HHTHHTHT rot: HHTHHTHT flip: 0 2 4 6 => HHHTTTTT\n", - " 63: HHHTTTTT rot: TTTTHHHT flip: 01234567 => HHHHHTTT\n", - " 64: HHHHHTTT rot: THHHHHTT flip: 012345 => HTTTTTTT\n", - " 65: HTTTTTTT rot: TTTTHTTT flip: 01234567 => HHHHHHHT\n", - " 66: HHHHHHHT rot: HHHHHHTH flip: 0 2 4 6 => HHHTHTHT\n", - " 67: HHHTHTHT rot: HTHTHHHT flip: 01234567 => HTHTHTTT\n", - " 68: HTHTHTTT rot: THTHTTTH flip: 01 45 => HHHTHHTT\n", - " 69: HHHTHHTT rot: TTHHHTHH flip: 01234567 => HHTTTHTT\n", - " 70: HHTTTHTT rot: THTTHHTT flip: 0 2 4 6 => HHHTTHHT\n", - " 71: HHHTTHHT rot: HHHTTHHT flip: 01234567 => HHTTHTTT\n", - " 72: HHTTHTTT rot: THHTTHTT flip: 012 456 => HTHTHTTT\n", - " 73: HTHTHTTT rot: THTHTHTT flip: 01234567 => HHHTHTHT\n", - " 74: HHHTHTHT rot: HHHTHTHT flip: 0 2 4 6 => HTTTTTTT\n", - " 75: HTTTTTTT rot: TTTTHTTT flip: 01234567 => HHHHHHHT\n", - " 76: HHHHHHHT rot: HTHHHHHH flip: 01 45 => HHHTTHHT\n", - " 77: HHHTTHHT rot: HTHHHTTH flip: 01234567 => HHTTHTTT\n", - " 78: HHTTHTTT rot: TTHHTTHT flip: 0 2 4 6 => HHTTTHTT\n", - " 79: HHTTTHTT rot: THHTTTHT flip: 01234567 => HHHTHHTT\n", - " 80: HHHTHHTT rot: HHTTHHHT flip: 0123 => HHHHHTTT\n", - " 81: HHHHHTTT rot: HHHHHTTT flip: 01234567 => HHHTTTTT\n", - " 82: HHHTTTTT rot: TTTTTHHH flip: 0 2 4 6 => HHTHHTHT\n", - " 83: HHTHHTHT rot: HHTHHTHT flip: 01234567 => HTHTTHTT\n", - " 84: HTHTTHTT rot: HTHTTHTT flip: 01 45 => HHTHTTTT\n", - " 85: HHTHTTTT rot: TTTHHTHT flip: 01234567 => HHHHTTHT\n", - " 86: HHHHTTHT rot: HHHHTTHT flip: 0 2 4 6 => HHTTTTHT\n", - " 87: HHTTTTHT rot: TTHTHHTT flip: 01234567 => HHHHTHTT\n", - " 88: HHHHTHTT rot: HTHTTHHH flip: 012 456 => HTHTTHTT\n", - " 89: HTHTTHTT rot: HTHTTHTT flip: 01234567 => HHTHHTHT\n", - " 90: HHTHHTHT rot: THHTHHTH flip: 0 2 4 6 => HHHHHTTT\n", - " 91: HHHHHTTT rot: HHHTTTHH flip: 01234567 => HHHTTTTT\n", - " 92: HHHTTTTT rot: TTTTTHHH flip: 01 45 => HHHHTTHT\n", - " 93: HHHHTTHT rot: HHTTHTHH flip: 01234567 => HHTHTTTT\n", - " 94: HHTHTTTT rot: THTTTTHH flip: 0 2 4 6 => HHHHTHTT\n", - " 95: HHHHTHTT rot: HHHTHTTH flip: 01234567 => HHTTTTHT\n", - " 96: HHTTTTHT rot: TTTHTHHT flip: 01234 6 => HHHTHHTT\n", - " 97: HHHTHHTT rot: HTTHHHTH flip: 01234567 => HHTTTHTT\n", - " 98: HHTTTHTT rot: TTTHTTHH flip: 0 2 4 6 => HHHTTHHT\n", - " 99: HHHTTHHT rot: HHTHHHTT flip: 01234567 => HHTTHTTT\n", - " 100: HHTTHTTT rot: TTTHHTTH flip: 01 45 => HHHTHTHT\n", - " 101: HHHTHTHT rot: THHHTHTH flip: 01234567 => HTHTHTTT\n", - " 102: HTHTHTTT rot: TTHTHTHT flip: 0 2 4 6 => HTTTTTTT\n", - " 103: HTTTTTTT rot: TTHTTTTT flip: 01234567 => HHHHHHHT\n", - " 104: HHHHHHHT rot: HHHHHHHT flip: 012 456 => HTTTTTTT\n", - " 105: HTTTTTTT rot: TTHTTTTT flip: 01234567 => HHHHHHHT\n", - " 106: HHHHHHHT rot: HHHHHHHT flip: 0 2 4 6 => HTHTHTTT\n", - " 107: HTHTHTTT rot: HTTTHTHT flip: 01234567 => HHHTHTHT\n", - " 108: HHHTHTHT rot: HTHHHTHT flip: 01 45 => HHHTHHTT\n", - " 109: HHHTHHTT rot: HHTHHTTH flip: 01234567 => HHTTTHTT\n", - " 110: HHTTTHTT rot: TTTHTTHH flip: 0 2 4 6 => HHHTTHHT\n", - " 111: HHHTTHHT rot: THHHTTHH flip: 01234567 => HHTTHTTT\n", - " 112: HHTTHTTT rot: HTTHTTTH flip: 0123 => HHTTTTHT\n", - " 113: HHTTTTHT rot: HTTTTHTH flip: 01234567 => HHHHTHTT\n", - " 114: HHHHTHTT rot: THHHHTHT flip: 0 2 4 6 => HHTHTTTT\n", - " 115: HHTHTTTT rot: TTHHTHTT flip: 01234567 => HHHHTTHT\n", - " 116: HHHHTTHT rot: HHHTTHTH flip: 01 45 => HTHTTHTT\n", - " 117: HTHTTHTT rot: HTTHTHTT flip: 01234567 => HHTHHTHT\n", - " 118: HHTHHTHT rot: HTHHTHHT flip: 0 2 4 6 => HHHTTTTT\n", - " 119: HHHTTTTT rot: HHHTTTTT flip: 01234567 => HHHHHTTT\n", - " 120: HHHHHTTT rot: TTHHHHHT flip: 012 456 => HHTHTTTT\n", - " 121: HHTHTTTT rot: TTTTHHTH flip: 01234567 => HHHHTTHT\n", - " 122: HHHHTTHT rot: HHHHTTHT flip: 0 2 4 6 => HHTTTTHT\n", - " 123: HHTTTTHT rot: TTTTHTHH flip: 01234567 => HHHHTHTT\n", - " 124: HHHHTHTT rot: TTHHHHTH flip: 01 45 => HHHHHTTT\n", - " 125: HHHHHTTT rot: HHHHTTTH flip: 01234567 => HHHTTTTT\n", - " 126: HHHTTTTT rot: TTTTTHHH flip: 0 2 4 6 => HHTHHTHT\n", - " 127: HHTHHTHT rot: THHTHHTH flip: 01234567 => HTHTTHTT\n", - " 128: HTHTTHTT rot: HTHTTHTT flip: 0123456 => HHTHTTHT\n", - " 129: HHTHTTHT rot: THTHHTHT flip: 01234567 => HHTHTTHT\n", - " 130: HHTHTTHT rot: TTHTHHTH flip: 0 2 4 6 => HHHHTTTT\n", - " 131: HHHHTTTT rot: HHHHTTTT flip: 01234567 => HHHHTTTT\n", - " 132: HHHHTTTT rot: THHHHTTT flip: 01 45 => HHTHTTHT\n", - " 133: HHTHTTHT rot: TTHTHHTH flip: 01234567 => HHTHTTHT\n", - " 134: HHTHTTHT rot: THTTHTHH flip: 0 2 4 6 => HHHHTTTT\n", - " 135: HHHHTTTT rot: TTTTHHHH flip: 01234567 => HHHHTTTT\n", - " 136: HHHHTTTT rot: THHHHTTT flip: 012 456 => HHTHTTHT\n", - " 137: HHTHTTHT rot: TTHTHHTH flip: 01234567 => HHTHTTHT\n", - " 138: HHTHTTHT rot: TTHTHHTH flip: 0 2 4 6 => HHHHTTTT\n", - " 139: HHHHTTTT rot: HHTTTTHH flip: 01234567 => HHHHTTTT\n", - " 140: HHHHTTTT rot: TTHHHHTT flip: 01 45 => HHHHTTTT\n", - " 141: HHHHTTTT rot: THHHHTTT flip: 01234567 => HHHHTTTT\n", - " 142: HHHHTTTT rot: HHHHTTTT flip: 0 2 4 6 => HHTHTTHT\n", - " 143: HHTHTTHT rot: THTTHTHH flip: 01234567 => HHTHTTHT\n", - " 144: HHTHTTHT rot: THTTHTHH flip: 0123 => HHHTHHHT\n", - " 145: HHHTHHHT rot: THHHTHHH flip: 01234567 => HTTTHTTT\n", - " 146: HTTTHTTT rot: THTTTHTT flip: 0 2 4 6 => HHHTHHHT\n", - " 147: HHHTHHHT rot: THHHTHHH flip: 01234567 => HTTTHTTT\n", - " 148: HTTTHTTT rot: TTHTTTHT flip: 01 45 => HHHTHHHT\n", - " 149: HHHTHHHT rot: HHTHHHTH flip: 01234567 => HTTTHTTT\n", - " 150: HTTTHTTT rot: THTTTHTT flip: 0 2 4 6 => HHHTHHHT\n", - " 151: HHHTHHHT rot: HHTHHHTH flip: 01234567 => HTTTHTTT\n", - " 152: HTTTHTTT rot: TTTHTTTH flip: 012 456 => HHHHHHHH\n" + " 1: HTTHTTHT | rot: THTTHTHT | flip: 01234567 HHTHHTHT\n", + " 2: HHTHHTHT | rot: THHTHHTH | flip: 0 2 4 6 HHHHHTTT\n", + " 3: HHHHHTTT | rot: TTTHHHHH | flip: 01234567 HHHTTTTT\n", + " 4: HHHTTTTT | rot: HHHTTTTT | flip: 01 45 HHTTTTHT\n", + " 5: HHTTTTHT | rot: HTHHTTTT | flip: 01234567 HHHHTHTT\n", + " 6: HHHHTHTT | rot: THTTHHHH | flip: 0 2 4 6 HHHHTTHT\n", + " 7: HHHHTTHT | rot: HHTTHTHH | flip: 01234567 HHTHTTTT\n", + " 8: HHTHTTTT | rot: THHTHTTT | flip: 012 456 HHTHTTTT\n", + " 9: HHTHTTTT | rot: THHTHTTT | flip: 01234567 HHHHTTHT\n", + " 10: HHHHTTHT | rot: THTHHHHT | flip: 0 2 4 6 HHHHTHTT\n", + " 11: HHHHTHTT | rot: THTTHHHH | flip: 01234567 HHTTTTHT\n", + " 12: HHTTTTHT | rot: THHTTTTH | flip: 01 45 HHTHHTHT\n", + " 13: HHTHHTHT | rot: HTHHTHTH | flip: 01234567 HTHTTHTT\n", + " 14: HTHTTHTT | rot: THTTHTHT | flip: 0 2 4 6 HHHTTTTT\n", + " 15: HHHTTTTT | rot: HTTTTTHH | flip: 01234567 HHHHHTTT\n", + " 16: HHHHHTTT | rot: HHTTTHHH | flip: 0123 HHHTTHHT\n", + " 17: HHHTTHHT | rot: THHHTTHH | flip: 01234567 HHTTHTTT\n", + " 18: HHTTHTTT | rot: THHTTHTT | flip: 0 2 4 6 HHHTHHTT\n", + " 19: HHHTHHTT | rot: THHTTHHH | flip: 01234567 HHTTTHTT\n", + " 20: HHTTTHTT | rot: THTTHHTT | flip: 01 45 HTTTTTTT\n", + " 21: HTTTTTTT | rot: TTTTTTTH | flip: 01234567 HHHHHHHT\n", + " 22: HHHHHHHT | rot: HHHHHTHH | flip: 0 2 4 6 HTHTHTTT\n", + " 23: HTHTHTTT | rot: THTHTTTH | flip: 01234567 HHHTHTHT\n", + " 24: HHHTHTHT | rot: HTHHHTHT | flip: 012 456 HTHTHTTT\n", + " 25: HTHTHTTT | rot: HTHTTTHT | flip: 01234567 HHHTHTHT\n", + " 26: HHHTHTHT | rot: THTHHHTH | flip: 0 2 4 6 HHHHHHHT\n", + " 27: HHHHHHHT | rot: HHHHHHHT | flip: 01234567 HTTTTTTT\n", + " 28: HTTTTTTT | rot: TTTTHTTT | flip: 01 45 HHTTTHTT\n", + " 29: HHTTTHTT | rot: HTTHHTTT | flip: 01234567 HHHTHHTT\n", + " 30: HHHTHHTT | rot: THHHTHHT | flip: 0 2 4 6 HHHTTHHT\n", + " 31: HHHTTHHT | rot: HTHHHTTH | flip: 01234567 HHTTHTTT\n", + " 32: HHTTHTTT | rot: HHTTHTTT | flip: 01234 6 HHTTHTTT\n", + " 33: HHTTHTTT | rot: TTHHTTHT | flip: 01234567 HHHTTHHT\n", + " 34: HHHTTHHT | rot: THHHTTHH | flip: 0 2 4 6 HHHTHHTT\n", + " 35: HHHTHHTT | rot: THHTTHHH | flip: 01234567 HHTTTHTT\n", + " 36: HHTTTHTT | rot: THTTHHTT | flip: 01 45 HTTTTTTT\n", + " 37: HTTTTTTT | rot: HTTTTTTT | flip: 01234567 HHHHHHHT\n", + " 38: HHHHHHHT | rot: HHHHHTHH | flip: 0 2 4 6 HTHTHTTT\n", + " 39: HTHTHTTT | rot: THTHTTTH | flip: 01234567 HHHTHTHT\n", + " 40: HHHTHTHT | rot: HHHTHTHT | flip: 012 456 HTTTTTTT\n", + " 41: HTTTTTTT | rot: TTTHTTTT | flip: 01234567 HHHHHHHT\n", + " 42: HHHHHHHT | rot: THHHHHHH | flip: 0 2 4 6 HHHTHTHT\n", + " 43: HHHTHTHT | rot: HTHTHTHH | flip: 01234567 HTHTHTTT\n", + " 44: HTHTHTTT | rot: TTHTHTHT | flip: 01 45 HHHTTHHT\n", + " 45: HHHTTHHT | rot: HHTHHHTT | flip: 01234567 HHTTHTTT\n", + " 46: HHTTHTTT | rot: TTHTTTHH | flip: 0 2 4 6 HHTTTHTT\n", + " 47: HHTTTHTT | rot: HHTTTHTT | flip: 01234567 HHHTHHTT\n", + " 48: HHHTHHTT | rot: HHHTHHTT | flip: 0123 HHHTTTTT\n", + " 49: HHHTTTTT | rot: TTTHHHTT | flip: 01234567 HHHHHTTT\n", + " 50: HHHHHTTT | rot: TTHHHHHT | flip: 0 2 4 6 HTHTTHTT\n", + " 51: HTHTTHTT | rot: HTTHTTHT | flip: 01234567 HHTHHTHT\n", + " 52: HHTHHTHT | rot: THTHHTHH | flip: 01 45 HHHHTTHT\n", + " 53: HHHHTTHT | rot: HHHHTTHT | flip: 01234567 HHTHTTTT\n", + " 54: HHTHTTTT | rot: TTTTHHTH | flip: 0 2 4 6 HHHHTHTT\n", + " 55: HHHHTHTT | rot: THTTHHHH | flip: 01234567 HHTTTTHT\n", + " 56: HHTTTTHT | rot: THTHHTTT | flip: 012 456 HHTHHTHT\n", + " 57: HHTHHTHT | rot: HTHHTHTH | flip: 01234567 HTHTTHTT\n", + " 58: HTHTTHTT | rot: HTTHTHTT | flip: 0 2 4 6 HHHHHTTT\n", + " 59: HHHHHTTT | rot: HHTTTHHH | flip: 01234567 HHHTTTTT\n", + " 60: HHHTTTTT | rot: TTTHHHTT | flip: 01 45 HHTHTTTT\n", + " 61: HHTHTTTT | rot: THTTTTHH | flip: 01234567 HHHHTTHT\n", + " 62: HHHHTTHT | rot: TTHTHHHH | flip: 0 2 4 6 HHTTTTHT\n", + " 63: HHTTTTHT | rot: HTHHTTTT | flip: 01234567 HHHHTHTT\n", + " 64: HHHHTHTT | rot: THTTHHHH | flip: 012345 HHHTHHTT\n", + " 65: HHHTHHTT | rot: HHTTHHHT | flip: 01234567 HHTTTHTT\n", + " 66: HHTTTHTT | rot: THHTTTHT | flip: 0 2 4 6 HHTTHTTT\n", + " 67: HHTTHTTT | rot: HHTTHTTT | flip: 01234567 HHHTTHHT\n", + " 68: HHHTTHHT | rot: HHHTTHHT | flip: 01 45 HTHTHTTT\n", + " 69: HTHTHTTT | rot: HTTTHTHT | flip: 01234567 HHHTHTHT\n", + " 70: HHHTHTHT | rot: THTHTHHH | flip: 0 2 4 6 HHHHHHHT\n", + " 71: HHHHHHHT | rot: HHHTHHHH | flip: 01234567 HTTTTTTT\n", + " 72: HTTTTTTT | rot: TTTHTTTT | flip: 012 456 HHHHHHHT\n", + " 73: HHHHHHHT | rot: HHHHTHHH | flip: 01234567 HTTTTTTT\n", + " 74: HTTTTTTT | rot: TTTTTHTT | flip: 0 2 4 6 HHHTHTHT\n", + " 75: HHHTHTHT | rot: THHHTHTH | flip: 01234567 HTHTHTTT\n", + " 76: HTHTHTTT | rot: THTHTTTH | flip: 01 45 HHHTHHTT\n", + " 77: HHHTHHTT | rot: HHTTHHHT | flip: 01234567 HHTTTHTT\n", + " 78: HHTTTHTT | rot: THTTHHTT | flip: 0 2 4 6 HHHTTHHT\n", + " 79: HHHTTHHT | rot: THHHTTHH | flip: 01234567 HHTTHTTT\n", + " 80: HHTTHTTT | rot: THTTTHHT | flip: 0123 HHTHHTHT\n", + " 81: HHTHHTHT | rot: HHTHTHHT | flip: 01234567 HTHTTHTT\n", + " 82: HTHTTHTT | rot: THTTHTTH | flip: 0 2 4 6 HHHHHTTT\n", + " 83: HHHHHTTT | rot: TTHHHHHT | flip: 01234567 HHHTTTTT\n", + " 84: HHHTTTTT | rot: HHHTTTTT | flip: 01 45 HHTTTTHT\n", + " 85: HHTTTTHT | rot: HHTTTTHT | flip: 01234567 HHHHTHTT\n", + " 86: HHHHTHTT | rot: HHTHTTHH | flip: 0 2 4 6 HHHHTTHT\n", + " 87: HHHHTTHT | rot: HHTTHTHH | flip: 01234567 HHTHTTTT\n", + " 88: HHTHTTTT | rot: HHTHTTTT | flip: 012 456 HHHHHTTT\n", + " 89: HHHHHTTT | rot: HHTTTHHH | flip: 01234567 HHHTTTTT\n", + " 90: HHHTTTTT | rot: HHHTTTTT | flip: 0 2 4 6 HTHTTHTT\n", + " 91: HTHTTHTT | rot: THTTHTHT | flip: 01234567 HHTHHTHT\n", + " 92: HHTHHTHT | rot: HTHTHHTH | flip: 01 45 HHTTTTHT\n", + " 93: HHTTTTHT | rot: TTTHTHHT | flip: 01234567 HHHHTHTT\n", + " 94: HHHHTHTT | rot: THHHHTHT | flip: 0 2 4 6 HHTHTTTT\n", + " 95: HHTHTTTT | rot: HTHTTTTH | flip: 01234567 HHHHTTHT\n", + " 96: HHHHTTHT | rot: HTHHHHTT | flip: 01234 6 HHTTHTTT\n", + " 97: HHTTHTTT | rot: HTTTHHTT | flip: 01234567 HHHTTHHT\n", + " 98: HHHTTHHT | rot: THHHTTHH | flip: 0 2 4 6 HHHTHHTT\n", + " 99: HHHTHHTT | rot: HHHTHHTT | flip: 01234567 HHTTTHTT\n", + " 100: HHTTTHTT | rot: HTTTHTTH | flip: 01 45 HTHTHTTT\n", + " 101: HTHTHTTT | rot: THTHTTTH | flip: 01234567 HHHTHTHT\n", + " 102: HHHTHTHT | rot: HTHTHTHH | flip: 0 2 4 6 HTTTTTTT\n", + " 103: HTTTTTTT | rot: TTHTTTTT | flip: 01234567 HHHHHHHT\n", + " 104: HHHHHHHT | rot: HHHHTHHH | flip: 012 456 HHTTHTTT\n", + " 105: HHTTHTTT | rot: THTTTHHT | flip: 01234567 HHHTTHHT\n", + " 106: HHHTTHHT | rot: HHHTTHHT | flip: 0 2 4 6 HHTTTHTT\n", + " 107: HHTTTHTT | rot: HTTHHTTT | flip: 01234567 HHHTHHTT\n", + " 108: HHHTHHTT | rot: THHHTHHT | flip: 01 45 HHHTHTHT\n", + " 109: HHHTHTHT | rot: THHHTHTH | flip: 01234567 HTHTHTTT\n", + " 110: HTHTHTTT | rot: TTHTHTHT | flip: 0 2 4 6 HTTTTTTT\n", + " 111: HTTTTTTT | rot: TTTTHTTT | flip: 01234567 HHHHHHHT\n", + " 112: HHHHHHHT | rot: HHHHHHTH | flip: 0123 HHTHTTTT\n", + " 113: HHTHTTTT | rot: TTTTHHTH | flip: 01234567 HHHHTTHT\n", + " 114: HHHHTTHT | rot: HHTTHTHH | flip: 0 2 4 6 HHTTTTHT\n", + " 115: HHTTTTHT | rot: HHTTTTHT | flip: 01234567 HHHHTHTT\n", + " 116: HHHHTHTT | rot: HTTHHHHT | flip: 01 45 HTHTTHTT\n", + " 117: HTHTTHTT | rot: HTTHTHTT | flip: 01234567 HHTHHTHT\n", + " 118: HHTHHTHT | rot: HTHHTHTH | flip: 0 2 4 6 HHHHHTTT\n", + " 119: HHHHHTTT | rot: HTTTHHHH | flip: 01234567 HHHTTTTT\n", + " 120: HHHTTTTT | rot: TTTTHHHT | flip: 012 456 HHHTTTTT\n", + " 121: HHHTTTTT | rot: TTTTTHHH | flip: 01234567 HHHHHTTT\n", + " 122: HHHHHTTT | rot: HHHHTTTH | flip: 0 2 4 6 HHTHHTHT\n", + " 123: HHTHHTHT | rot: HHTHTHHT | flip: 01234567 HTHTTHTT\n", + " 124: HTHTTHTT | rot: HTTHTTHT | flip: 01 45 HHHHTTHT\n", + " 125: HHHHTTHT | rot: HHTTHTHH | flip: 01234567 HHTHTTTT\n", + " 126: HHTHTTTT | rot: HHTHTTTT | flip: 0 2 4 6 HHHHTHTT\n", + " 127: HHHHTHTT | rot: HHHTHTTH | flip: 01234567 HHTTTTHT\n", + " 128: HHTTTTHT | rot: TTTHTHHT | flip: 0123456 HHHTHTTT\n", + " 129: HHHTHTTT | rot: HHTHTTTH | flip: 01234567 HHHTTTHT\n", + " 130: HHHTTTHT | rot: HTHHHTTT | flip: 0 2 4 6 HTTHTTTT\n", + " 131: HTTHTTTT | rot: TTTHTTHT | flip: 01234567 HHHHTHHT\n", + " 132: HHHHTHHT | rot: HTHHHHTH | flip: 01 45 HHHTTTHT\n", + " 133: HHHTTTHT | rot: TTTHTHHH | flip: 01234567 HHHTHTTT\n", + " 134: HHHTHTTT | rot: HTTTHHHT | flip: 0 2 4 6 HTTHTTTT\n", + " 135: HTTHTTTT | rot: THTTTTHT | flip: 01234567 HHHHTHHT\n", + " 136: HHHHTHHT | rot: THHHHTHH | flip: 012 456 HHTTHTHT\n", + " 137: HHTTHTHT | rot: HHTTHTHT | flip: 01234567 HHTHTHTT\n", + " 138: HHTHTHTT | rot: THTTHHTH | flip: 0 2 4 6 HHHHHHTT\n", + " 139: HHHHHHTT | rot: HTTHHHHH | flip: 01234567 HHTTTTTT\n", + " 140: HHTTTTTT | rot: THHTTTTT | flip: 01 45 HHTTHTHT\n", + " 141: HHTTHTHT | rot: HHTTHTHT | flip: 01234567 HHTHTHTT\n", + " 142: HHTHTHTT | rot: HHTHTHTT | flip: 0 2 4 6 HHHHHHTT\n", + " 143: HHHHHHTT | rot: HTTHHHHH | flip: 01234567 HHTTTTTT\n", + " 144: HHTTTTTT | rot: HHTTTTTT | flip: 0123 HHTTTTTT\n", + " 145: HHTTTTTT | rot: TTTTHHTT | flip: 01234567 HHHHHHTT\n", + " 146: HHHHHHTT | rot: HHHHHHTT | flip: 0 2 4 6 HHTTHTHT\n", + " 147: HHTTHTHT | rot: THTHHTTH | flip: 01234567 HHTHTHTT\n", + " 148: HHTHTHTT | rot: THHTHTHT | flip: 01 45 HHTHTHTT\n", + " 149: HHTHTHTT | rot: HHTHTHTT | flip: 01234567 HHTTHTHT\n", + " 150: HHTTHTHT | rot: HHTTHTHT | flip: 0 2 4 6 HHTTTTTT\n", + " 151: HHTTTTTT | rot: TTTHHTTT | flip: 01234567 HHHHHHTT\n", + " 152: HHHHHHTT | rot: HHHHHHTT | flip: 012 456 HTTHTTTT\n", + " 153: HTTHTTTT | rot: TTHTTHTT | flip: 01234567 HHHHTHHT\n", + " 154: HHHHTHHT | rot: HHTHHTHH | flip: 0 2 4 6 HHHTTTHT\n", + " 155: HHHTTTHT | rot: HHTTTHTH | flip: 01234567 HHHTHTTT\n", + " 156: HHHTHTTT | rot: HHHTHTTT | flip: 01 45 HTTHTTTT\n", + " 157: HTTHTTTT | rot: THTTHTTT | flip: 01234567 HHHHTHHT\n", + " 158: HHHHTHHT | rot: HTHHHHTH | flip: 0 2 4 6 HHHTTTHT\n", + " 159: HHHTTTHT | rot: HHHTTTHT | flip: 01234567 HHHTHTTT\n", + " 160: HHHTHTTT | rot: HHTHTTTH | flip: 01234 6 HHTTHTHT\n", + " 161: HHTTHTHT | rot: THHTTHTH | flip: 01234567 HHTHTHTT\n", + " 162: HHTHTHTT | rot: HTTHHTHT | flip: 0 2 4 6 HHTTTTTT\n", + " 163: HHTTTTTT | rot: TTTTHHTT | flip: 01234567 HHHHHHTT\n", + " 164: HHHHHHTT | rot: HHHTTHHH | flip: 01 45 HHTTHTHT\n", + " 165: HHTTHTHT | rot: HTTHTHTH | flip: 01234567 HHTHTHTT\n", + " 166: HHTHTHTT | rot: HTHTHTTH | flip: 0 2 4 6 HHTTTTTT\n", + " 167: HHTTTTTT | rot: TTTTTTHH | flip: 01234567 HHHHHHTT\n", + " 168: HHHHHHTT | rot: HHTTHHHH | flip: 012 456 HTTHTTTT\n", + " 169: HTTHTTTT | rot: HTTTTHTT | flip: 01234567 HHHHTHHT\n", + " 170: HHHHTHHT | rot: THHHHTHH | flip: 0 2 4 6 HHHTHTTT\n", + " 171: HHHTHTTT | rot: TTTHHHTH | flip: 01234567 HHHTTTHT\n", + " 172: HHHTTTHT | rot: TTTHTHHH | flip: 01 45 HHHHTHHT\n", + " 173: HHHHTHHT | rot: THHTHHHH | flip: 01234567 HTTHTTTT\n", + " 174: HTTHTTTT | rot: TTTHTTHT | flip: 0 2 4 6 HHHTTTHT\n", + " 175: HHHTTTHT | rot: THTHHHTT | flip: 01234567 HHHTHTTT\n", + " 176: HHHTHTTT | rot: TTHHHTHT | flip: 0123 HHTTHTHT\n", + " 177: HHTTHTHT | rot: THHTTHTH | flip: 01234567 HHTHTHTT\n", + " 178: HHTHTHTT | rot: THTHTTHH | flip: 0 2 4 6 HHHHHHTT\n", + " 179: HHHHHHTT | rot: HHTTHHHH | flip: 01234567 HHTTTTTT\n", + " 180: HHTTTTTT | rot: TTTHHTTT | flip: 01 45 HHTHTHTT\n", + " 181: HHTHTHTT | rot: THHTHTHT | flip: 01234567 HHTTHTHT\n", + " 182: HHTTHTHT | rot: HTHHTTHT | flip: 0 2 4 6 HHTTTTTT\n", + " 183: HHTTTTTT | rot: THHTTTTT | flip: 01234567 HHHHHHTT\n", + " 184: HHHHHHTT | rot: TTHHHHHH | flip: 012 456 HHHTHTTT\n", + " 185: HHHTHTTT | rot: HHHTHTTT | flip: 01234567 HHHTTTHT\n", + " 186: HHHTTTHT | rot: THHHTTTH | flip: 0 2 4 6 HHHHTHHT\n", + " 187: HHHHTHHT | rot: THHTHHHH | flip: 01234567 HTTHTTTT\n", + " 188: HTTHTTTT | rot: THTTHTTT | flip: 01 45 HTTHTTTT\n", + " 189: HTTHTTTT | rot: TTTHTTHT | flip: 01234567 HHHHTHHT\n", + " 190: HHHHTHHT | rot: HHHHTHHT | flip: 0 2 4 6 HHHTTTHT\n", + " 191: HHHTTTHT | rot: HTTTHTHH | flip: 01234567 HHHTHTTT\n", + " 192: HHHTHTTT | rot: TTHHHTHT | flip: 012345 HHTHHTTT\n", + " 193: HHTHHTTT | rot: HTTTHHTH | flip: 01234567 HHHTTHTT\n", + " 194: HHHTTHTT | rot: THHHTTHT | flip: 0 2 4 6 HHTHHTTT\n", + " 195: HHTHHTTT | rot: TTHHTHHT | flip: 01234567 HHHTTHTT\n", + " 196: HHHTTHTT | rot: HTTHTTHH | flip: 01 45 HHHHHTHT\n", + " 197: HHHHHTHT | rot: HHHTHTHH | flip: 01234567 HTHTTTTT\n", + " 198: HTHTTTTT | rot: TTTTHTHT | flip: 0 2 4 6 HTHTTTTT\n", + " 199: HTHTTTTT | rot: TTTTHTHT | flip: 01234567 HHHHHTHT\n", + " 200: HHHHHTHT | rot: HTHTHHHH | flip: 012 456 HTHTTTTT\n", + " 201: HTHTTTTT | rot: TTTTHTHT | flip: 01234567 HHHHHTHT\n", + " 202: HHHHHTHT | rot: HHHHTHTH | flip: 0 2 4 6 HHHHHTHT\n", + " 203: HHHHHTHT | rot: HHHHHTHT | flip: 01234567 HTHTTTTT\n", + " 204: HTHTTTTT | rot: TTTTHTHT | flip: 01 45 HHTHHTTT\n", + " 205: HHTHHTTT | rot: TTTHHTHH | flip: 01234567 HHHTTHTT\n", + " 206: HHHTTHTT | rot: HHHTTHTT | flip: 0 2 4 6 HHHTTHTT\n", + " 207: HHHTTHTT | rot: HTTHTTHH | flip: 01234567 HHTHHTTT\n", + " 208: HHTHHTTT | rot: HHTHHTTT | flip: 0123 HTHTTTTT\n", + " 209: HTHTTTTT | rot: THTHTTTT | flip: 01234567 HHHHHTHT\n", + " 210: HHHHHTHT | rot: HHTHTHHH | flip: 0 2 4 6 HHHHHTHT\n", + " 211: HHHHHTHT | rot: HHHHTHTH | flip: 01234567 HTHTTTTT\n", + " 212: HTHTTTTT | rot: TTTTHTHT | flip: 01 45 HHTHHTTT\n", + " 213: HHTHHTTT | rot: THHTHHTT | flip: 01234567 HHHTTHTT\n", + " 214: HHHTTHTT | rot: HHTTHTTH | flip: 0 2 4 6 HHTHHTTT\n", + " 215: HHTHHTTT | rot: HHTTTHHT | flip: 01234567 HHHTTHTT\n", + " 216: HHHTTHTT | rot: HTTHTTHH | flip: 012 456 HHHHHTHT\n", + " 217: HHHHHTHT | rot: HTHHHHHT | flip: 01234567 HTHTTTTT\n", + " 218: HTHTTTTT | rot: HTTTTTHT | flip: 0 2 4 6 HTHTTTTT\n", + " 219: HTHTTTTT | rot: THTTTTTH | flip: 01234567 HHHHHTHT\n", + " 220: HHHHHTHT | rot: HTHTHHHH | flip: 01 45 HHTHHTTT\n", + " 221: HHTHHTTT | rot: TTTHHTHH | flip: 01234567 HHHTTHTT\n", + " 222: HHHTTHTT | rot: HHTTHTTH | flip: 0 2 4 6 HHTHHTTT\n", + " 223: HHTHHTTT | rot: THHTTTHH | flip: 01234567 HHHTTHTT\n", + " 224: HHHTTHTT | rot: HTTHTTHH | flip: 01234 6 HHTHTTHT\n", + " 225: HHTHTTHT | rot: HHTHTTHT | flip: 01234567 HHTHTTHT\n", + " 226: HHTHTTHT | rot: HTHHTHTT | flip: 0 2 4 6 HHHHTTTT\n", + " 227: HHHHTTTT | rot: TTTHHHHT | flip: 01234567 HHHHTTTT\n", + " 228: HHHHTTTT | rot: TTTHHHHT | flip: 01 45 HHTHTTHT\n", + " 229: HHTHTTHT | rot: THTTHTHH | flip: 01234567 HHTHTTHT\n", + " 230: HHTHTTHT | rot: HHTHTTHT | flip: 0 2 4 6 HHHHTTTT\n", + " 231: HHHHTTTT | rot: HHTTTTHH | flip: 01234567 HHHHTTTT\n", + " 232: HHHHTTTT | rot: HHHHTTTT | flip: 012 456 HHHHTTTT\n", + " 233: HHHHTTTT | rot: HHTTTTHH | flip: 01234567 HHHHTTTT\n", + " 234: HHHHTTTT | rot: HHHHTTTT | flip: 0 2 4 6 HHTHTTHT\n", + " 235: HHTHTTHT | rot: THTHHTHT | flip: 01234567 HHTHTTHT\n", + " 236: HHTHTTHT | rot: HTHTTHTH | flip: 01 45 HHTHTTHT\n", + " 237: HHTHTTHT | rot: HTTHTHHT | flip: 01234567 HHTHTTHT\n", + " 238: HHTHTTHT | rot: HTHHTHTT | flip: 0 2 4 6 HHHHTTTT\n", + " 239: HHHHTTTT | rot: TTTTHHHH | flip: 01234567 HHHHTTTT\n", + " 240: HHHHTTTT | rot: TTTHHHHT | flip: 0123 HHHTHHHT\n", + " 241: HHHTHHHT | rot: HTHHHTHH | flip: 01234567 HTTTHTTT\n", + " 242: HTTTHTTT | rot: TTTHTTTH | flip: 0 2 4 6 HHHTHHHT\n", + " 243: HHHTHHHT | rot: HHTHHHTH | flip: 01234567 HTTTHTTT\n", + " 244: HTTTHTTT | rot: HTTTHTTT | flip: 01 45 HTTTHTTT\n", + " 245: HTTTHTTT | rot: TTTHTTTH | flip: 01234567 HHHTHHHT\n", + " 246: HHHTHHHT | rot: HTHHHTHH | flip: 0 2 4 6 HTTTHTTT\n", + " 247: HTTTHTTT | rot: HTTTHTTT | flip: 01234567 HHHTHHHT\n", + " 248: HHHTHHHT | rot: THHHTHHH | flip: 012 456 HHTTHHTT\n", + " 249: HHTTHHTT | rot: HHTTHHTT | flip: 01234567 HHTTHHTT\n", + " 250: HHTTHHTT | rot: HHTTHHTT | flip: 0 2 4 6 HHTTHHTT\n", + " 251: HHTTHHTT | rot: TTHHTTHH | flip: 01234567 HHTTHHTT\n", + " 252: HHTTHHTT | rot: HHTTHHTT | flip: 01 45 TTTTTTTT\n", + " 253: TTTTTTTT | rot: TTTTTTTT | flip: 01234567 HHHHHHHH\n" ] }, { @@ -1096,14 +1237,21 @@ "'HHHHHHHH'" ] }, - "execution_count": 26, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "play('HTTHTTHT', strategy, True)" + "play(strategy8, 'HTTHTTHT', True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": {