More and better puzzles
[ou-summer-of-code-2017.git] / wordsearch / wordsearch-creation.ipynb
index c4ca081eb93d2397cdec1ddc2f804ca3a87882fe..4a70378e75b18d46cd20917c299d5500bd1e762e 100644 (file)
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 65,
    "metadata": {
     "collapsed": false
    },
@@ -29,7 +29,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 66,
    "metadata": {
     "collapsed": false
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 67,
    "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"
-    }
-   ],
+   "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('wordsearch-words').readlines()\n",
-    "            if all(c in string.ascii_lowercase for c in w.strip())]\n",
-    "ws_words[:10]"
+    "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": 5,
+   "execution_count": 69,
    "metadata": {
     "collapsed": true
    },
@@ -89,7 +81,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 70,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 71,
    "metadata": {
     "collapsed": false
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 72,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 73,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 74,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 75,
    "metadata": {
     "collapsed": false
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 76,
    "metadata": {
     "collapsed": false
    },
        "'..e.....'"
       ]
      },
-     "execution_count": 12,
+     "execution_count": 76,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 77,
    "metadata": {
     "collapsed": false
    },
        "<_sre.SRE_Match object; span=(0, 4), match='keen'>"
       ]
      },
-     "execution_count": 13,
+     "execution_count": 77,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 78,
    "metadata": {
     "collapsed": false
    },
        "<_sre.SRE_Match object; span=(0, 3), match='kee'>"
       ]
      },
-     "execution_count": 14,
+     "execution_count": 78,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 79,
    "metadata": {
     "collapsed": false
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 80,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 81,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 82,
    "metadata": {
     "collapsed": false
    },
        "<_sre.SRE_Match object; span=(0, 4), match='keen'>"
       ]
      },
-     "execution_count": 18,
+     "execution_count": 82,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 83,
    "metadata": {
     "collapsed": false
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 84,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "<Direction.up: 3>"
+       "<Direction.downleft: 7>"
       ]
      },
-     "execution_count": 20,
+     "execution_count": 84,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 129,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
-    "def fill_grid(grid, words, word_count, max_attempts= 1000):\n",
+    "def fill_grid(grid, words, word_count, max_attempts=10000):\n",
     "    attempts = 0\n",
     "    added_words = []\n",
     "    w = len(grid[0])\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",
+    "        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",
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 86,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "35"
+       "40"
       ]
      },
-     "execution_count": 22,
+     "execution_count": 86,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 87,
    "metadata": {
     "collapsed": false
    },
      "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"
