Add files via upload
This commit is contained in:
116
Coin Flip.ipynb
116
Coin Flip.ipynb
@@ -337,7 +337,11 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"That's a 15-move sequence that is guaranteed to lead to a win. Do I believe it? It does appear to work. A colleague did the puzzle and got the same answer. And here's further validation: The function `random_devil` takes a sequence of moves and plays those moves with a devil that chooses randomly:"
|
||||
"That's a 15-move sequence that is guaranteed to lead to a win. \n",
|
||||
"\n",
|
||||
"# Verifying the Solution\n",
|
||||
"\n",
|
||||
"Do I believe the solution is correct? Playing with paper and pencil, it does appear to work. A colleague did the puzzle and got the same answer. And here's further validation: The function `random_devil` takes a sequence of moves and plays those moves with a devil that chooses randomly, returning the number of moves it takes until the player wins:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -376,22 +380,22 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Counter({0: 969,\n",
|
||||
" 1: 1034,\n",
|
||||
" 2: 966,\n",
|
||||
" 3: 1026,\n",
|
||||
" 4: 975,\n",
|
||||
" 5: 979,\n",
|
||||
" 6: 987,\n",
|
||||
" 7: 1047,\n",
|
||||
" 8: 978,\n",
|
||||
" 9: 979,\n",
|
||||
" 10: 998,\n",
|
||||
" 11: 1033,\n",
|
||||
" 12: 1025,\n",
|
||||
" 13: 973,\n",
|
||||
" 14: 1038,\n",
|
||||
" 15: 993})"
|
||||
"Counter({0: 1037,\n",
|
||||
" 1: 1006,\n",
|
||||
" 2: 1011,\n",
|
||||
" 3: 998,\n",
|
||||
" 4: 980,\n",
|
||||
" 5: 976,\n",
|
||||
" 6: 1057,\n",
|
||||
" 7: 1043,\n",
|
||||
" 8: 963,\n",
|
||||
" 9: 1021,\n",
|
||||
" 10: 966,\n",
|
||||
" 11: 1012,\n",
|
||||
" 12: 995,\n",
|
||||
" 13: 975,\n",
|
||||
" 14: 990,\n",
|
||||
" 15: 970})"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
@@ -409,8 +413,82 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This says that the player won all 16,000 times. If the player ever lost, there would be an entry for `None` in the Counter.\n",
|
||||
"The remarkable thing, which I can't explain, is that there are very nearly 1,000 results for each of the counts from 0 to 15. Can you explain that?"
|
||||
"This says that the player won all 16,000 times. (If the player ever lost, there would have been an entry for `None` in the Counter.)\n",
|
||||
"The remarkable thing, which I can't explain, is that there are very nearly 1,000 results for each of the counts from 0 to 15. Can you explain that?\n",
|
||||
"\n",
|
||||
"# Visualizing the Solution\n",
|
||||
"\n",
|
||||
"How does the solution work? One answer is \"it takes care of all possibilities.\" But it would be nice to gain more insight. I'll print a table showing the belief state after each move. But I will do two things to make the belief state easier to read. First, I will *canonicalize* the belief state to be independent of rotations. By that I mean that if the belief stae contains `{'HHHT', 'HHTH', 'HTHH', 'THHH'}`, which are all rotations of each other, I will only print one of them. (Arbitrarily, I choose the one that comes first alphabetically, `'HHHT'`.) This gets us down from 16 coin sequences in the belief state to six.\n",
|
||||
"Second, I will print each coin sequence in its own column, so that they line up and it is easy to see when a particular coin sequence disappears from the belief state"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def show(moves):\n",
|
||||
" \"For each move, print the move number, move, and belief state.\"\n",
|
||||
" belief = initial_belief\n",
|
||||
" show_line(0, 'start', belief)\n",
|
||||
" for (i, move) in enumerate(moves, 1):\n",
|
||||
" belief = update(belief, move)\n",
|
||||
" show_line(i, move, belief)\n",
|
||||
" \n",
|
||||
"def join(items, sep=''): return sep.join(map(str, items))\n",
|
||||
" \n",
|
||||
"def canonical(belief): return sorted(set(min(rotations(coins)) for coins in belief))\n",
|
||||
"\n",
|
||||
"def show_line(i, move, belief, order=canonical(initial_belief)):\n",
|
||||
" \"Print the move number, move, and belief state.\"\n",
|
||||
" ordered_belief = [(coins if coins in belief else ' ')\n",
|
||||
" for coins in order]\n",
|
||||
" print('{:2} {:5} {}'.format(i, join(move), join(ordered_belief, ' ')))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 0 start HHHH HHHT HHTT HTHT HTTT TTTT\n",
|
||||
" 1 0123 HHHH HHHT HHTT HTHT HTTT \n",
|
||||
" 2 02 HHHH HHHT HHTT HTTT TTTT\n",
|
||||
" 3 0123 HHHH HHHT HHTT HTTT \n",
|
||||
" 4 01 HHHH HHHT HTHT HTTT TTTT\n",
|
||||
" 5 0123 HHHH HHHT HTHT HTTT \n",
|
||||
" 6 02 HHHH HHHT HTTT TTTT\n",
|
||||
" 7 0123 HHHH HHHT HTTT \n",
|
||||
" 8 0 HHHH HHTT HTHT TTTT\n",
|
||||
" 9 0123 HHHH HHTT HTHT \n",
|
||||
"10 02 HHHH HHTT TTTT\n",
|
||||
"11 0123 HHHH HHTT \n",
|
||||
"12 01 HHHH HTHT TTTT\n",
|
||||
"13 0123 HHHH HTHT \n",
|
||||
"14 02 HHHH TTTT\n",
|
||||
"15 0123 HHHH \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"show(search())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can see that every odd-numbered move flips all four coins to eliminate the possibility of `TTTT`.\n",
|
||||
"We can also see that moves 2, 4, and 6 flip two coins and have the effect of eventually eliminating the two \"two heads\" sequences from the belief state, and then move 8 flips a single coin, thus eliminating the \"three heads\" and \"one heads\" sequences, and bringing back the \"two heads\" possibilities. Repeating moves 2, 4, and 6 in moves 10, 12, and 14 then re-eliminates the \"two heads\", and move 15 gets rid of the last possibility."
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user