Add files via upload

This commit is contained in:
Peter Norvig
2017-08-29 11:39:07 -07:00
committed by GitHub
parent c260cbc87d
commit 4d80be6834

View File

@@ -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."
]
}
],