+      "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"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 88,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 89,
    "metadata": {
     "collapsed": false,
     "scrolled": true
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "ineluctably (True, 16, 15, <Direction.upleft: 5>)\n",
-      "limpness (True, 0, 16, <Direction.downleft: 7>)\n",
-      "countrymen (True, 2, 1, <Direction.down: 4>)\n",
-      "slinking (True, 15, 11, <Direction.left: 1>)\n",
-      "beaching (True, 8, 17, <Direction.down: 4>)\n",
-      "restocking (True, 9, 5, <Direction.upright: 6>)\n",
-      "vellum (True, 14, 8, <Direction.upright: 6>)\n",
-      "convoyed (True, 4, 4, <Direction.down: 4>)\n",
-      "winterises (True, 12, 0, <Direction.up: 3>)\n",
-      "tusked (True, 9, 12, <Direction.upleft: 5>)\n",
-      "leathernecks (True, 17, 15, <Direction.left: 1>)\n",
-      "sugarcoated (True, 11, 12, <Direction.upleft: 5>)\n",
-      "mayfly (True, 13, 18, <Direction.down: 4>)\n",
-      "mulching (True, 11, 7, <Direction.downleft: 7>)\n",
-      "popinjays (True, 18, 5, <Direction.right: 2>)\n",
-      "magnitudes (True, 3, 14, <Direction.down: 4>)\n",
-      "unsnapped (True, 1, 3, <Direction.right: 2>)\n",
-      "prudential (True, 3, 3, <Direction.down: 4>)\n",
-      "yapping (True, 16, 9, <Direction.left: 1>)\n",
-      "spuds (True, 19, 7, <Direction.right: 2>)\n",
-      "softest (True, 5, 15, <Direction.down: 4>)\n",
-      "boron (True, 11, 5, <Direction.downleft: 7>)\n",
-      "craning (True, 2, 11, <Direction.left: 1>)\n",
-      "unemployable (True, 0, 18, <Direction.down: 4>)\n",
-      "reformers (True, 14, 16, <Direction.up: 3>)\n",
-      "bicycles (True, 11, 8, <Direction.downright: 8>)\n",
-      "swooping (True, 0, 6, <Direction.right: 2>)\n",
-      "recondite (True, 10, 2, <Direction.up: 3>)\n",
-      "dowdiness (True, 15, 19, <Direction.up: 3>)\n",
-      "gumming (True, 19, 6, <Direction.left: 1>)\n",
-      "pervades (True, 0, 19, <Direction.down: 4>)\n",
-      "beveled (True, 8, 12, <Direction.downleft: 7>)\n",
-      "valises (True, 3, 15, <Direction.downleft: 7>)\n",
-      "suppler (True, 19, 19, <Direction.left: 1>)\n",
-      "prated (True, 16, 1, <Direction.upright: 6>)\n"
+      "understands (True, 18, 1, <Direction.right: 2>)\n",
+      "crappiest (True, 11, 8, <Direction.right: 2>)\n",
+      "archery (True, 1, 10, <Direction.downleft: 7>)\n",
+      "mallows (True, 12, 7, <Direction.upleft: 5>)\n",
+      "depraved (True, 12, 8, <Direction.right: 2>)\n",
+      "cawing (True, 1, 12, <Direction.right: 2>)\n",
+      "rawest (True, 9, 11, <Direction.upleft: 5>)\n",
+      "curd (True, 15, 9, <Direction.right: 2>)\n",
+      "tiny (True, 8, 12, <Direction.upright: 6>)\n",
+      "tiddlywinks (True, 18, 19, <Direction.up: 3>)\n",
+      "fiestas (True, 0, 2, <Direction.right: 2>)\n",
+      "zombi (True, 14, 17, <Direction.left: 1>)\n",
+      "duties (True, 16, 7, <Direction.left: 1>)\n",
+      "ricochet (True, 13, 9, <Direction.right: 2>)\n",
+      "uneconomical (True, 11, 0, <Direction.up: 3>)\n",
+      "hope (True, 5, 13, <Direction.upleft: 5>)\n",
+      "litchis (True, 17, 3, <Direction.right: 2>)\n",
+      "strongly (True, 2, 12, <Direction.right: 2>)\n",
+      "verified (True, 19, 18, <Direction.up: 3>)\n",
+      "logging (True, 13, 8, <Direction.left: 1>)\n",
+      "handing (True, 5, 12, <Direction.downright: 8>)\n",
+      "anonymous (True, 8, 1, <Direction.down: 4>)\n",
+      "quaver (True, 5, 4, <Direction.upright: 6>)\n",
+      "flours (True, 4, 13, <Direction.downright: 8>)\n",
+      "boost (True, 3, 10, <Direction.downleft: 7>)\n",
+      "holy (True, 6, 16, <Direction.up: 3>)\n",
+      "saffrons (True, 0, 17, <Direction.left: 1>)\n",
+      "errs (True, 9, 9, <Direction.right: 2>)\n",
+      "hooligan (True, 19, 11, <Direction.left: 1>)\n",
+      "male (True, 3, 9, <Direction.downright: 8>)\n",
+      "belong (True, 7, 3, <Direction.up: 3>)\n",
+      "tumor (True, 17, 16, <Direction.left: 1>)\n",
+      "dishevel (True, 16, 15, <Direction.left: 1>)\n",
+      "fuzzed (True, 7, 11, <Direction.upleft: 5>)\n",
+      "raglans (True, 10, 16, <Direction.left: 1>)\n",
+      "pensively (True, 14, 4, <Direction.right: 2>)\n",
+      "murks (True, 8, 18, <Direction.up: 3>)\n",
+      "dents (True, 5, 1, <Direction.upright: 6>)\n",
+      "cilia (True, 11, 8, <Direction.up: 3>)\n",
+      "doors (True, 9, 14, <Direction.upleft: 5>)\n"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 125,
    "metadata": {
     "collapsed": true
    },
    "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)"
+    "    return len(words) > 40 and len(dirs) + 1 >= len(delta)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 126,
    "metadata": {
     "collapsed": false
    },
        "False"
       ]
      },
