{ "cells": [ { "cell_type": "code", "execution_count": 65, "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": 66, "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": 67, "metadata": { "collapsed": false }, "outputs": [], "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": 68, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ws_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())]" ] }, { "cell_type": "code", "execution_count": 69, "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": 70, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def show_grid(grid):\n", " return lcat(cat(r) for r in grid)" ] }, { "cell_type": "code", "execution_count": 71, "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": 72, "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": 73, "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": 74, "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": 75, "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": 76, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'..e.....'" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat(gslice(grid, 3, 2, 15, Direction.right))" ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<_sre.SRE_Match object; span=(0, 4), match='keen'>" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.match(cat(gslice(grid, 3, 2, 4, Direction.right)), 'keen')" ] }, { "cell_type": "code", "execution_count": 78, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<_sre.SRE_Match object; span=(0, 3), match='kee'>" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "re.match(cat(gslice(grid, 3, 2, 3, Direction.right)), 'keen')" ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "collapsed": false }, "outputs": [], "source": [ "re.fullmatch(cat(gslice(grid, 3, 2, 3, Direction.right)), 'keen')" ] }, { "cell_type": "code", "execution_count": 80, "metadata": { "collapsed": true }, "outputs": [], "source": [ "re.match(cat(gslice(grid, 3, 2, 4, Direction.right)), 'kine')" ] }, { "cell_type": "code", "execution_count": 81, "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": 82, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "<_sre.SRE_Match object; span=(0, 4), match='keen'>" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "could_add(grid, 3, 2, Direction.right, 'keen')" ] }, { "cell_type": "code", "execution_count": 83, "metadata": { "collapsed": false }, "outputs": [], "source": [ "could_add(grid, 3, 2, Direction.right, 'kine')" ] }, { "cell_type": "code", "execution_count": 84, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "random.choice(list(Direction))" ] }, { "cell_type": "code", "execution_count": 129, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def fill_grid(grid, words, word_count, max_attempts=10000):\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 len(word) >=4 and not any(word in w2 for w2 in added_words) and 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": 86, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "40" ] }, "execution_count": 86, "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": 87, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "l.fiestasrsnorffas..\n", "a....s..e.a.cawing..\n", "c..gt.dv.re.strongly\n", "i..n..aecmbp....y...\n", "m.eo.uthzoa.of..l.s.\n", "od.lq.esozslhhlyo.k.\n", "ns.e.r.se.ureanoh.r.\n", "o.wby.t.aw.foin.u.u.\n", "ca.o....i.a.to.d.rms\n", "en..l...lerrs.d.i.sk\n", "no...l..i.snalgarn.n\n", "un....a.crappiest.gi\n", ".y.....mdepraved..dw\n", ".mgniggolricochet.ey\n", ".o..pensivelyibmozil\n", ".u.......curd.....fd\n", ".sseitudlevehsid..id\n", "...litchis..romut.ri\n", ".understands......et\n", "....nagilooh......v.\n", "40 words added\n", "understands crappiest archery mallows depraved cawing rawest curd tiny tiddlywinks fiestas zombi duties ricochet uneconomical hope litchis strongly verified logging handing anonymous quaver flours boost holy saffrons errs hooligan male belong tumor dishevel fuzzed raglans pensively murks dents cilia doors\n" ] } ], "source": [ "print(show_grid(g))\n", "print(len(ws), 'words added')\n", "print(wcat(ws))" ] }, { "cell_type": "code", "execution_count": 88, "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": 89, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "understands (True, 18, 1, )\n", "crappiest (True, 11, 8, )\n", "archery (True, 1, 10, )\n", "mallows (True, 12, 7, )\n", "depraved (True, 12, 8, )\n", "cawing (True, 1, 12, )\n", "rawest (True, 9, 11, )\n", "curd (True, 15, 9, )\n", "tiny (True, 8, 12, )\n", "tiddlywinks (True, 18, 19, )\n", "fiestas (True, 0, 2, )\n", "zombi (True, 14, 17, )\n", "duties (True, 16, 7, )\n", "ricochet (True, 13, 9, )\n", "uneconomical (True, 11, 0, )\n", "hope (True, 5, 13, )\n", "litchis (True, 17, 3, )\n", "strongly (True, 2, 12, )\n", "verified (True, 19, 18, )\n", "logging (True, 13, 8, )\n", "handing (True, 5, 12, )\n", "anonymous (True, 8, 1, )\n", "quaver (True, 5, 4, )\n", "flours (True, 4, 13, )\n", "boost (True, 3, 10, )\n", "holy (True, 6, 16, )\n", "saffrons (True, 0, 17, )\n", "errs (True, 9, 9, )\n", "hooligan (True, 19, 11, )\n", "male (True, 3, 9, )\n", "belong (True, 7, 3, )\n", "tumor (True, 17, 16, )\n", "dishevel (True, 16, 15, )\n", "fuzzed (True, 7, 11, )\n", "raglans (True, 10, 16, )\n", "pensively (True, 14, 4, )\n", "murks (True, 8, 18, )\n", "dents (True, 5, 1, )\n", "cilia (True, 11, 8, )\n", "doors (True, 9, 14, )\n" ] } ], "source": [ "for w in ws:\n", " print(w, present(g, w))" ] }, { "cell_type": "code", "execution_count": 125, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def interesting(grid, words):\n", " dirs = set(present(grid, w)[3] for w in words)\n", " return len(words) > 40 and len(dirs) + 1 >= len(delta)" ] }, { "cell_type": "code", "execution_count": 126, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 126, "metadata": {}, "output_type": "execute_result" } ], "source": [ "interesting(g, ws)" ] }, { "cell_type": "code", "execution_count": 131, "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, 80)\n", " boring = not interesting(grid, words)\n", " return grid, words" ] }, { "cell_type": "code", "execution_count": 132, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "....gnixof...keem...\n", "feihc.spollawvase..s\n", "p.h.shs..snetsafnun.\n", "aeiy.adt..plehdowned\n", "rmcfmzhennaturali.h.\n", "abkake.pteebyelawsay\n", "dlcweln.lnmvrdrawllr\n", "ealnes.s.aeeieslaroe\n", ".zaelreffidclwl...gs\n", ".omtisadeelbst.bg.ei\n", ".noantr...tunet.o.nm\n", "serigamchamoixbemnsb\n", "sd.tnuu..lleterls..e\n", "e.dounf..dekcalsu..s\n", "gyegtcfknobetatser.t\n", "rlkeshskcelf..ploptr\n", "alon.l..sriahdawnsgi\n", "lac..y..gnittilps.od\n", ".eyeball..denedragse\n", ".r..ygnamsecstirg.hs\n", "57 words added; 7 directions\n", "chamoix staunchly keeling wive inns restate settlements byelaws blurt help foxing flecks orals differ unfastens mangy hymens wallops negotiate bestrides largess dawns nobler chief eyeball splitting bleed halogens clamor parade emblazoned hairs meek earmuff slacked retell scented gardened natural grits misery drawl gosh smog stung coked knob tune really secs plop alphas vase downed hazels hick fawn\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": 94, "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": 95, "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": 96, "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": 97, "metadata": { "collapsed": false }, "outputs": [], "source": [ "wordsearch_counts = collections.Counter(cat(ws_words))\n", "normalised_wordsearch_counts = normalise(wordsearch_counts)" ] }, { "cell_type": "code", "execution_count": 118, "metadata": { "collapsed": false }, "outputs": [], "source": [ "normalised_wordsearch_counts = normalise(collections.Counter(normalised_wordsearch_counts) + collections.Counter({l: 0.05 for l in string.ascii_lowercase}))" ] }, { "cell_type": "code", "execution_count": 98, "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": 99, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'aaaaaaaaaabcdddeeeeeeeeeeeefffffgghhhhhhhhhiiiiiiikllmnnnnnnnooooooooprrrrssssssssssssttttttuuvwwwww'" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat(sorted(random_english_letter() for i in range(100)))" ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'aaaaaaccccdddeeeeeeeeeeeeeeeeeeeffgghhiiiiikkklllmmmnnnnnnooooooppprrrrrrrrssssssssttttttuuuuuuvwyyy'" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat(sorted(random_wordsearch_letter() for i in range(100)))" ] }, { "cell_type": "code", "execution_count": 101, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'e'" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "random_wordsearch_letter()" ] }, { "cell_type": "code", "execution_count": 102, "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": 103, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nwtautoimmuneeyinsdl\n", "majorlyerasescmcider\n", "edthrallednxlcawoeaa\n", "gnizeensbnahwwgpsksr\n", "rmisrksiosgiitndtaep\n", "rioigoeopeglbnegsesu\n", "esurnrbdifecihtniust\n", "eeauuieimddlgiiigqan\n", "srcplooscrlufestosve\n", "pdcasmhemaonrgialcel\n", "lguvrepkcrekennronru\n", "ensesmtiesrtiogocwcr\n", "niadpnetulasgpdfeesi\n", "dgthgreoonavhsorinyv\n", "inilpehmnrnntuaeeoae\n", "dioesnmnocstennpolcm\n", "etniwvredwtidnmfdshm\n", "sgsoaarunyyoslurstts\n", "tetoyisimdmaderetlaf\n", "ettflightasnlclquasi\n" ] } ], "source": [ "padded = pad_grid(g)\n", "print(show_grid(padded))" ] }, { "cell_type": "code", "execution_count": 104, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "...autoimmune.......\n", "majorlyerases.m..d..\n", "..thralledn...a..e..\n", "gnizeens..a..wg.sk..\n", ".m.s..si..g.i.ndtae.\n", ".i.ig.eo..gl..egses.\n", ".s.rnrbd..ec.htniust\n", ".eauuiei.ddlg.iigqan\n", "srcploos..lufestosve\n", "p.casmhe.aonrgial.el\n", "lguv.ep.crekennro.ru\n", "ense.m.i.s..iogoc.cr\n", "niad.netulasgp.fee.i\n", "dgt..reo....hs.r.nyv\n", "ini..ehm....t.ae.oa.\n", "dio..nm.o...en.p.lc.\n", "etn.w..e.w..d.....h.\n", "s.so....n.yoslurs.t.\n", "t.t......dmaderetlaf\n", "...flight.s.l..quasi\n" ] } ], "source": [ "print(show_grid(g))" ] }, { "cell_type": "code", "execution_count": 105, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "thralled (True, 2, 2, )\n", "slung (True, 9, 4, )\n", "freighted (True, 8, 12, )\n", "townhouse (True, 18, 2, )\n", "salute (True, 12, 11, )\n", "phoebes (True, 10, 6, )\n", "faltered (True, 18, 19, )\n", "laywomen (True, 19, 12, )\n", "squeaked (True, 8, 17, )\n", "perforating (True, 15, 15, )\n", "iodise (True, 4, 7, )\n", "lacier (True, 8, 10, )\n", "autoimmune (True, 0, 3, )\n", "tinging (True, 16, 1, )\n", "snagged (True, 1, 10, )\n", "splendidest (True, 8, 0, )\n", "roughed (True, 10, 9, )\n", "crevasse (True, 11, 18, )\n", "lone (True, 15, 17, )\n", "ecologists (True, 12, 16, )\n", "sponge (True, 13, 13, )\n", "magnetising (True, 1, 14, )\n", "sneezing (True, 3, 7, )\n", "virulent (True, 13, 19, )\n", "flight (True, 19, 3, )\n", "sirup (True, 4, 3, )\n", "yacht (True, 13, 18, )\n", "random (True, 13, 15, )\n", "accusations (True, 7, 2, )\n", "wiled (True, 3, 13, )\n", "paved (True, 8, 3, )\n", "majorly (True, 1, 0, )\n", "miser (True, 4, 1, )\n", "memoir (True, 11, 5, )\n", "emends (True, 14, 5, )\n", "slurs (True, 17, 12, )\n", "clunk (True, 6, 11, )\n", "erases (True, 1, 7, )\n", "quasi (True, 19, 15, )\n" ] } ], "source": [ "for w in ws:\n", " print(w, present(padded, w))" ] }, { "cell_type": "code", "execution_count": 141, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def decoys(grid, words, all_words, limit=100):\n", " decoy_words = []\n", " dlen_limit = max(len(w) for w in words)\n", " while len(words) + len(decoy_words) < limit:\n", " d = random.choice(all_words)\n", " if d not in words and len(d) >= 4 and len(d) <= dlen_limit and not present(grid, d)[0]:\n", " decoy_words += [d]\n", " return decoy_words" ] }, { "cell_type": "code", "execution_count": 135, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['incisor',\n", " 'steeled',\n", " 'immobility',\n", " 'undertakings',\n", " 'exhorts',\n", " 'hairnet',\n", " 'placarded',\n", " 'sackful',\n", " 'covenanting',\n", " 'invoking',\n", " 'deltas',\n", " 'nonplus',\n", " 'exactest',\n", " 'eggs',\n", " 'tercentenary',\n", " 'angelic',\n", " 'relearning',\n", " 'ardors',\n", " 'imprints',\n", " 'chamoix',\n", " 'governance',\n", " 'rampart',\n", " 'estuary',\n", " 'poltroons',\n", " 'expect',\n", " 'restaurant',\n", " 'ashrams',\n", " 'illuminates',\n", " 'reprises',\n", " 'seismology',\n", " 'announce',\n", " 'tomorrows',\n", " 'carcinogenics',\n", " 'duplex',\n", " 'transmitters',\n", " 'prosier',\n", " 'anther',\n", " 'masticates',\n", " 'raunchy',\n", " 'briefs',\n", " 'poniard',\n", " 'daunted',\n", " 'topmasts',\n", " 'mynas']" ] }, "execution_count": 135, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds = decoys(padded, ws, ws_words)\n", "ds" ] }, { "cell_type": "code", "execution_count": 108, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "thralled (True, 2, 2, )\n", "slung (True, 9, 4, )\n", "freighted (True, 8, 12, )\n", "townhouse (True, 18, 2, )\n", "salute (True, 12, 11, )\n", "phoebes (True, 10, 6, )\n", "faltered (True, 18, 19, )\n", "laywomen (True, 19, 12, )\n", "squeaked (True, 8, 17, )\n", "perforating (True, 15, 15, )\n", "iodise (True, 4, 7, )\n", "lacier (True, 8, 10, )\n", "autoimmune (True, 0, 3, )\n", "tinging (True, 16, 1, )\n", "snagged (True, 1, 10, )\n", "splendidest (True, 8, 0, )\n", "roughed (True, 10, 9, )\n", "crevasse (True, 11, 18, )\n", "lone (True, 15, 17, )\n", "ecologists (True, 12, 16, )\n", "sponge (True, 13, 13, )\n", "magnetising (True, 1, 14, )\n", "sneezing (True, 3, 7, )\n", "virulent (True, 13, 19, )\n", "flight (True, 19, 3, )\n", "sirup (True, 4, 3, )\n", "yacht (True, 13, 18, )\n", "random (True, 13, 15, )\n", "accusations (True, 7, 2, )\n", "wiled (True, 3, 13, )\n", "paved (True, 8, 3, )\n", "majorly (True, 1, 0, )\n", "miser (True, 4, 1, )\n", "memoir (True, 11, 5, )\n", "emends (True, 14, 5, )\n", "slurs (True, 17, 12, )\n", "clunk (True, 6, 11, )\n", "erases (True, 1, 7, )\n", "quasi (True, 19, 15, )\n", "leakiest (False, 0, 0, )\n", "lumpiest (False, 0, 0, )\n", "bastion (False, 0, 0, )\n", "steamier (False, 0, 0, )\n", "elegant (False, 0, 0, )\n", "slogging (False, 0, 0, )\n", "rejects (False, 0, 0, )\n", "gaze (False, 0, 0, )\n", "swopping (False, 0, 0, )\n", "resonances (False, 0, 0, )\n", "treasonous (False, 0, 0, )\n", "corm (False, 0, 0, )\n", "abuses (False, 0, 0, )\n", "toga (False, 0, 0, )\n", "upcountry (False, 0, 0, )\n", "scrawled (False, 0, 0, )\n", "cellar (False, 0, 0, )\n", "skinflint (False, 0, 0, )\n", "wasteland (False, 0, 0, )\n", "madman (False, 0, 0, )\n", "lash (False, 0, 0, )\n" ] } ], "source": [ "for w in ws + ds:\n", " print(w, present(padded, w))" ] }, { "cell_type": "code", "execution_count": 142, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ".strigger.essegassum\n", "acselacs.tapri..pgcr\n", "moeclienterr.em.uaie\n", "apisearsclmo.kvpmntp\n", "lebpg..ohlucfaeaespe\n", "ifbi.ev.aafeesr.urol\n", "riae.el.iwfse.o.oqss\n", "evcsr...n..sd.dv..r.\n", "pestdewels..e.aw.ut.\n", "mrlimmersionrl.ob.e.\n", "iyllatnemadnufwls.nl\n", "..sdboomovulesivl.ri\n", ".eiepsreggij.tdeljif\n", "dkwn.atread..oereiat\n", "uais..efile..pnihlhi\n", "rhkripelyt.illsnst.n\n", "iweekendunotablete.g\n", "nfondlyrytsenohsuo..\n", "g.mriffa....naysnp..\n", ".meatspoodle.within.\n", "cstriggerpessegassum\n", "acselacsytapriijpgcr\n", "moeclienterrtemnuaie\n", "apisearsclmookvpmntp\n", "lebpgatohlucfaeaespe\n", "ifbisevxaafeesrlurol\n", "riaehelciwfseioioqss\n", "evcsrkuynpasdfdvetrq\n", "pestdewelsniegawkutd\n", "mrlimmersionrloobuel\n", "iyllatnemadnufwlsanl\n", "dwsdboomovulesivlyri\n", "oeiepsreggijntdeljif\n", "dkwnkatreadvnoereiat\n", "uaiscuefilehapnihlhi\n", "rhkripelytqillsnsten\n", "iweekendunotabletetg\n", "nfondlyrytsenohsuocc\n", "gemriffanternaysnpef\n", "bmeatspoodleswithing\n", "62 words added; 8 directions\n", "Present: adore affirm ages boom burs chain client dens during earmuff feeder file fiver fondly fundamentally hairnet hake honesty ills immersion imperil jiggers jilt kiwis lama leap legs lifting meat muss nays notable nutshells optic oval overtly ovule pies poet poodle process quavers repels ripely sake scabbiest scale scope sears simpers slewed snag spume stop tread trigger turfs wallet weekend widen within wolverines\n", "Decoys: chitchats colloquium conveyances convulsively debates dieting dudes dumpster dwarfed experienced feasibility festooning groupie grunted highfalutin humanise incubuses infiltrate ingratiated jotting linearly lotus masculines meanders nucleuses plunks ponderously prerecording riskiest scavenging splashier sportsmanship strawberry twirler unjustified wariness wavy yeast\n" ] } ], "source": [ "g, ws = interesting_grid()\n", "p = pad_grid(g)\n", "ds = decoys(p, ws, ws_words)\n", "print(show_grid(g))\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": 143, "metadata": { "collapsed": false, "scrolled": true }, "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", "20\n", "21\n", "22\n", "23\n", "24\n", "25\n", "26\n", "27\n", "28\n", "29\n", "30\n", "31\n", "32\n", "33\n", "34\n", "35\n", "36\n", "37\n", "38\n", "39\n", "40\n", "41\n", "42\n", "43\n", "44\n", "45\n", "46\n", "47\n", "48\n", "49\n", "50\n", "51\n", "52\n", "53\n", "54\n", "55\n", "56\n", "57\n", "58\n", "59\n", "60\n", "61\n", "62\n", "63\n", "64\n", "65\n", "66\n", "67\n", "68\n", "69\n", "70\n", "71\n", "72\n", "73\n", "74\n", "75\n", "76\n", "77\n", "78\n", "79\n", "80\n", "81\n", "82\n", "83\n", "84\n", "85\n", "86\n", "87\n", "88\n", "89\n", "90\n", "91\n", "92\n", "93\n", "94\n", "95\n", "96\n", "97\n", "98\n", "99\n" ] } ], "source": [ "for i in range(100):\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 }