Anonymous user
Word search: Difference between revisions
Add implementation in python
(Add implementation in python) |
|||
Line 1,687:
[0,0]: ski [6,3]: lack
102
</pre>
=={{header|Python}}==
{{trans|Java}}
{{works with|Python|3.x}}
<lang python>
import re
from random import shuffle, randint
dirs = [[1, 0], [0, 1], [1, 1], [1, -1], [-1, 0], [0, -1], [-1, -1], [-1, 1]]
n_rows = 10
n_cols = 10
grid_size = n_rows * n_cols
min_words = 25
class Grid:
def __init__(self):
self.num_attempts = 0
self.cells = [['' for _ in range(n_cols)] for _ in range(n_rows)]
self.solutions = []
def read_words(filename):
max_len = max(n_rows, n_cols)
words = []
with open(filename, "r") as file:
for line in file:
s = line.strip().lower()
if re.match(r'^[a-z]{3,' + re.escape(str(max_len)) + r'}$', s) is not None:
words.append(s)
return words
def place_message(grid, msg):
msg = re.sub(r'[^A-Z]', "", msg.upper())
message_len = len(msg)
if 0 < message_len < grid_size:
gap_size = grid_size // message_len
for i in range(0, message_len):
pos = i * gap_size + randint(0, gap_size)
grid.cells[pos // n_cols][pos % n_cols] = msg[i]
return message_len
return 0
def try_location(grid, word, direction, pos):
r = pos // n_cols
c = pos % n_cols
length = len(word)
# check bounds
if (dirs[direction][0] == 1 and (length + c) > n_cols) or \
(dirs[direction][0] == -1 and (length - 1) > c) or \
(dirs[direction][1] == 1 and (length + r) > n_rows) or \
(dirs[direction][1] == -1 and (length - 1) > r):
return 0
rr = r
cc = c
i = 0
overlaps = 0
# check cells
while i < length:
if grid.cells[rr][cc] != '' and grid.cells[rr][cc] != word[i]:
return 0
cc += dirs[direction][0]
rr += dirs[direction][1]
i += 1
rr = r
cc = c
i = 0
# place
while i < length:
if grid.cells[rr][cc] == word[i]:
overlaps += 1
else:
grid.cells[rr][cc] = word[i]
if i < length - 1:
cc += dirs[direction][0]
rr += dirs[direction][1]
i += 1
letters_placed = length - overlaps
if letters_placed > 0:
grid.solutions.append("{0:<10} ({1},{2})({3},{4})".format(word, c, r, cc, rr))
return letters_placed
def try_place_word(grid, word):
rand_dir = randint(0, len(dirs))
rand_pos = randint(0, grid_size)
for direction in range(0, len(dirs)):
direction = (direction + rand_dir) % len(dirs)
for pos in range(0, grid_size):
pos = (pos + rand_pos) % grid_size
letters_placed = try_location(grid, word, direction, pos)
if letters_placed > 0:
return letters_placed
return 0
def create_word_search(words):
grid = None
num_attempts = 0
while num_attempts < 100:
num_attempts += 1
shuffle(words)
grid = Grid()
message_len = place_message(grid, "Rosetta Code")
target = grid_size - message_len
cells_filled = 0
for word in words:
cells_filled += try_place_word(grid, word)
if cells_filled == target:
if len(grid.solutions) >= min_words:
grid.num_attempts = num_attempts
return grid
else:
break # grid is full but we didn't pack enough words, start over
return grid
def print_result(grid):
if grid is None or grid.num_attempts == 0:
print("No grid to display")
return
size = len(grid.solutions)
print("Attempts: {0}".format(grid.num_attempts))
print("Number of words: {0}".format(size))
print("\n 0 1 2 3 4 5 6 7 8 9\n")
for r in range(0, n_rows):
print("{0} ".format(r), end='')
for c in range(0, n_cols):
print(" %c " % grid.cells[r][c], end='')
print()
print()
for i in range(0, size - 1, 2):
print("{0} {1}".format(grid.solutions[i], grid.solutions[i+1]))
if size % 2 == 1:
print(grid.solutions[size - 1])
if __name__ == "__main__":
print_result(create_word_search(read_words("unixdict.txt")))
</lang>
{{out}}
<pre>
Attempts: 1
Number of words: 25
0 1 2 3 4 5 6 7 8 9
0 f b R u e r u l t h
1 o n o t v O e r o p
2 a S a b a x o b E m
3 l e d s h w T p e u
4 w p v a n s u c k i
5 o T u r A t u t s r
6 n s o p u m y d i t
7 t h C j a c o b i O
8 t i r e h n i m D p
9 y n o l o c E s a c
exhaust (6,1)(0,7) hornwort (1,7)(8,0)
btu (3,2)(3,0) jacobi (3,7)(8,7)
foal (0,0)(0,3) triumph (9,6)(9,0)
inherit (6,8)(0,8) mecum (9,2)(5,6)
colony (5,9)(0,9) curve (5,7)(1,3)
wont (0,4)(0,7) lure (7,0)(4,0)
hob (9,0)(7,2) tidy (9,6)(6,6)
suck (5,4)(8,4) san (3,3)(1,1)
sac (7,9)(9,9) put (7,3)(5,5)
led (0,3)(2,3) stu (8,5)(6,5)
have (4,3)(4,0) min (7,8)(5,8)
bob (1,0)(3,2) pup (3,6)(1,4)
dip (7,6)(9,8)
</pre>
|