-     "execution_count": 27,
+     "execution_count": 126,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 131,
    "metadata": {
     "collapsed": true
    },
     "    boring = True\n",
     "    while boring:\n",
     "        grid = empty_grid(20, 20)\n",
-    "        grid, words = fill_grid(grid, ws_words, 40)\n",
+    "        grid, words = fill_grid(grid, ws_words, 80)\n",
     "        boring = not interesting(grid, words)\n",
     "    return grid, words"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 132,
    "metadata": {
     "collapsed": false
    },
      "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"
+      "....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"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 94,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": 95,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 96,
    "metadata": {
     "collapsed": false
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": 97,
    "metadata": {
     "collapsed": false
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "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
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 99,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'aaaaaaaabcccddddeeeeeeeeeeeeeeefffggghhhhhiiiiiillllmnnnnnnoooooooooprrsssssssssssssttttttttuuuvwwwy'"
+       "'aaaaaaaaaabcdddeeeeeeeeeeeefffffgghhhhhhhhhiiiiiiikllmnnnnnnnooooooooprrrrssssssssssssttttttuuvwwwww'"
       ]
      },
-     "execution_count": 36,
+     "execution_count": 99,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 37,
+   "execution_count": 100,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'aaaaaabcccddddddeeeeeeggggghhiiiiiiiiiiiiklllmmmmnnnnnnnnnnoooooooooppprrrrrrrrrssssssttttttuuuwwwyy'"
+       "'aaaaaaccccdddeeeeeeeeeeeeeeeeeeeffgghhiiiiikkklllmmmnnnnnnooooooppprrrrrrrrssssssssttttttuuuuuuvwyyy'"
       ]
      },
-     "execution_count": 37,
+     "execution_count": 100,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 38,
+   "execution_count": 101,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'a'"
+       "'e'"
       ]
      },
-     "execution_count": 38,
+     "execution_count": 101,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 39,
+   "execution_count": 102,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 103,
    "metadata": {
     "collapsed": false
    },
      "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"
+      "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"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 41,
+   "execution_count": 104,
    "metadata": {
     "collapsed": false
    },
      "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"
