Using sets in solution, stand-alone solution
authorNeil Smith <neil.git@njae.me.uk>
Fri, 28 Jul 2017 09:00:20 +0000 (10:00 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Fri, 28 Jul 2017 09:00:20 +0000 (10:00 +0100)
10-word-search/wordsearch-solution.ipynb
10-word-search/wordsearch-solution.py [new file with mode: 0644]

index 5c5269fe7aaef5a78b4d878ed05b0d19ab0df2f2..bf6f6c111d4a1fb3cbcd2e98855cae20994a4b14 100644 (file)
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 30,
    "metadata": {
     "collapsed": true
    },
     "    lines = [l.strip() for l in open(fn).readlines()]\n",
     "    w, h = [int(s) for s in lines[0].split('x')]\n",
     "    grid = lines[1:h+1]\n",
-    "    words = lines[h+1:]\n",
+    "    words = set(lines[h+1:])\n",
     "    return w, h, grid, words"
    ]
   },
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 31,
    "metadata": {},
    "outputs": [
     {
        "(100, 100)"
       ]
      },
-     "execution_count": 10,
+     "execution_count": 31,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 32,
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 33,
    "metadata": {},
    "outputs": [
     {
        "8092"
       ]
      },
-     "execution_count": 12,
+     "execution_count": 33,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 34,
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "1 loop, best of 3: 31.3 s per loop\n"
+      "1 loop, best of 3: 6.79 s per loop\n"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 35,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "1149"
+       "(1149, 1149, 1149)"
       ]
      },
-     "execution_count": 14,
+     "execution_count": 35,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
     "width, height, grid, words = puzzle\n",
-    "len(present_many(grid, words))"
+    "presences = present_many(grid, words)\n",
+    "found_words = [p[0] for p in presences]\n",
+    "len(presences), len(found_words), len(set(found_words))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 loop, best of 3: 6.76 s per loop\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%timeit\n",
+    "presences = present_many(grid, words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(1149, 1149)"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "found_words = [p[0] for p in presences]\n",
+    "len(found_words), len(set(found_words))"
    ]
   },
   {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "1 loop, best of 3: 31.4 s per loop\n"
+      "1 loop, best of 3: 30.8 s per loop\n"
      ]
     }
    ],
diff --git a/10-word-search/wordsearch-solution.py b/10-word-search/wordsearch-solution.py
new file mode 100644 (file)
index 0000000..3c756a3
--- /dev/null
@@ -0,0 +1,108 @@
+import string
+import re
+import collections
+import copy
+import os
+
+from enum import Enum
+Direction = Enum('Direction', 'left right up down upleft upright downleft downright')
+    
+delta = {Direction.left: (0, -1),Direction.right: (0, 1), 
+         Direction.up: (-1, 0), Direction.down: (1, 0), 
+         Direction.upleft: (-1, -1), Direction.upright: (-1, 1), 
+         Direction.downleft: (1, -1), Direction.downright: (1, 1)}
+
+cat = ''.join
+wcat = ' '.join
+lcat = '\n'.join
+
+def empty_grid(w, h):
+    return [['.' for c in range(w)] for r in range(h)]
+
+def show_grid(grid):
+    return lcat(cat(r) for r in grid)
+
+def indices(grid, r, c, l, d):
+    dr, dc = delta[d]
+    w = len(grid[0])
+    h = len(grid)
+    inds = [(r + i * dr, c + i * dc) for i in range(l)]
+    return [(i, j) for i, j in inds
+           if i >= 0
+           if j >= 0
+           if i < h
+           if j < w]
+
+
+def gslice(grid, r, c, l, d):
+    return [grid[i][j] for i, j in indices(grid, r, c, l, d)]
+
+
+def set_grid(grid, r, c, d, word):
+    for (i, j), l in zip(indices(grid, r, c, len(word), d), word):
+        grid[i][j] = l
+    return grid
+
+
+def present_many(grid, words):
+    w = len(grid[0])
+    h = len(grid)
+    wordlens = set(len(w) for w in words)
+    presences = []
+    for r in range(h):
+        for c in range(w):
+            for d in Direction:
+                for wordlen in wordlens:
+                    word = cat(gslice(grid, r, c, wordlen, d))
+                    if word in words:
+                        presences += [(word, r, c, d)]
+    return set(presences)
+
+
+
+def read_wordsearch(fn):
+    lines = [l.strip() for l in open(fn).readlines()]
+    w, h = [int(s) for s in lines[0].split('x')]
+    grid = lines[1:h+1]
+    words = set(lines[h+1:])
+    return w, h, grid, words
+
+
+
+
+# ## Part 1
+
+
+def found_words_length(puzzle):
+    width, height, grid, words = puzzle
+    return sum(len(p[0]) for p in present_many(grid, words))
+
+def total_found_words_length(puzzles):
+    return sum(found_words_length(p) for p in puzzles)
+
+
+
+
+
+
+# ## Part 2
+
+
+def unused_vowels(puzzle, presences):
+    width, height, grid, words = puzzle
+    
+    unused_grid = [[c for c in r] for r in grid]
+    for w, r, c, d in presences:
+        set_grid(unused_grid, r, c, d, '.' * len(w))
+    unused_vowel_count = sum(1 for l in unused_grid for c in l if c in 'aeiou')
+    return unused_vowel_count
+
+
+puzzle = read_wordsearch('10-wordsearch.txt')
+
+width, height, grid, words = puzzle
+presences = present_many(grid, words)
+# found_words = [p[0] for p in presences]
+
+print("Part 1: Found {} words".format(len(presences)))
+print("Part 2: {} unused vowels".format(unused_vowels(puzzle, presences)))