13 "import collections\n",
17 "from enum import Enum\n",
18 "Direction = Enum('Direction', 'left right up down upleft upright downleft downright')\n",
20 "delta = {Direction.left: (0, -1),Direction.right: (0, 1), \n",
21 " Direction.up: (-1, 0), Direction.down: (1, 0), \n",
22 " Direction.upleft: (-1, -1), Direction.upright: (-1, 1), \n",
23 " Direction.downleft: (1, -1), Direction.downright: (1, 1)}\n",
32 "execution_count": 14,
38 "def empty_grid(w, h):\n",
39 " return [['.' for c in range(w)] for r in range(h)]"
44 "execution_count": 15,
50 "def show_grid(grid):\n",
51 " return lcat(cat(r) for r in grid)"
56 "execution_count": 16,
62 "def indices(grid, r, c, l, d):\n",
63 " dr, dc = delta[d]\n",
64 " w = len(grid[0])\n",
66 " inds = [(r + i * dr, c + i * dc) for i in range(l)]\n",
67 " return [(i, j) for i, j in inds\n",
76 "execution_count": 17,
82 "def gslice(grid, r, c, l, d):\n",
83 " return [grid[i][j] for i, j in indices(grid, r, c, l, d)]"
88 "execution_count": 18,
94 "def set_grid(grid, r, c, d, word):\n",
95 " for (i, j), l in zip(indices(grid, r, c, len(word), d), word):\n",
102 "execution_count": 20,
108 "def present(grid, word):\n",
109 " w = len(grid[0])\n",
111 " for r in range(h):\n",
112 " for c in range(w):\n",
113 " for d in Direction:\n",
114 " if cat(gslice(grid, r, c, len(word), d)) == word:\n",
115 " return True, r, c, d\n",
116 " return False, 0, 0, list(Direction)[0]"
121 "execution_count": 22,
127 "def read_wordsearch(fn):\n",
128 " lines = [l.strip() for l in open(fn).readlines()]\n",
129 " w, h = [int(s) for s in lines[0].split('x')]\n",
130 " grid = lines[1:h+1]\n",
131 " words = lines[h+1:]\n",
132 " return w, h, grid, words"
137 "execution_count": 50,
146 "(['pistrohxegniydutslxt',\n",
147 " 'wmregunarbpiledsyuoo',\n",
148 " 'hojminbmutartslrlmgo',\n",
149 " 'isrsdniiekildabolpll',\n",
150 " 'tstsnyekentypkalases',\n",
151 " 'ssnetengcrfetedirgdt',\n",
152 " 'religstasuslatxauner',\n",
153 " 'elgcpgatsklglzistilo',\n",
154 " 'tndlimitationilkasan',\n",
155 " 'aousropedlygiifeniog',\n",
156 " 'kilrprepszffsyzqsrhs',\n",
157 " 'itlaadorableorpccese',\n",
158 " 'noaeewoodedpngmqicnl',\n",
159 " 'gmrtoitailingchelrok',\n",
160 " 'jadsngninetsahtooeic',\n",
161 " 'xeernighestsailarmtu',\n",
162 " 'aeabsolvednscumdfnon',\n",
163 " 'gydammingawlcandornk',\n",
164 " 'hurlerslvkaccxcinosw',\n",
165 " 'iqnanoitacifitrofqqi'],\n",
192 " 'fortification',\n",
201 " 'hopelessness',\n",
209 " 'justification',\n",
236 " 'reformulated',\n",
268 "execution_count": 50,
270 "output_type": "execute_result"
274 "width, height, g, ws = read_wordsearch('wordsearch04.txt')\n",
280 "execution_count": 51,
288 "output_type": "stream",
290 "absolved (True, 16, 2, <Direction.right: 2>)\n",
291 "adorable (True, 11, 4, <Direction.right: 2>)\n",
292 "aeon (True, 11, 4, <Direction.down: 4>)\n",
293 "alias (True, 15, 15, <Direction.left: 1>)\n",
294 "ancestor (False, 0, 0, <Direction.left: 1>)\n",
295 "baritone (False, 0, 0, <Direction.left: 1>)\n",
296 "bemusing (False, 0, 0, <Direction.left: 1>)\n",
297 "blonds (False, 0, 0, <Direction.left: 1>)\n",
298 "bran (True, 1, 9, <Direction.left: 1>)\n",
299 "calcite (True, 19, 9, <Direction.upright: 6>)\n",
300 "candor (True, 17, 12, <Direction.right: 2>)\n",
301 "conciseness (False, 0, 0, <Direction.left: 1>)\n",
302 "consequent (False, 0, 0, <Direction.left: 1>)\n",
303 "cuddle (False, 0, 0, <Direction.left: 1>)\n",
304 "damming (True, 17, 2, <Direction.right: 2>)\n",
305 "dashboards (False, 0, 0, <Direction.left: 1>)\n",
306 "despairing (False, 0, 0, <Direction.left: 1>)\n",
307 "dint (False, 0, 0, <Direction.left: 1>)\n",
308 "dullard (True, 8, 2, <Direction.down: 4>)\n",
309 "dynasty (True, 3, 4, <Direction.downright: 8>)\n",
310 "employer (False, 0, 0, <Direction.left: 1>)\n",
311 "exhorts (True, 0, 8, <Direction.left: 1>)\n",
312 "feted (True, 5, 10, <Direction.right: 2>)\n",
313 "fill (True, 9, 14, <Direction.upleft: 5>)\n",
314 "flattens (True, 10, 10, <Direction.upleft: 5>)\n",
315 "foghorn (True, 10, 11, <Direction.downright: 8>)\n",
316 "fortification (True, 19, 16, <Direction.left: 1>)\n",
317 "freakish (False, 0, 0, <Direction.left: 1>)\n",
318 "frolics (True, 16, 16, <Direction.up: 3>)\n",
319 "gall (False, 0, 0, <Direction.left: 1>)\n",
320 "gees (True, 17, 0, <Direction.upright: 6>)\n",
321 "genies (True, 5, 7, <Direction.upleft: 5>)\n",
322 "gets (True, 6, 4, <Direction.upleft: 5>)\n",
323 "hastening (True, 14, 13, <Direction.left: 1>)\n",
324 "hits (True, 2, 0, <Direction.down: 4>)\n",
325 "hopelessness (False, 0, 0, <Direction.left: 1>)\n",
326 "hurlers (True, 18, 0, <Direction.right: 2>)\n",
327 "impales (False, 0, 0, <Direction.left: 1>)\n",
328 "infix (False, 0, 0, <Direction.left: 1>)\n",
329 "inflow (False, 0, 0, <Direction.left: 1>)\n",
330 "innumerable (False, 0, 0, <Direction.left: 1>)\n",
331 "intentional (False, 0, 0, <Direction.left: 1>)\n",
332 "jerkin (False, 0, 0, <Direction.left: 1>)\n",
333 "justification (False, 0, 0, <Direction.left: 1>)\n",
334 "kitty (True, 8, 15, <Direction.upleft: 5>)\n",
335 "knuckles (True, 17, 19, <Direction.up: 3>)\n",
336 "leaving (False, 0, 0, <Direction.left: 1>)\n",
337 "like (True, 3, 11, <Direction.left: 1>)\n",
338 "limitation (True, 8, 3, <Direction.right: 2>)\n",
339 "locoweeds (False, 0, 0, <Direction.left: 1>)\n",
340 "loot (True, 3, 19, <Direction.up: 3>)\n",
341 "lucking (True, 7, 10, <Direction.upleft: 5>)\n",
342 "lumps (True, 0, 17, <Direction.down: 4>)\n",
343 "mercerising (True, 15, 17, <Direction.up: 3>)\n",
344 "monickers (False, 0, 0, <Direction.left: 1>)\n",
345 "motionless (True, 13, 1, <Direction.up: 3>)\n",
346 "naturally (True, 9, 16, <Direction.up: 3>)\n",
347 "nighest (True, 15, 4, <Direction.right: 2>)\n",
348 "notion (True, 17, 18, <Direction.up: 3>)\n",
349 "ogled (True, 1, 18, <Direction.down: 4>)\n",
350 "originality (False, 0, 0, <Direction.left: 1>)\n",
351 "outings (False, 0, 0, <Direction.left: 1>)\n",
352 "pendulous (False, 0, 0, <Direction.left: 1>)\n",
353 "piled (True, 1, 10, <Direction.right: 2>)\n",
354 "pins (True, 7, 4, <Direction.upleft: 5>)\n",
355 "pithier (False, 0, 0, <Direction.left: 1>)\n",
356 "prep (True, 10, 4, <Direction.right: 2>)\n",
357 "randomness (False, 0, 0, <Direction.left: 1>)\n",
358 "rectors (False, 0, 0, <Direction.left: 1>)\n",
359 "redrew (False, 0, 0, <Direction.left: 1>)\n",
360 "reformulated (False, 0, 0, <Direction.left: 1>)\n",
361 "remoteness (False, 0, 0, <Direction.left: 1>)\n",
362 "retaking (True, 6, 0, <Direction.down: 4>)\n",
363 "rethink (False, 0, 0, <Direction.left: 1>)\n",
364 "rope (True, 9, 4, <Direction.right: 2>)\n",
365 "rubier (True, 0, 4, <Direction.downright: 8>)\n",
366 "sailors (True, 7, 15, <Direction.up: 3>)\n",
367 "scowls (False, 0, 0, <Direction.left: 1>)\n",
368 "scum (True, 16, 11, <Direction.right: 2>)\n",
369 "sepals (True, 6, 10, <Direction.upright: 6>)\n",
370 "sequencers (False, 0, 0, <Direction.left: 1>)\n",
371 "serf (False, 0, 0, <Direction.left: 1>)\n",
372 "shoaled (True, 11, 18, <Direction.up: 3>)\n",
373 "shook (False, 0, 0, <Direction.left: 1>)\n",
374 "sonic (True, 18, 18, <Direction.left: 1>)\n",
375 "spottiest (False, 0, 0, <Direction.left: 1>)\n",
376 "stag (True, 7, 8, <Direction.left: 1>)\n",
377 "stood (False, 0, 0, <Direction.left: 1>)\n",
378 "stratum (True, 2, 13, <Direction.left: 1>)\n",
379 "strong (True, 4, 19, <Direction.down: 4>)\n",
380 "studying (True, 0, 16, <Direction.left: 1>)\n",
381 "surtaxing (False, 0, 0, <Direction.left: 1>)\n",
382 "tailing (True, 13, 6, <Direction.right: 2>)\n",
383 "tears (True, 13, 3, <Direction.up: 3>)\n",
384 "teazles (True, 4, 10, <Direction.downright: 8>)\n",
385 "vans (True, 18, 8, <Direction.upright: 6>)\n",
386 "wardrobes (False, 0, 0, <Direction.left: 1>)\n",
387 "wooded (True, 12, 5, <Direction.right: 2>)\n",
388 "worsts (True, 1, 0, <Direction.downright: 8>)\n",
389 "zings (True, 10, 14, <Direction.upleft: 5>)\n"
395 " print(w, present(g, w))"
399 "cell_type": "markdown",
402 "Which words are present?"
407 "execution_count": 52,
431 " 'fortification',\n",
476 "execution_count": 52,
478 "output_type": "execute_result"
482 "[w for w in ws if present(g, w)[0]]"
486 "cell_type": "markdown",
489 "What is the longest word that is present?"
494 "execution_count": 53,
505 "execution_count": 53,
507 "output_type": "execute_result"
511 "sorted([w for w in ws if present(g, w)[0]], key=len)[-1]"
515 "cell_type": "markdown",
518 "What is the longest word that is absent?"
523 "execution_count": 54,
534 "execution_count": 54,
536 "output_type": "execute_result"
540 "sorted([w for w in ws if not present(g, w)[0]], key=len)[-1]"
544 "cell_type": "markdown",
547 "How many letters are unused?"
552 "execution_count": 55,
563 "execution_count": 55,
565 "output_type": "execute_result"
569 "g0 = empty_grid(width, height)\n",
571 " p, r, c, d = present(g, w)\n",
573 " set_grid(g0, r, c, d, w)\n",
574 "len([c for c in cat(cat(l) for l in g0) if c == '.'])"
578 "cell_type": "markdown",
581 "What is the longest word you can make form the leftover letters?"
586 "execution_count": 56,
595 "Counter({'a': 4,\n",
617 "execution_count": 56,
619 "output_type": "execute_result"
623 "unused_letters = [l for l, u in zip((c for c in cat(cat(l) for l in g)), (c for c in cat(cat(l) for l in g0)))\n",
625 "unused_letter_count = collections.Counter(unused_letters)\n",
626 "unused_letter_count"
631 "execution_count": 57,
653 " 'hopelessness',\n",
660 " 'justification',\n",
671 " 'reformulated',\n",
684 "execution_count": 57,
686 "output_type": "execute_result"
690 "unused_words = [w for w in ws if not present(g, w)[0]]\n",
696 "execution_count": 59,
704 "output_type": "stream",
706 "ancestor Counter({'c': 1, 'a': 1, 's': 1, 't': 1, 'n': 1, 'r': 1, 'o': 1, 'e': 1})\n",
707 "baritone Counter({'a': 1, 'i': 1, 'r': 1, 't': 1, 'b': 1, 'n': 1, 'o': 1, 'e': 1})\n",
708 "bemusing Counter({'g': 1, 'u': 1, 'i': 1, 's': 1, 'n': 1, 'm': 1, 'b': 1, 'e': 1})\n",
709 "blonds Counter({'s': 1, 'd': 1, 'n': 1, 'b': 1, 'o': 1, 'l': 1})\n",
710 "conciseness Counter({'s': 3, 'c': 2, 'n': 2, 'e': 2, 'i': 1, 'o': 1})\n",
711 "consequent Counter({'n': 2, 'e': 2, 'u': 1, 'c': 1, 's': 1, 't': 1, 'q': 1, 'o': 1})\n",
712 "cuddle Counter({'d': 2, 'u': 1, 'e': 1, 'c': 1, 'l': 1})\n",
713 "dashboards Counter({'a': 2, 's': 2, 'd': 2, 'o': 1, 'r': 1, 'b': 1, 'h': 1})\n",
714 "*despairing Counter({'i': 2, 'g': 1, 'a': 1, 's': 1, 'r': 1, 'd': 1, 'n': 1, 'p': 1, 'e': 1})\n",
715 "dint Counter({'d': 1, 'n': 1, 'i': 1, 't': 1})\n",
716 "employer Counter({'e': 2, 'y': 1, 'r': 1, 'm': 1, 'p': 1, 'o': 1, 'l': 1})\n",
717 "freakish Counter({'k': 1, 'a': 1, 'i': 1, 'r': 1, 'f': 1, 's': 1, 'h': 1, 'e': 1})\n",
718 "*gall Counter({'l': 2, 'g': 1, 'a': 1})\n",
719 "hopelessness Counter({'s': 4, 'e': 3, 'h': 1, 'n': 1, 'p': 1, 'o': 1, 'l': 1})\n",
720 "*impales Counter({'s': 1, 'a': 1, 'i': 1, 'm': 1, 'e': 1, 'p': 1, 'l': 1})\n",
721 "infix Counter({'i': 2, 'f': 1, 'n': 1, 'x': 1})\n",
722 "inflow Counter({'i': 1, 'w': 1, 'f': 1, 'n': 1, 'o': 1, 'l': 1})\n",
723 "innumerable Counter({'n': 2, 'e': 2, 'u': 1, 'l': 1, 'a': 1, 'i': 1, 'r': 1, 'm': 1, 'b': 1})\n",
724 "intentional Counter({'n': 3, 'i': 2, 't': 2, 'a': 1, 'l': 1, 'o': 1, 'e': 1})\n",
725 "*jerkin Counter({'k': 1, 'i': 1, 'r': 1, 'n': 1, 'j': 1, 'e': 1})\n",
726 "justification Counter({'i': 3, 't': 2, 'u': 1, 'c': 1, 's': 1, 'n': 1, 'f': 1, 'j': 1, 'o': 1, 'a': 1})\n",
727 "leaving Counter({'g': 1, 'l': 1, 'a': 1, 'i': 1, 'n': 1, 'v': 1, 'e': 1})\n",
728 "locoweeds Counter({'o': 2, 'e': 2, 'c': 1, 's': 1, 'd': 1, 'w': 1, 'l': 1})\n",
729 "monickers Counter({'k': 1, 'c': 1, 's': 1, 'i': 1, 'r': 1, 'n': 1, 'm': 1, 'o': 1, 'e': 1})\n",
730 "originality Counter({'i': 3, 'g': 1, 'a': 1, 'r': 1, 't': 1, 'n': 1, 'y': 1, 'o': 1, 'l': 1})\n",
731 "outings Counter({'g': 1, 'u': 1, 's': 1, 'i': 1, 't': 1, 'n': 1, 'o': 1})\n",
732 "pendulous Counter({'u': 2, 's': 1, 'd': 1, 'n': 1, 'l': 1, 'p': 1, 'o': 1, 'e': 1})\n",
733 "pithier Counter({'i': 2, 'r': 1, 't': 1, 'p': 1, 'h': 1, 'e': 1})\n",
734 "randomness Counter({'s': 2, 'n': 2, 'a': 1, 'r': 1, 'd': 1, 'm': 1, 'o': 1, 'e': 1})\n",
735 "rectors Counter({'r': 2, 'c': 1, 's': 1, 't': 1, 'o': 1, 'e': 1})\n",
736 "redrew Counter({'e': 2, 'r': 2, 'd': 1, 'w': 1})\n",
737 "reformulated Counter({'r': 2, 'e': 2, 'u': 1, 'a': 1, 'f': 1, 't': 1, 'm': 1, 'l': 1, 'd': 1, 'o': 1})\n",
738 "remoteness Counter({'e': 3, 's': 2, 'r': 1, 't': 1, 'm': 1, 'n': 1, 'o': 1})\n",
739 "rethink Counter({'k': 1, 'i': 1, 'r': 1, 't': 1, 'n': 1, 'h': 1, 'e': 1})\n",
740 "scowls Counter({'s': 2, 'w': 1, 'c': 1, 'o': 1, 'l': 1})\n",
741 "sequencers Counter({'e': 3, 's': 2, 'u': 1, 'c': 1, 'r': 1, 'n': 1, 'q': 1})\n",
742 "serf Counter({'f': 1, 'r': 1, 's': 1, 'e': 1})\n",
743 "shook Counter({'o': 2, 'k': 1, 'h': 1, 's': 1})\n",
744 "spottiest Counter({'t': 3, 's': 2, 'i': 1, 'p': 1, 'o': 1, 'e': 1})\n",
745 "stood Counter({'o': 2, 'd': 1, 't': 1, 's': 1})\n",
746 "surtaxing Counter({'i': 1, 'u': 1, 'x': 1, 'g': 1, 'a': 1, 's': 1, 'r': 1, 't': 1, 'n': 1})\n",
747 "wardrobes Counter({'r': 2, 'a': 1, 's': 1, 'd': 1, 'w': 1, 'b': 1, 'o': 1, 'e': 1})\n"
752 "makeable_words = []\n",
753 "for w in unused_words:\n",
754 " unused_word_count = collections.Counter(w)\n",
755 " if all(unused_word_count[l] <= unused_letter_count[l] for l in unused_word_count):\n",
756 " makeable_words += [w]\n",
757 " print('*', end='')\n",
758 " print(w, unused_word_count)"
763 "execution_count": 48,
774 "execution_count": 48,
776 "output_type": "execute_result"
780 "max(len(w) for w in makeable_words)"
785 "execution_count": 49,
796 "execution_count": 49,
798 "output_type": "execute_result"
802 "sorted(makeable_words, key=len)[-1]"
807 "execution_count": 74,
813 "def do_wordsearch_tasks(fn, show_anyway=False):\n",
814 " width, height, grid, words = read_wordsearch(fn)\n",
815 " used_words = [w for w in words if present(grid, w)[0]]\n",
816 " unused_words = [w for w in words if not present(grid, w)[0]]\n",
817 " lwp = sorted([w for w in words if present(grid, w)[0]], key=len)[-1]\n",
818 " lwps = [w for w in used_words if len(w) == len(lwp)]\n",
819 " lwa = sorted(unused_words, key=len)[-1]\n",
820 " lwas = [w for w in unused_words if len(w) == len(lwa)]\n",
821 " g0 = empty_grid(width, height)\n",
822 " for w in words:\n",
823 " p, r, c, d = present(grid, w)\n",
825 " set_grid(g0, r, c, d, w) \n",
826 " 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",
828 " unused_letter_count = collections.Counter(unused_letters)\n",
829 " makeable_words = []\n",
830 " for w in unused_words:\n",
831 " unused_word_count = collections.Counter(w)\n",
832 " if all(unused_word_count[l] <= unused_letter_count[l] for l in unused_word_count):\n",
833 " makeable_words += [w]\n",
834 " lwm = sorted(makeable_words, key=len)[-1]\n",
835 " lwms = [w for w in makeable_words if len(w) == len(lwm)]\n",
836 " if show_anyway or len(set((len(lwp),len(lwa),len(lwm)))) == 3:\n",
837 " print('\\n{}'.format(fn))\n",
838 " print('{} words present'.format(len(words) - len(unused_words)))\n",
839 " print('Longest word present: {}, {} letters ({})'.format(lwp, len(lwp), lwps))\n",
840 " print('Longest word absent: {}, {} letters ({})'.format(lwa, len(lwa), lwas))\n",
841 " print('{} unused letters'.format(len([c for c in cat(cat(l) for l in g0) if c == '.'])))\n",
842 " print('Longest makeable word: {}, {} ({})'.format(lwm, len(lwm), lwms))"
847 "execution_count": 75,
854 "output_type": "stream",
857 "wordsearch04.txt\n",
858 "58 words present\n",
859 "Longest word present: fortification, 13 letters (['fortification'])\n",
860 "Longest word absent: justification, 13 letters (['justification'])\n",
861 "57 unused letters\n",
862 "Longest makeable word: despairing, 10 (['despairing'])\n"
867 "do_wordsearch_tasks('wordsearch04.txt', show_anyway=True)"
872 "execution_count": 70,
879 "output_type": "stream",
882 "wordsearch08.txt\n",
883 "62 words present\n",
884 "Longest word present: compassionately, 15 letters (['compassionately'])\n",
885 "Longest word absent: retrospectives, 14 letters (['retrospectives'])\n",
886 "65 unused letters\n",
887 "Longest makeable word: vacationing, 11 (['vacationing'])\n"
892 "do_wordsearch_tasks('wordsearch08.txt')"
897 "execution_count": 76,
905 "output_type": "stream",
908 "wordsearch08.txt\n",
909 "62 words present\n",
910 "Longest word present: compassionately, 15 letters (['compassionately'])\n",
911 "Longest word absent: retrospectives, 14 letters (['retrospectives'])\n",
912 "65 unused letters\n",
913 "Longest makeable word: vacationing, 11 (['vacationing'])\n",
915 "wordsearch17.txt\n",
916 "58 words present\n",
917 "Longest word present: complementing, 13 letters (['complementing'])\n",
918 "Longest word absent: upholstering, 12 letters (['domestically', 'upholstering'])\n",
919 "56 unused letters\n",
920 "Longest makeable word: plunderer, 9 (['plunderer'])\n",
922 "wordsearch32.txt\n",
923 "60 words present\n",
924 "Longest word present: reciprocating, 13 letters (['reciprocating'])\n",
925 "Longest word absent: parenthesise, 12 letters (['collectibles', 'frontrunners', 'parenthesise'])\n",
926 "65 unused letters\n",
927 "Longest makeable word: sultanas, 8 (['sultanas'])\n",
929 "wordsearch52.txt\n",
930 "51 words present\n",
931 "Longest word present: prefabricated, 13 letters (['prefabricated'])\n",
932 "Longest word absent: catastrophic, 12 letters (['capitalistic', 'catastrophic'])\n",
933 "86 unused letters\n",
934 "Longest makeable word: unimpressed, 11 (['bloodstream', 'brainstorms', 'reassembles', 'rhapsodises', 'synergistic', 'unimpressed'])\n",
936 "wordsearch62.txt\n",
937 "58 words present\n",
938 "Longest word present: diametrically, 13 letters (['diametrically'])\n",
939 "Longest word absent: streetlights, 12 letters (['harmonically', 'skyrocketing', 'streetlights'])\n",
940 "59 unused letters\n",
941 "Longest makeable word: tabernacle, 10 (['falterings', 'tabernacle'])\n",
943 "wordsearch76.txt\n",
944 "60 words present\n",
945 "Longest word present: bloodthirstier, 14 letters (['bloodthirstier'])\n",
946 "Longest word absent: incriminating, 13 letters (['incriminating'])\n",
947 "59 unused letters\n",
948 "Longest makeable word: stubbornly, 10 (['leafletted', 'stubbornly'])\n",
950 "wordsearch94.txt\n",
951 "59 words present\n",
952 "Longest word present: unforgettable, 13 letters (['unforgettable'])\n",
953 "Longest word absent: accommodated, 12 letters (['accommodated'])\n",
954 "69 unused letters\n",
955 "Longest makeable word: respectably, 11 (['predictions', 'respectably'])\n"
960 "for fn in sorted(os.listdir()):\n",
961 " if re.match('wordsearch\\d\\d\\.txt', fn):\n",
962 " do_wordsearch_tasks(fn)"
967 "execution_count": 38,
974 "output_type": "stream",
976 "absolved (True, 16, 2, <Direction.right: 2>)\n",
977 "adorable (True, 11, 4, <Direction.right: 2>)\n",
978 "aeon (True, 11, 4, <Direction.down: 4>)\n",
979 "alias (True, 15, 15, <Direction.left: 1>)\n",
980 "ancestor (False, 0, 0, <Direction.left: 1>)\n",
981 "baritone (False, 0, 0, <Direction.left: 1>)\n",
982 "bemusing (False, 0, 0, <Direction.left: 1>)\n",
983 "blonds (False, 0, 0, <Direction.left: 1>)\n",
984 "bran (True, 1, 9, <Direction.left: 1>)\n",
985 "calcite (True, 19, 9, <Direction.upright: 6>)\n",
986 "candor (True, 17, 12, <Direction.right: 2>)\n",
987 "conciseness (False, 0, 0, <Direction.left: 1>)\n",
988 "consequent (False, 0, 0, <Direction.left: 1>)\n",
989 "cuddle (False, 0, 0, <Direction.left: 1>)\n",
990 "damming (True, 17, 2, <Direction.right: 2>)\n",
991 "dashboards (False, 0, 0, <Direction.left: 1>)\n",
992 "despairing (False, 0, 0, <Direction.left: 1>)\n",
993 "dint (False, 0, 0, <Direction.left: 1>)\n",
994 "dullard (True, 8, 2, <Direction.down: 4>)\n",
995 "dynasty (True, 3, 4, <Direction.downright: 8>)\n",
996 "employer (False, 0, 0, <Direction.left: 1>)\n",
997 "exhorts (True, 0, 8, <Direction.left: 1>)\n",
998 "feted (True, 5, 10, <Direction.right: 2>)\n",
999 "fill (True, 9, 14, <Direction.upleft: 5>)\n",
1000 "flattens (True, 10, 10, <Direction.upleft: 5>)\n",
1001 "foghorn (True, 10, 11, <Direction.downright: 8>)\n",
1002 "fortification (True, 19, 16, <Direction.left: 1>)\n",
1003 "freakish (False, 0, 0, <Direction.left: 1>)\n",
1004 "frolics (True, 16, 16, <Direction.up: 3>)\n",
1005 "gall (False, 0, 0, <Direction.left: 1>)\n",
1006 "gees (True, 17, 0, <Direction.upright: 6>)\n",
1007 "genies (True, 5, 7, <Direction.upleft: 5>)\n",
1008 "gets (True, 6, 4, <Direction.upleft: 5>)\n",
1009 "hastening (True, 14, 13, <Direction.left: 1>)\n",
1010 "hits (True, 2, 0, <Direction.down: 4>)\n",
1011 "hopelessness (False, 0, 0, <Direction.left: 1>)\n",
1012 "hurlers (True, 18, 0, <Direction.right: 2>)\n",
1013 "impales (False, 0, 0, <Direction.left: 1>)\n",
1014 "infix (False, 0, 0, <Direction.left: 1>)\n",
1015 "inflow (False, 0, 0, <Direction.left: 1>)\n",
1016 "innumerable (False, 0, 0, <Direction.left: 1>)\n",
1017 "intentional (False, 0, 0, <Direction.left: 1>)\n",
1018 "jerkin (False, 0, 0, <Direction.left: 1>)\n",
1019 "justification (False, 0, 0, <Direction.left: 1>)\n",
1020 "kitty (True, 8, 15, <Direction.upleft: 5>)\n",
1021 "knuckles (True, 17, 19, <Direction.up: 3>)\n",
1022 "leaving (False, 0, 0, <Direction.left: 1>)\n",
1023 "like (True, 3, 11, <Direction.left: 1>)\n",
1024 "limitation (True, 8, 3, <Direction.right: 2>)\n",
1025 "locoweeds (False, 0, 0, <Direction.left: 1>)\n",
1026 "loot (True, 3, 19, <Direction.up: 3>)\n",
1027 "lucking (True, 7, 10, <Direction.upleft: 5>)\n",
1028 "lumps (True, 0, 17, <Direction.down: 4>)\n",
1029 "mercerising (True, 15, 17, <Direction.up: 3>)\n",
1030 "monickers (False, 0, 0, <Direction.left: 1>)\n",
1031 "motionless (True, 13, 1, <Direction.up: 3>)\n",
1032 "naturally (True, 9, 16, <Direction.up: 3>)\n",
1033 "nighest (True, 15, 4, <Direction.right: 2>)\n",
1034 "notion (True, 17, 18, <Direction.up: 3>)\n",
1035 "ogled (True, 1, 18, <Direction.down: 4>)\n",
1036 "originality (False, 0, 0, <Direction.left: 1>)\n",
1037 "outings (False, 0, 0, <Direction.left: 1>)\n",
1038 "pendulous (False, 0, 0, <Direction.left: 1>)\n",
1039 "piled (True, 1, 10, <Direction.right: 2>)\n",
1040 "pins (True, 7, 4, <Direction.upleft: 5>)\n",
1041 "pithier (False, 0, 0, <Direction.left: 1>)\n",
1042 "prep (True, 10, 4, <Direction.right: 2>)\n",
1043 "randomness (False, 0, 0, <Direction.left: 1>)\n",
1044 "rectors (False, 0, 0, <Direction.left: 1>)\n",
1045 "redrew (False, 0, 0, <Direction.left: 1>)\n",
1046 "reformulated (False, 0, 0, <Direction.left: 1>)\n",
1047 "remoteness (False, 0, 0, <Direction.left: 1>)\n",
1048 "retaking (True, 6, 0, <Direction.down: 4>)\n",
1049 "rethink (False, 0, 0, <Direction.left: 1>)\n",
1050 "rope (True, 9, 4, <Direction.right: 2>)\n",
1051 "rubier (True, 0, 4, <Direction.downright: 8>)\n",
1052 "sailors (True, 7, 15, <Direction.up: 3>)\n",
1053 "scowls (False, 0, 0, <Direction.left: 1>)\n",
1054 "scum (True, 16, 11, <Direction.right: 2>)\n",
1055 "sepals (True, 6, 10, <Direction.upright: 6>)\n",
1056 "sequencers (False, 0, 0, <Direction.left: 1>)\n",
1057 "serf (False, 0, 0, <Direction.left: 1>)\n",
1058 "shoaled (True, 11, 18, <Direction.up: 3>)\n",
1059 "shook (False, 0, 0, <Direction.left: 1>)\n",
1060 "sonic (True, 18, 18, <Direction.left: 1>)\n",
1061 "spottiest (False, 0, 0, <Direction.left: 1>)\n",
1062 "stag (True, 7, 8, <Direction.left: 1>)\n",
1063 "stood (False, 0, 0, <Direction.left: 1>)\n",
1064 "stratum (True, 2, 13, <Direction.left: 1>)\n",
1065 "strong (True, 4, 19, <Direction.down: 4>)\n",
1066 "studying (True, 0, 16, <Direction.left: 1>)\n",
1067 "surtaxing (False, 0, 0, <Direction.left: 1>)\n",
1068 "tailing (True, 13, 6, <Direction.right: 2>)\n",
1069 "tears (True, 13, 3, <Direction.up: 3>)\n",
1070 "teazles (True, 4, 10, <Direction.downright: 8>)\n",
1071 "vans (True, 18, 8, <Direction.upright: 6>)\n",
1072 "wardrobes (False, 0, 0, <Direction.left: 1>)\n",
1073 "wooded (True, 12, 5, <Direction.right: 2>)\n",
1074 "worsts (True, 1, 0, <Direction.downright: 8>)\n",
1075 "zings (True, 10, 14, <Direction.upleft: 5>)\n"
1080 "width, height, grid, words = read_wordsearch('wordsearch04.txt')\n",
1081 "for w in words:\n",
1082 " print(w, present(grid, w))"
1086 "cell_type": "code",
1087 "execution_count": null,
1097 "display_name": "Python 3",
1098 "language": "python",
1102 "codemirror_mode": {
1106 "file_extension": ".py",
1107 "mimetype": "text/x-python",
1109 "nbconvert_exporter": "python",
1110 "pygments_lexer": "ipython3",