Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
163
Task/Word-search/Python/word-search.py
Normal file
163
Task/Word-search/Python/word-search.py
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
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")))
|
||||
Loading…
Add table
Add a link
Reference in a new issue