forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrossword_puzzle_solver.py
72 lines (64 loc) · 2.68 KB
/
crossword_puzzle_solver.py
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
# https://www.geeksforgeeks.org/solve-crossword-puzzle/
def solve_crossword(puzzle, words) -> None:
rows, cols = len(puzzle), len(puzzle[0])
def is_valid(word, r, c, direction):
if direction == "across":
return c + len(word) <= cols and all(puzzle[r][c + i] in ("", word[i]) for i in range(len(word)))
else: # direction == "down"
return r + len(word) <= rows and all(puzzle[r + i][c] in ("", word[i]) for i in range(len(word)))
def place_word(word, r, c, direction) -> None:
if direction == "across":
for i in range(len(word)):
puzzle[r][c + i] = word[i]
else: # direction == "down"
for i in range(len(word)):
puzzle[r + i][c] = word[i]
def remove_word(word, r, c, direction) -> None:
if direction == "across":
for i in range(len(word)):
puzzle[r][c + i] = ""
else: # direction == "down"
for i in range(len(word)):
puzzle[r + i][c] = ""
def backtrack(puzzle, words):
for r in range(rows):
for c in range(cols):
if puzzle[r][c] == "":
for word in words[:]:
for direction in ["across", "down"]:
if is_valid(word, r, c, direction):
place_word(word, r, c, direction)
words.remove(word)
if not words:
return True
if backtrack(puzzle, words):
return True
words.append(word)
remove_word(word, r, c, direction)
return False
return True
# Create a copy of the puzzle to preserve the original
copied_puzzle = [row[:] for row in puzzle]
if backtrack(copied_puzzle, words):
return copied_puzzle
else:
return None
# Example usage:
puzzle = [
["#", "#", "c", "#", "#", "#", "#", "#", "#"],
["#", "#", "a", "t", "#", "t", "r", "a", "#"],
["#", "#", "o", "#", "#", "#", "o", "#", "#"],
["#", "#", "w", "#", "c", "a", "r", "#", "#"],
["#", "#", "#", "#", "#", "a", "#", "#", "#"],
["#", "#", "t", "#", "t", "a", "x", "i", "#"],
["#", "#", "e", "#", "#", "n", "#", "#", "#"],
["#", "#", "n", "#", "a", "t", "e", "x", "#"],
["#", "#", "#", "#", "x", "#", "#", "#", "#"]
]
words = ["car", "cat", "tax", "rat", "ate", "axe", "won"]
solution = solve_crossword(puzzle, words)
if solution:
for row in solution:
print(" ".join(row))
else:
print("No solution found.")