52cbbdcd082588912156d2fc10432f92ed6e6f64
[ou-summer-of-code-2017.git] / 04-word-search / wordsearch-creation.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 206,
6 "metadata": {
7 "collapsed": true
8 },
9 "outputs": [],
10 "source": [
11 "import string\n",
12 "import re\n",
13 "import random\n",
14 "import collections\n",
15 "import copy\n",
16 "import os\n",
17 "\n",
18 "from IPython.display import clear_output\n",
19 "\n",
20 "from enum import Enum\n",
21 "Direction = Enum('Direction', 'left right up down upleft upright downleft downright')\n",
22 " \n",
23 "delta = {Direction.left: (0, -1),Direction.right: (0, 1), \n",
24 " Direction.up: (-1, 0), Direction.down: (1, 0), \n",
25 " Direction.upleft: (-1, -1), Direction.upright: (-1, 1), \n",
26 " Direction.downleft: (1, -1), Direction.downright: (1, 1)}\n",
27 "\n",
28 "cat = ''.join\n",
29 "wcat = ' '.join\n",
30 "lcat = '\\n'.join"
31 ]
32 },
33 {
34 "cell_type": "code",
35 "execution_count": 180,
36 "metadata": {
37 "collapsed": true
38 },
39 "outputs": [],
40 "source": [
41 "# all_words = [w.strip() for w in open('/usr/share/dict/british-english').readlines()\n",
42 "# if all(c in string.ascii_lowercase for c in w.strip())]\n",
43 "# words = [w for w in all_words\n",
44 "# if not any(w in w2 for w2 in all_words if w != w2)]\n",
45 "# open('wordsearch-words', 'w').write(lcat(words))"
46 ]
47 },
48 {
49 "cell_type": "code",
50 "execution_count": 181,
51 "metadata": {
52 "collapsed": true
53 },
54 "outputs": [],
55 "source": [
56 "# ws_words = [w.strip() for w in open('wordsearch-words').readlines()\n",
57 "# if all(c in string.ascii_lowercase for c in w.strip())]\n",
58 "# ws_words[:10]"
59 ]
60 },
61 {
62 "cell_type": "code",
63 "execution_count": 182,
64 "metadata": {
65 "collapsed": true
66 },
67 "outputs": [],
68 "source": [
69 "ws_words = [w.strip() for w in open('/usr/share/dict/british-english').readlines()\n",
70 " if all(c in string.ascii_lowercase for c in w.strip())]"
71 ]
72 },
73 {
74 "cell_type": "code",
75 "execution_count": 183,
76 "metadata": {},
77 "outputs": [
78 {
79 "data": {
80 "text/plain": [
81 "62183"
82 ]
83 },
84 "execution_count": 183,
85 "metadata": {},
86 "output_type": "execute_result"
87 }
88 ],
89 "source": [
90 "len([w for w in ws_words if len(w) >= 4])"
91 ]
92 },
93 {
94 "cell_type": "code",
95 "execution_count": 184,
96 "metadata": {
97 "collapsed": true
98 },
99 "outputs": [],
100 "source": [
101 "def empty_grid(w, h):\n",
102 " return [['.' for c in range(w)] for r in range(h)]"
103 ]
104 },
105 {
106 "cell_type": "code",
107 "execution_count": 185,
108 "metadata": {
109 "collapsed": true
110 },
111 "outputs": [],
112 "source": [
113 "def show_grid(grid):\n",
114 " return lcat(cat(r) for r in grid)"
115 ]
116 },
117 {
118 "cell_type": "code",
119 "execution_count": 186,
120 "metadata": {},
121 "outputs": [
122 {
123 "name": "stdout",
124 "output_type": "stream",
125 "text": [
126 "..........\n",
127 "..........\n",
128 "..........\n",
129 "..........\n",
130 "..........\n",
131 "..........\n",
132 "..........\n",
133 "..........\n",
134 "..........\n",
135 "..........\n"
136 ]
137 }
138 ],
139 "source": [
140 "grid = empty_grid(10, 10)\n",
141 "print(show_grid(grid))"
142 ]
143 },
144 {
145 "cell_type": "code",
146 "execution_count": 187,
147 "metadata": {
148 "collapsed": true
149 },
150 "outputs": [],
151 "source": [
152 "def indices(grid, r, c, l, d):\n",
153 " dr, dc = delta[d]\n",
154 " w = len(grid[0])\n",
155 " h = len(grid)\n",
156 " inds = [(r + i * dr, c + i * dc) for i in range(l)]\n",
157 " return [(i, j) for i, j in inds\n",
158 " if i >= 0\n",
159 " if j >= 0\n",
160 " if i < h\n",
161 " if j < w]"
162 ]
163 },
164 {
165 "cell_type": "code",
166 "execution_count": 188,
167 "metadata": {
168 "collapsed": true
169 },
170 "outputs": [],
171 "source": [
172 "def gslice(grid, r, c, l, d):\n",
173 " return [grid[i][j] for i, j in indices(grid, r, c, l, d)]"
174 ]
175 },
176 {
177 "cell_type": "code",
178 "execution_count": 189,
179 "metadata": {
180 "collapsed": true
181 },
182 "outputs": [],
183 "source": [
184 "def set_grid(grid, r, c, d, word):\n",
185 " for (i, j), l in zip(indices(grid, r, c, len(word), d), word):\n",
186 " grid[i][j] = l\n",
187 " return grid"
188 ]
189 },
190 {
191 "cell_type": "code",
192 "execution_count": 190,
193 "metadata": {},
194 "outputs": [
195 {
196 "name": "stdout",
197 "output_type": "stream",
198 "text": [
199 "..........\n",
200 "..........\n",
201 "...t......\n",
202 "....e.....\n",
203 ".....s....\n",
204 "......t...\n",
205 ".......w..\n",
206 "........o.\n",
207 ".........r\n",
208 "..........\n"
209 ]
210 }
211 ],
212 "source": [
213 "set_grid(grid, 2, 3, Direction.downright, 'testword')\n",
214 "print(show_grid(grid))"
215 ]
216 },
217 {
218 "cell_type": "code",
219 "execution_count": 191,
220 "metadata": {},
221 "outputs": [
222 {
223 "data": {
224 "text/plain": [
225 "'..e.....'"
226 ]
227 },
228 "execution_count": 191,
229 "metadata": {},
230 "output_type": "execute_result"
231 }
232 ],
233 "source": [
234 "cat(gslice(grid, 3, 2, 15, Direction.right))"
235 ]
236 },
237 {
238 "cell_type": "code",
239 "execution_count": 192,
240 "metadata": {},
241 "outputs": [
242 {
243 "data": {
244 "text/plain": [
245 "<_sre.SRE_Match object; span=(0, 4), match='keen'>"
246 ]
247 },
248 "execution_count": 192,
249 "metadata": {},
250 "output_type": "execute_result"
251 }
252 ],
253 "source": [
254 "re.match(cat(gslice(grid, 3, 2, 4, Direction.right)), 'keen')"
255 ]
256 },
257 {
258 "cell_type": "code",
259 "execution_count": 193,
260 "metadata": {},
261 "outputs": [
262 {
263 "data": {
264 "text/plain": [
265 "<_sre.SRE_Match object; span=(0, 3), match='kee'>"
266 ]
267 },
268 "execution_count": 193,
269 "metadata": {},
270 "output_type": "execute_result"
271 }
272 ],
273 "source": [
274 "re.match(cat(gslice(grid, 3, 2, 3, Direction.right)), 'keen')"
275 ]
276 },
277 {
278 "cell_type": "code",
279 "execution_count": 194,
280 "metadata": {
281 "collapsed": true
282 },
283 "outputs": [],
284 "source": [
285 "re.fullmatch(cat(gslice(grid, 3, 2, 3, Direction.right)), 'keen')"
286 ]
287 },
288 {
289 "cell_type": "code",
290 "execution_count": 195,
291 "metadata": {
292 "collapsed": true
293 },
294 "outputs": [],
295 "source": [
296 "re.match(cat(gslice(grid, 3, 2, 4, Direction.right)), 'kine')"
297 ]
298 },
299 {
300 "cell_type": "code",
301 "execution_count": 196,
302 "metadata": {
303 "collapsed": true
304 },
305 "outputs": [],
306 "source": [
307 "def could_add(grid, r, c, d, word):\n",
308 " s = gslice(grid, r, c, len(word), d)\n",
309 " return re.fullmatch(cat(s), word)"
310 ]
311 },
312 {
313 "cell_type": "code",
314 "execution_count": 197,
315 "metadata": {},
316 "outputs": [
317 {
318 "data": {
319 "text/plain": [
320 "<_sre.SRE_Match object; span=(0, 4), match='keen'>"
321 ]
322 },
323 "execution_count": 197,
324 "metadata": {},
325 "output_type": "execute_result"
326 }
327 ],
328 "source": [
329 "could_add(grid, 3, 2, Direction.right, 'keen')"
330 ]
331 },
332 {
333 "cell_type": "code",
334 "execution_count": 198,
335 "metadata": {
336 "collapsed": true
337 },
338 "outputs": [],
339 "source": [
340 "could_add(grid, 3, 2, Direction.right, 'kine')"
341 ]
342 },
343 {
344 "cell_type": "code",
345 "execution_count": 199,
346 "metadata": {},
347 "outputs": [
348 {
349 "data": {
350 "text/plain": [
351 "<Direction.up: 3>"
352 ]
353 },
354 "execution_count": 199,
355 "metadata": {},
356 "output_type": "execute_result"
357 }
358 ],
359 "source": [
360 "random.choice(list(Direction))"
361 ]
362 },
363 {
364 "cell_type": "code",
365 "execution_count": 207,
366 "metadata": {
367 "collapsed": true
368 },
369 "outputs": [],
370 "source": [
371 "def fill_grid(grid, words, word_count, max_attempts=10000, min_word_len=4):\n",
372 " attempts = 0\n",
373 " added_words = []\n",
374 " w = len(grid[0])\n",
375 " h = len(grid)\n",
376 " while len(added_words) < word_count and attempts < max_attempts:\n",
377 " clear_output(wait=True)\n",
378 " print(\"Added\", len(added_words), '; attempt', attempts)\n",
379 " attempts += 1\n",
380 " r = random.randrange(w)\n",
381 " c = random.randrange(h)\n",
382 " word = random.choice(words)\n",
383 " d = random.choice(list(Direction))\n",
384 "# print(word, r, c, d, \n",
385 "# len(word) >= min_word_len, \n",
386 "# not any(word in w2 for w2 in added_words), \n",
387 "# could_add(grid, r, c, d, word), \n",
388 "# not present(grid, word)[0]\n",
389 "# )\n",
390 " if (len(word) >= min_word_len\n",
391 " and not any(word in w2 for w2 in added_words) \n",
392 " and could_add(grid, r, c, d, word)\n",
393 " and not present(grid, word)[0]):\n",
394 " grid2 = copy.deepcopy(grid)\n",
395 " set_grid(grid2, r, c, d, word)\n",
396 "# print(present_many(grid2, [word]))\n",
397 " if collections.Counter(p[0] for p in \n",
398 " present_many(grid2, added_words + [word])).most_common(1)[0][1] == 1:\n",
399 " set_grid(grid, r, c, d, word)\n",
400 " added_words += [word]\n",
401 " attempts = 0\n",
402 " return grid, added_words"
403 ]
404 },
405 {
406 "cell_type": "code",
407 "execution_count": 201,
408 "metadata": {},
409 "outputs": [
410 {
411 "ename": "KeyboardInterrupt",
412 "evalue": "",
413 "output_type": "error",
414 "traceback": [
415 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
416 "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
417 "\u001b[0;32m<ipython-input-201-6ab66457c812>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mempty_grid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mws\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfill_grid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mws_words\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m40\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mws\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
418 "\u001b[0;32m<ipython-input-200-42497f37ad7f>\u001b[0m in \u001b[0;36mfill_grid\u001b[0;34m(grid, words, word_count, max_attempts, min_word_len)\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;31m# print(present_many(grid2, [word]))\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 25\u001b[0m if collections.Counter(p[0] for p in \n\u001b[0;32m---> 26\u001b[0;31m present_many(grid2, added_words + [word])).most_common(1)[0][1] == 1:\n\u001b[0m\u001b[1;32m 27\u001b[0m \u001b[0mset_grid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mword\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0madded_words\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mword\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
419 "\u001b[0;32m<ipython-input-123-ff8574b12cf0>\u001b[0m in \u001b[0;36mpresent_many\u001b[0;34m(grid, words)\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0md\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mDirection\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mwordlen\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mwordlens\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mword\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgslice\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwordlen\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mword\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mwords\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mpresences\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mword\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
420 "\u001b[0;32m<ipython-input-188-a5adda74be28>\u001b[0m in \u001b[0;36mgslice\u001b[0;34m(grid, r, c, l, d)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgslice\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mindices\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
421 "\u001b[0;32m<ipython-input-187-e0e67252b972>\u001b[0m in \u001b[0;36mindices\u001b[0;34m(grid, r, c, l, d)\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mdef\u001b[0m \u001b[0mindices\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mdr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdelta\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mw\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mh\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0minds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mdr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mdc\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ml\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
422 "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
423 ]
424 }
425 ],
426 "source": [
427 "g = empty_grid(20, 20)\n",
428 "g, ws = fill_grid(g, ws_words, 40)\n",
429 "len(ws)"
430 ]
431 },
432 {
433 "cell_type": "code",
434 "execution_count": null,
435 "metadata": {},
436 "outputs": [],
437 "source": [
438 "print(show_grid(g))\n",
439 "print(len(ws), 'words added')\n",
440 "print(wcat(ws))"
441 ]
442 },
443 {
444 "cell_type": "code",
445 "execution_count": null,
446 "metadata": {
447 "collapsed": true
448 },
449 "outputs": [],
450 "source": [
451 "def present(grid, word):\n",
452 " w = len(grid[0])\n",
453 " h = len(grid)\n",
454 " for r in range(h):\n",
455 " for c in range(w):\n",
456 " for d in Direction:\n",
457 " if cat(gslice(grid, r, c, len(word), d)) == word:\n",
458 " return True, r, c, d\n",
459 " return False, 0, 0, list(Direction)[0]"
460 ]
461 },
462 {
463 "cell_type": "code",
464 "execution_count": null,
465 "metadata": {
466 "collapsed": true
467 },
468 "outputs": [],
469 "source": [
470 "def present_many(grid, words):\n",
471 " w = len(grid[0])\n",
472 " h = len(grid)\n",
473 " wordlens = set(len(w) for w in words)\n",
474 " presences = []\n",
475 " for r in range(h):\n",
476 " for c in range(w):\n",
477 " for d in Direction:\n",
478 " for wordlen in wordlens:\n",
479 " word = cat(gslice(grid, r, c, wordlen, d))\n",
480 " if word in words:\n",
481 " presences += [(word, r, c, d)]\n",
482 " return set(presences)"
483 ]
484 },
485 {
486 "cell_type": "code",
487 "execution_count": null,
488 "metadata": {
489 "scrolled": true
490 },
491 "outputs": [],
492 "source": [
493 "for w in ws:\n",
494 " print(w, present(g, w))"
495 ]
496 },
497 {
498 "cell_type": "code",
499 "execution_count": null,
500 "metadata": {
501 "collapsed": true
502 },
503 "outputs": [],
504 "source": [
505 "def interesting(grid, words, words_limit=40, direction_slack=1):\n",
506 " dirs = set(present(grid, w)[3] for w in words)\n",
507 " return len(words) > words_limit and len(dirs) + direction_slack >= len(delta)"
508 ]
509 },
510 {
511 "cell_type": "code",
512 "execution_count": null,
513 "metadata": {},
514 "outputs": [],
515 "source": [
516 "interesting(g, ws)"
517 ]
518 },
519 {
520 "cell_type": "code",
521 "execution_count": null,
522 "metadata": {
523 "collapsed": true
524 },
525 "outputs": [],
526 "source": [
527 "def interesting_grid(width=20, height=20, words_limit=40, max_words=80, direction_slack=1):\n",
528 " boring = True\n",
529 " while boring:\n",
530 " grid = empty_grid(width, height)\n",
531 " grid, words = fill_grid(grid, ws_words, max_words)\n",
532 " boring = not interesting(grid, words, words_limit=words_limit, direction_slack=direction_slack)\n",
533 " return grid, words"
534 ]
535 },
536 {
537 "cell_type": "code",
538 "execution_count": null,
539 "metadata": {},
540 "outputs": [],
541 "source": [
542 "g, ws = interesting_grid()\n",
543 "print(show_grid(g))\n",
544 "print(len(ws), 'words added; ', len(set(present(g, w)[3] for w in ws)), 'directions')\n",
545 "print(wcat(ws))"
546 ]
547 },
548 {
549 "cell_type": "code",
550 "execution_count": null,
551 "metadata": {
552 "collapsed": true
553 },
554 "outputs": [],
555 "source": [
556 "def datafile(name, sep='\\t'):\n",
557 " \"\"\"Read key,value pairs from file.\n",
558 " \"\"\"\n",
559 " with open(name) as f:\n",
560 " for line in f:\n",
561 " splits = line.split(sep)\n",
562 " yield [splits[0], int(splits[1])]"
563 ]
564 },
565 {
566 "cell_type": "code",
567 "execution_count": null,
568 "metadata": {
569 "collapsed": true
570 },
571 "outputs": [],
572 "source": [
573 "def normalise(frequencies):\n",
574 " \"\"\"Scale a set of frequencies so they sum to one\n",
575 " \n",
576 " >>> sorted(normalise({1: 1, 2: 0}).items())\n",
577 " [(1, 1.0), (2, 0.0)]\n",
578 " >>> sorted(normalise({1: 1, 2: 1}).items())\n",
579 " [(1, 0.5), (2, 0.5)]\n",
580 " >>> sorted(normalise({1: 1, 2: 1, 3: 1}).items()) # doctest: +ELLIPSIS\n",
581 " [(1, 0.333...), (2, 0.333...), (3, 0.333...)]\n",
582 " >>> sorted(normalise({1: 1, 2: 2, 3: 1}).items())\n",
583 " [(1, 0.25), (2, 0.5), (3, 0.25)]\n",
584 " \"\"\"\n",
585 " length = sum(f for f in frequencies.values())\n",
586 " return collections.defaultdict(int, ((k, v / length) \n",
587 " for (k, v) in frequencies.items()))\n"
588 ]
589 },
590 {
591 "cell_type": "code",
592 "execution_count": null,
593 "metadata": {
594 "collapsed": true
595 },
596 "outputs": [],
597 "source": [
598 "english_counts = collections.Counter(dict(datafile('count_1l.txt')))\n",
599 "normalised_english_counts = normalise(english_counts)"
600 ]
601 },
602 {
603 "cell_type": "code",
604 "execution_count": null,
605 "metadata": {
606 "collapsed": true
607 },
608 "outputs": [],
609 "source": [
610 "wordsearch_counts = collections.Counter(cat(ws_words))\n",
611 "normalised_wordsearch_counts = normalise(wordsearch_counts)"
612 ]
613 },
614 {
615 "cell_type": "code",
616 "execution_count": null,
617 "metadata": {
618 "collapsed": true
619 },
620 "outputs": [],
621 "source": [
622 "normalised_wordsearch_counts = normalise(collections.Counter(normalised_wordsearch_counts) + collections.Counter({l: 0.05 for l in string.ascii_lowercase}))"
623 ]
624 },
625 {
626 "cell_type": "code",
627 "execution_count": null,
628 "metadata": {
629 "collapsed": true
630 },
631 "outputs": [],
632 "source": [
633 "def weighted_choice(d):\n",
634 " \"\"\"Generate random item from a dictionary of item counts\n",
635 " \"\"\"\n",
636 " target = random.uniform(0, sum(d.values()))\n",
637 " cuml = 0.0\n",
638 " for (l, p) in d.items():\n",
639 " cuml += p\n",
640 " if cuml > target:\n",
641 " return l\n",
642 " return None\n",
643 "\n",
644 "def random_english_letter():\n",
645 " \"\"\"Generate a random letter based on English letter counts\n",
646 " \"\"\"\n",
647 " return weighted_choice(normalised_english_counts)\n",
648 "\n",
649 "def random_wordsearch_letter():\n",
650 " \"\"\"Generate a random letter based on wordsearch letter counts\n",
651 " \"\"\"\n",
652 " return weighted_choice(normalised_wordsearch_counts)"
653 ]
654 },
655 {
656 "cell_type": "code",
657 "execution_count": null,
658 "metadata": {},
659 "outputs": [],
660 "source": [
661 "cat(sorted(random_english_letter() for i in range(100)))"
662 ]
663 },
664 {
665 "cell_type": "code",
666 "execution_count": null,
667 "metadata": {},
668 "outputs": [],
669 "source": [
670 "cat(sorted(random_wordsearch_letter() for i in range(100)))"
671 ]
672 },
673 {
674 "cell_type": "code",
675 "execution_count": null,
676 "metadata": {},
677 "outputs": [],
678 "source": [
679 "random_wordsearch_letter()"
680 ]
681 },
682 {
683 "cell_type": "code",
684 "execution_count": null,
685 "metadata": {
686 "collapsed": true
687 },
688 "outputs": [],
689 "source": [
690 "def pad_grid(g0):\n",
691 " grid = copy.deepcopy(g0)\n",
692 " w = len(grid[0])\n",
693 " h = len(grid)\n",
694 " for r in range(h):\n",
695 " for c in range(w):\n",
696 " if grid[r][c] == '.':\n",
697 " grid[r][c] = random_wordsearch_letter()\n",
698 " return grid"
699 ]
700 },
701 {
702 "cell_type": "code",
703 "execution_count": null,
704 "metadata": {},
705 "outputs": [],
706 "source": [
707 "padded = pad_grid(g)\n",
708 "print(show_grid(padded))"
709 ]
710 },
711 {
712 "cell_type": "code",
713 "execution_count": null,
714 "metadata": {},
715 "outputs": [],
716 "source": [
717 "print(show_grid(g))"
718 ]
719 },
720 {
721 "cell_type": "code",
722 "execution_count": null,
723 "metadata": {
724 "scrolled": true
725 },
726 "outputs": [],
727 "source": [
728 "for w in ws:\n",
729 " print(w, present(padded, w))"
730 ]
731 },
732 {
733 "cell_type": "code",
734 "execution_count": null,
735 "metadata": {
736 "collapsed": true
737 },
738 "outputs": [],
739 "source": [
740 "def decoys(grid, words, all_words, limit=100):\n",
741 " decoy_words = []\n",
742 " dlen_limit = max(len(w) for w in words)\n",
743 " while len(words) + len(decoy_words) < limit:\n",
744 " d = random.choice(all_words)\n",
745 " if d not in words and len(d) >= 4 and len(d) <= dlen_limit and not present(grid, d)[0]:\n",
746 " decoy_words += [d]\n",
747 " return decoy_words"
748 ]
749 },
750 {
751 "cell_type": "code",
752 "execution_count": null,
753 "metadata": {
754 "collapsed": true
755 },
756 "outputs": [],
757 "source": [
758 "def decoys(grid, words, all_words, limit=100, min_word_len=4):\n",
759 " decoy_words = []\n",
760 "# dlen_limit = max(len(w) for w in words)\n",
761 " while len(words) + len(decoy_words) < limit:\n",
762 " d = random.choice(all_words)\n",
763 " if d not in words and len(d) >= min_word_len and not present(grid, d)[0]:\n",
764 " decoy_words += [d]\n",
765 " return decoy_words"
766 ]
767 },
768 {
769 "cell_type": "code",
770 "execution_count": null,
771 "metadata": {},
772 "outputs": [],
773 "source": [
774 "ds = decoys(padded, ws, ws_words)\n",
775 "ds"
776 ]
777 },
778 {
779 "cell_type": "code",
780 "execution_count": null,
781 "metadata": {
782 "scrolled": true
783 },
784 "outputs": [],
785 "source": [
786 "for w in ws + ds:\n",
787 " print(w, present(padded, w))"
788 ]
789 },
790 {
791 "cell_type": "code",
792 "execution_count": null,
793 "metadata": {
794 "scrolled": true
795 },
796 "outputs": [],
797 "source": [
798 "g, ws = interesting_grid()\n",
799 "p = pad_grid(g)\n",
800 "ds = decoys(p, ws, ws_words)\n",
801 "print(show_grid(g))\n",
802 "print(show_grid(p))\n",
803 "print(len(ws), 'words added; ', len(set(present(g, w)[3] for w in ws)), 'directions')\n",
804 "print('Present:', wcat(sorted(ws)))\n",
805 "print('Decoys:', wcat(sorted(ds)))"
806 ]
807 },
808 {
809 "cell_type": "code",
810 "execution_count": null,
811 "metadata": {
812 "scrolled": true
813 },
814 "outputs": [],
815 "source": [
816 "g, ws = interesting_grid(width=10, height=10, words_limit=5, direction_slack=6)\n",
817 "p = pad_grid(g)\n",
818 "ds = decoys(p, ws, ws_words)\n",
819 "print(show_grid(g))\n",
820 "print()\n",
821 "print(show_grid(p))\n",
822 "print(len(ws), 'words added; ', len(set(present(g, w)[3] for w in ws)), 'directions')\n",
823 "print('Present:', wcat(sorted(ws)))\n",
824 "print('Decoys:', wcat(sorted(ds)))"
825 ]
826 },
827 {
828 "cell_type": "code",
829 "execution_count": null,
830 "metadata": {},
831 "outputs": [],
832 "source": [
833 "ds_original = ['regards', 'perfect', 'instants', 'refined', 'coddle', 'fickler', 'gambol', 'misprint', 'tapes', 'impugns', 'moonshot', 'chump', 'brick', 'siren', 'faddish', 'winced', 'kielbasy', 'market', 'puckered', 'trains', 'welts', 'cackles', 'foaming', 'proceed', 'gliding', 'guts', 'uric', 'oaks', 'molested', 'curled', 'boor', 'solaria', 'gristle', 'bombing', 'loamier', 'ensuing', 'cunt', 'sunder', 'revel', 'coaster', 'grunts', 'mucking', 'typesets', 'carnal', 'whimsy', 'scoff', 'coccyxes', 'meanly', 'sprain', 'minuend', 'ringlet', 'fest', 'winced', 'shinier', 'dicier', 'thirds', 'olives', 'garoting', 'pastrami', 'tranquil', 'tamped', 'sunup', 'crumbled', 'throw', 'ridges', 'chaplets', 'curlier', 'lugs', 'collies', 'adapting', 'demeanor', 'deepen', 'lanyard', 'tiller', 'transfix', 'wariness', 'times', 'mitts', 'dowses', 'creels', 'curds', 'quashed', 'orgasmic', 'ibex', 'retraces', 'casino']\n",
834 "ds = random.sample(ds_original, 15)\n",
835 "ds"
836 ]
837 },
838 {
839 "cell_type": "code",
840 "execution_count": null,
841 "metadata": {
842 "scrolled": true
843 },
844 "outputs": [],
845 "source": [
846 "ds_original"
847 ]
848 },
849 {
850 "cell_type": "code",
851 "execution_count": null,
852 "metadata": {
853 "scrolled": true
854 },
855 "outputs": [],
856 "source": [
857 "print('grid = ', g)\n",
858 "print('padded_grid = ', p)\n",
859 "print('present_words = ', ws)\n",
860 "print('decoy_words = ', ds)\n",
861 "print('Directions: ', [(w, '`' + str(present(g, w)) + '`') for w in ws])"
862 ]
863 },
864 {
865 "cell_type": "code",
866 "execution_count": null,
867 "metadata": {
868 "collapsed": true
869 },
870 "outputs": [],
871 "source": [
872 "# with open('example-wordsearch.txt', 'w') as f:\n",
873 "# f.write('10x10\\n')\n",
874 "# f.write(show_grid(p))\n",
875 "# f.write('\\n')\n",
876 "# f.write(lcat(sorted(ws + ds)))\n",
877 "# with open('exmaple-wordsearch-solution.txt', 'w') as f:\n",
878 "# f.write('10x10\\n')\n",
879 "# f.write(show_grid(g))\n",
880 "# f.write('\\n')\n",
881 "# f.write(lcat(sorted(ws)) + '\\n\\n')\n",
882 "# f.write(lcat(sorted(ds)))"
883 ]
884 },
885 {
886 "cell_type": "code",
887 "execution_count": null,
888 "metadata": {
889 "scrolled": true
890 },
891 "outputs": [],
892 "source": [
893 "cts = collections.Counter()\n",
894 "for w in ws:\n",
895 " _, r, c, d = present(g, w)\n",
896 " inds = indices(g, r, c, len(w), d)\n",
897 " for i in inds:\n",
898 " cts[i] += 1\n",
899 " print(w, r, c, len(w), d, inds)\n",
900 "[i for i in cts if cts[i] > 1]"
901 ]
902 },
903 {
904 "cell_type": "code",
905 "execution_count": null,
906 "metadata": {
907 "collapsed": true
908 },
909 "outputs": [],
910 "source": []
911 },
912 {
913 "cell_type": "code",
914 "execution_count": null,
915 "metadata": {
916 "collapsed": true,
917 "scrolled": true
918 },
919 "outputs": [],
920 "source": [
921 "# for i in range(100):\n",
922 "# print(i)\n",
923 "# g, ws = interesting_grid()\n",
924 "# p = pad_grid(g)\n",
925 "# ds = decoys(p, ws, ws_words)\n",
926 "# with open('wordsearch{:02}.txt'.format(i), 'w') as f:\n",
927 "# f.write('20x20\\n')\n",
928 "# f.write(show_grid(p))\n",
929 "# f.write('\\n')\n",
930 "# f.write(lcat(sorted(ws + ds)))\n",
931 "# with open('wordsearch-solution{:02}.txt'.format(i), 'w') as f:\n",
932 "# f.write('20x20\\n')\n",
933 "# f.write(show_grid(g))\n",
934 "# f.write('\\n')\n",
935 "# f.write(lcat(sorted(ws)) + '\\n\\n')\n",
936 "# f.write(lcat(sorted(ds)))"
937 ]
938 },
939 {
940 "cell_type": "code",
941 "execution_count": null,
942 "metadata": {
943 "collapsed": true
944 },
945 "outputs": [],
946 "source": [
947 "g, ws = interesting_grid(width=100, height=100, words_limit=1, max_words=2000, direction_slack=1)\n",
948 "p = pad_grid(g)\n",
949 "ds = decoys(p, ws, ws_words, limit=2500)\n",
950 "# print(show_grid(g))\n",
951 "# print()\n",
952 "# print(show_grid(p))"
953 ]
954 },
955 {
956 "cell_type": "code",
957 "execution_count": null,
958 "metadata": {},
959 "outputs": [],
960 "source": [
961 "print(len(ws), 'words added; ', len(set(present(g, w)[3] for w in ws)), 'directions')\n",
962 "# print('Present:', wcat(sorted(ws)))\n",
963 "# print('Decoys:', wcat(sorted(ds)))"
964 ]
965 },
966 {
967 "cell_type": "code",
968 "execution_count": null,
969 "metadata": {
970 "collapsed": true,
971 "scrolled": true
972 },
973 "outputs": [],
974 "source": [
975 "with open('huge-wordsearch.txt', 'w') as f:\n",
976 " f.write('{}x{}\\n'.format(len(g[0]), len(g)))\n",
977 " f.write(show_grid(p))\n",
978 " f.write('\\n')\n",
979 " f.write(lcat(sorted(ws + ds)))"
980 ]
981 },
982 {
983 "cell_type": "code",
984 "execution_count": null,
985 "metadata": {
986 "collapsed": true
987 },
988 "outputs": [],
989 "source": [
990 "def read_wordsearch(fn):\n",
991 " lines = [l.strip() for l in open(fn).readlines()]\n",
992 " w, h = [int(s) for s in lines[0].split('x')]\n",
993 " grid = lines[1:h+1]\n",
994 " words = lines[h+1:]\n",
995 " return w, h, grid, words"
996 ]
997 },
998 {
999 "cell_type": "code",
1000 "execution_count": null,
1001 "metadata": {
1002 "collapsed": true
1003 },
1004 "outputs": [],
1005 "source": [
1006 "def do_wordsearch_tasks(fn, show_anyway=False):\n",
1007 " width, height, grid, words = read_wordsearch(fn)\n",
1008 " used_words = [w for w in words if present(grid, w)[0]]\n",
1009 " unused_words = [w for w in words if not present(grid, w)[0]]\n",
1010 " lwp = sorted([w for w in words if present(grid, w)[0]], key=len)[-1]\n",
1011 " lwps = [w for w in used_words if len(w) == len(lwp)]\n",
1012 " lwa = sorted(unused_words, key=len)[-1]\n",
1013 " lwas = [w for w in unused_words if len(w) == len(lwa)]\n",
1014 " g0 = empty_grid(width, height)\n",
1015 " for w in words:\n",
1016 " p, r, c, d = present(grid, w)\n",
1017 " if p:\n",
1018 " set_grid(g0, r, c, d, w) \n",
1019 " unused_letters = [l for l, u in zip((c for c in cat(cat(l) for l in grid)), (c for c in cat(cat(l) for l in g0)))\n",
1020 " if u == '.']\n",
1021 " unused_letter_count = collections.Counter(unused_letters)\n",
1022 " makeable_words = []\n",
1023 " for w in unused_words:\n",
1024 " unused_word_count = collections.Counter(w)\n",
1025 " if all(unused_word_count[l] <= unused_letter_count[l] for l in unused_word_count):\n",
1026 " makeable_words += [w]\n",
1027 " lwm = sorted(makeable_words, key=len)[-1]\n",
1028 " lwms = [w for w in makeable_words if len(w) == len(lwm)]\n",
1029 " if show_anyway or len(set((len(lwp),len(lwa),len(lwm)))) == 3:\n",
1030 " print('\\n{}'.format(fn))\n",
1031 " print('{} words present'.format(len(words) - len(unused_words)))\n",
1032 " print('Longest word present: {}, {} letters ({})'.format(lwp, len(lwp), lwps))\n",
1033 " print('Longest word absent: {}, {} letters ({})'.format(lwa, len(lwa), lwas))\n",
1034 " print('{} unused letters'.format(len([c for c in cat(cat(l) for l in g0) if c == '.'])))\n",
1035 " print('Longest makeable word: {}, {} ({})'.format(lwm, len(lwm), lwms))"
1036 ]
1037 },
1038 {
1039 "cell_type": "code",
1040 "execution_count": null,
1041 "metadata": {},
1042 "outputs": [],
1043 "source": [
1044 "[w for w in ws_words if len(w) == 16]"
1045 ]
1046 },
1047 {
1048 "cell_type": "code",
1049 "execution_count": null,
1050 "metadata": {
1051 "collapsed": true
1052 },
1053 "outputs": [],
1054 "source": [
1055 "# all_lines = []\n",
1056 "# for fn in sorted(os.listdir()):\n",
1057 "# if re.match('wordsearch\\d\\d\\.txt', fn):\n",
1058 "# all_lines += open(fn).readlines()\n",
1059 "# all_lines += ['\\n'] * 2\n",
1060 "\n",
1061 "# open('all-wordsearches.txt', 'w').writelines(all_lines)"
1062 ]
1063 },
1064 {
1065 "cell_type": "code",
1066 "execution_count": 209,
1067 "metadata": {
1068 "scrolled": true
1069 },
1070 "outputs": [
1071 {
1072 "name": "stdout",
1073 "output_type": "stream",
1074 "text": [
1075 "Added 6 ; attempt 19\n"
1076 ]
1077 },
1078 {
1079 "data": {
1080 "text/plain": [
1081 "6"
1082 ]
1083 },
1084 "execution_count": 209,
1085 "metadata": {},
1086 "output_type": "execute_result"
1087 }
1088 ],
1089 "source": [
1090 "g = empty_grid(10, 10)\n",
1091 "g, ws = fill_grid(g, ws_words, 200, min_word_len=4, max_attempts=20)\n",
1092 "len(ws)"
1093 ]
1094 },
1095 {
1096 "cell_type": "code",
1097 "execution_count": 210,
1098 "metadata": {},
1099 "outputs": [
1100 {
1101 "name": "stdout",
1102 "output_type": "stream",
1103 "text": [
1104 "Added 1149 ; attempt 9427\n"
1105 ]
1106 },
1107 {
1108 "name": "stderr",
1109 "output_type": "stream",
1110 "text": [
1111 "IOPub message rate exceeded.\n",
1112 "The notebook server will temporarily stop sending output\n",
1113 "to the client in order to avoid crashing it.\n",
1114 "To change this limit, set the config variable\n",
1115 "`--NotebookApp.iopub_msg_rate_limit`.\n"
1116 ]
1117 }
1118 ],
1119 "source": [
1120 "g = empty_grid(100, 100)\n",
1121 "g, ws = fill_grid(g, ws_words, 2000, min_word_len=5)\n",
1122 "len(ws)"
1123 ]
1124 },
1125 {
1126 "cell_type": "code",
1127 "execution_count": 216,
1128 "metadata": {},
1129 "outputs": [
1130 {
1131 "data": {
1132 "text/plain": [
1133 "(1149, 1149, [('scofflaw', 1)])"
1134 ]
1135 },
1136 "execution_count": 216,
1137 "metadata": {},
1138 "output_type": "execute_result"
1139 }
1140 ],
1141 "source": [
1142 "pm = present_many(g, ws)\n",
1143 "pold = [w for w in ws if present(g, w)[0]]\n",
1144 "len(pm), len(pold), collections.Counter(p[0] for p in pm).most_common(1)"
1145 ]
1146 },
1147 {
1148 "cell_type": "code",
1149 "execution_count": 219,
1150 "metadata": {},
1151 "outputs": [],
1152 "source": [
1153 "\n",
1154 "with open('huge-unpadded-wordsearch.txt', 'w') as f:\n",
1155 " f.write('{}x{}\\n'.format(len(g[0]), len(g)))\n",
1156 " f.write(show_grid(g))\n",
1157 " f.write('\\n')\n",
1158 " f.write(lcat(sorted(ws)))"
1159 ]
1160 },
1161 {
1162 "cell_type": "code",
1163 "execution_count": 218,
1164 "metadata": {
1165 "scrolled": true
1166 },
1167 "outputs": [
1168 {
1169 "name": "stdout",
1170 "output_type": "stream",
1171 "text": [
1172 "smuiclacphysics.hcnebrevilingd..skcabllup.s...gnitnacs..blusted.....pilafeldrig..enquireddetnawnu...\n",
1173 "e....nutmegs.t..telbanimret...e..tseikwagewoodpeckerstirwas.b.r...picksn...ylhsiroobsuspectingsexevd\n",
1174 "cgnittacdliw..isuoniallivsegas.lrafts.y.vcs..demrofsnart.mla...e.c....e..fannysdiscrimination.oe..e.\n",
1175 "nnytima.wharfrep.stswashbucklersw....m.eos...noprat....ao.rs....t.h..m.relabele..sss...b.sc.ts..vb.s\n",
1176 "eid..desivedaia.shegdtg.gniyugys.o..a.rme.gpantedsobeysodgm.a....t.osabound...s.bttp...uje.orhd.boe.\n",
1177 "tverediw...dtlw.eiar.ehacrierhsrmccosiant.nbestridi..sreepegarotedadr.slaropauses..e..rdis.oteia.lld\n",
1178 "nardd.p...itli.i.pesu.srwe...ciuuhfsnti.sgingivitislubl.fotkcuhs..rmsensitisedeu...eleygbutsiyjcf.u.\n",
1179 "eerne.u..aiin.r.i.nset.ioku..taeia.gods.e.n..dh.n.emld.r.lht.hobnobsi.s..l.c.trs...jnb.ieoizw.llka.f\n",
1180 "shiense.nhae.s.n.aietun.owig.idtrp.srsayi.w..ogu.oecnie..yo.u...whmt.t..u.a.lcds...tb.ondran.oeersa.\n",
1181 ".nhpnnktsts...g.d.cve.qe.pblohdoaseomtc.r.a.tgnrgdnaiae.spd.sc.sora...nt.r.en.no..ro...g.l..msbfdue.\n",
1182 ".asxiiasehcnerdj.moido.edsoayvebr.w.ufh.rtr.sgiaxgdekm.rtfo.k.noir.....ag.se..ur.al..sreraehsu.xnoet\n",
1183 "gr.erah.peeweeu.i.tdir..h.acc.mard..tie.u.pdeehbo.eyx.u.ralge.kucnoveltiesseirfdp..buttocksn..laodne\n",
1184 "nr.sgls..d..sdwrg.iela...c.uikise.o.altwf.i.idcbtged...poeoatsqo...gratefully..sportingsweepersaa..s\n",
1185 "iaw.bp...e.hgor.ulnnstullee.ntl.t.mttps.os..d.tienstc...nhggcst.gsugaringinsight..snifters.....cde.i\n",
1186 "nta..m..ssteno..i.eckef..b...ar..y.ieu.lpls.n.endirswu..gsiehs..n.delbaf....interpose..dsurt..r.el.u\n",
1187 "oeg..oae.usdr..kl..ecd.aiproveso..llsdsayeb.a.ra.iee.er.l.esih.ti.sllihygrellapractisedatcneea..gg.r\n",
1188 "sdeb.cziofe.r.e.d..da..rgthrive.p.agearetr.hs.stsavr..riy.srec.ar.pocketbooktrotxe.....nw.unlk..gg.b\n",
1189 "a.re.a.m.rs.espumoneb.t..o.semorhc.rnadau.istp.eehio..cpoga.sn.uuyratchetswisher.....n.se..fepc.aos.\n",
1190 "e.saf...fsrrh.a.retpada...t.....e.iggiiv.llcaam.vgnt.o.t.sidtu.pj.r.retemarapecnarussau.a.l.frpante.\n",
1191 "rretarcurne.c.g.pellagra...s...d.wni.dk.elgnaae.inusm..msgibehfedtsl..prowldenimn.shiedrka...l.il.ss\n",
1192 "n..i..leatgbt.rc..s..sesitengamedinkafgnonn.tladta.m....uentbl.aa.oeegniyartrop.eseitoobsnoleme.tpuu\n",
1193 "ub.f.lent.gri.afassevissimagingslgiryuoriit...nsahaseigodniiyelwb..upwthguorb.obmil....hfeedings..tr\n",
1194 ".a.yydne..aew.ryrri.emackintoshw.trsbnasnh.u..trksr.gasketrpc.raar..ptereinterpretingie....deggiwtnp\n",
1195 ".s..nyl...raslitloeett.splinesobtih.gnlgtkt.r.ealwasset....usu.bvgi..eej......rtss.dnrtonnaccords.oa\n",
1196 ".ihikers..bkawa.rtssrao...gc.r.yek..ues..rhn.ennaob.gmovers.bid.riwcsketches.esar.etsi.gswollefdebcs\n",
1197 ".leticilli.zaen..uftsrnv..log..dils.rrc..noau.nitrlbr.eidrib.iwa.irea..st...ieiadxe.n.lrolocsid....s\n",
1198 "sr...m....edl.s...loyeage.ap...e.pc....h..ilk.am.roouevilamsidv.r.e.gt..ge.gfdeaer.s.ygnideerbnquoit\n",
1199 "reprobatesdiyruovasbs.d.oddu..hks..h.s..e..kliee.uoae.lairetsigamt.r..e..nneedmsp.t.p.incisesuhctulc\n",
1200 "s.vr.t.sdld..s.controllablel.s.aleavese..l..s..s.btrshalvesylsuougibma.s.sim.pgo.avhshortensr.zzazip\n",
1201 ".ebae.oliedpmsuesilangisg..a..hc.zingsyy..oqueryingdoreopened..endless...l.bs.lrlsnikskcub.t..knifed\n",
1202 "jiklruons.lefilbsnwodwohsn.ttupnit..tdretsenohl..cvsm...gnimirgnidaetsemoh..baamongst..y.wucustomers\n",
1203 "doionfgh.a.lsotej.....e.h.iee...gniretnuas..s..o.oa.e.g.r...snoitulos.selppitue..w...io.trrbfruits..\n",
1204 ".eydj.g.n..i.iutvosplithsejlhp.s.eieinveighing..mnl.rlbu..pineapple....a.f.e.nsrealiseadel.ar.eevell\n",
1205 "r.ertu.e..gc..dleoi....htiiyi.m.avr..transducers.fe.aatempts.b.....d.n.f.ud.t.scales.r.tr.aopinion.l\n",
1206 ".d.yoveterinaryoenrn..a.bapg.wjuin..psalmist.x...innlenvd...iebrashereat.ne...snaeco..aeiide.ps...ii\n",
1207 "..pb.dtacosei.l.sr.gim.b.eb.ho.nrideraems....opa.dcdri.ie..n.lv.sc.k.kweent.outsmartedwl.oaef.ek..mb\n",
1208 "feweste....p.v.a.p..enisreesbtg..t.h.e.k.tt..bem.eecas.lpggday.ipmrn.akrqeasedoberofmrr.l.nhp..de.pn\n",
1209 "dy.sighting...o.spalfngsd..b.cellistott.nscc.hdesshlhe.leinde.aas.ea.ewnulcsekytmrg.oa..co..la...tao\n",
1210 ".ddr..object...r.aehg.ee..ipr......degmreioascontrrits.an.oieinw.umlzwaoa.iss..i.netu.midictatorialo\n",
1211 ".e.em..muiretcab.sn.rnh.gnoigimletslry.denreftmdie.trsygdm.rssvsealplyrobcll.gx.i.egusnm..b.c.ps..ap\n",
1212 ".pstekcolsopyh..s...schngpsteppes.esoadwcaib.aesvsrhiiree.iprikvrc.l.ydniapisenb.banaoicar.yagr...ss\n",
1213 "ep.sew......macinimin.islp..s....xrpaotoirdf.mto.eoomharntse.elti.a.a.eslrxarebiajdahvalaslprnoarbez\n",
1214 "so.ykbongothistlektass.iidsreg..e.ia.lreogaiweevilgg..n.tagrw.ia.d.r..s.ioemsoinsa.pnnavtr.adidllucs\n",
1215 "il.oloverwhelmednilni.neegee.cnd.as.mduvrch.n.r..lurd.oarnasenilesab..t.tul.stkxuie.ctesae.rigd.....\n",
1216 "rp..y.......l..ivbal.nrigdn.l.ni.n.damava..t.g...seaeyi.ik..se...rtheoryysab.shnolreeril.edknniesohw\n",
1217 "oproponents.etli.kacotr.in.o.t.en.innsidu...relruc.pgetge.d.lciportosi...ega.itgeplpyautge.egon.ar..\n",
1218 "ecaudalyokelrst.ynoiif.l.piklstsrrtf.aenvoyeuristichnludta.b.se.i.ngnirabrer.entuleaugsno.gd.rgdlibd\n",
1219 "h..configurationontnt.g...omr.toteo.fsg.g..stsefni.yora.psa.t.l.msa.....e.rbd.sseol.e.at.x.dwhesieee\n",
1220 "tpalsy.r..c.e..ivcsrscinap.tma.irsfm.uliuqnartoday..racp.neo..u.plncaninev.eg.eduynr.rg.e.ieat.lgngp\n",
1221 "..fleshyuk.s.dteeme.eruptingtah.lhir.gm.r.contrastedhbe.ugni..p.uei.yamsidad.nreal..r.ny.rrntc.antoy\n",
1222 "....yogins..earnis..ripeness.edsmethe.na.bsromalgte.trr.ni..k.m.lemigfieryed..iwvtta.wia.hnis.ss.eth\n",
1223 "nonhuman..knnsnte...e...cupolargiitapt.igreideew.s.re.pie....oaespo.nrcb.y.ke.wlfiee.hdws.p...mu.d..\n",
1224 "bywords...osiohme..estnemegagnedlnstcon.ya...primessn.mshockerhleyd..sehe.t.ssealra.daua.s....ar....\n",
1225 "outlastedt.ocsb.c.x....enilefileeavgotsi.lrfordssgt..ettautnessbdebbadieil.p.ur.po.w.lle......oe.k.g\n",
1226 "ddetsyrte.n..l.gnp.esuccocddypl.ppdeisi..rlpimplyn..ecg..dsuitcases.a.ksnfl.mdtnekrahecs.etsawfpn.cn\n",
1227 "iawaitss.s..e.a.e..lp....euhauwpi.udrv.ve..er.a..udt..as.se...ctlocn.c.ltifsretaehcc.rnempollenag.ii\n",
1228 "essertsimdaehrsci.gdr...tstrcocrn.stesidi..ejs...o.e..erq..lt.i.akaco.ksussocondoretsaocno....tdnnls\n",
1229 "s.rettab.es.rptgc.ide..itaeidodohb.cynen.sn.o....y..vrcua..uclb.earhgiyhla.hn..lebil..c..ak..senioli\n",
1230 "retsim.tlu.eoo.rssfaa.xsendns.ehoqa.oeesgdtpmoppets.ueeu.moseyu.cygan.tlaib..detoormoisterpe.l.olial\n",
1231 "......hbbdtpr..inmt.desrtaetjhpilu.rlrtdsso.derunettceirltesl.csneofis.aenssregnifrettub...od.asbtha\n",
1232 "sfeergalebia.f.noui.iobattlae.ebei.bdwe..r..os...gpoz.orslsl.le.odefdr..tvdn...adjectivess.dr.geaapr\n",
1233 "....isitultscrbdccn.n.lelipa.gnime..is.dp....we..ane.b..toi..bikc.sener..ii.eslays.rp..c.du..pagnr.t\n",
1234 "f..limocleiasoaegsgignduear..udtut.l...gambol.nsrv.ib.o.re.ni..mupfdete..ysa.t....ea.oa..fetm.taeu.n\n",
1235 "o.ideokoslb.ewnr.nrso.psnss.reeifelatrinems....ei..etb.s..rvg...ol..rtc.y.lin.u..t.lsne.cp.tceeyypte\n",
1236 "owd.mel.ear.isir.eipeatsenye.snvfr..latticeworkndlrfesgnihsalpslagf.suunsprlv...u..otk.tardslassgpcc\n",
1237 "t.yltd.dl.e.hysam.uhtl.so.tm.scelcascadinghl..c.asiyrse.vexed.tsng.fshpaslpua..c.oasislliiumtocsguie\n",
1238 "wynifnpseydscetdso.acyyi.e..i.elihslanifbstsle.r.vevrycv.....rhi.ne.tsetoahdstaupset..eascae.rj.isvd\n",
1239 "euamrae.sliuraeicccecnttmstner.yn.st....olansonsade.ieeoi...oeo..i.ga.rubqyaito..deposittdaat.a.wael\n",
1240 "apmeitr.ussrarra..aaraiosgy...g.g.gie...tewor.wart.n.cbrfd.odds.hrpnb.ar.usddlltpoesyrr.js.l...wt.he\n",
1241 "rpisasmtoutgid.l..ilctnl.nabiopsy.gnbi..cwsii.gepei.g..u.fn.ee.cseiimptaweiecoae..s.euyu...ynominees\n",
1242 ".ictrsiarorerr..gdiipoi.fiwgnilratsnibu.hortcgn.saef.e.rtslrre.lcknlooelahcka.rvre.isdraeslather...r\n",
1243 "yekopuspalirtu.eenf.re.m.nbslartueneiloqebeakoihstlhi.ru...ap.aaonilculirskrs..nnsntaarttdetcartsbao\n",
1244 ".s.n.bsrclcyamnmei.h.pl..nu.deniapeptllns.kvslky.mymce.fs.mawussrane.nasdaiut.ylsasetmae.canoes.oe.m\n",
1245 "...e.oio.at.ptmrt.c..r...estappinggp.odos.cahfnm..imi.dfl.c.gtudihgv.cieiunlerugpshietetniksgipdnt..\n",
1246 "flierroo.cs.liac.gunfire.pwhimsd..aa..grr.ucasue...rmn.lis.hidu.n..i.etdnqgerfoceaodidsdewotwokrgals\n",
1247 "latconnm.f.e..epaimedc...deducesddshs..aunfx..rn....kugie.tgdl..g..n..y.g.nawn.krnilse.snoopingisgil\n",
1248 "obmibsss..asir..l..a.eeviecerggee.em....ecue..tstoadspynveael....resonantgtan.ugseiti.ruolev...freao\n",
1249 "u..gdarnsspegniciee.sylbatonarpgfhrsodomychaiserelbmuh.grtnsstseebedliw.o.la.p..ncmpr.enrapturetertv\n",
1250 "t...rd...oncc.t.srnclennut.cainoaap...od..bfrolics.k....o.rosseforp...brazzesb.laopa.eseifidoc.elgee\n",
1251 "v...ee..o..ooe.eslsth.ke...drarnwan.l.es..a...sc.liatesrohc.sdellennekgi..s.u.af.albtkn...clawsrigrn\n",
1252 "o..bdbyc....krsindekyasa..etredsdodi.l.re.l..tgo.nobscuredhh..securere..al.c.nsfn.iace.i.coupledoanl\n",
1253 "t.mei.si..maximaltedynn.sdstss.doem.iebe.dm.n.nng.gnippohca....m....dt..eso.dnes.a.operpetuatingbo.i\n",
1254 "eegggclassroomss...ral.t.pssp.ewbidtlelpd.yedoic.g.....s.dnm..otopaetn.t.lsmov..sfh.s.piling....i..e\n",
1255 "dahh.n...h..pecnarpeeti.yeeredsrte.ere.e..mdepkrn.np....iucsun..ae...eotisaie..eis.ey.rknittings..br\n",
1256 "rt.eenickinglfy...l.rdig..ie.neet.cev.ha.eo.naceo.wispsenme.eie.gr..lmncertrntdxs.bdpsao.tokenismda.\n",
1257 "...dla.g..i.oar.cc.e.onchnn.ktihttfi.s.lgg.lwqitcp.en.rpttmt.ldnn.ti.i.bkii.hgeamyseprzk.r..mld.e.l.\n",
1258 ".vwkibp.a.n.wlo.ifg..g.ugtw.afglrtr.i..nwpa.auleae.crorpoaaek.ueo.ssoai.ds.a.ryognhkaaec..euye.ce.ad\n",
1259 "..ai.nmseph.msvsta..st.qh.ow.iiirden..iornp.pes.ec.eboigarxcrld.tslp.r.ahsw.sitsra.ortde..svt.a.ndne\n",
1260 "b.rl.inacae.aeatel.yortuetl.l.fn.irr.rooe..e.s..dcv.vuytireypii.i.a.c.rlessdnoluvy.pcsggsidaim.aoect\n",
1261 "u.loi.rerrr.nssacs.tuoaac.bp.y..iuakfdpr..egatsopasetznlapsni.nmf.zs.tynctrgrato..c.so.in.repnr.rbet\n",
1262 "tgibps.idceott.nsi.ittnrntnalaesfsnnseysword.c..lrdedoygst.lrnggisi.xaoinoscvrcharsa.cngmesiamn.kkdu\n",
1263 "tnkye.e.uusel..cat.lh.aaa.legabnaei.r...kinderou.y.pler.lksleeg.e.eevtteleaeezzaipddpis.nmntfgfo.csp\n",
1264 "eietd..mpqankffh.yaie.gnt.....use.gallivants..ic.l.uydpuner.uyttdysinadlcrove....ee.tslu.geuijnrcipt\n",
1265 "rbred..peri.usoe.srbayetimikespl.debrutrepnu.n.rkl.mb.npsera.fosm.dimieiscovsrd.vtyr.om...l..fioisiu\n",
1266 "nbisl.e.or.a..rs.eoastrireitliugselttit.....g..e.u.pr..iadmsbnemil.gcrt..siepeclrrapteswovasidfvcgro\n",
1267 "uupcer.o..y.d.gtstulte.ne...rtsicitnamoraincoatk.bfearedkhayyeutycacyc.hwlgrc.oeematr...vended.ei.i.\n",
1268 "trxrm.msinimefe.tani.i.ih..i.....edutingamsnoynac..decay..ceagd.ara.a.celnie.vsndwo...pinup...l.dntd\n",
1269 "sgeosdrenblurbscalda.o.nn.n..cimonoxatkinetic..e....narks.k.rl..pl.r.teaihe.eer.pwryly...tubes.e..g.\n",
1270 "..saesuohdraug..ie.v.m.gig.ycnangiop.tawdrier..w....scallopedsesiwp.atstcl.ddo.astelfael..bumblers..\n",
1271 ".t.krandomises..rr.a..gripestsivitcellocsbawsshapeliest..gnitontoofhylluftsaobwsocilac..located..s..\n"
1272 ]
1273 }
1274 ],
1275 "source": [
1276 "print(show_grid(g))"
1277 ]
1278 },
1279 {
1280 "cell_type": "code",
1281 "execution_count": 221,
1282 "metadata": {},
1283 "outputs": [
1284 {
1285 "name": "stdout",
1286 "output_type": "stream",
1287 "text": [
1288 "Attempt 249 ; most common is [('scofflaw', 1)]\n"
1289 ]
1290 },
1291 {
1292 "data": {
1293 "text/plain": [
1294 "(True, [('scofflaw', 1)])"
1295 ]
1296 },
1297 "execution_count": 221,
1298 "metadata": {},
1299 "output_type": "execute_result"
1300 }
1301 ],
1302 "source": [
1303 "padded = False\n",
1304 "padding_attempts = 0\n",
1305 "while not padded and padding_attempts < 10**6:\n",
1306 " clear_output(wait=True)\n",
1307 " padding_attempts += 1\n",
1308 " pg = pad_grid(g)\n",
1309 " pm = present_many(pg, ws)\n",
1310 " print('Attempt', padding_attempts, '; most common is', collections.Counter(p[0] for p in pm).most_common(1))\n",
1311 " if collections.Counter(p[0] for p in pm).most_common(1)[0][1] == 1:\n",
1312 " padded = True\n",
1313 " \n",
1314 "padded, collections.Counter(p[0] for p in pm).most_common(1)"
1315 ]
1316 },
1317 {
1318 "cell_type": "code",
1319 "execution_count": 222,
1320 "metadata": {},
1321 "outputs": [
1322 {
1323 "data": {
1324 "text/plain": [
1325 "249"
1326 ]
1327 },
1328 "execution_count": 222,
1329 "metadata": {},
1330 "output_type": "execute_result"
1331 }
1332 ],
1333 "source": [
1334 "padding_attempts"
1335 ]
1336 },
1337 {
1338 "cell_type": "code",
1339 "execution_count": 230,
1340 "metadata": {},
1341 "outputs": [
1342 {
1343 "data": {
1344 "text/plain": [
1345 "851"
1346 ]
1347 },
1348 "execution_count": 230,
1349 "metadata": {},
1350 "output_type": "execute_result"
1351 }
1352 ],
1353 "source": [
1354 "dws = decoys(pg, ws, ws_words, limit=2000, min_word_len=5)\n",
1355 "len(dws)"
1356 ]
1357 },
1358 {
1359 "cell_type": "code",
1360 "execution_count": 231,
1361 "metadata": {
1362 "scrolled": true
1363 },
1364 "outputs": [
1365 {
1366 "name": "stdout",
1367 "output_type": "stream",
1368 "text": [
1369 "smuiclacphysicsihcnebrevilingdroskcabllupcsowygnitnacsipblustedpesnipilafeldrigclenquireddetnawnufly\n",
1370 "eqdbmnutmegsvtzdtelbanimretanmelptseikwagewoodpeckerstirwaszbdrrdypicksnzikylhsiroobsuspectingsexevd\n",
1371 "cgnittacdliwffisuoniallivsegasplraftstyevcsgcdemrofsnartrmlaydzescpopxehsfannysdiscriminationdoeypen\n",
1372 "nnytimavwharfrepjstswashbucklerswklqimkeosulxnopratpsitaoorsrtrjtthnsmxrelabelesrssstribiscutsddvbrs\n",
1373 "eidgkdesivedaiajshegdtgrgniyugyshohaabrmedgpantedsobeysodgmraoozdteosaboundgfjsmbttpygjujedorhdvboeh\n",
1374 "tverediwtczdtlwdeiaryehacrierhsrmccosiantnnbestridikysreepegarotedadrpslaropausesubepnrdissoteiailld\n",
1375 "narddypasjitligihpesubsrwewfgciuuhfsntizsgingivitislublefotkcuhschrmsensitisedeugnveleygbutsiyjcflud\n",
1376 "eernefunuaiindrsilnsethiokutttaeiapgodsteknerdhlngemldlrslhtrhobnobsizsvdlocdtrszbnjnbpieoizwillkarf\n",
1377 "shiensetnhaepslnnaietundowigvidtrptsrsayiewreogudoecniebbyofugamwhmtntwsufaulcdsmlptbeondrancoeersak\n",
1378 "onhpnnktstsdovgsdicvevqeypblohdoaseomtcdrbaatgnrgdnaiaejspdtscrsoratzdntmrgenqnomiroixqgslltmsbfduee\n",
1379 "lasxiiasehcnerdjomoidodedsoayvebrawnufhcrtrtsgiaxgdekmkrtfodkinoirfekkaagvsermuroalabsreraehsuxxnoet\n",
1380 "grderahepeeweeusiutdirnohmaccsmardrztienunpdeehbomeyxruyralgeskucnoveltiesseirfdpyebuttocksntqlaodne\n",
1381 "nrrsglsmxdupsdwrgoielalgmccuikisexoaaltwfniaidcbtgednzcpoeoatsqoszdgratefullytisportingsweepersaapys\n",
1382 "iawlbpsleeyhgorhulnnstulleemntlgtnmttpssostidstienstcbfnnhggcstegsugaringinsighthrsniftersmmfwicdeoi\n",
1383 "ntabemghsstenongideckefombnlrarlxynieuplplsznnendirswunfgsiehsuensdelbafetkzinterposexldsurtimreelhu\n",
1384 "oegleoaeiusdrixklisecdiaiprovesoatllsdsayebsawrasieeterrlaesihztixsllihygrellapractisedatcneeavgggpr\n",
1385 "sdebzczioferrsexdiadatergthrivelpdagearetrfhststsavrbyriymsrecharupocketbooktrotxextuvznwkunlkaqggtb\n",
1386 "ayrewatmerseespumonebatlnoisemorhcdrnadaubistpoeehiouxcpogaesnsuuyratchetswishereatjingsepnfepckaose\n",
1387 "eosafgcffsrrhsawretpadaspitgewuheaiggiivrllcaamkvgntrodtbsidtutpjnrgretemarapecnarussaugaylcfrpantet\n",
1388 "rretarcurneicwgnpellagraupmsixcdswniodknelgnaaetinusmlomsgibehfedtslabprowldenimnushiedrkaqndltillss\n",
1389 "ntoimlleatgbtlrcsxsehsesitengamedinkafgnonnxtladtabmvkifuentblwaaroeegniyartropieseitoobsnolemedtpuu\n",
1390 "ubqfilentigrigafassevissimagingslgiryuoriitoarnsahaseigodniiyelwblmupwthguorbkobmilkiaxhfeedingspptr\n",
1391 "nanyydnerxaewaryrriaemackintoshwftrsbnasnhsukntrksragasketrpcsraarliptereinterpretingieycoudeggiwtnp\n",
1392 "msrgnylmnkraslitloeettosplinesobtihfgnlgtktmrxealwassetpiykusurbvgijzeejgpkxclrtssfdnrtonnaccordshoa\n",
1393 "aihikersaebkawarrtssraodcrgckrpyekbruesuorhnpennaobwgmoversabidgriwcsketchesuesartetsicgswollefdebcs\n",
1394 "zleticilliozaenkfuftsrnvzylogeldilsrrrcrinoautnitrlbroeidribuiwaeireakrstmioieiadxesnnlrolocsidazdms\n",
1395 "srsyamajsmedlkssrdloyeagevapwanespcemorhucilkxamhroouevilamsidvarcemgtqggezgfdeaerosyygnideerbnquoit\n",
1396 "reprobatesdiyruovasbsidboddubehksoehnssseevklieepuoaetlairetsigamtorocevinneedmspwtnpfincisesuhctulc\n",
1397 "smvrnttsdldfysbcontrollablelfsraleaveseuslvpsavsgbtrshalvesylsuougibmaesesimcpgopavhshortensrszzazip\n",
1398 "vebaeioliedpmsuesilangisgynainhcazingsyymqoqueryingdoreopenedhsendlessasolbbsqlrlsnikskcubetbrknifed\n",
1399 "jiklruonsflefilbsnwodwohsnittupnitfstdretsenohlcrcvsmphngnimirgnidaetsemohgbbaamongstljykwucustomers\n",
1400 "doionfghfaalsotejhlrgmewhiieelbbgniretnuasuqsuiouoazeggqrhrisnoituloswselppitueaowymrioutrrbfruitspa\n",
1401 "veydjogonywisiutvosplithsejlhpesseieinveighingqymnlerlbukfpineappleeunkagfieensrealiseadelaarjeevell\n",
1402 "rkertuiegvgcbodleoievtwhtiiyiomravrsetransducersafelaatemptspbjhkrudenifiudktdscalesfratreaopinionql\n",
1403 "tddyoveterinaryoenrnedaebapgowjuiniepsalmistyxadtinnlenvdnakiebrashereatmneirdsnaecomfaeiidedpskfzii\n",
1404 "kfpbgdtacoseizlfsrfgimrblebehopnrideraemsnfhropatdcdriuieyjnilvmschkhkweentaoutsmartedwlooaefiekydmb\n",
1405 "fewestegwhcpuviacpfrenisreesbtgcktshueckfttuzbemteecaswlpggdaypipmrniakrqeasedoberofmrrqltnhphqdefpn\n",
1406 "dyesightingateonspalfngsdqfbxcellistottrnscchhdesshlhefleindegaasmeatewnulcsekytmrgyoaoecoiilanlatao\n",
1407 "hddrafobjectkatrsaehgdeertiprrzyalndegmreioascontrritspanloieinwiumlzwaoaiissziicnetuimidictatorialo\n",
1408 "renemidmuiretcabgsnwrnhegnoigimletslrywdenreftmdiectrsygdmgrssvsealplyrobcllugxxibegusnmqebycrpsguap\n",
1409 "npstekcolsopyhbnsthtschngpsteppeseesoadwcaibraesvsrhiireediprikvrcrlpydniapisenbibanaoicarlyagrflsss\n",
1410 "epksewpfsbkymacinimincislpsvsvyifxrpaotoirdfzmtoreoomharntseseltiuazaeeslrxarebiajdahvalaslprnoarbez\n",
1411 "soeykbongothistlektasssiidsregsleaiarlreogaiweevilggwznttagrwniaiddroasiioemsoinsaepnnavtrnadidllucs\n",
1412 "illoloverwhelmednilnicneegeetcndjasdmduvrchpnnrfzlurdloarnasenilesabemtdtulestkxuiepctesaerrigdekiup\n",
1413 "rpriyewmjoqxltmivbalqnrigdnglcniinfdamavaoitsgrskseaeyipikliserpcrtheoryysabushnolreerilpedknniesohw\n",
1414 "oproponentsmetliekacotroinaoltrenlinnsidutbgrelrucqpgetgemdklciportosipuaegamitgeplpyautgefegoniarcu\n",
1415 "ecaudalyokelrsttynoiifilipiklstsrrtftaenvoyeuristichnludtaqbgsewinngnirabrergentuleaugsnofgdfrgdlibd\n",
1416 "hahconfigurationontntzghhtomrbtoteorfsgyguostsefninyoranpsaqtllumsaqodnbecrbdysseoluetatzxpdwhesieee\n",
1417 "tpalsygrarcdeobivcsrscinapbtmanirsfmeuliuqnartodayebracpnneowyuaplncaninevnegxeduynrargueuieatllgngp\n",
1418 "ixfleshyukesedteemeueruptingtahmlhirugmvrccontrastedhbehugniblpsueiayamsidadinrealahrenyyrrntcwantoy\n",
1419 "fefmyoginsnnearnisieripenessjedsmethelnaabsromalgtentrrxnilrkgmjlemigfieryedopiwvttanwiafhnisrsseeth\n",
1420 "nonhumanvcknnsnteayuemsncupolargiitapthigreideewosireipieirnooaespoanrcbqygkemwlfieefhdwsppehwmubdkw\n",
1421 "bywordswjtosiohmetlestnemegagnedlnstcontyanlaprimessnbmshockerhleydesseheotossealraodauaascpraardpga\n",
1422 "outlastedtaocsbbcrxmgjeenilefileeavgotsiulrfordssgtrsettautnessbdebbadieilppfurvpopwylleemnsiuoelksg\n",
1423 "ddetsyrtemntalngnpwesuccocddyplqppdeisifmrlpimplyntzecggndsuitcaseskarksnflomdtnekrahecsuetsawfpnpcn\n",
1424 "iawaitssbskoedamenelphzijeuhauwpieudrvzvennerraytudtcpasbsencactlocnrcaltifsretaehccsrnempollenagtii\n",
1425 "essertsimdaehrsciagdrphststrcocrnvstesidiayejswheosedmerqhhltviuakacooksussocondoretsaocnofktptdnnls\n",
1426 "ssrettabiesarptgciideyhitaeidodohbvcynenmsncoesiqyvgvrcuaxauclbcearhgiyhladhniblebiluncraakussenioli\n",
1427 "retsimdtluweoolrssfaajxsendnszehoqaxoeesgdtpmoppetsgueeuamoseyumcyganhtlaibeodetoormoisterpejltolial\n",
1428 "sbtrsyhbbdtprleinmtddesrtaetjhpilusrlrtdssoqderunettceirlteslhcsneofisxaenssregnifrettubudnodgasbtha\n",
1429 "sfeergalebiamfsnouieiobattlaebebeicbdweejrruostolgpozsorslslvleiodefdrietvdniqtadjectivesswdrfgeaapr\n",
1430 "widrisitultscrbdccninelelipahgnimeqeisldpjierweqianeubcetoiwsbikcusenerqniiceslaysxrpbmcedunupagnrnt\n",
1431 "fcclimocleiasoaegsgignduearteudtutolkjugambolbnsrvyibvoxrerniipmupfdetezmysaatrcmpeatoaarfetmftaeuqn\n",
1432 "okideokoslbcewnrxnrsospsnsszreeifelatrinemsnxnaeieeetbcsiurvgiesolqsrtcjyrlinaujstelsneqcpatceeyypte\n",
1433 "owdmmeldeargisiraeipeatsenyecsnvfriilatticeworkndlrfesgnihsalpslagfosuunsprlvarnucjotkptardslassgpcc\n",
1434 "tryltdndlgeehysamtuhtlcsoitmpscelcascadinghlsiceasiyrseovexeditsnghfshpaslpuadicsoasislliiumtocsguie\n",
1435 "wynifnpseydscetdsofacyyiledfiqelihslanifbstslewrevevrycvygetxrhipnestsetoahdstaupsetxneascaearjmisvd\n",
1436 "euamraessliuraeicccecnttmstneroynlstodopolansonsadetieeoinoeoeouwiegarrubqyaitovtdeposittdaatnarwael\n",
1437 "apmeitrrussrarrazqaaraiosgypgbgagsgieunuteworpwartrnmcbrfdcoddsihrpnbearlusddlltpoesyrrtjsyljalwtghe\n",
1438 "rpisasmtoutgidqlsuilctnlgnabiopsyngnbilacwsiibgepeiogstutfnheescseiimptaweiecoaegesdeuyuyfeynominees\n",
1439 "aictrsiarorerromgdiipoirfiwgnilratsnibuohortcgnisaefzedrtslrreylcknlooelahckasrvregisdraeslatheriwhr\n",
1440 "yekopuspalirtuneenfmresmonbslartueneiloqebeakoihstlhirruqapaptaaonilculirskrsqtnnsntaarttdetcartsbao\n",
1441 "bsenobsrclcyamnmeiphrpleenufdeniapeptllnsvkvslkyamymceufsrmawussraneonasdaiutdylsasetmaeacanoesroefm\n",
1442 "ruoejoioeatwptmrtkcaarqtgestappinggprodosicahfnmolimiydflecugtudihgvocieiunlerugpshietetniksgipdntmn\n",
1443 "flierrooicsrliacagunfirejpwhimsdphaatngrreucasueufnrmnilisihiduinnlibetdnqgerfoceaodidsdewotwokrgals\n",
1444 "latconnmtfoessepaimedcsatdeducesddshsvvaunfxnsrnvgszkugiettgdldtgrqnhqykgdnawnekrnilseisnoopingisgil\n",
1445 "obmibsssylasirralfpameeviecerggeesemrbegecuebvtstoadspynveaelmhdiresonantgtanaugseitiiruolevtizfreao\n",
1446 "uppgdarnsspegnicieersylbatonarpgfhrsodomychaiserelbmuhvgrtnsstseebedliwmoqlarpobncmpryenrapturetertv\n",
1447 "tvawrdzsponccwtfsrnclennutrcainoaapnbhodepbfrolicsaktziuogrosseforpqfdbrazzesbolaopaneseifidocselgee\n",
1448 "vesjeegvojmooeoeslsthukexwudrarnwanxlkestjacvhscgliatesrohcqsdellennekgiqnslueafsalbtkncttclawsrigrn\n",
1449 "ozpbdbycrenekrsindekyasascetredsdodislbrejlrstgocnobscuredhhabsecurerechaliconsfnciacesixcoupledoanl\n",
1450 "tlmeicsihqmaximaltedynnwsdstssldoemtiebeedmdnbnngvgnippohcaeetsmespodtfmesosdnesjaloperpetuatingbosi\n",
1451 "eegggclassroomssniiralitlpsspsewbidtlelpduyedoicsgumgwfswdnmgfotopaetnrtvlsmovrnsfhfsmpilingcppuiafe\n",
1452 "dahhjnprnhwepecnarpeetixyeeredsrtezeredeldmdepkrnmnpqfgsiucsunneaegsueotisaiecreisueyirknittingsbdbr\n",
1453 "rtyeenickinglfygenlxrdigwsievneetfcevthaeeolnaceoiwispsenmedeielgrwblmncertrntdxsibdpsaostokenismdad\n",
1454 "aeedlafgiuigoarnccgezonchnnlktihttfiasllggalwqitcpcencrpttmteldnnutixisbkiilhgeamyseprzkmrhnmldneild\n",
1455 "tvwkibpeatnhwlozifgiigdugtwoafglrtrwizsnwpaiauleaencrorpoaaekiueoissoaihdszanryognhkaaeccceuyegcehad\n",
1456 "ifaitnmsephymsvstaxfstrqhlowziiirdendhiornplpesyecbeboigarxcrldhtslpgrnahswasitsraiortdemysvtjaindne\n",
1457 "berlyinacaepaeateliyortuetlclofnsirrdrooerleystfdcvlvuytireypiiaidamcyrlessdnoluvyzpcsggsidaimraoect\n",
1458 "unloijrerrrcnssacsetuoaaccbpdymciuakfdpreuegatsopasetznlapsnirnmfkzsztynctrgratoeectsoainarepnrmrbet\n",
1459 "tgibpsridceottensigittnrntnalaesfsnnseysworddcgtlrdedoygstrlrnggisimxaoinoscvrcharsapcngmesiamnmkkdu\n",
1460 "tnkyeuejuuselpscatelhdaaarlegabnaeimriohkinderouaydplerylksleegheueevtteleaeezzaipddpismnmntfgfowcsp\n",
1461 "eietdrimpqankffhpyaietgntwtyrbusesgallivantsdyicelxuydpunerjuyttdysinadlcrovejtloeeitsludgeuijnrcipt\n",
1462 "rbredgyperimusoejsrbayetimikesplkdebrutrepnumnbrklwmbanpserahfosmtdimieiscovsrdrvtyraomissluafioisiu\n",
1463 "nbisluelornaaorsteoastrireitliugselttitndxadgsweiufpreiiadmsbnemilqgcrtrnsiepeclrrapteswovasidfvcgro\n",
1464 "uupceraowdyedtgtstulteoneucertsicitnamoraincoatkubfearedkhayyeutycacyclhwlgrcjoeematrvilvendedaeisin\n",
1465 "trxrmgmsinimefestaniridihueiokfkdedutingamsnoynacqndecayswceagdoarakagcelniesvsndwomagpinupjyrlfdntd\n",
1466 "sgeosdrenblurbscaldahomnnoncncimonoxatkineticrseqorhnarksokurlsqplrreteaiheeeerepwrylykpdtubesuerogi\n",
1467 "qmsaesuohdraugzuiecvemsgigtycnangiopatawdrieroawjsonscallopedsesiwpratstclfddoiastelfaelihbumblersru\n",
1468 "itekrandomisessvrraayrgripestsivitcellocsbawsshapeliestmjgnitontoofhylluftsaobwsocilacidlocatedlrsee\n"
1469 ]
1470 }
1471 ],
1472 "source": [
1473 "print(show_grid(pg))"
1474 ]
1475 },
1476 {
1477 "cell_type": "code",
1478 "execution_count": 232,
1479 "metadata": {},
1480 "outputs": [
1481 {
1482 "data": {
1483 "text/plain": [
1484 "2000"
1485 ]
1486 },
1487 "execution_count": 232,
1488 "metadata": {},
1489 "output_type": "execute_result"
1490 }
1491 ],
1492 "source": [
1493 "len(dws) + len(ws)"
1494 ]
1495 },
1496 {
1497 "cell_type": "code",
1498 "execution_count": 233,
1499 "metadata": {
1500 "collapsed": true
1501 },
1502 "outputs": [],
1503 "source": [
1504 "with open('huge-wordsearch.txt', 'w') as f:\n",
1505 " f.write('{}x{}\\n'.format(len(pg[0]), len(pg)))\n",
1506 " f.write(show_grid(pg))\n",
1507 " f.write('\\n')\n",
1508 " f.write(lcat(sorted(ws + dws)))"
1509 ]
1510 },
1511 {
1512 "cell_type": "code",
1513 "execution_count": 234,
1514 "metadata": {},
1515 "outputs": [
1516 {
1517 "data": {
1518 "text/plain": [
1519 "(1149, 1149)"
1520 ]
1521 },
1522 "execution_count": 234,
1523 "metadata": {},
1524 "output_type": "execute_result"
1525 }
1526 ],
1527 "source": [
1528 "pm = present_many(g, ws)\n",
1529 "pold = [w for w in ws if present(g, w)[0]]\n",
1530 "len(pm), len(pold)"
1531 ]
1532 },
1533 {
1534 "cell_type": "code",
1535 "execution_count": 235,
1536 "metadata": {},
1537 "outputs": [
1538 {
1539 "data": {
1540 "text/plain": [
1541 "(1149, 1149)"
1542 ]
1543 },
1544 "execution_count": 235,
1545 "metadata": {},
1546 "output_type": "execute_result"
1547 }
1548 ],
1549 "source": [
1550 "ppm = present_many(pg, ws)\n",
1551 "ppold = [w for w in ws if present(pg, w)[0]]\n",
1552 "len(ppm), len(ppold)"
1553 ]
1554 },
1555 {
1556 "cell_type": "code",
1557 "execution_count": 236,
1558 "metadata": {
1559 "scrolled": true
1560 },
1561 "outputs": [
1562 {
1563 "name": "stdout",
1564 "output_type": "stream",
1565 "text": [
1566 "smuiclacphysics.hcnebrevilingd..skcabllup.s...gnitnacs..blusted.....pilafeldrig..enquireddetnawnu...\n",
1567 "e....nutmegs.t..telbanimret...e..tseikwagewoodpeckerstirwas.b.r...picksn...ylhsiroobsuspectingsexevd\n",
1568 "cgnittacdliw..isuoniallivsegas.lrafts.y.vcs..demrofsnart.mla...e.c....e..fannysdiscrimination.oe..e.\n",
1569 "nnytima.wharfrep.stswashbucklersw....m.eos...noprat....ao.rs....t.h..m.relabele..sss...b.sc.ts..vb.s\n",
1570 "eid..desivedaia.shegdtg.gniyugys.o..a.rme.gpantedsobeysodgm.a....t.osabound...s.bttp...uje.orhd.boe.\n",
1571 "tverediw...dtlw.eiar.ehacrierhsrmccosiant.nbestridi..sreepegarotedadr.slaropauses..e..rdis.oteia.lld\n",
1572 "nardd.p...itli.i.pesu.srwe...ciuuhfsnti.sgingivitislubl.fotkcuhs..rmsensitisedeu...eleygbutsiyjcf.u.\n",
1573 "eerne.u..aiin.r.i.nset.ioku..taeia.gods.e.n..dh.n.emld.r.lht.hobnobsi.s..l.c.trs...jnb.ieoizw.llka.f\n",
1574 "shiense.nhae.s.n.aietun.owig.idtrp.srsayi.w..ogu.oecnie..yo.u...whmt.t..u.a.lcds...tb.ondran.oeersa.\n",
1575 ".nhpnnktsts...g.d.cve.qe.pblohdoaseomtc.r.a.tgnrgdnaiae.spd.sc.sora...nt.r.en.no..ro...g.l..msbfdue.\n",
1576 ".asxiiasehcnerdj.moido.edsoayvebr.w.ufh.rtr.sgiaxgdekm.rtfo.k.noir.....ag.se..ur.al..sreraehsu.xnoet\n",
1577 "gr.erah.peeweeu.i.tdir..h.acc.mard..tie.u.pdeehbo.eyx.u.ralge.kucnoveltiesseirfdp..buttocksn..laodne\n",
1578 "nr.sgls..d..sdwrg.iela...c.uikise.o.altwf.i.idcbtged...poeoatsqo...gratefully..sportingsweepersaa..s\n",
1579 "iaw.bp...e.hgor.ulnnstullee.ntl.t.mttps.os..d.tienstc...nhggcst.gsugaringinsight..snifters.....cde.i\n",
1580 "nta..m..ssteno..i.eckef..b...ar..y.ieu.lpls.n.endirswu..gsiehs..n.delbaf....interpose..dsurt..r.el.u\n",
1581 "oeg..oae.usdr..kl..ecd.aiproveso..llsdsayeb.a.ra.iee.er.l.esih.ti.sllihygrellapractisedatcneea..gg.r\n",
1582 "sdeb.cziofe.r.e.d..da..rgthrive.p.agearetr.hs.stsavr..riy.srec.ar.pocketbooktrotxe.....nw.unlk..gg.b\n",
1583 "a.re.a.m.rs.espumoneb.t..o.semorhc.rnadau.istp.eehio..cpoga.sn.uuyratchetswisher.....n.se..fepc.aos.\n",
1584 "e.saf...fsrrh.a.retpada...t.....e.iggiiv.llcaam.vgnt.o.t.sidtu.pj.r.retemarapecnarussau.a.l.frpante.\n",
1585 "rretarcurne.c.g.pellagra...s...d.wni.dk.elgnaae.inusm..msgibehfedtsl..prowldenimn.shiedrka...l.il.ss\n",
1586 "n..i..leatgbt.rc..s..sesitengamedinkafgnonn.tladta.m....uentbl.aa.oeegniyartrop.eseitoobsnoleme.tpuu\n",
1587 "ub.f.lent.gri.afassevissimagingslgiryuoriit...nsahaseigodniiyelwb..upwthguorb.obmil....hfeedings..tr\n",
1588 ".a.yydne..aew.ryrri.emackintoshw.trsbnasnh.u..trksr.gasketrpc.raar..ptereinterpretingie....deggiwtnp\n",
1589 ".s..nyl...raslitloeett.splinesobtih.gnlgtkt.r.ealwasset....usu.bvgi..eej......rtss.dnrtonnaccords.oa\n",
1590 ".ihikers..bkawa.rtssrao...gc.r.yek..ues..rhn.ennaob.gmovers.bid.riwcsketches.esar.etsi.gswollefdebcs\n",
1591 ".leticilli.zaen..uftsrnv..log..dils.rrc..noau.nitrlbr.eidrib.iwa.irea..st...ieiadxe.n.lrolocsid....s\n",
1592 "sr...m....edl.s...loyeage.ap...e.pc....h..ilk.am.roouevilamsidv.r.e.gt..ge.gfdeaer.s.ygnideerbnquoit\n",
1593 "reprobatesdiyruovasbs.d.oddu..hks..h.s..e..kliee.uoae.lairetsigamt.r..e..nneedmsp.t.p.incisesuhctulc\n",
1594 "s.vr.t.sdld..s.controllablel.s.aleavese..l..s..s.btrshalvesylsuougibma.s.sim.pgo.avhshortensr.zzazip\n",
1595 ".ebae.oliedpmsuesilangisg..a..hc.zingsyy..oqueryingdoreopened..endless...l.bs.lrlsnikskcub.t..knifed\n",
1596 "jiklruons.lefilbsnwodwohsn.ttupnit..tdretsenohl..cvsm...gnimirgnidaetsemoh..baamongst..y.wucustomers\n",
1597 "doionfgh.a.lsotej.....e.h.iee...gniretnuas..s..o.oa.e.g.r...snoitulos.selppitue..w...io.trrbfruits..\n",
1598 ".eydj.g.n..i.iutvosplithsejlhp.s.eieinveighing..mnl.rlbu..pineapple....a.f.e.nsrealiseadel.ar.eevell\n",
1599 "r.ertu.e..gc..dleoi....htiiyi.m.avr..transducers.fe.aatempts.b.....d.n.f.ud.t.scales.r.tr.aopinion.l\n",
1600 ".d.yoveterinaryoenrn..a.bapg.wjuin..psalmist.x...innlenvd...iebrashereat.ne...snaeco..aeiide.ps...ii\n",
1601 "..pb.dtacosei.l.sr.gim.b.eb.ho.nrideraems....opa.dcdri.ie..n.lv.sc.k.kweent.outsmartedwl.oaef.ek..mb\n",
1602 "feweste....p.v.a.p..enisreesbtg..t.h.e.k.tt..bem.eecas.lpggday.ipmrn.akrqeasedoberofmrr.l.nhp..de.pn\n",
1603 "dy.sighting...o.spalfngsd..b.cellistott.nscc.hdesshlhe.leinde.aas.ea.ewnulcsekytmrg.oa..co..la...tao\n",
1604 ".ddr..object...r.aehg.ee..ipr......degmreioascontrrits.an.oieinw.umlzwaoa.iss..i.netu.midictatorialo\n",
1605 ".e.em..muiretcab.sn.rnh.gnoigimletslry.denreftmdie.trsygdm.rssvsealplyrobcll.gx.i.egusnm..b.c.ps..ap\n",
1606 ".pstekcolsopyh..s...schngpsteppes.esoadwcaib.aesvsrhiiree.iprikvrc.l.ydniapisenb.banaoicar.yagr...ss\n",
1607 "ep.sew......macinimin.islp..s....xrpaotoirdf.mto.eoomharntse.elti.a.a.eslrxarebiajdahvalaslprnoarbez\n",
1608 "so.ykbongothistlektass.iidsreg..e.ia.lreogaiweevilgg..n.tagrw.ia.d.r..s.ioemsoinsa.pnnavtr.adidllucs\n",
1609 "il.oloverwhelmednilni.neegee.cnd.as.mduvrch.n.r..lurd.oarnasenilesab..t.tul.stkxuie.ctesae.rigd.....\n",
1610 "rp..y.......l..ivbal.nrigdn.l.ni.n.damava..t.g...seaeyi.ik..se...rtheoryysab.shnolreeril.edknniesohw\n",
1611 "oproponents.etli.kacotr.in.o.t.en.innsidu...relruc.pgetge.d.lciportosi...ega.itgeplpyautge.egon.ar..\n",
1612 "ecaudalyokelrst.ynoiif.l.piklstsrrtf.aenvoyeuristichnludta.b.se.i.ngnirabrer.entuleaugsno.gd.rgdlibd\n",
1613 "h..configurationontnt.g...omr.toteo.fsg.g..stsefni.yora.psa.t.l.msa.....e.rbd.sseol.e.at.x.dwhesieee\n",
1614 "tpalsy.r..c.e..ivcsrscinap.tma.irsfm.uliuqnartoday..racp.neo..u.plncaninev.eg.eduynr.rg.e.ieat.lgngp\n",
1615 "..fleshyuk.s.dteeme.eruptingtah.lhir.gm.r.contrastedhbe.ugni..p.uei.yamsidad.nreal..r.ny.rrntc.antoy\n",
1616 "....yogins..earnis..ripeness.edsmethe.na.bsromalgte.trr.ni..k.m.lemigfieryed..iwvtta.wia.hnis.ss.eth\n",
1617 "nonhuman..knnsnte...e...cupolargiitapt.igreideew.s.re.pie....oaespo.nrcb.y.ke.wlfiee.hdws.p...mu.d..\n",
1618 "bywords...osiohme..estnemegagnedlnstcon.ya...primessn.mshockerhleyd..sehe.t.ssealra.daua.s....ar....\n",
1619 "outlastedt.ocsb.c.x....enilefileeavgotsi.lrfordssgt..ettautnessbdebbadieil.p.ur.po.w.lle......oe.k.g\n",
1620 "ddetsyrte.n..l.gnp.esuccocddypl.ppdeisi..rlpimplyn..ecg..dsuitcases.a.ksnfl.mdtnekrahecs.etsawfpn.cn\n",
1621 "iawaitss.s..e.a.e..lp....euhauwpi.udrv.ve..er.a..udt..as.se...ctlocn.c.ltifsretaehcc.rnempollenag.ii\n",
1622 "essertsimdaehrsci.gdr...tstrcocrn.stesidi..ejs...o.e..erq..lt.i.akaco.ksussocondoretsaocno....tdnnls\n",
1623 "s.rettab.es.rptgc.ide..itaeidodohb.cynen.sn.o....y..vrcua..uclb.earhgiyhla.hn..lebil..c..ak..senioli\n",
1624 "retsim.tlu.eoo.rssfaa.xsendns.ehoqa.oeesgdtpmoppets.ueeu.moseyu.cygan.tlaib..detoormoisterpe.l.olial\n",
1625 "......hbbdtpr..inmt.desrtaetjhpilu.rlrtdsso.derunettceirltesl.csneofis.aenssregnifrettub...od.asbtha\n",
1626 "sfeergalebia.f.noui.iobattlae.ebei.bdwe..r..os...gpoz.orslsl.le.odefdr..tvdn...adjectivess.dr.geaapr\n",
1627 "....isitultscrbdccn.n.lelipa.gnime..is.dp....we..ane.b..toi..bikc.sener..ii.eslays.rp..c.du..pagnr.t\n",
1628 "f..limocleiasoaegsgignduear..udtut.l...gambol.nsrv.ib.o.re.ni..mupfdete..ysa.t....ea.oa..fetm.taeu.n\n",
1629 "o.ideokoslb.ewnr.nrso.psnss.reeifelatrinems....ei..etb.s..rvg...ol..rtc.y.lin.u..t.lsne.cp.tceeyypte\n",
1630 "owd.mel.ear.isir.eipeatsenye.snvfr..latticeworkndlrfesgnihsalpslagf.suunsprlv...u..otk.tardslassgpcc\n",
1631 "t.yltd.dl.e.hysam.uhtl.so.tm.scelcascadinghl..c.asiyrse.vexed.tsng.fshpaslpua..c.oasislliiumtocsguie\n",
1632 "wynifnpseydscetdso.acyyi.e..i.elihslanifbstsle.r.vevrycv.....rhi.ne.tsetoahdstaupset..eascae.rj.isvd\n",
1633 "euamrae.sliuraeicccecnttmstner.yn.st....olansonsade.ieeoi...oeo..i.ga.rubqyaito..deposittdaat.a.wael\n",
1634 "apmeitr.ussrarra..aaraiosgy...g.g.gie...tewor.wart.n.cbrfd.odds.hrpnb.ar.usddlltpoesyrr.js.l...wt.he\n",
1635 "rpisasmtoutgid.l..ilctnl.nabiopsy.gnbi..cwsii.gepei.g..u.fn.ee.cseiimptaweiecoae..s.euyu...ynominees\n",
1636 ".ictrsiarorerr..gdiipoi.fiwgnilratsnibu.hortcgn.saef.e.rtslrre.lcknlooelahcka.rvre.isdraeslather...r\n",
1637 "yekopuspalirtu.eenf.re.m.nbslartueneiloqebeakoihstlhi.ru...ap.aaonilculirskrs..nnsntaarttdetcartsbao\n",
1638 ".s.n.bsrclcyamnmei.h.pl..nu.deniapeptllns.kvslky.mymce.fs.mawussrane.nasdaiut.ylsasetmae.canoes.oe.m\n",
1639 "...e.oio.at.ptmrt.c..r...estappinggp.odos.cahfnm..imi.dfl.c.gtudihgv.cieiunlerugpshietetniksgipdnt..\n",
1640 "flierroo.cs.liac.gunfire.pwhimsd..aa..grr.ucasue...rmn.lis.hidu.n..i.etdnqgerfoceaodidsdewotwokrgals\n",
1641 "latconnm.f.e..epaimedc...deducesddshs..aunfx..rn....kugie.tgdl..g..n..y.g.nawn.krnilse.snoopingisgil\n",
1642 "obmibsss..asir..l..a.eeviecerggee.em....ecue..tstoadspynveael....resonantgtan.ugseiti.ruolev...freao\n",
1643 "u..gdarnsspegniciee.sylbatonarpgfhrsodomychaiserelbmuh.grtnsstseebedliw.o.la.p..ncmpr.enrapturetertv\n",
1644 "t...rd...oncc.t.srnclennut.cainoaap...od..bfrolics.k....o.rosseforp...brazzesb.laopa.eseifidoc.elgee\n",
1645 "v...ee..o..ooe.eslsth.ke...drarnwan.l.es..a...sc.liatesrohc.sdellennekgi..s.u.af.albtkn...clawsrigrn\n",
1646 "o..bdbyc....krsindekyasa..etredsdodi.l.re.l..tgo.nobscuredhh..securere..al.c.nsfn.iace.i.coupledoanl\n",
1647 "t.mei.si..maximaltedynn.sdstss.doem.iebe.dm.n.nng.gnippohca....m....dt..eso.dnes.a.operpetuatingbo.i\n",
1648 "eegggclassroomss...ral.t.pssp.ewbidtlelpd.yedoic.g.....s.dnm..otopaetn.t.lsmov..sfh.s.piling....i..e\n",
1649 "dahh.n...h..pecnarpeeti.yeeredsrte.ere.e..mdepkrn.np....iucsun..ae...eotisaie..eis.ey.rknittings..br\n",
1650 "rt.eenickinglfy...l.rdig..ie.neet.cev.ha.eo.naceo.wispsenme.eie.gr..lmncertrntdxs.bdpsao.tokenismda.\n",
1651 "...dla.g..i.oar.cc.e.onchnn.ktihttfi.s.lgg.lwqitcp.en.rpttmt.ldnn.ti.i.bkii.hgeamyseprzk.r..mld.e.l.\n",
1652 ".vwkibp.a.n.wlo.ifg..g.ugtw.afglrtr.i..nwpa.auleae.crorpoaaek.ueo.ssoai.ds.a.ryognhkaaec..euye.ce.ad\n",
1653 "..ai.nmseph.msvsta..st.qh.ow.iiirden..iornp.pes.ec.eboigarxcrld.tslp.r.ahsw.sitsra.ortde..svt.a.ndne\n",
1654 "b.rl.inacae.aeatel.yortuetl.l.fn.irr.rooe..e.s..dcv.vuytireypii.i.a.c.rlessdnoluvy.pcsggsidaim.aoect\n",
1655 "u.loi.rerrr.nssacs.tuoaac.bp.y..iuakfdpr..egatsopasetznlapsni.nmf.zs.tynctrgrato..c.so.in.repnr.rbet\n",
1656 "tgibps.idceott.nsi.ittnrntnalaesfsnnseysword.c..lrdedoygst.lrnggisi.xaoinoscvrcharsa.cngmesiamn.kkdu\n",
1657 "tnkye.e.uusel..cat.lh.aaa.legabnaei.r...kinderou.y.pler.lksleeg.e.eevtteleaeezzaipddpis.nmntfgfo.csp\n",
1658 "eietd..mpqankffh.yaie.gnt.....use.gallivants..ic.l.uydpuner.uyttdysinadlcrove....ee.tslu.geuijnrcipt\n",
1659 "rbred..peri.usoe.srbayetimikespl.debrutrepnu.n.rkl.mb.npsera.fosm.dimieiscovsrd.vtyr.om...l..fioisiu\n",
1660 "nbisl.e.or.a..rs.eoastrireitliugselttit.....g..e.u.pr..iadmsbnemil.gcrt..siepeclrrapteswovasidfvcgro\n",
1661 "uupcer.o..y.d.gtstulte.ne...rtsicitnamoraincoatk.bfearedkhayyeutycacyc.hwlgrc.oeematr...vended.ei.i.\n",
1662 "trxrm.msinimefe.tani.i.ih..i.....edutingamsnoynac..decay..ceagd.ara.a.celnie.vsndwo...pinup...l.dntd\n",
1663 "sgeosdrenblurbscalda.o.nn.n..cimonoxatkinetic..e....narks.k.rl..pl.r.teaihe.eer.pwryly...tubes.e..g.\n",
1664 "..saesuohdraug..ie.v.m.gig.ycnangiop.tawdrier..w....scallopedsesiwp.atstcl.ddo.astelfael..bumblers..\n",
1665 ".t.krandomises..rr.a..gripestsivitcellocsbawsshapeliest..gnitontoofhylluftsaobwsocilac..located..s..\n"
1666 ]
1667 }
1668 ],
1669 "source": [
1670 "print(show_grid(g))"
1671 ]
1672 },
1673 {
1674 "cell_type": "code",
1675 "execution_count": null,
1676 "metadata": {
1677 "collapsed": true
1678 },
1679 "outputs": [],
1680 "source": []
1681 }
1682 ],
1683 "metadata": {
1684 "kernelspec": {
1685 "display_name": "Python 3",
1686 "language": "python",
1687 "name": "python3"
1688 },
1689 "language_info": {
1690 "codemirror_mode": {
1691 "name": "ipython",
1692 "version": 3
1693 },
1694 "file_extension": ".py",
1695 "mimetype": "text/x-python",
1696 "name": "python",
1697 "nbconvert_exporter": "python",
1698 "pygments_lexer": "ipython3",
1699 "version": "3.5.2+"
1700 }
1701 },
1702 "nbformat": 4,
1703 "nbformat_minor": 1
1704 }