+      "...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"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 42,
+   "execution_count": 105,
    "metadata": {
     "collapsed": false,
     "scrolled": true
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "wombs (True, 1, 19, <Direction.downleft: 7>)\n",
-      "persimmons (True, 14, 7, <Direction.upright: 6>)\n",
-      "computerisation (True, 15, 18, <Direction.left: 1>)\n",
-      "ascribes (True, 14, 17, <Direction.left: 1>)\n",
-      "coopering (True, 1, 11, <Direction.down: 4>)\n",
-      "goalies (True, 17, 12, <Direction.left: 1>)\n",
-      "beamed (True, 3, 0, <Direction.down: 4>)\n",
-      "modifying (True, 11, 19, <Direction.down: 4>)\n",
-      "insets (True, 13, 2, <Direction.right: 2>)\n",
-      "cigarets (True, 12, 3, <Direction.up: 3>)\n",
-      "statures (True, 2, 7, <Direction.left: 1>)\n",
-      "libels (True, 6, 7, <Direction.down: 4>)\n",
-      "remarked (True, 3, 19, <Direction.down: 4>)\n",
-      "baggy (True, 13, 11, <Direction.right: 2>)\n",
-      "juxtaposes (True, 19, 17, <Direction.left: 1>)\n",
-      "mesdames (True, 7, 13, <Direction.up: 3>)\n",
-      "grumpiness (True, 4, 17, <Direction.down: 4>)\n",
-      "artefacts (True, 16, 6, <Direction.right: 2>)\n",
-      "skeins (True, 10, 2, <Direction.down: 4>)\n",
-      "assizes (True, 6, 12, <Direction.up: 3>)\n",
-      "inflow (True, 6, 5, <Direction.upright: 6>)\n",
-      "depleting (True, 7, 1, <Direction.down: 4>)\n",
-      "beeped (True, 11, 16, <Direction.left: 1>)\n",
-      "reneges (True, 18, 17, <Direction.left: 1>)\n",
-      "interning (True, 12, 13, <Direction.left: 1>)\n",
-      "yellowish (True, 2, 10, <Direction.down: 4>)\n",
-      "regicides (True, 19, 0, <Direction.right: 2>)\n",
-      "eyelids (True, 18, 5, <Direction.right: 2>)\n",
-      "cools (True, 7, 9, <Direction.upleft: 5>)\n",
-      "orgy (True, 7, 18, <Direction.up: 3>)\n",
-      "nifty (True, 8, 4, <Direction.up: 3>)\n",
-      "knottier (True, 0, 9, <Direction.left: 1>)\n",
-      "destroyers (True, 8, 0, <Direction.down: 4>)\n",
-      "unfurls (True, 14, 18, <Direction.up: 3>)\n",
-      "tinctured (True, 1, 0, <Direction.right: 2>)\n",
-      "bigamy (True, 4, 2, <Direction.down: 4>)\n",
-      "winos (True, 17, 14, <Direction.right: 2>)\n",
-      "essays (True, 11, 9, <Direction.left: 1>)\n"
+      "thralled (True, 2, 2, <Direction.right: 2>)\n",
+      "slung (True, 9, 4, <Direction.up: 3>)\n",
+      "freighted (True, 8, 12, <Direction.down: 4>)\n",
+      "townhouse (True, 18, 2, <Direction.upright: 6>)\n",
+      "salute (True, 12, 11, <Direction.left: 1>)\n",
+      "phoebes (True, 10, 6, <Direction.up: 3>)\n",
+      "faltered (True, 18, 19, <Direction.left: 1>)\n",
+      "laywomen (True, 19, 12, <Direction.upleft: 5>)\n",
+      "squeaked (True, 8, 17, <Direction.up: 3>)\n",
+      "perforating (True, 15, 15, <Direction.up: 3>)\n",
+      "iodise (True, 4, 7, <Direction.down: 4>)\n",
+      "lacier (True, 8, 10, <Direction.downleft: 7>)\n",
+      "autoimmune (True, 0, 3, <Direction.right: 2>)\n",
+      "tinging (True, 16, 1, <Direction.up: 3>)\n",
+      "snagged (True, 1, 10, <Direction.down: 4>)\n",
+      "splendidest (True, 8, 0, <Direction.down: 4>)\n",
+      "roughed (True, 10, 9, <Direction.upright: 6>)\n",
+      "crevasse (True, 11, 18, <Direction.up: 3>)\n",
+      "lone (True, 15, 17, <Direction.up: 3>)\n",
+      "ecologists (True, 12, 16, <Direction.up: 3>)\n",
+      "sponge (True, 13, 13, <Direction.up: 3>)\n",
+      "magnetising (True, 1, 14, <Direction.down: 4>)\n",
+      "sneezing (True, 3, 7, <Direction.left: 1>)\n",
+      "virulent (True, 13, 19, <Direction.up: 3>)\n",
+      "flight (True, 19, 3, <Direction.right: 2>)\n",
+      "sirup (True, 4, 3, <Direction.down: 4>)\n",
+      "yacht (True, 13, 18, <Direction.down: 4>)\n",
+      "random (True, 13, 15, <Direction.downleft: 7>)\n",
+      "accusations (True, 7, 2, <Direction.down: 4>)\n",
+      "wiled (True, 3, 13, <Direction.downleft: 7>)\n",
+      "paved (True, 8, 3, <Direction.down: 4>)\n",
+      "majorly (True, 1, 0, <Direction.right: 2>)\n",
+      "miser (True, 4, 1, <Direction.down: 4>)\n",
+      "memoir (True, 11, 5, <Direction.up: 3>)\n",
+      "emends (True, 14, 5, <Direction.downright: 8>)\n",
+      "slurs (True, 17, 12, <Direction.right: 2>)\n",
+      "clunk (True, 6, 11, <Direction.down: 4>)\n",
+      "erases (True, 1, 7, <Direction.right: 2>)\n",
+      "quasi (True, 19, 15, <Direction.right: 2>)\n"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 51,
+   "execution_count": 141,
    "metadata": {
     "collapsed": false
    },
    "outputs": [],
    "source": [
-    "def decoys(grid, words, all_words, limit=60):\n",
+    "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) < dlen_limit and not present(grid, d)[0]:\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": 52,
+   "execution_count": 135,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "['ditches',\n",
-       " 'fuzes',\n",
-       " 'antivirals',\n",
-       " 'chronology',\n",
-       " 'yacked',\n",
-       " 'percentages',\n",
-       " 'heftier',\n",
-       " 'inimitably',\n",
-       " 'conveys',\n",
-       " 'remaindered',\n",
-       " 'retaken',\n",
-       " 'reckoned',\n",
-       " 'emery',\n",
-       " 'squats',\n",
-       " 'tenderfoots',\n",
-       " 'sociology',\n",
-       " 'arbutuses',\n",
-       " 'betook',\n",
-       " 'coniferous',\n",
-       " 'gambled',\n",
-       " 'crouching']"
+       "['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": 52,
+     "execution_count": 135,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 53,
+   "execution_count": 108,
    "metadata": {
     "collapsed": false,
     "scrolled": true
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "freckled (False, 0, 0, <Direction.left: 1>)\n",
-      "transcripts (False, 0, 0, <Direction.left: 1>)\n",
-      "dinnering (False, 0, 0, <Direction.left: 1>)\n",
-      "insulating (False, 0, 0, <Direction.left: 1>)\n",
-      "regurgitates (False, 0, 0, <Direction.left: 1>)\n",
-      "drouthes (False, 0, 0, <Direction.left: 1>)\n",
-      "cocky (False, 0, 0, <Direction.left: 1>)\n",
-      "stodgy (False, 0, 0, <Direction.left: 1>)\n",
-      "bestrides (False, 0, 0, <Direction.left: 1>)\n",
-      "perceives (False, 0, 0, <Direction.left: 1>)\n",
-      "waned (False, 0, 0, <Direction.left: 1>)\n",
-      "pisses (False, 0, 0, <Direction.left: 1>)\n",
-      "alienating (False, 0, 0, <Direction.left: 1>)\n",
-      "hyperbolas (False, 0, 0, <Direction.left: 1>)\n",
-      "yeshivoth (False, 0, 0, <Direction.left: 1>)\n",
-      "allured (False, 0, 0, <Direction.left: 1>)\n",
-      "outstaying (False, 0, 0, <Direction.left: 1>)\n",
-      "bureaus (False, 0, 0, <Direction.left: 1>)\n",
-      "tragedians (False, 0, 0, <Direction.left: 1>)\n",
-      "wooed (False, 0, 0, <Direction.left: 1>)\n",
-      "unwary (False, 0, 0, <Direction.left: 1>)\n",
-      "provoking (False, 0, 0, <Direction.left: 1>)\n",
-      "curies (False, 0, 0, <Direction.left: 1>)\n",
-      "deviltry (False, 0, 0, <Direction.left: 1>)\n",
-      "wooly (False, 0, 0, <Direction.left: 1>)\n",
-      "abysmally (False, 0, 0, <Direction.left: 1>)\n",
-      "ladled (False, 0, 0, <Direction.left: 1>)\n",
-      "tamable (False, 0, 0, <Direction.left: 1>)\n",
-      "minors (False, 0, 0, <Direction.left: 1>)\n",
-      "aortas (False, 0, 0, <Direction.left: 1>)\n",
-      "souses (False, 0, 0, <Direction.left: 1>)\n",
-      "heinously (False, 0, 0, <Direction.left: 1>)\n",
-      "cardiac (False, 0, 0, <Direction.left: 1>)\n",
-      "peons (True, 17, 1, <Direction.right: 2>)\n",
-      "karate (False, 0, 0, <Direction.left: 1>)\n",
-      "tansy (False, 0, 0, <Direction.left: 1>)\n",
-      "unruly (False, 0, 0, <Direction.left: 1>)\n",
-      "absently (False, 0, 0, <Direction.left: 1>)\n",
-      "pads (False, 0, 0, <Direction.left: 1>)\n",
-      "ditches (False, 0, 0, <Direction.left: 1>)\n",
-      "fuzes (False, 0, 0, <Direction.left: 1>)\n",
-      "antivirals (False, 0, 0, <Direction.left: 1>)\n",
-      "chronology (False, 0, 0, <Direction.left: 1>)\n",
-      "yacked (False, 0, 0, <Direction.left: 1>)\n",
-      "percentages (False, 0, 0, <Direction.left: 1>)\n",
-      "heftier (False, 0, 0, <Direction.left: 1>)\n",
-      "inimitably (False, 0, 0, <Direction.left: 1>)\n",
-      "conveys (False, 0, 0, <Direction.left: 1>)\n",
-      "remaindered (False, 0, 0, <Direction.left: 1>)\n",
-      "retaken (False, 0, 0, <Direction.left: 1>)\n",
-      "reckoned (False, 0, 0, <Direction.left: 1>)\n",
-      "emery (False, 0, 0, <Direction.left: 1>)\n",
-      "squats (False, 0, 0, <Direction.left: 1>)\n",
-      "tenderfoots (False, 0, 0, <Direction.left: 1>)\n",
-      "sociology (False, 0, 0, <Direction.left: 1>)\n",
-      "arbutuses (False, 0, 0, <Direction.left: 1>)\n",
-      "betook (False, 0, 0, <Direction.left: 1>)\n",
-      "coniferous (False, 0, 0, <Direction.left: 1>)\n",
-      "gambled (False, 0, 0, <Direction.left: 1>)\n",
-      "crouching (False, 0, 0, <Direction.left: 1>)\n"
+      "thralled (True, 2, 2, <Direction.right: 2>)\n",
+      "slung (True, 9, 4, <Direction.up: 3>)\n",
+      "freighted (True, 8, 12, <Direction.down: 4>)\n",
+      "townhouse (True, 18, 2, <Direction.upright: 6>)\n",
+      "salute (True, 12, 11, <Direction.left: 1>)\n",
+      "phoebes (True, 10, 6, <Direction.up: 3>)\n",
+      "faltered (True, 18, 19, <Direction.left: 1>)\n",
+      "laywomen (True, 19, 12, <Direction.upleft: 5>)\n",
+      "squeaked (True, 8, 17, <Direction.up: 3>)\n",
+      "perforating (True, 15, 15, <Direction.up: 3>)\n",
+      "iodise (True, 4, 7, <Direction.down: 4>)\n",
+      "lacier (True, 8, 10, <Direction.downleft: 7>)\n",
+      "autoimmune (True, 0, 3, <Direction.right: 2>)\n",
+      "tinging (True, 16, 1, <Direction.up: 3>)\n",
+      "snagged (True, 1, 10, <Direction.down: 4>)\n",
+      "splendidest (True, 8, 0, <Direction.down: 4>)\n",
+      "roughed (True, 10, 9, <Direction.upright: 6>)\n",
+      "crevasse (True, 11, 18, <Direction.up: 3>)\n",
+      "lone (True, 15, 17, <Direction.up: 3>)\n",
+      "ecologists (True, 12, 16, <Direction.up: 3>)\n",
+      "sponge (True, 13, 13, <Direction.up: 3>)\n",
+      "magnetising (True, 1, 14, <Direction.down: 4>)\n",
+      "sneezing (True, 3, 7, <Direction.left: 1>)\n",
+      "virulent (True, 13, 19, <Direction.up: 3>)\n",
+      "flight (True, 19, 3, <Direction.right: 2>)\n",
+      "sirup (True, 4, 3, <Direction.down: 4>)\n",
+      "yacht (True, 13, 18, <Direction.down: 4>)\n",
+      "random (True, 13, 15, <Direction.downleft: 7>)\n",
+      "accusations (True, 7, 2, <Direction.down: 4>)\n",
+      "wiled (True, 3, 13, <Direction.downleft: 7>)\n",
+      "paved (True, 8, 3, <Direction.down: 4>)\n",
+      "majorly (True, 1, 0, <Direction.right: 2>)\n",
+      "miser (True, 4, 1, <Direction.down: 4>)\n",
+      "memoir (True, 11, 5, <Direction.up: 3>)\n",
+      "emends (True, 14, 5, <Direction.downright: 8>)\n",
+      "slurs (True, 17, 12, <Direction.right: 2>)\n",
+      "clunk (True, 6, 11, <Direction.down: 4>)\n",
+      "erases (True, 1, 7, <Direction.right: 2>)\n",
+      "quasi (True, 19, 15, <Direction.right: 2>)\n",
+      "leakiest (False, 0, 0, <Direction.left: 1>)\n",
+      "lumpiest (False, 0, 0, <Direction.left: 1>)\n",
+      "bastion (False, 0, 0, <Direction.left: 1>)\n",
+      "steamier (False, 0, 0, <Direction.left: 1>)\n",
+      "elegant (False, 0, 0, <Direction.left: 1>)\n",
+      "slogging (False, 0, 0, <Direction.left: 1>)\n",
+      "rejects (False, 0, 0, <Direction.left: 1>)\n",
+      "gaze (False, 0, 0, <Direction.left: 1>)\n",
+      "swopping (False, 0, 0, <Direction.left: 1>)\n",
+      "resonances (False, 0, 0, <Direction.left: 1>)\n",
+      "treasonous (False, 0, 0, <Direction.left: 1>)\n",
+      "corm (False, 0, 0, <Direction.left: 1>)\n",
+      "abuses (False, 0, 0, <Direction.left: 1>)\n",
+      "toga (False, 0, 0, <Direction.left: 1>)\n",
+      "upcountry (False, 0, 0, <Direction.left: 1>)\n",
+      "scrawled (False, 0, 0, <Direction.left: 1>)\n",
+      "cellar (False, 0, 0, <Direction.left: 1>)\n",
+      "skinflint (False, 0, 0, <Direction.left: 1>)\n",
+      "wasteland (False, 0, 0, <Direction.left: 1>)\n",
+      "madman (False, 0, 0, <Direction.left: 1>)\n",
+      "lash (False, 0, 0, <Direction.left: 1>)\n"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 54,
+   "execution_count": 142,
    "metadata": {
     "collapsed": false
    },
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "ihaceglstcongealedim\n",
-      "locnlanmecdwsieyieyp\n",
-      "uslrbacimdmedruyirfo\n",
-      "hyacaascsatireeaiefm\n",
-      "epyatooheutryldpifum\n",
-      "chiuantaedrivgeouihe\n",
-      "diehehdftsionrsdmoil\n",
-      "ylrnpsounaonhspadtrs\n",
-      "linhegiglgirgcidagug\n",
-      "gsaornesallliseilnwo\n",
-      "nlnenigpsnnhllsrlins\n",
-      "ityvuprergselipdohyi\n",
-      "mstismocwduusngeygsw\n",
-      "oextoooincnhksshsuci\n",
-      "cmiiprvfanedcwuctook\n",
-      "ersnptyiaclippingsur\n",
-      "biauindcemostlysietd\n",
-      "rflpebesmsskrepppsil\n",
-      "yssorgnileereouepyna\n",
-      "taeaeweathercockswgs\n",
-      "36 words added;  7 directions\n",
-      "Present: acceding alloys annulled becomingly chorusing chugs clashes clayier clippings congealed dullness espies firmest groovy groupers hogans huffy kiwis matins mostly outmoded perks pommels punitive reeling scouting sixty soppier soughing specifics syphilis taillights tromping unrepeatable weathercocks wispy\n",
-      "Decoys: belittled buzzwords climbs congaed criterions drifters exteriors filial flattery gambolling haversacks insiders interferon leukaemia liabilities mavens mentalities padlocking ptarmigans puking retarded seaming skimpiness wanderers\n"
+      ".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"
      ]
     }
    ],
     "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",
   },
   {
    "cell_type": "code",
-   "execution_count": 55,
+   "execution_count": 143,
    "metadata": {
-    "collapsed": false
+    "collapsed": false,
+    "scrolled": true
    },
    "outputs": [
     {
       "16\n",
       "17\n",
       "18\n",
-      "19\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(20):\n",
+    "for i in range(100):\n",
     "    print(i)\n",
     "    g, ws = interesting_grid()\n",
     "    p = pad_grid(g)\n",