},
{
"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"
]
}
],
--- /dev/null
+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)))