Add files via upload
This commit is contained in:
339
Ghost.ipynb
339
Ghost.ipynb
@@ -15,7 +15,7 @@
|
||||
"- **Words**: I will read a standard online word list, `enable1`, and make a set of all the words of sufficient length.\n",
|
||||
"- **Fragment**: a fragment is a `str` of letters, such as `'gho'`.\n",
|
||||
"- **Beginning**: each word has a set of valid beginnings: for `ghost` it is `{'', g, gh, gho, ghos, ghost}`. \"Prefix\" is a synonym of \"beginning\".\n",
|
||||
"- **Vocabulary**: `Vocabulary(words)` is an object with: a set of all the `words`, and a set of all the valid `fragments` (beginnings) of the words.\n",
|
||||
"- **Vocabulary**: A `Vocabulary` object holds a set of all the `words` in a dictionary, as well as all the valid `fragments` (beginnings) of the words.\n",
|
||||
"- **Player**: The first player will be called player `0`; the second player `1`. \n",
|
||||
"- **Play**: A play is a new fragment formed by adding one letter to the end of the existing fragment.\n",
|
||||
"- **Legal Play**: A play that is a valid prefix of some word. `enable1.legal_plays('gho') = {'ghos, 'ghou'}`.\n",
|
||||
@@ -30,7 +30,7 @@
|
||||
"source": [
|
||||
"# Vocabulary: Words, Fragments, Legal Plays, and `enable1`\n",
|
||||
"\n",
|
||||
"`Vocabulary(text)` takes a collection of words as input, stores the words as a set, and also stores all the legal fragments of those words (that is, the beginnings). `legal_plays(fragments)` gives a set of all plays that can be formed by adding a letter to create a legal word fragment (where 'fragment' includes complete words). I also define the function `words` to split any string into component words."
|
||||
"`Vocabulary(words)` takes a collection of words as input, stores the words as a set, and also stores all the legal fragments of those words. `legal_plays(fragments)` gives a set of all plays that can be formed by adding a letter to create a legal word fragment. I also define the function `words` to split any string into component words."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -65,9 +65,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -89,9 +87,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -129,9 +125,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"enable1 = Vocabulary(words(open('enable1.txt').read()))"
|
||||
@@ -141,15 +135,13 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here I explore `enable1`:"
|
||||
"Let's explore `enable1`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -169,9 +161,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -191,9 +181,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -213,9 +201,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -263,21 +249,19 @@
|
||||
"Who wins a game if both players play rationally? To answer that, consider the general situation at some point\n",
|
||||
"during the game where\n",
|
||||
"a player is presented with a fragment. That player can win if either:\n",
|
||||
"- The fragment is a word (meaning the other player formed the word, and lost).\n",
|
||||
"- The fragment is not a legal fragment (meaning the other player made a mistake, and lost).\n",
|
||||
"- The fragment is a complete word (meaning the other player just formed the word, and thereby lost).\n",
|
||||
"- The fragment is not a legal fragment (meaning the other player made a mistake, and thereby lost).\n",
|
||||
"- At least one of the legal plays in this position puts the opponent in a position from which they *cannot* win.\n",
|
||||
"\n",
|
||||
"The function `win(vocab, fragment)` implements this. It returns a winning fragment if there is one, otherwise `False`. In particular, it returns `fragment` if the current player has already won (because `fragment` is\n",
|
||||
"a word or illegal fragment), and it returns one of the legal plays if the play leads to a position from\n",
|
||||
"a word or illegal fragment), and it returns one of the legal plays if that play leads to a position from\n",
|
||||
"which the opponent *cannot* `win`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def win(vocab, fragment=''):\n",
|
||||
@@ -301,9 +285,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -324,9 +306,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -340,16 +320,14 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 'g' is a winning play (but 'c' wuld be a loser)\n",
|
||||
"# 'g' is a winning play (but 'c' would be a loser)\n",
|
||||
"win(Vocabulary(words('cat camel goat gerbil'))) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -363,16 +341,14 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# No winning play; dommed to 'camel' or 'gar'\n",
|
||||
"# No winning play; doomed to 'camel' or 'gar'\n",
|
||||
"win(Vocabulary(words('cat camel goat gecko gerbil gar'))) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -386,7 +362,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 'g' wins because 'ga' can be answered with 'gan'\n",
|
||||
"# 'g' wins because 'ga' can be answered with 'gan' and 'ge' with 'ge'\n",
|
||||
"win(Vocabulary(words('cat camel goat gecko gerbil gar gannet'))) "
|
||||
]
|
||||
},
|
||||
@@ -402,9 +378,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -434,22 +408,12 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"CPU times: user 6.35 ms, sys: 179 µs, total: 6.53 ms\n",
|
||||
"Wall time: 7.14 ms\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'h'"
|
||||
"'n'"
|
||||
]
|
||||
},
|
||||
"execution_count": 17,
|
||||
@@ -460,7 +424,7 @@
|
||||
"source": [
|
||||
"enable1_4 = Vocabulary(enable1.words, 4)\n",
|
||||
"\n",
|
||||
"%time win(enable1_4)"
|
||||
"win(enable1_4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -482,9 +446,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import random\n",
|
||||
@@ -495,22 +457,20 @@
|
||||
"\n",
|
||||
"def ask(name):\n",
|
||||
" \"Return a strategy that asks for the next letter.\"\n",
|
||||
" return (lambda _, fragment: input('Player {}, given \"{}\", plays? '.format(name, fragment)))"
|
||||
" return lambda _, fragment: input('Player ' + name + ' given \"' + fragment + '\" plays? ')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here is a function to play a game. You give it a vocabulary, two (or potentially more) strategies, and optionally a `verbose` keyword to say if you want a line printed for each play or not."
|
||||
"Here is a function to play a game. You give it a vocabulary, two (or possibly more) strategies, and optionally a `verbose` keyword to say if you want a line printed for each play or not."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from itertools import cycle\n",
|
||||
@@ -533,14 +493,12 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(1, 'llama')"
|
||||
"(1, 'odyssey')"
|
||||
]
|
||||
},
|
||||
"execution_count": 20,
|
||||
@@ -555,33 +513,31 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[(1, 'dreck'),\n",
|
||||
" (1, 'mho'),\n",
|
||||
"[(1, 'truancies'),\n",
|
||||
" (1, 'xebec'),\n",
|
||||
" (1, 'ods'),\n",
|
||||
" (1, 'vying'),\n",
|
||||
" (1, 'ewe'),\n",
|
||||
" (1, 'bwana'),\n",
|
||||
" (1, 'vying'),\n",
|
||||
" (1, 'knell'),\n",
|
||||
" (1, 'zloty'),\n",
|
||||
" (1, 'flirt'),\n",
|
||||
" (1, 'zlote'),\n",
|
||||
" (1, 'bwana'),\n",
|
||||
" (1, 'aal'),\n",
|
||||
" (1, 'gjetost'),\n",
|
||||
" (1, 'oquassa'),\n",
|
||||
" (1, 'oquassa'),\n",
|
||||
" (1, 'yperite'),\n",
|
||||
" (1, 'yperite'),\n",
|
||||
" (1, 'plica'),\n",
|
||||
" (1, 'wrest'),\n",
|
||||
" (1, 'qursh'),\n",
|
||||
" (1, 'aal'),\n",
|
||||
" (1, 'aas'),\n",
|
||||
" (1, 'tweak'),\n",
|
||||
" (1, 'uintahite'),\n",
|
||||
" (1, 'uintahite'),\n",
|
||||
" (1, 'hmm'),\n",
|
||||
" (1, 'uintahite'),\n",
|
||||
" (1, 'jnana')]"
|
||||
" (1, 'pliancies'),\n",
|
||||
" (1, 'flounce'),\n",
|
||||
" (1, 'ufologist'),\n",
|
||||
" (1, 'flour'),\n",
|
||||
" (1, 'dweeb'),\n",
|
||||
" (1, 'flirt'),\n",
|
||||
" (1, 'ignatia')]"
|
||||
]
|
||||
},
|
||||
"execution_count": 21,
|
||||
@@ -598,14 +554,12 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(0, 'hugs')"
|
||||
"(0, 'nyctalopia')"
|
||||
]
|
||||
},
|
||||
"execution_count": 22,
|
||||
@@ -620,23 +574,22 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Player 0, given \"\", plays? d\n",
|
||||
"Player 0, given \"dr\", plays? dri\n",
|
||||
"Player 0, given \"drif\", plays? drift\n"
|
||||
"Player P given \"\" plays? d\n",
|
||||
"Player P given \"dw\" plays? dwa\n",
|
||||
"Player P given \"dwar\" plays? dwarv\n",
|
||||
"Player P given \"dwarve\" plays? dwarves\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(1, 'drift')"
|
||||
"(1, 'dwarves')"
|
||||
]
|
||||
},
|
||||
"execution_count": 23,
|
||||
@@ -645,7 +598,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"play(enable1, ask(0), rational)"
|
||||
"play(enable1, ask('P'), rational)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -665,9 +618,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import textwrap \n",
|
||||
@@ -717,9 +668,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@@ -745,16 +694,14 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Outcomes (7) for player 0:\n",
|
||||
"Winners (7): nays nene ngultrum nirvanic nolo null nyctalopia\n"
|
||||
"Winners (7): naan nene ngultrum nirvanic nolo null nyctalopia\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -778,21 +725,19 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Outcomes (55) for player 1:\n",
|
||||
"Winners (55): aah aal aargh aas bwana cwm drake dreck drift droit\n",
|
||||
"druse dry ewe fjeld fjord gjetost hmm ihram jnana kwashiorkor llama\n",
|
||||
"mho nth oquassa praam prequel prill pro prurigo pry qua quell quiff\n",
|
||||
"quondam qursh rhamnus rheum rhizoid rho rhumb rhyolitic sjambok\n",
|
||||
"tchotchke uhlan vroom wrang wrest wrick wrong wrung wry xanthic\n",
|
||||
"xanthin yperite zucchetto\n"
|
||||
"Winners (55): aah aal aargh aas bwana cwm drave dreck drink droit\n",
|
||||
"druid dry ewe fjeld fjord gjetost hmm ihram jnana kwashiorkor llano\n",
|
||||
"mho nth oquassa prawn prequel prill pro prurigo pry qua quell quiff\n",
|
||||
"quomodo qursh rhamnus rheum rhizoid rho rhumb rhyolitic squoosh\n",
|
||||
"tchotchke uhlan vying wrath wrest wrist wrong wrung wry xanthic\n",
|
||||
"xanthin yttrium zucchetto\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -812,26 +757,24 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Outcomes (85) for player 1:\n",
|
||||
"Losers (4): hybrid hyphen hyte ngultrum\n",
|
||||
"Losers (4): hybris hyphen hyte ngultrum\n",
|
||||
"Winners (81): aquiculture aquifer aquilegia aquiver bwana cnidarian\n",
|
||||
"drake dreck drift droit druse drywall eschatologies eschatology\n",
|
||||
"escheat eserine eskar esophagus esplanade esquire esquiring essay\n",
|
||||
"drave dreck drink droit druid dryness eschatologies eschatology\n",
|
||||
"escheat eserine esker esophagus esplanade esquire esquiring essay\n",
|
||||
"estuarine estuary esurience fjeld fjord gjetost hyaenic hydatid hyena\n",
|
||||
"hyenine hyenoid hygeist hying hylozoism hylozoist hymen hyoid hypha\n",
|
||||
"hyraces hyrax hyson ihram jnana kwashiorkor llama mbira ngwee oquassa\n",
|
||||
"plaza plethoric plica plonk pluck plyer quaff quell quiff quondam\n",
|
||||
"qursh rhamnus rheum rhizoid rhomb rhumb rhyolitic sjambok tchotchke\n",
|
||||
"uhlan vroom wrang wrest wrick wrong wrung wryly xanthic xanthin\n",
|
||||
"yperite zucchetto\n"
|
||||
"hyraces hyrax hyson ihram jnana kwashiorkor llano mbira ngwee oquassa\n",
|
||||
"plaza plethoric plica plonk pluck plyer quaff quell quiff quomodo\n",
|
||||
"qursh rhamnus rheum rhizoid rhomb rhumb rhyolitic squoosh tchotchke\n",
|
||||
"uhlan vying wrath wrest wrist wrong wrung wryly xanthic xanthin\n",
|
||||
"yttrium zucchetto\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -858,9 +801,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class SuperVocabulary(Vocabulary):\n",
|
||||
@@ -886,21 +827,17 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"enable1s = SuperVocabulary(enable1.words, 3)\n",
|
||||
"enable1_4s = SuperVocabulary(enable1.words, 4)"
|
||||
"enable1_3super = SuperVocabulary(enable1.words, 3)\n",
|
||||
"enable1_4super = SuperVocabulary(enable1.words, 4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -932,20 +869,18 @@
|
||||
],
|
||||
"source": [
|
||||
"# Example legal plays\n",
|
||||
"enable1s.legal_plays('crop')"
|
||||
"enable1_3super.legal_plays('crop')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'y'"
|
||||
"'u'"
|
||||
]
|
||||
},
|
||||
"execution_count": 32,
|
||||
@@ -956,20 +891,18 @@
|
||||
"source": [
|
||||
"# Can the first player win in SuperGhost with 3-letter words?\n",
|
||||
"\n",
|
||||
"win(enable1s)"
|
||||
"win(enable1_3super)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'y'"
|
||||
"'u'"
|
||||
]
|
||||
},
|
||||
"execution_count": 33,
|
||||
@@ -980,7 +913,7 @@
|
||||
"source": [
|
||||
"# How about with a 4-letter limit?\n",
|
||||
"\n",
|
||||
"win(enable1_4s)"
|
||||
"win(enable1_4super)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -993,24 +926,22 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Player 0, given \"\", plays? q\n",
|
||||
"Player 0, given \"mq\", plays? mqu\n",
|
||||
"Player 0, given \"umqu\", plays? umqua\n",
|
||||
"Player 0, given \"cumqua\", plays? cumquat\n"
|
||||
"Player P given \"\" plays? q\n",
|
||||
"Player P given \"cq\" plays? cqu\n",
|
||||
"Player P given \"cque\" plays? acque\n",
|
||||
"Player P given \"acques\" plays? acquest\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(1, 'cumquat')"
|
||||
"(1, 'acquest')"
|
||||
]
|
||||
},
|
||||
"execution_count": 34,
|
||||
@@ -1019,7 +950,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"play(enable1s, ask(0), rational)"
|
||||
"play(enable1_3super, ask('P'), rational)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1047,9 +978,7 @@
|
||||
" \n",
|
||||
" def legal_plays(self, fragment):\n",
|
||||
" \"All plays that form a valid infix; optionally reverse fragment first.\"\n",
|
||||
" def all4(frag, L): \n",
|
||||
" return (frag + L, frag[::-1] + L, \n",
|
||||
" L + frag, L + frag[::-1])\n",
|
||||
" def all4(f, L): return (f + L, f[::-1] + L, L + f, L + f[::-1])\n",
|
||||
" return {p for L in alphabet for p in all4(fragment, L)} & self.fragments"
|
||||
]
|
||||
},
|
||||
@@ -1061,16 +990,14 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"enable1sd = SuperDuperVocabulary(enable1.words)\n",
|
||||
"enable1_4sd = SuperDuperVocabulary(enable1.words, 4)"
|
||||
"enable1_3duper = SuperDuperVocabulary(enable1.words)\n",
|
||||
"enable1_4duper = SuperDuperVocabulary(enable1.words, 4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 37,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -1108,22 +1035,20 @@
|
||||
],
|
||||
"source": [
|
||||
"# Example legal plays\n",
|
||||
"enable1sd.legal_plays('crop')"
|
||||
"enable1_3duper.legal_plays('crop')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now we should check who wins. But I'm impateint: I tried `win(enable1sd)`, waited a minute, and it still hadn't returned, so I interrupted that computation and threw in a `lru_cache` decorator; which stops `win` from wasting time repeating the same computation over and over. This brings the time down to about 2 seconds."
|
||||
"Now we should check who wins. But I'm impateint: I tried `win(enable1_3duper)`, waited a minute, and it still hadn't returned, so I interrupted that computation and threw in a `lru_cache` decorator; which stops `win` from wasting time repeating the same computation over and over. This brings the time down to about 2 seconds."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from functools import lru_cache\n",
|
||||
@@ -1143,14 +1068,12 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'y'"
|
||||
"'p'"
|
||||
]
|
||||
},
|
||||
"execution_count": 39,
|
||||
@@ -1159,20 +1082,18 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"win(enable1sd)"
|
||||
"win(enable1_3duper)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'y'"
|
||||
"'p'"
|
||||
]
|
||||
},
|
||||
"execution_count": 40,
|
||||
@@ -1181,7 +1102,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"win(enable1_4sd)"
|
||||
"win(enable1_4duper)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1194,30 +1115,28 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 41,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Player 0, given \"\", plays \"y\".\n",
|
||||
"Player 1, given \"y\", plays \"zy\".\n",
|
||||
"Player 0, given \"zy\", plays \"izy\".\n",
|
||||
"Player 1, given \"izy\", plays \"mizy\".\n",
|
||||
"Player 0, given \"mizy\", plays \"mizyg\".\n",
|
||||
"Player 1, given \"mizyg\", plays \"emizyg\".\n",
|
||||
"Player 0, given \"emizyg\", plays \"emizygo\".\n",
|
||||
"Player 1, given \"emizygo\", plays \"emizygou\".\n",
|
||||
"Player 0, given \"emizygou\", plays \"hemizygou\".\n",
|
||||
"Player 1, given \"hemizygou\", plays \"hemizygous\".\n"
|
||||
"Player 0, given \"\", plays \"p\".\n",
|
||||
"Player 1, given \"p\", plays \"pr\".\n",
|
||||
"Player 0, given \"pr\", plays \"lpr\".\n",
|
||||
"Player 1, given \"lpr\", plays \"rple\".\n",
|
||||
"Player 0, given \"rple\", plays \"rplex\".\n",
|
||||
"Player 1, given \"rplex\", plays \"rplexe\".\n",
|
||||
"Player 0, given \"rplexe\", plays \"urplexe\".\n",
|
||||
"Player 1, given \"urplexe\", plays \"urplexes\".\n",
|
||||
"Player 0, given \"urplexes\", plays \"ourplexes\".\n",
|
||||
"Player 1, given \"ourplexes\", plays \"fourplexes\".\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(0, 'hemizygous')"
|
||||
"(0, 'fourplexes')"
|
||||
]
|
||||
},
|
||||
"execution_count": 41,
|
||||
@@ -1226,7 +1145,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"play(enable1sd, rational, rational, verbose=True)"
|
||||
"play(enable1_3duper, rational, rational, verbose=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1239,9 +1158,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@@ -1256,7 +1173,7 @@
|
||||
],
|
||||
"source": [
|
||||
"[len(v.fragments) \n",
|
||||
" for v in [enable1, enable1_4, enable1s, enable1_4s, enable1sd, enable1_4sd]]"
|
||||
" for v in [enable1, enable1_4, enable1_3super, enable1_4super, enable1_3duper, enable1_4duper]]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1268,7 +1185,7 @@
|
||||
"Here's a summary of what we have learned. (*Note:* the bold **qursh** means it is a losing word):\n",
|
||||
"\n",
|
||||
"| Variant \t| Shortest \t| Winner \t| First Player Forced Outcomes | 2nd Outcomes | Fragments\n",
|
||||
"|----\t|---:\t |---\t |--- |--- |---:\n",
|
||||
"|:----:\t|:---:\t |:---:\t |:---: |:---: |---:\n",
|
||||
"| Ghost | 3 \t | Second \t| qaid qiviut qoph **qursh** qurush qwerty | 55 words | 387,878\n",
|
||||
"| Ghost | 4 \t | First \t| naan nene ngultrum nirvanic nolo null nyctalopia | 85 words | 387,844\n",
|
||||
"| Super | 3\t| First \t| ? | ? | 1,076,434\n",
|
||||
@@ -1306,7 +1223,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.0"
|
||||
"version": "3.5.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
Reference in New Issue
Block a user