forked from mrailton/boggle-solver
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathboggle.py
More file actions
executable file
·98 lines (74 loc) · 2.5 KB
/
boggle.py
File metadata and controls
executable file
·98 lines (74 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from random import choice
from string import ascii_uppercase
import logging
import time
# logging.basicConfig(level=logging.INFO)
def timeit(method):
"""Calculates time taken to run a function when called"""
def timed(*args, **kw):
t1 = time.time()
result = method(*args, **kw)
print '%r %2.2f sec' % (method.__name__, time.time() -t1)
return result
return timed
def get_grid():
"""Return a dictionary of grid positions to random letters"""
return {(x, y): choice(ascii_uppercase) for x in range(X) for y in range(Y)}
def get_neighbours():
"""Return a dictionary with all the neighbours surrounding a particular position"""
neighbours = {}
for position in grid:
x, y = position
positions = [(x - 1, y - 1), (x, y - 1), (x + 1, y - 1), (x + 1, y),
(x + 1, y + 1), (x, y + 1), (x - 1, y + 1), (x - 1, y)]
neighbours[position] = [p for p in positions if 0 <= p[0] < X and 0 <= p[1] < Y]
return neighbours
def path_to_word(path):
"""Convert a list of grid positions to a word"""
return ''.join([grid[p] for p in path])
def search(path):
"""Recursively search the grid for words"""
word = path_to_word(path)
logging.debug('%s: %s' % (path, word))
if word not in stems:
return
if word in dictionary:
paths.append(path)
for next_pos in neighbours[path[-1]]:
if next_pos not in path:
search(path + [next_pos])
else:
logging.debug('skipping %s because in path' % grid[next_pos])
def get_dictionary():
"""Return a list of uppercase english words, including word stems"""
stems, dictionary = set(), set()
with open('words.txt') as f:
for word in f:
word = word.strip().upper()
dictionary.add(word)
for i in range(len(word)):
stems.add(word[:i + 1])
return dictionary, stems
@timeit
def get_words():
"""Search each grid position and return all the words found"""
for position in grid:
logging.info('searching %s' % str(position))
search([position])
return [path_to_word(p) for p in paths]
def print_grid(grid):
"""Print the grid as a readable string"""
s = ''
for y in range(Y):
for x in range(X):
s += grid[x, y] + ' '
s += '\n'
print s
size = X, Y = 4, 4
grid = get_grid()
neighbours = get_neighbours()
dictionary, stems = get_dictionary()
paths = []
print_grid(grid)
words = get_words()
print words