xkcd-Name-Dominoes.ipynb
This commit is contained in:
1 parent
06e7a9f520
commit
d5b3f6128e
1 file changed
+407
-124
+407
-124
@@ -5,15 +5,14 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div style=\"text-align:right\">Peter Norvig<br>21 March 2018</div>\n",
|
||||
"\n",
|
||||
"# `xkcd` Name Dominoes\n",
|
||||
"\n",
|
||||
"The March 21, 2018 `xkcd` comic number 1970 was [Name Dominoes](https://xkcd.com/1970/): domino tiles laid out in a legal array,\n",
|
||||
"but with each tile having names of famous poeple rather than numbers. In regular [dominoes](https://en.wikipedia.org/wiki/Dominoes), each tile has two halves, and a tile can be legally placed only if one half is adjacent to another tile with the same number/name, and neither half is adjacent to any tile with a different number/name. (The very first tile in a game has no adjacent tiles, so it can be placed anywhere.) `xkcd 1970` also allows some tiles to three names, with matches allowed against the middle name; I won't allow that.\n",
|
||||
"but with each tile having names of famous poeple rather than numbers. In regular [dominoes](https://en.wikipedia.org/wiki/Dominoes), each tile has two halves, and a tile can be legally placed only if one half is adjacent to another tile with the same number/name, and neither half is adjacent to any tile with a different number/name. (The very first tile in a game has no adjacent tiles, so it can be placed anywhere.) I will write a function to lay out dominoes in a random, legal array. I'll start with two key data structures:\n",
|
||||
"\n",
|
||||
"I will write a function to lay out dominoes in a random, legal array. I'll start with two key data structures:\n",
|
||||
"\n",
|
||||
"- **`Board(n)`**: Creates an [n × n] 2-dimensional array of locations; each location holds as a value one half of a tile, or it can be `empty`, or it can be a `border`, meaning nothing can be placed there.\n",
|
||||
"- **`tiles(text)`**: a function to create a list of tiles, each of which is a 2-element list, like `['a', 'b']`, indicating the two halves. The input is a string, consisting of comma-and/or-space-separated tiles, where the two halves of the tile are separated by a `|` character."
|
||||
"- **`Tile`**: a tile is a 2-element tuple, like `('Tim', 'Cook')`, indicating the two halves.\n",
|
||||
"- **`Board(n)`**: Creates an [n × n] 2-dimensional array of locations; each location holds as a value one half of a tile, or it can be `empty`, or it can be a `border`, meaning nothing can be placed there.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -27,6 +26,8 @@
|
||||
"empty = ' '\n",
|
||||
"border = '--'\n",
|
||||
"\n",
|
||||
"Tile = tuple\n",
|
||||
"\n",
|
||||
"class Board(list):\n",
|
||||
" \"A board is a 2d array of values.\"\n",
|
||||
" \n",
|
||||
@@ -38,7 +39,9 @@
|
||||
" \n",
|
||||
" def get(self, loc): return self[loc[1]][loc[0]]\n",
|
||||
" \n",
|
||||
" def put(self, loc, value): self[loc[1]][loc[0]] = value"
|
||||
" def put(self, loc, value): self[loc[1]][loc[0]] = value\n",
|
||||
" \n",
|
||||
"tiles1 = [('Bo', 'Ja'), ('Ja', 'Po'), ('Ja', 'Ry'), ('Ry', 'Ke'), ('Gr', 'Ke'), ('Gr', 'Ho')]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -68,50 +71,6 @@
|
||||
"Board(4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def tiles(text):\n",
|
||||
" \"tiles('Bo|Ja, Ja|Po') => [['Bo', 'Ja'], ['Ja', 'Po']\"\n",
|
||||
" return [tile.split('|') for tile in split(text)]\n",
|
||||
"\n",
|
||||
"def split(text): return text.replace(',', ' ').split()\n",
|
||||
"\n",
|
||||
"tiles1 = tiles('Bo|Ja, Ja|Po, Ja|Ry, Ry|Ke, Gr|Ke, Gr|Ho')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[['Bo', 'Ja'],\n",
|
||||
" ['Ja', 'Po'],\n",
|
||||
" ['Ja', 'Ry'],\n",
|
||||
" ['Ry', 'Ke'],\n",
|
||||
" ['Gr', 'Ke'],\n",
|
||||
" ['Gr', 'Ho']]"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"tiles1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@@ -130,7 +89,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -139,15 +98,15 @@
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[['--', '--', '--', '--', '--', '--', '--'],\n",
|
||||
" ['--', ' ', ' ', 'Ja', 'Ja', 'Bo', '--'],\n",
|
||||
" ['--', ' ', 'Ry', 'Ry', ' ', ' ', '--'],\n",
|
||||
" ['--', ' ', 'Ke', ' ', ' ', ' ', '--'],\n",
|
||||
" ['--', ' ', 'Ke', 'Gr', ' ', ' ', '--'],\n",
|
||||
" ['--', ' ', ' ', 'Gr', 'Ho', ' ', '--'],\n",
|
||||
" ['--', 'Ho', ' ', 'Po', 'Ja', ' ', '--'],\n",
|
||||
" ['--', 'Gr', 'Gr', ' ', 'Ja', 'Bo', '--'],\n",
|
||||
" ['--', ' ', 'Ke', ' ', 'Ja', ' ', '--'],\n",
|
||||
" ['--', ' ', 'Ke', 'Ry', 'Ry', ' ', '--'],\n",
|
||||
" ['--', ' ', ' ', ' ', ' ', ' ', '--'],\n",
|
||||
" ['--', '--', '--', '--', '--', '--', '--']]"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -225,9 +184,9 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -244,7 +203,8 @@
|
||||
" for (y, row) in enumerate(board):\n",
|
||||
" for (x, val) in enumerate(row):\n",
|
||||
" if val is not border:\n",
|
||||
" plt.text(x + 0.5, y + 0.3, val, ha='center', fontsize=9)\n",
|
||||
" plt.text(x + 0.5, y + 0.3, val.replace('-', ' '),\n",
|
||||
" ha='center', fontsize=8)\n",
|
||||
" \n",
|
||||
"class Board(list):\n",
|
||||
" \"A board is a 2d array of values.\"\n",
|
||||
@@ -274,16 +234,16 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAFpCAYAAACMK9MWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADMBJREFUeJzt3V+Ipfddx/HP12xSGxJTQjVWqU1VTPEPWQjYNiTdRBYq\nKQjBgrDFSqstiDctIlRRvBAhF5ZQNF40LdYWV2OLNKkYMKHZQGka7cJWS7GlQmqxtVZIqKm5yJ+v\nF3PWbrO7sxszu895vvN6wZCZc7Hz4eyZ9/7mmd0n1d0BYP2+Z+kBAOwNQQcYQtABhhB0gCEEHWAI\nQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEE\nHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0\ngCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtAB\nhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcY\nQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAI\nQQcYQtABhhB0gCEEHWCIA0sPAHihquqdSY4sveMFOtrd77+Qn8AJHVijI0kOLj3iBTiYi/AHkBM6\nsFYnuvuWpUecj6o6djE+jxM6wBCCDjCEoAMMIegAQwg6wBCCDjCEoAMMIegAQwg6wBCCDjCEoAMM\nIegAQwg6wBCCDjCEoAMMIegAQwg6wBCCDjCEoAMMIegAQwg6wBCCDuxbVXVtVT34vMe+vNSeF0vQ\nAYY4sPQAgG1TVdck+VCSy5N8O8mvdPc3Fx11HpzQgf3uhqo6dvJt89hvJ/nL7j6U5K82H289QQf2\nu+PdfcvJt81j1yX59Ob9Tyd5zSLLXiBBBzjdF5PcuHn/xs3HW881dIDT3ZHkz6vq15L8T5K3Lrzn\nvAg6sG9192NJDj/vsR/fvPvGiz7oRXLJBWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAI\nQQcYQtABhljFvVyq6p1Jjiy9Y6hXbP779UVXzHW0u9+/9IjzsbKvs4NJvrH0iG2zlhP6kez8BrL3\nfmzzxt47mPUEMlnX19kVSa5ZesS2WcUJfePEKTefZ49U1RNJ4rnde6f832/WZBVfZydft3y3tZzQ\nATgHQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYQtABhhB0\ngCEEHWAIQQcYQtABhhB0gCEEHWAIQQcYYl8FvaqurarHq+pYVX22qo4svelcNpsfXHrH+VjL1ue9\nDh6tqnctvWmSqrq+qu6vqoer6lNVdXdVXbr0rrNZ297dHFh6wAKOd/fhqvq+JP9UVX/d3c8sPYqL\n7uTr4JIkX6iqu7v720uPWruquirJR5Lc3t3/unnspiSXJHl68/El3f3sciu/Y217z2VfndBP1d3f\nSvIfSd6yOaU9UlW/t/Sus6mqI5sTxCNV9YGqqqU3nc2atia5PMllSQ5X1ftOPlhVD1TVq5abtVpv\nSnLfyTgmSXd/KskPVtU/VtVHkty92LrTrW3vrvZt0Kvqh5Nck+R3k7wxyY1JDlXV9YsOO7v7uvtQ\nd78+yZVJbl560C7WsPWGqno4yVeT3JXkE0luqqqXVNWrkzzT3V9ZdOE6vTI7z2mq6vs3l7U+n+Tl\nSa5N8hvd/fYF9z3f2vbuaj8G/Yaqeig732a9J8k3uvuJ7u4kn0ly3aLrzu7mqvrkJkKvzc4LcVut\nYevx7j6U5FCSw939XJKPJ7k9yduSfHDJcSv21Wx+v7v7m919S5LPJvneJJ/ffGe8Tda2d1f7MejH\nu/vW7v65JB9Nck1VvWxzWeB1Sb647LyzuiPJWzYRejTJNl/GWM3W7v5ckq9V1W3Zifjbk9yW5N5F\nh63X3yX5har60VMeO/mzum28Dr22vbvajz8U/T/d/VxV/VaSv0/yXJL7N1/g26Sy88L6cJIHqupf\nFt6zmzVtPdWdSe7q7jdU1VNJHurup5cetUbd/URVvTXJn1bVS5M8leTfkmzlD5zXtvdcaudKw3ar\nqmNJsvl2aF+pqluT/PKFuo5XVU8kSXe/bA9+rQu69WKoqr9J8p7u/tIe/FrHkvW8bte0dy9ftxfD\nxXpu9/UJfdtt/p78u5O8Y+kt57KmrWey+XvH9yZ5bC9iDksQ9C3W3UeTHF16x/lY09Yz2VxiuW3p\nHfBi7McfigKMJOgAQwg6wBCCDjCEoAMMIegAQwg6wBCCDjCEoAMMsZZ/KXoo+c79EFbgFdm51/oa\n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\n",
|
||||
"image/png": "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\nRU5ErkJggg==\n",
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x111873cf8>"
|
||||
"<matplotlib.figure.Figure at 0x10eb19b70>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -298,12 +258,379 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Scaling Up Names\n",
|
||||
"# All the Names\n",
|
||||
"\n",
|
||||
"Now let's try with more tiles, with names taken (mostly) from `xkcd 1970`, and with approximate matches, like \"Amy\" matching \"Aimee\".\n",
|
||||
"Now let's try **all** the names from `xkcd 1970`, as reported \n",
|
||||
"by [explainxkcd](http://www.explainxkcd.com/wiki/index.php/1970:_Name_Dominoes), with a few typo corrections:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"270"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def split_names(text):\n",
|
||||
" \"For each line of text, create a Tile of ('First Name(s)', 'Lastname').\"\n",
|
||||
" return [name.rpartition(' ')[0::2]\n",
|
||||
" for name in text.strip().splitlines()]\n",
|
||||
" \n",
|
||||
"tiles1970 = split_names(\"\"\"\n",
|
||||
"Christian Campbell\n",
|
||||
"Neve Campbell\n",
|
||||
"Joe McCarthy\n",
|
||||
"Eugene McCarthy\n",
|
||||
"Gene Vincent\n",
|
||||
"Gene Kelly\n",
|
||||
"Kate Hudson\n",
|
||||
"Rock Hudson\n",
|
||||
"Gordon Brown\n",
|
||||
"James Brown\n",
|
||||
"Jon Brown\n",
|
||||
"John Howard\n",
|
||||
"Columbo\n",
|
||||
"Chris Columbus\n",
|
||||
"Christopher Columbus\n",
|
||||
"Naomi Campbell\n",
|
||||
"Joseph Campbell\n",
|
||||
"Joseph Smith\n",
|
||||
"Frank Vincent\n",
|
||||
"John Kelly\n",
|
||||
"Katherine Johnson\n",
|
||||
"The Rock\n",
|
||||
"Chris Rock\n",
|
||||
"Chris Isaac\n",
|
||||
"James Newton Howard\n",
|
||||
"John Wayne\n",
|
||||
"Howard Stern\n",
|
||||
"Howard Hunt\n",
|
||||
"Chris Hughes\n",
|
||||
"Naomi Watts\n",
|
||||
"Naomi Klein\n",
|
||||
"Kevin Kline\n",
|
||||
"Francis Bacon\n",
|
||||
"Francis Drake\n",
|
||||
"Lyndon Johnson\n",
|
||||
"Oscar the Grouch\n",
|
||||
"Oscar Isaac\n",
|
||||
"Isaac Hayes\n",
|
||||
"Isaac Newton\n",
|
||||
"Wayne Newton\n",
|
||||
"Wayne Knight\n",
|
||||
"Helen Hunt\n",
|
||||
"Helen Hughes\n",
|
||||
"James Watt\n",
|
||||
"James Watt\n",
|
||||
"Kevin Costner\n",
|
||||
"Kevin Bacon\n",
|
||||
"Kevin Love\n",
|
||||
"Lisa Frank\n",
|
||||
"Frank Drake\n",
|
||||
"Drake\n",
|
||||
"Oscar de la Renta\n",
|
||||
"Oscar de la Hoya\n",
|
||||
"Sean Hayes\n",
|
||||
"Wallace Shawn\n",
|
||||
"Wayne Howard\n",
|
||||
"Wayne Brady\n",
|
||||
"James Brady\n",
|
||||
"Tom Brady\n",
|
||||
"Helen Thomas\n",
|
||||
"Tom Hanks\n",
|
||||
"Hank Aaron\n",
|
||||
"Aaron Carter\n",
|
||||
"Stephen James\n",
|
||||
"Will Smith\n",
|
||||
"Kevin Smith\n",
|
||||
"Kein James\n",
|
||||
"Garfield\n",
|
||||
"James Garfield\n",
|
||||
"Warren Buffett\n",
|
||||
"Jimmy Buffett\n",
|
||||
"Warren Beatty\n",
|
||||
"Elizabeth Warren\n",
|
||||
"Earl Warren\n",
|
||||
"Eliabeth Kolbert\n",
|
||||
"Stephen Colbert\n",
|
||||
"George Wallace\n",
|
||||
"Charles Wallace\n",
|
||||
"James Monroe\n",
|
||||
"Marilyn Monroe\n",
|
||||
"Hank Williams\n",
|
||||
"William C. Williams\n",
|
||||
"Steve Harvey\n",
|
||||
"Domino Harvey\n",
|
||||
"Harvey Milk\n",
|
||||
"James Saint James\n",
|
||||
"Etta James\n",
|
||||
"Jim Jones\n",
|
||||
"James Earl Jones\n",
|
||||
"Charlie Parker\n",
|
||||
"Ray Parker\n",
|
||||
"Ray Charles\n",
|
||||
"Charles Manson\n",
|
||||
"Marilyn Manson\n",
|
||||
"Robin Williams\n",
|
||||
"Billy D. Williams\n",
|
||||
"Will Wright\n",
|
||||
"Fats Domino\n",
|
||||
"Bill Clinton\n",
|
||||
"Jimmy John\n",
|
||||
"Tom Jones\n",
|
||||
"Tommy John\n",
|
||||
"Quincy Jones\n",
|
||||
"James Earl Ray\n",
|
||||
"Man Ray\n",
|
||||
"Rachel Ray\n",
|
||||
"Ray Allen\n",
|
||||
"Tim Allen\n",
|
||||
"Tim Cook\n",
|
||||
"Tim Howard\n",
|
||||
"Robin Wright\n",
|
||||
"Wilbur Wright\n",
|
||||
"Fatty Arbuckle\n",
|
||||
"Fat Joe\n",
|
||||
"George Clinton\n",
|
||||
"John Kerry\n",
|
||||
"Kerry Washington\n",
|
||||
"John Irving\n",
|
||||
"John Quincy Adams\n",
|
||||
"John Adams\n",
|
||||
"Amy Adams\n",
|
||||
"Aimee Mann\n",
|
||||
"Super Man\n",
|
||||
"Bat Man\n",
|
||||
"Ayn Rand\n",
|
||||
"Lily Allen\n",
|
||||
"Paul Allen\n",
|
||||
"Ron Howard\n",
|
||||
"Howard Hughes\n",
|
||||
"Joe Kennedy\n",
|
||||
"George Bush\n",
|
||||
"George Wasington\n",
|
||||
"Wasington Irving\n",
|
||||
"Martha Wasington\n",
|
||||
"Ma Rainey\n",
|
||||
"Jack Ma\n",
|
||||
"Super Grover\n",
|
||||
"Jack Black\n",
|
||||
"Rand Paul\n",
|
||||
"Paul Ryan\n",
|
||||
"Paul Simon\n",
|
||||
"Ron Paul\n",
|
||||
"John Hughes\n",
|
||||
"Langston Hughes\n",
|
||||
"John F. Kennedy\n",
|
||||
"Little Richard\n",
|
||||
"Rich Little\n",
|
||||
"Martha Stewart\n",
|
||||
"Yo Yo Ma\n",
|
||||
"Ma Bell\n",
|
||||
"Grover Cleveland Alexander\n",
|
||||
"Grover Cleveland\n",
|
||||
"Jack White\n",
|
||||
"Jack Ryan\n",
|
||||
"Debby Ryan\n",
|
||||
"Carly Simon\n",
|
||||
"Carly Hughes\n",
|
||||
"Charles Evans Hughes\n",
|
||||
"John Williams\n",
|
||||
"Little John\n",
|
||||
"Stuart Little\n",
|
||||
"Potter Stewart\n",
|
||||
"Kristen Stewart\n",
|
||||
"Kristen Bell\n",
|
||||
"Kristen Hooks\n",
|
||||
"Alexander Graham Bell\n",
|
||||
"Franklin Graham\n",
|
||||
"Lloyd Alexander\n",
|
||||
"Meg White\n",
|
||||
"Meg Ryan\n",
|
||||
"Debbie Reynolds\n",
|
||||
"John Reynolds\n",
|
||||
"Carly Fiorina\n",
|
||||
"Grace Lee Boggs\n",
|
||||
"Wade Boggs\n",
|
||||
"William Safire\n",
|
||||
"Prince William\n",
|
||||
"Little Prince\n",
|
||||
"Harry Potter\n",
|
||||
"James Potter\n",
|
||||
"James Hook\n",
|
||||
"James Dean\n",
|
||||
"Aretha Franklin\n",
|
||||
"Frank Lloyd Wright\n",
|
||||
"Barry White\n",
|
||||
"Walter White\n",
|
||||
"Walt Whitman\n",
|
||||
"John Kelly\n",
|
||||
"Grace Lee\n",
|
||||
"Nancy Grace\n",
|
||||
"Garnet\n",
|
||||
"Prince\n",
|
||||
"Prince Felder\n",
|
||||
"Prince Harry\n",
|
||||
"Harry Styles\n",
|
||||
"John Dean\n",
|
||||
"Benjamin Franklin\n",
|
||||
"Harrold Lloyd\n",
|
||||
"Harrold Ford\n",
|
||||
"Betty White\n",
|
||||
"Meg Whitman\n",
|
||||
"Christine Todd Whitman\n",
|
||||
"Megyn Kelly\n",
|
||||
"Grace Kelly\n",
|
||||
"Grace Jones\n",
|
||||
"Jack Nicholson\n",
|
||||
"Jack Ruby\n",
|
||||
"Jack Russel\n",
|
||||
"Harry Fielder\n",
|
||||
"Harry Trueman\n",
|
||||
"Harry Jon Benjamin\n",
|
||||
"John Edward\n",
|
||||
"Benjamin Harrison\n",
|
||||
"Harrison Ford\n",
|
||||
"Henry Ford\n",
|
||||
"Betty Ford\n",
|
||||
"Betty Friedan\n",
|
||||
"Chris Christie\n",
|
||||
"Chris Pratt\n",
|
||||
"Maggie Grace\n",
|
||||
"Grace Hopper\n",
|
||||
"Russel Crowe\n",
|
||||
"Russ Smith\n",
|
||||
"John Smith\n",
|
||||
"Justin Long\n",
|
||||
"John Bel Edwards\n",
|
||||
"John Candy\n",
|
||||
"John Henry\n",
|
||||
"Henry James\n",
|
||||
"Bill James\n",
|
||||
"Chris Cooper\n",
|
||||
"Chris Hemsworth\n",
|
||||
"Chris Evans\n",
|
||||
"Topher Grace\n",
|
||||
"Van Morrison\n",
|
||||
"Sheryl Crow\n",
|
||||
"Sheryl Sandberg\n",
|
||||
"Cameron Crow\n",
|
||||
"Long John Silver\n",
|
||||
"Olivia Newton John\n",
|
||||
"Huey long\n",
|
||||
"John Edwards\n",
|
||||
"Candy Crowley\n",
|
||||
"Aleister Crowley\n",
|
||||
"James Fenimore Cooper\n",
|
||||
"James Cook\n",
|
||||
"Robert Frost\n",
|
||||
"Bob Evans\n",
|
||||
"Evan Tayler Jones\n",
|
||||
"James Cameron\n",
|
||||
"Cam Newton\n",
|
||||
"Cameron Diaz\n",
|
||||
"Huey Newton\n",
|
||||
"Huey Lewis\n",
|
||||
"John Lewis\n",
|
||||
"Jenny Lewis\n",
|
||||
"Ryan Lewis\n",
|
||||
"Burt Reynolds\n",
|
||||
"Alistair Cooke\n",
|
||||
"Alistair Cookie\n",
|
||||
"Cokie Roberts\n",
|
||||
"John Roberts\n",
|
||||
"Robert Johnson\n",
|
||||
"Robert E. Lee\n",
|
||||
"Tommy Lee\n",
|
||||
"Tommy Lee Jones\n",
|
||||
"Etta James\n",
|
||||
"John Oliver\n",
|
||||
"Ryan Reynolds\n",
|
||||
"Alastair Reynolds\n",
|
||||
"\"\"\")\n",
|
||||
"\n",
|
||||
"With many names, the program can get stuck before it has placed many tiles. I could modify the program to *back up* in this case, but it will be easier to just add a new function, `best_dominoes(tiles, repeat=R)` that calls `dominoes` R times, and returns (and optionally displays) the\n",
|
||||
"board that has placed the most tiles out of those R boards (as measured by `len(board.boxes)`)."
|
||||
"len(tiles1970)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Approximate and Partial Matches\n",
|
||||
"\n",
|
||||
"The halves of two tiles match if they are an exact match, like \"Amy\" and \"Amy\", but also if they are an **approximate match**, like \"Amy\" and \"Aimee\". You can manually allow for this with:\n",
|
||||
"\n",
|
||||
" synsets = synonyms(\"Amy=Aimee, ...\")\n",
|
||||
"\n",
|
||||
"Another issue is a **partial match**: \"John Smith\" is allowed to match \"Long John Silver\"\n",
|
||||
"because the first name \"John\" is a piece of the first name \"Long John\". allowed to match. If you pass in a list of tiles as a second argument to `synsets`, then all the pieces of a first name (if it has more than one piece) will be (individually) made synonyms of the whole first name.\n",
|
||||
"\n",
|
||||
"I also update `legal_match` to consult the `synsets` global variable for an approximate or partial match, and to handle a special case: a single names like \"Prince\" gets represented as the tile `('', 'Prince')`, but we don't want the empty first name of this tile to match the empty first name of \"Drake\", so we disallow an empty-to-empty match."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import collections\n",
|
||||
"\n",
|
||||
"Synset = set\n",
|
||||
"\n",
|
||||
"def synonyms(text, tiles=()): \n",
|
||||
" \"synonyms('a=A, b=B') => dict(a={'a', 'A'}, A={'a', 'A'}, b={'b', 'B'}, B={'b', 'B'}\"\n",
|
||||
" synsets = collections.defaultdict(set)\n",
|
||||
" # Process `text`\n",
|
||||
" for text1 in text.split(','):\n",
|
||||
" synset = Synset(text1.strip().split('='))\n",
|
||||
" for s in synset:\n",
|
||||
" synsets[s] |= synset\n",
|
||||
" # Process `tiles`\n",
|
||||
" for (first, last) in tiles:\n",
|
||||
" if ' ' in first:\n",
|
||||
" for piece in first.split():\n",
|
||||
" synsets[piece].add(first)\n",
|
||||
" synsets[first].add(piece)\n",
|
||||
" return synsets\n",
|
||||
"\n",
|
||||
"synsets = synonyms(\"\"\"\n",
|
||||
" Amy=Aimee, Cook=Cooke=Cookie=Cokie, Alastair=Alistair, Columbo=Columbus, \n",
|
||||
" Safire=Sapphire=Garnet, Garnet=Ruby, Charlie=Charles, Sean=Shawn, \n",
|
||||
" Jimmy=James, Man=Mann, Jack=John, Tom=Tommy, Will=William=Williams, \n",
|
||||
" Robert=Roberts=Bob, Cam=Cameron, Oliver=Olivia, Edward=Edwards, \n",
|
||||
" Rich=Richard, Oscar=Oscar, Frank=Frank, Chris=Christopher=Topher,\n",
|
||||
" Fat=Fats=Fatty\n",
|
||||
" \"\"\", tiles1970)\n",
|
||||
"\n",
|
||||
"def legal_match(value, nbrval):\n",
|
||||
" \"Does this value match the neighbor's value?\"\n",
|
||||
" if value == '' == nbrval: return False\n",
|
||||
" return (nbrval == value or nbrval is empty or nbrval is border or\n",
|
||||
" nbrval in synsets[value])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Random Restart\n",
|
||||
"\n",
|
||||
"With many tiles, the program can get stuck before it has placed enough tiles. I could modify the program to *back up* in this case, but it will be easier to just *give up* and start again with an empty board. I can repeat this multiple times, and take the board on which the most tiles were placed. The function `best_dominoes` does this, and optionally plots the result. (I could fit more tiles on a larger square (with smaller tiles), but then the text would overflow the tiles even more than now.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -312,72 +639,19 @@
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tiles2 = tiles(\"\"\"\n",
|
||||
" The|Rock, Chris|Rock, Rock|Hudson, Chris|Isaac, Isaac|Newton, Olivia|Newton-John, Isaac|Hayes, \n",
|
||||
" Sean|Hayes, Wallace|Shawn, Charles|Wallace, George|Wallace, Charles|Manson, Ray|Charles, \n",
|
||||
" Rachel|Ray, Ray|Allen, Tim|Allen, Lily|Allen, Tim|Cook, James-Earl|Ray, James-Earl|Jones, \n",
|
||||
" Man|Ray, Ray|Mann, Bat|Man, Super|Man, Tim|Howard, Ron|Howard, Ron|Paul, Paul|Allen, \n",
|
||||
" Rand|Paul, Ayn|Rand, Paul|Ryan, Jack|Ryan, Debby|Ryan, Paul|Simon, Carly|Simon, John|Kelly, \n",
|
||||
" Megyn|Kelly, John|Henry, Grace|Kelly, Grace|Jones, Grace|Hopper, Jack|Ma, Ma|Bell, Yo-Yo|Ma, \n",
|
||||
" Jack|Ruby, Jack|Russell, Marilyn|Manson, Marilyn|Monroe, James|Monroe, George|Bush, \n",
|
||||
" George|Clinton, Bill|Clinton, Jack|White, Meg|Ryan, Meg|White, Barry|White, Walter|White, \n",
|
||||
" Betty|White, Charlie|Parker, Tommy|John, John|Kerry, Kerry|Washington, Jimmy|John, \n",
|
||||
" John|Adams, Amy|Adams, Aimee|Man, Benjamin|Harrison, Benjamin|Franklin, Aretha|Franklin, \n",
|
||||
" Franklin|Graham, James|Garfield, Garfield|, Kristen|Bell, Kristen|Stewart, Martha|Stewart, \n",
|
||||
" Martha|Washington, Wsshington|Irving, John|Irving, Jimmy|Buffett, Jimmy|Jones, Warren|Buffett, \n",
|
||||
" Elizabeth|Warren, Betty|Ford, Henry|Ford, Harrison|Ford, Kevin|Bacon, Kevin|Kline, Kevin|Love, \n",
|
||||
" Kevin|Smith, Kevin|Costner, Will|Smith, Tommy|Lee, Robert-E|Lee, John|Wayne, Wayne|Newton, \n",
|
||||
" Wayne|Knight, Wayne|Howard, Wayne|Brady, Tom|Brady, James|Brady, Cam|Newton, Cameron|Diaz,\n",
|
||||
" James|Cameron, Etta|James, John|Oliver, John|Candy, John|Edward, John|Edwards, John|Lewis,\n",
|
||||
" Huey|Lewis, Huey|Newton, Huey|Long, Long|John-Silver, Prince|, Prince|Harry, Harry|Potter,\n",
|
||||
" Harry|Truman, Little|Prince, Stuart|Little, Little|Richard, Rich|Little, Chris|Pratt,\n",
|
||||
" Chris|Evans, Bob|Evans, Tommy|Lee-Jones, Super|Grover\n",
|
||||
" \"\"\")\n",
|
||||
"\n",
|
||||
"def synonyms(text): return [set(group.split('=')) for group in split(text)]\n",
|
||||
"\n",
|
||||
"match_groups = synonyms(\"\"\"\n",
|
||||
" Charlie=Charles, Newton=Newton-John, Sean=Shawn, James=James-Earl=Jimmy, Man=Mann, Amy=Aimee,\n",
|
||||
" Jack=John=John-Silver, Tom=Tommy, Will=William, Robert-E=Robert=Bob, Cam=Cameron, Oliver=Olivia,\n",
|
||||
" Edward=Edwards, Rich=Richard, Lee=Lee-Jones, Jones=Lee-Jones\n",
|
||||
" \"\"\")\n",
|
||||
"\n",
|
||||
"def legal_match(value, nbrval):\n",
|
||||
" \"Does this value match the neighbor's value?\"\n",
|
||||
" return (nbrval in (empty, border, value) or \n",
|
||||
" any(value in group and nbrval in group\n",
|
||||
" for group in match_groups))\n",
|
||||
"\n",
|
||||
"def best_dominoes(tiles, n=24, figsize=16, verbose=True, repeat=300):\n",
|
||||
" board = max((dominoes(tiles, n) for _ in range(repeat)), \n",
|
||||
" key=lambda board: len(board.boxes))\n",
|
||||
" if verbose:\n",
|
||||
" print(len(board.boxes), '/', len(tiles), 'tiles placed')\n",
|
||||
" plot_board(board, figsize)\n",
|
||||
" return board"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"110 / 126 tiles placed\n"
|
||||
"110 / 270 tiles placed\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA6wAAAOICAYAAADSBnxkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XuYZVV95//3xwavBPCCBM3PAWQeL8TQiIBJVBpERZx4\nCY7ECxEjYjTJxBiNQY2iwWTiZeIt6CCJaCuISlQERA10A2KwBWnUMWpUNIoIPJNB7BhF4fv7Y6+y\ny7KqqO6qOmedqvfrec5zdu+965zvWXuvtfZ3rX1Op6qQJEmSJKk3txt3AJIkSZIkzcaEVZIkSZLU\nJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIk\ndcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIk\nSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIk\nSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIk\nSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUk\nSZIkdWmHcQegpZfkeOBp445jwu3Rnq8daxTzO72qThl3EFo+1uUlY11Z4SakrkxCvzIJrM+LMCF1\nZRJ4Ho6QM6wr09OAteMOYsLdtz16tRY7nNXAurx41pXVYRLqSu/9yiSwPi/eJNSV3nkejpgzrCvX\n5qpaN+4gJlWSGwF6LcMkG8cdg0bGurwI1pVVpeu60nu/Mgmsz0um67rSO8/D0XOGVZIkSZLUJRNW\nSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmE\nVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0y\nYZUkSZIkdcmEVZIkSZLUJRNWSZIkSVKXTFglSZIkSV0yYZUkSZIkdcmEdZVLsi7Jt5JsTHJpkgeM\nO6YpSd6V5IFt+eQkr27LhyX5v0mOm7H/EUkel2TXJL9tjFqNWp0+aY5tnxp1PDPe/zFJLmntzf9K\nsmYqpiR/nuTe44xPq8+0PnBDkk8mufu4Y5qp9xhnXEd8JMkdF/h3JyY5fLnj0+LM7FOSnJZkn3HG\nNJv5+j5NPhNWAayvqnXAi4Hfn2/HJLeb799L7LPAgW15Z+A+bflA4LUzd66q86vqXGBXYFTJ4CTE\nKI1dknsALwOOaO3NDcBzprZX1f+sqmu243Xtx7RY66vqUOBdwFPHHcwceo9x6jri08CTxxyLpBXG\njl7T7QzclOSEJBcl+UyS/QHayOlrgXcnOTbJmUnOBV6c5A/bPmuTvGUJ49kEHJTk9sDNbD1fDwSu\nBx6b5Lz2SIvrOOB44FEt5t2SHNdmdS5J8uAljG9SYtQqlOQl7a6JC5NMDaTskuT0JFclWdv2+8LM\ndcvkcQwXtf/R/v23wJOmxXtakn2SfDTJLm3dG5Ic1NZ/orVLL5+2/1uB85cxZq0uuwIkOTzJZe1x\neFu3sZ2Pn03ybGOc02bgV1oslyf53Rbbz2blkmwcU2xaOidOO+9OS7JnkjslOaP1OWcm2bHNuN+1\n7ffGJAcsd2Cz9X2z9XNJTkpycZK3JDltuePS4piwCuCYJBcD7wTeD7ypqg4Bng68aNp+H6qqZ7Tl\nG6vqccCbgSPbuqOBM5Ywrs3Afu1xFfBvSfYE9gQK+E5VHQlcA/zatL87BfhkG+0t4PHAI4AnAK9Y\nwvgmJUatPr8MHFZVv8lwPp3Q1t8T+D3g+cAz51m3HPYAvjv1j6r6EXD7Wfb7KEN9ADigqjYBrwGe\n3dqlfZP8Stt+aVU9ehlj1upwTJLLGerAeuBE4NHt8epp+70HeBjLW0/mMgkxwtCP/Vvr2x4KPHdM\ncWhpHdMGITYCR8yxz3HA2VV1GLCRYab9A8BR7U6Y/arqimWOc0F9X5I9gAdX1SOAsX5VRgtjwioY\nZj0eAawF/oqtCeypwL2m7XfFzOWq+k/g+jaKdTDwz0sVVFXd3BZ/A7i8PY4Ermvrv9ier6GNOs9i\nb4ZkcgPwj/Pst2Jj1Kq0J/D5tnw5MPV9o6+1RHH6+TjbuuVwLdPakwzfc/vJLPt9CHhiG4n/XFt3\nP2B9u1h6ADD1XdflvvjR6rC+qh7CcMfMfYCqqpuq6ibglmn7fbGqfgzcaoy/4JgkGxjakGuS/BNw\nAfDAtr2m7ZsRx6bFW19V69pAxPnAv07bNnU8HwC8oLXTz2RIEj8M/BbwcODiEcS5Jwvr+/4LW6/P\nNo8gLi3SDuMOQF35AcNtwc8H9gfuC7xj2vZb51g+HXgDsKmqpndKS+Eq4NgWx92BvwTOatvm6gB/\nAqxpy1cDn62qJwMk2XGJ45uUGLW6fJNhEATgIcDX2/Js5+OoLiQ/BpyV5PR2W/CfMFzMPG36TlV1\nQ0tmj2XrHRtfAV5QVdcmWdNifh7jSRy0cv01w8zl7ZLs3NatmbZ9qfu37dFrjOuraup2/Y8yzLZd\nA3y1bf8+sEeSbwP/dTwhagn9B8PxDLBvW/cV4IKqOguGa5mq+kmSm4A/Bl46gri+ycL6vm+xdTBl\n+t1v6pQzrIJ2qwdwIfA6hhHci4FnLfDvL2AYPVvK24GnbALWVNUPq+rbDCN2m27jb74H3C3JBxlG\nns9t31PYAPz5Ko1Rq0cYLhQ3JPk0cBLDRe5YVdX1LY7zk1wE7M5wa/xszmW4LXjqjo2XAf+Q5ELg\nPODOyxyuVqGq+gqwG/C/gU+2x6vGGtQMkxAjw10SH2G4S+vGtu7dwFvbuu+NKS4tnU3AC4APsvUY\nnwI8KckFra2e+j2O9wF7VdWXRxDX91hA31dV1wKbk1wCHM7sd/uoI1n6CTGN29QPGrRbN0bxfmuA\n86vqUaN4v1FIciNAVXV5e+6oj7HGY3uOc5JjgJ2q6m3LFNZEsa6sDpNwnHvvVybBJBzn3o3hGvFI\nYN+qet0o3m+hkuxQVT9NcjSwd1UteGDX83D0vCVYi5Lkbgy3v/7vcccirXat4z0eOGrcsUiSVrck\nRzF8/eMJ445lFq9J8usMd7k9ZdzBaH4mrFqUqvp34NBxxyEJqupM4MxxxyFJUvs+61m3ueMYVNVL\nxh2DFs7vsEqSJEmSumTCKkmSJEnqkgmrJEmSJKlLJqySJEmSpC6ZsEqSJEmSumTCKkmSJEnqkgmr\nJEmSJKlLJqySJEmSpC7tMO4AtCwOAUiyccxxTLKdgC3jDmKSJTkeeNq441iA06vqlHEHMYepunzj\nuAO5DdcB1447iDmsBTaPO4j5WFdWjV3AvnmRuq7PE1KX7VcW7yDg5gmoyyumzXaGVZrdFobGUtvv\naQwXFz1bS/8XF73bCdh93EHMYzNw+riDuA3WFWlheq/Pk1CXJ0Hv/crNwO3HHcRtWFFttjOsK1BV\nZdwxTLoJGDWbFJurat24g5jLBBzniwAmoQx7jnFCWFdWvu7rs5ZE13V5EvTer/QeH6y8NtsZVkmS\nJElSl0xYJUmSJEldMmGVJEmSJHXJhFWSJEmS1CUTVkmSJElSl0xYJUmSJEldMmGVJEmSJHXJhFWS\nJEmS1CUTVkmSJElSl0xYJUmSJEldMmGVJEmSJHXJhFWSJEmS1CUTVkmSJElSl0xYJUmSJEldMmGV\nJEmSJHXJhFWSJEmS1CUTVkmSJElSl0xYJUmSJEldMmGVJEmSJHXJhFWSJEmS1CUTVmmRkqxL8q0k\nG5NcmuQBc+x3bJLbteUnJrnbaCPtz0LLTgvXyvSkObZ9atTxaHkkeWSrNxcn+VCSuy/w705Lss9y\nx9eTmXViucugvf6ey/X6mkztPPxBkl3bv7f5PEzye8sT3bzvOdL6M6mS7NLa5I1Jvt+e35nk8HHH\nthKYsEpLY31VrQNeDPz+HPscy9Y690Rg1SeszaxlN5XcS/p5SXYDXgH8VlU9AngJcPvxRrV62VZp\nG3wbOG4Rfz/yhFULU1Xfr6p17XrmC+35W+ONauWwkZWW1s7ATUkOnjZr+KwkBwFrgQuSPBM4Anhv\nkhcn2ZBkDUCSDybZfYzxj9NU2W1M8lrg3W3E8pw2i/RmgCTva+ufk+TDbd05SdYkuSzJO5JsTnLE\nOD/MuCV5STv/Lkxyn7Z6lySnJ7kqydq23xdmrlP3jmQY6PkBQFV9FbhnO96XJXkGQJL9Zq6bkuTQ\nJO9NsuPow+/CXbaxbXlTkouSXDJVn1q5vg14fZK9knwmydnA3uP7WOrcR4DfmurzgTslOaO102cm\n2XGe8/AJwINaH/moJIe3c/CyqVm8tu0NST6b5NnL+DlOnPaepyXZM8lsn+UjSe7a9ntjkgOWMaZe\n/W6Sf0pyKkCS+7QyujTJS9q6E5O8u+33riR/0Y7rK9r2I9qxvTzJ77Z1f9D22ZDkweP7eKNhwiot\njWOSXAy8E3g/8Grg8cDDgKcDm9vjkVX1LuB84OlV9TrgAuDQJDsDd6iq68bxAcZoZtkBfKiqngEc\nD5zZZpHunORg4DPAQ4EDgR+3C+5bq+oWhlnrlwGPA5474s/Rk18GDquq32SYiTuhrb8nwwj984Fn\nzrNOfdsDuHbGur9kaGseDvxRqxezrQNYBzwHOLaqfjKSiMfvmHbBt5FhwPDRbFvbckJVHQK8iq1t\nyz2A11TVCxnuEHkh8NvAgm7P1qp0C/BRhvMEhrp4dlUdBmwEnszc5+FHaDN3VfVJ4Line truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x11af01320>"
|
||||
"<matplotlib.figure.Figure at 0x1158ec7b8>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -385,7 +659,16 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"best_dominoes(tiles2);"
|
||||
"def best_dominoes(tiles, n=20, figsize=16, plot=True, repeat=30):\n",
|
||||
" board = max((dominoes(tiles, n) for _ in range(repeat)), \n",
|
||||
" key=lambda board: len(board.boxes))\n",
|
||||
" if plot:\n",
|
||||
" print(len(board.boxes), '/', len(tiles), 'tiles placed')\n",
|
||||
" plot_board(board, figsize)\n",
|
||||
" else:\n",
|
||||
" return board\n",
|
||||
"\n",
|
||||
"best_dominoes(tiles1970)"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user