{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import string\n", "import re\n", "import random\n", "import collections\n", "import copy\n", "\n", "from enum import Enum\n", "Direction = Enum('Direction', 'left right up down upleft upright downleft downright')\n", " \n", "delta = {Direction.left: (0, -1),Direction.right: (0, 1), \n", " Direction.up: (-1, 0), Direction.down: (1, 0), \n", " Direction.upleft: (-1, -1), Direction.upright: (-1, 1), \n", " Direction.downleft: (1, -1), Direction.downright: (1, 1)}\n", "\n", "cat = ''.join\n", "wcat = ' '.join\n", "lcat = '\\n'.join" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# all_words = [w.strip() for w in open('/usr/share/dict/british-english').readlines()\n", "# if all(c in string.ascii_lowercase for c in w.strip())]\n", "# words = [w for w in all_words\n", "# if not any(w in w2 for w2 in all_words if w != w2)]\n", "# open('wordsearch-words', 'w').write(lcat(words))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['aardvarks',\n", " 'abaci',\n", " 'abacuses',\n", " 'abaft',\n", " 'abalones',\n", " 'abandoned',\n", " 'abandoning',\n", " 'abandonment',\n", " 'abandons',\n", " 'abased']" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ws_words = [w.strip() for w in open('wordsearch-words').readlines()\n", " if all(c in string.ascii_lowercase for c in w.strip())]\n", "ws_words[:10]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def empty_grid(w, h):\n", " return [['.' for c in range(w)] for r in range(h)]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def show_grid(grid):\n", " return lcat(cat(r) for r in grid)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "..........\n", "..........\n", "..........\n", "..........\n", "..........\n", "..........\n", "..........\n", "..........\n", "..........\n", "..........\n" ] } ], "source": [ "grid = empty_grid(10, 10)\n", "print(show_grid(grid))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def indices(grid, r, c, l, d):\n", " dr, dc = delta[d]\n", " w = len(grid[0])\n", " h = len(grid)\n", " inds = [(r + i * dr, c + i * dc) for i in range(l)]\n", " return [(i, j) for i, j in inds\n", " if i >= 0\n", " if j >= 0\n", " if i < h\n", " if j < w]" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def gslice(grid, r, c, l, d):\n", " return [grid[i][j] for i, j in indices(grid, r, c, l, d)]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def set_grid(grid, r, c, d, word):\n", " for (i, j), l in zip(indices(grid, r, c, len(word), d), word):\n", " grid[i][j] = l\n", " return grid" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "..........\n", "..........\n", "...t......\n", "....e.....\n", ".....s....\n", "......t...\n", ".......w..\n", "........o.\n", ".........r\n", "..........\n" ] } ], "source": [ "set_grid(grid, 2, 3, Direction.downright, 'testword')\n", "print(show_grid(grid))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'..e.....'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat(gslice(grid, 3, 2, 15, Direction.right))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<_sre.SRE_Match object; span=(0, 4), match='keen'>" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.match(cat(gslice(grid, 3, 2, 4, Direction.right)), 'keen')" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<_sre.SRE_Match object; span=(0, 3), match='kee'>" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.match(cat(gslice(grid, 3, 2, 3, Direction.right)), 'keen')" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [], "source": [ "re.fullmatch(cat(gslice(grid, 3, 2, 3, Direction.right)), 'keen')" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "re.match(cat(gslice(grid, 3, 2, 4, Direction.right)), 'kine')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def could_add(grid, r, c, d, word):\n", " s = gslice(grid, r, c, len(word), d)\n", " return re.fullmatch(cat(s), word)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<_sre.SRE_Match object; span=(0, 4), match='keen'>" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "could_add(grid, 3, 2, Direction.right, 'keen')" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [], "source": [ "could_add(grid, 3, 2, Direction.right, 'kine')" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "random.choice(list(Direction))" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def fill_grid(grid, words, word_count, max_attempts= 1000):\n", " attempts = 0\n", " added_words = []\n", " w = len(grid[0])\n", " h = len(grid)\n", " while len(added_words) < word_count and attempts < max_attempts:\n", " attempts += 1\n", " r = random.randrange(w)\n", " c = random.randrange(h)\n", " word = random.choice(words)\n", " d = random.choice(list(Direction))\n", " if could_add(grid, r, c, d, word):\n", " set_grid(grid, r, c, d, word)\n", " added_words += [word]\n", " attempts = 0\n", " return grid, added_words" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "35" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = empty_grid(20, 20)\n", "g, ws = fill_grid(g, ws_words, 40)\n", "len(ws)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "......swoopingg.l.up\n", "..dunsnapped.n.i..ne\n", ".cee.gninarci.m...er\n", "sotpt......k.pmv..mv\n", "euirca.d..c.n.a...pa\n", "snduo.o.eo.e.lgs..ld\n", "itndny.ctks.i.nos.oe\n", "rroev.lsrsss..ifr.ys\n", "eycno.eb.aeub.ttebas\n", "tmetyr..asgetmuemebe\n", "nerie....tvuu.dsraln\n", "in.adbdmbecls.etocei\n", "w..loeu.lilu..s.fh.d\n", "...rtl.e.ec.l...eimw\n", "..oac.d.v..y.e..rnao\n", ".nrhgniknilsc.n..gyd\n", ".pignippay...l.i..f.\n", ".n..skcenrehtael..l.\n", "g....popinjays.s..y.\n", "gnimmugspuds.relppus\n", "35 words added\n", "ineluctably limpness countrymen slinking beaching restocking vellum convoyed winterises tusked leathernecks sugarcoated mayfly mulching popinjays magnitudes unsnapped prudential yapping spuds softest boron craning unemployable reformers bicycles swooping recondite dowdiness gumming pervades beveled valises suppler prated\n" ] } ], "source": [ "print(show_grid(g))\n", "print(len(ws), 'words added')\n", "print(wcat(ws))" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def present(grid, word):\n", " w = len(grid[0])\n", " h = len(grid)\n", " for r in range(h):\n", " for c in range(w):\n", " for d in Direction:\n", " if cat(gslice(grid, r, c, len(word), d)) == word:\n", " return True, r, c, d\n", " return False, 0, 0, list(Direction)[0]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ineluctably (True, 16, 15, )\n", "limpness (True, 0, 16, )\n", "countrymen (True, 2, 1, )\n", "slinking (True, 15, 11, )\n", "beaching (True, 8, 17, )\n", "restocking (True, 9, 5, )\n", "vellum (True, 14, 8, )\n", "convoyed (True, 4, 4, )\n", "winterises (True, 12, 0, )\n", "tusked (True, 9, 12, )\n", "leathernecks (True, 17, 15, )\n", "sugarcoated (True, 11, 12, )\n", "mayfly (True, 13, 18, )\n", "mulching (True, 11, 7, )\n", "popinjays (True, 18, 5, )\n", "magnitudes (True, 3, 14, )\n", "unsnapped (True, 1, 3, )\n", "prudential (True, 3, 3, )\n", "yapping (True, 16, 9, )\n", "spuds (True, 19, 7, )\n", "softest (True, 5, 15, )\n", "boron (True, 11, 5, )\n", "craning (True, 2, 11, )\n", "unemployable (True, 0, 18, )\n", "reformers (True, 14, 16, )\n", "bicycles (True, 11, 8, )\n", "swooping (True, 0, 6, )\n", "recondite (True, 10, 2, )\n", "dowdiness (True, 15, 19, )\n", "gumming (True, 19, 6, )\n", "pervades (True, 0, 19, )\n", "beveled (True, 8, 12, )\n", "valises (True, 3, 15, )\n", "suppler (True, 19, 19, )\n", "prated (True, 16, 1, )\n" ] } ], "source": [ "for w in ws:\n", " print(w, present(g, w))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def interesting(grid, words):\n", " dirs = set(present(grid, w)[3] for w in words)\n", " return len(words) > 35 and len(words) < 40 and len(dirs) + 1 >= len(delta)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "interesting(g, ws)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def interesting_grid():\n", " boring = True\n", " while boring:\n", " grid = empty_grid(20, 20)\n", " grid, words = fill_grid(grid, ws_words, 40)\n", " boring = not interesting(grid, words)\n", " return grid, words" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "..reittonk..ss......\n", "tinctured.wcee.....w\n", "serutats.oyozm....o.\n", "b....s..l.eoia...m.r\n", "e.b.y.lf..lpsd..bgye\n", "a.ist.no..less.ssrgm\n", "m.gtfi.lo.orae.n.ura\n", "edaei..i.cwi.mo..mor\n", "demrn..b..in.m...psk\n", "epya...e..sgm....ile\n", "slsg...l..hi.....nrd\n", "tekisyassesdepeebeum\n", "rtec.gninretni...sfo\n", "oiinsetse..baggy.snd\n", "ynn....p..sebircsaui\n", "egs.noitasiretupmocf\n", "r.....artefacts....y\n", "s.....seilaog.winosi\n", ".....eyelidsegener.n\n", "regicidesesopatxuj.g\n", "38 words added; 7 directions\n", "wombs persimmons computerisation ascribes coopering goalies beamed modifying insets cigarets statures libels remarked baggy juxtaposes mesdames grumpiness artefacts skeins assizes inflow depleting beeped reneges interning yellowish regicides eyelids cools orgy nifty knottier destroyers unfurls tinctured bigamy winos essays\n" ] } ], "source": [ "g, ws = interesting_grid()\n", "print(show_grid(g))\n", "print(len(ws), 'words added; ', len(set(present(g, w)[3] for w in ws)), 'directions')\n", "print(wcat(ws))" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def datafile(name, sep='\\t'):\n", " \"\"\"Read key,value pairs from file.\n", " \"\"\"\n", " with open(name) as f:\n", " for line in f:\n", " splits = line.split(sep)\n", " yield [splits[0], int(splits[1])]" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def normalise(frequencies):\n", " \"\"\"Scale a set of frequencies so they sum to one\n", " \n", " >>> sorted(normalise({1: 1, 2: 0}).items())\n", " [(1, 1.0), (2, 0.0)]\n", " >>> sorted(normalise({1: 1, 2: 1}).items())\n", " [(1, 0.5), (2, 0.5)]\n", " >>> sorted(normalise({1: 1, 2: 1, 3: 1}).items()) # doctest: +ELLIPSIS\n", " [(1, 0.333...), (2, 0.333...), (3, 0.333...)]\n", " >>> sorted(normalise({1: 1, 2: 2, 3: 1}).items())\n", " [(1, 0.25), (2, 0.5), (3, 0.25)]\n", " \"\"\"\n", " length = sum(f for f in frequencies.values())\n", " return collections.defaultdict(int, ((k, v / length) \n", " for (k, v) in frequencies.items()))\n" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [], "source": [ "english_counts = collections.Counter(dict(datafile('count_1l.txt')))\n", "normalised_english_counts = normalise(english_counts)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [], "source": [ "wordsearch_counts = collections.Counter(cat(ws_words))\n", "normalised_wordsearch_counts = normalise(wordsearch_counts)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def weighted_choice(d):\n", " \"\"\"Generate random item from a dictionary of item counts\n", " \"\"\"\n", " target = random.uniform(0, sum(d.values()))\n", " cuml = 0.0\n", " for (l, p) in d.items():\n", " cuml += p\n", " if cuml > target:\n", " return l\n", " return None\n", "\n", "def random_english_letter():\n", " \"\"\"Generate a random letter based on English letter counts\n", " \"\"\"\n", " return weighted_choice(normalised_english_counts)\n", "\n", "def random_wordsearch_letter():\n", " \"\"\"Generate a random letter based on wordsearch letter counts\n", " \"\"\"\n", " return weighted_choice(normalised_wordsearch_counts)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'aaaaaaaabcccddddeeeeeeeeeeeeeeefffggghhhhhiiiiiillllmnnnnnnoooooooooprrsssssssssssssttttttttuuuvwwwy'" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat(sorted(random_english_letter() for i in range(100)))" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'aaaaaabcccddddddeeeeeeggggghhiiiiiiiiiiiiklllmmmmnnnnnnnnnnoooooooooppprrrrrrrrrssssssttttttuuuwwwyy'" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat(sorted(random_wordsearch_letter() for i in range(100)))" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'a'" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "random_wordsearch_letter()" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def pad_grid(g0):\n", " grid = copy.deepcopy(g0)\n", " w = len(grid[0])\n", " h = len(grid)\n", " for r in range(h):\n", " for c in range(w):\n", " if grid[r][c] == '.':\n", " grid[r][c] = random_wordsearch_letter()\n", " return grid" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "streittonkorsssatnal\n", "tincturedswceedrlnuw\n", "serutatsloyozmeieiot\n", "baanfsollleoiasnlmar\n", "ewblyhlfetlpsdyvbgye\n", "aeistonoeilessassrgm\n", "mlgtfitloioraeenwura\n", "edaeiupiscwiamoygmor\n", "demrnasbhcinsmiiapsk\n", "epyakraedrsgmolsnile\n", "slsgtuoloihireneonrd\n", "tekisyassesdepeebeum\n", "rtecigninretnincesfo\n", "oiinsetseddbaggydsnd\n", "ynnnsfapcfsebircsaui\n", "egsonoitasiretupmocf\n", "raioelartefactseawfy\n", "speonsseilaogrwinosi\n", "wrndfeyelidsegenerln\n", "regicidesesopatxujrg\n" ] } ], "source": [ "padded = pad_grid(g)\n", "print(show_grid(padded))" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "..reittonk..ss......\n", "tinctured.wcee.....w\n", "serutats.oyozm....o.\n", "b....s..l.eoia...m.r\n", "e.b.y.lf..lpsd..bgye\n", "a.ist.no..less.ssrgm\n", "m.gtfi.lo.orae.n.ura\n", "edaei..i.cwi.mo..mor\n", "demrn..b..in.m...psk\n", "epya...e..sgm....ile\n", "slsg...l..hi.....nrd\n", "tekisyassesdepeebeum\n", "rtec.gninretni...sfo\n", "oiinsetse..baggy.snd\n", "ynn....p..sebircsaui\n", "egs.noitasiretupmocf\n", "r.....artefacts....y\n", "s.....seilaog.winosi\n", ".....eyelidsegener.n\n", "regicidesesopatxuj.g\n" ] } ], "source": [ "print(show_grid(g))" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "wombs (True, 1, 19, )\n", "persimmons (True, 14, 7, )\n", "computerisation (True, 15, 18, )\n", "ascribes (True, 14, 17, )\n", "coopering (True, 1, 11, )\n", "goalies (True, 17, 12, )\n", "beamed (True, 3, 0, )\n", "modifying (True, 11, 19, )\n", "insets (True, 13, 2, )\n", "cigarets (True, 12, 3, )\n", "statures (True, 2, 7, )\n", "libels (True, 6, 7, )\n", "remarked (True, 3, 19, )\n", "baggy (True, 13, 11, )\n", "juxtaposes (True, 19, 17, )\n", "mesdames (True, 7, 13, )\n", "grumpiness (True, 4, 17, )\n", "artefacts (True, 16, 6, )\n", "skeins (True, 10, 2, )\n", "assizes (True, 6, 12, )\n", "inflow (True, 6, 5, )\n", "depleting (True, 7, 1, )\n", "beeped (True, 11, 16, )\n", "reneges (True, 18, 17, )\n", "interning (True, 12, 13, )\n", "yellowish (True, 2, 10, )\n", "regicides (True, 19, 0, )\n", "eyelids (True, 18, 5, )\n", "cools (True, 7, 9, )\n", "orgy (True, 7, 18, )\n", "nifty (True, 8, 4, )\n", "knottier (True, 0, 9, )\n", "destroyers (True, 8, 0, )\n", "unfurls (True, 14, 18, )\n", "tinctured (True, 1, 0, )\n", "bigamy (True, 4, 2, )\n", "winos (True, 17, 14, )\n", "essays (True, 11, 9, )\n" ] } ], "source": [ "for w in ws:\n", " print(w, present(padded, w))" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def decoys(grid, words, all_words, limit=60):\n", " decoy_words = []\n", " while len(words) + len(decoy_words) < limit:\n", " d = random.choice(all_words)\n", " if d not in words and not present(grid, d)[0]:\n", " decoy_words += [d]\n", " return decoy_words" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['blindfolding',\n", " 'televised',\n", " 'climaxed',\n", " 'autumns',\n", " 'aquaria',\n", " 'bilks',\n", " 'psychologies',\n", " 'sparkled',\n", " 'dorkiest',\n", " 'corollas',\n", " 'polygons',\n", " 'accessioning',\n", " 'bubbled',\n", " 'astringency',\n", " 'debunking',\n", " 'cannery',\n", " 'exhilarates',\n", " 'overzealous',\n", " 'primping',\n", " 'geckos',\n", " 'admiration',\n", " 'misconstructions']" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds = decoys(padded, ws, ws_words)\n", "ds" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "wombs (True, 1, 19, )\n", "persimmons (True, 14, 7, )\n", "computerisation (True, 15, 18, )\n", "ascribes (True, 14, 17, )\n", "coopering (True, 1, 11, )\n", "goalies (True, 17, 12, )\n", "beamed (True, 3, 0, )\n", "modifying (True, 11, 19, )\n", "insets (True, 13, 2, )\n", "cigarets (True, 12, 3, )\n", "statures (True, 2, 7, )\n", "libels (True, 6, 7, )\n", "remarked (True, 3, 19, )\n", "baggy (True, 13, 11, )\n", "juxtaposes (True, 19, 17, )\n", "mesdames (True, 7, 13, )\n", "grumpiness (True, 4, 17, )\n", "artefacts (True, 16, 6, )\n", "skeins (True, 10, 2, )\n", "assizes (True, 6, 12, )\n", "inflow (True, 6, 5, )\n", "depleting (True, 7, 1, )\n", "beeped (True, 11, 16, )\n", "reneges (True, 18, 17, )\n", "interning (True, 12, 13, )\n", "yellowish (True, 2, 10, )\n", "regicides (True, 19, 0, )\n", "eyelids (True, 18, 5, )\n", "cools (True, 7, 9, )\n", "orgy (True, 7, 18, )\n", "nifty (True, 8, 4, )\n", "knottier (True, 0, 9, )\n", "destroyers (True, 8, 0, )\n", "unfurls (True, 14, 18, )\n", "tinctured (True, 1, 0, )\n", "bigamy (True, 4, 2, )\n", "winos (True, 17, 14, )\n", "essays (True, 11, 9, )\n", "blindfolding (False, 0, 0, )\n", "televised (False, 0, 0, )\n", "climaxed (False, 0, 0, )\n", "autumns (False, 0, 0, )\n", "aquaria (False, 0, 0, )\n", "bilks (False, 0, 0, )\n", "psychologies (False, 0, 0, )\n", "sparkled (False, 0, 0, )\n", "dorkiest (False, 0, 0, )\n", "corollas (False, 0, 0, )\n", "polygons (False, 0, 0, )\n", "accessioning (False, 0, 0, )\n", "bubbled (False, 0, 0, )\n", "astringency (False, 0, 0, )\n", "debunking (False, 0, 0, )\n", "cannery (False, 0, 0, )\n", "exhilarates (False, 0, 0, )\n", "overzealous (False, 0, 0, )\n", "primping (False, 0, 0, )\n", "geckos (False, 0, 0, )\n", "admiration (False, 0, 0, )\n", "misconstructions (False, 0, 0, )\n" ] } ], "source": [ "for w in ws + ds:\n", " print(w, present(padded, w))" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tuiababblerssknalbft\n", "gnewerodeswskrowerif\n", "nballooningosfriedum\n", "iuebksidesaddlessldt\n", "mrncdbmnnyllasuaceet\n", "udiesnettirwtsohglli\n", "uepoeyremeenoyreveum\n", "cnuselitnegfatterbdp\n", "asslmulleveiadieneer\n", "visnmewsrelrsbtleddi\n", "crouchinghogetrzooms\n", "dstrihstaewseteaotoo\n", "vkssrdovulatesrldgon\n", "snnvengefullyuiawets\n", "uiofendelleuferrcosi\n", "ahsdenoixelpmocluitt\n", "vcdauthorisesnfsnenp\n", "eyoelmferociouslypng\n", "lngimmpauperisedtnon\n", "ytnthstnemecitnehhpc\n", "38 words added; 7 directions\n", "Present: abrades authorises babblers ballooning blanks causally chinks complexioned crouching deluded emery enticements erodes everyone fatter ferociously fireworks fried gentiles ghostwritten godsons imprisons mews ovulates owlets pauperised refuelled retracing sidesaddles suavely supine sweatshirts unburdens vacuuming vellum vengefully yeti zooms\n", "Decoys: chastened doodling ethnologists executrixes freelancing generously halfheartedness harries kinswoman mangles narrowly optimising oversimplifies polystyrene recounts riffing slicking smackers squashy thirsting tiebreakers unexampled\n" ] } ], "source": [ "g, ws = interesting_grid()\n", "p = pad_grid(g)\n", "ds = decoys(p, ws, ws_words)\n", "print(show_grid(p))\n", "print(len(ws), 'words added; ', len(set(present(g, w)[3] for w in ws)), 'directions')\n", "print('Present:', wcat(sorted(ws)))\n", "print('Decoys:', wcat(sorted(ds)))" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "11\n", "12\n", "13\n", "14\n", "15\n", "16\n", "17\n", "18\n", "19\n" ] } ], "source": [ "for i in range(20):\n", " print(i)\n", " g, ws = interesting_grid()\n", " p = pad_grid(g)\n", " ds = decoys(p, ws, ws_words)\n", " with open('wordsearch{:02}.txt'.format(i), 'w') as f:\n", " f.write('20x20\\n')\n", " f.write(show_grid(p))\n", " f.write('\\n')\n", " f.write(lcat(sorted(ws + ds)))\n", " with open('wordsearch-solution{:02}.txt'.format(i), 'w') as f:\n", " f.write('20x20\\n')\n", " f.write(show_grid(g))\n", " f.write('\\n')\n", " f.write(lcat(sorted(ws)) + '\\n\\n')\n", " f.write(lcat(sorted(ds)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2+" } }, "nbformat": 4, "nbformat_minor": 0 }