From 6f90a162b1cf36416d271290defb448e3fd4d610 Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Thu, 26 Oct 2023 23:48:20 +0530 Subject: [PATCH 01/27] Create crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 backtracking/crossword_puzzle_solver.py diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py new file mode 100644 index 000000000000..bfdd8d5d463c --- /dev/null +++ b/backtracking/crossword_puzzle_solver.py @@ -0,0 +1,71 @@ +def solve_crossword(puzzle, words): + 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): + 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): + 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.") From e2d5a02b7b2b717942b7b9570cb0a8c078f59019 Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Thu, 26 Oct 2023 23:52:32 +0530 Subject: [PATCH 02/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index bfdd8d5d463c..6ef4b7292d3c 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,4 +1,5 @@ -def solve_crossword(puzzle, words): +# 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): @@ -7,7 +8,7 @@ def is_valid(word, r, c, direction): 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): + def place_word(word, r, c, direction) -> None: if direction == "across": for i in range(len(word)): puzzle[r][c + i] = word[i] @@ -15,7 +16,7 @@ def place_word(word, r, c, direction): for i in range(len(word)): puzzle[r + i][c] = word[i] - def remove_word(word, r, c, direction): + def remove_word(word, r, c, direction) -> None: if direction == "across": for i in range(len(word)): puzzle[r][c + i] = "" From 1feac5765835e88a60264a07976c6fd87a8fb780 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:26:13 +0000 Subject: [PATCH 03/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 6ef4b7292d3c..1a47f088a503 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -4,9 +4,13 @@ def solve_crossword(puzzle, words) -> None: 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))) + 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))) + 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": @@ -49,6 +53,7 @@ def backtrack(puzzle, words): else: return None + # Example usage: puzzle = [ ["#", "#", "c", "#", "#", "#", "#", "#", "#"], @@ -59,7 +64,7 @@ def backtrack(puzzle, words): ["#", "#", "t", "#", "t", "a", "x", "i", "#"], ["#", "#", "e", "#", "#", "n", "#", "#", "#"], ["#", "#", "n", "#", "a", "t", "e", "x", "#"], - ["#", "#", "#", "#", "x", "#", "#", "#", "#"] + ["#", "#", "#", "#", "x", "#", "#", "#", "#"], ] words = ["car", "cat", "tax", "rat", "ate", "axe", "won"] From 4781e0b3e15a0b1f2a7f6d283b69a5c24d3215ce Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Thu, 26 Oct 2023 23:59:15 +0530 Subject: [PATCH 04/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 40 +++++++++++-------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 1a47f088a503..98c46a1c9cff 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,18 +1,16 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ -def solve_crossword(puzzle, words) -> None: +from typing import List, Optional + +def solve_crossword(puzzle: List[List[str]], words: List[str]) -> Optional[List[List[str]]]: rows, cols = len(puzzle), len(puzzle[0]) - def is_valid(word, r, c, direction): + def is_valid(word: str, r: int, c: int, direction: str) -> bool: if direction == "across": - return c + len(word) <= cols and all( - puzzle[r][c + i] in ("", word[i]) for i in range(len(word)) - ) + 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)) - ) + 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: + def place_word(word: str, r: int, c: int, direction: str) -> None: if direction == "across": for i in range(len(word)): puzzle[r][c + i] = word[i] @@ -20,7 +18,7 @@ def place_word(word, r, c, direction) -> None: for i in range(len(word)): puzzle[r + i][c] = word[i] - def remove_word(word, r, c, direction) -> None: + def remove_word(word: str, r: int, c: int, direction: str) -> None: if direction == "across": for i in range(len(word)): puzzle[r][c + i] = "" @@ -28,7 +26,7 @@ def remove_word(word, r, c, direction) -> None: for i in range(len(word)): puzzle[r + i][c] = "" - def backtrack(puzzle, words): + def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: for r in range(rows): for c in range(cols): if puzzle[r][c] == "": @@ -53,21 +51,17 @@ def backtrack(puzzle, words): 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", "#", "#", "#", "#"], + ["#", "#", "c", "#", "#", "#", "#"], + ["#", "#", "r", "a", "c", "k", "#"], + ["#", "#", "o", "#", "#", "#", "#"], + ["#", "#", "r", "#", "b", "#", "#"], + ["#", "#", "a", "a", "t", "a", "x"], + ["#", "#", "t", "#", "i", "n", "#"], + ["#", "#", "e", "#", "n", "#", "#"], ] - -words = ["car", "cat", "tax", "rat", "ate", "axe", "won"] +words = ["car", "rack", "bat", "cat", "rat", "in", "tax", "eat"] solution = solve_crossword(puzzle, words) if solution: From 2a78274350942dc57c3880a884f5e9db1677f928 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:30:22 +0000 Subject: [PATCH 05/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 98c46a1c9cff..cd14deef751e 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,14 +1,21 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ from typing import List, Optional -def solve_crossword(puzzle: List[List[str]], words: List[str]) -> Optional[List[List[str]]]: + +def solve_crossword( + puzzle: List[List[str]], words: List[str] +) -> Optional[List[List[str]]]: rows, cols = len(puzzle), len(puzzle[0]) def is_valid(word: str, r: int, c: int, direction: str) -> bool: if direction == "across": - return c + len(word) <= cols and all(puzzle[r][c + i] in ("", word[i]) for i in range(len(word))) + 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))) + return r + len(word) <= rows and all( + puzzle[r + i][c] in ("", word[i]) for i in range(len(word)) + ) def place_word(word: str, r: int, c: int, direction: str) -> None: if direction == "across": @@ -51,6 +58,7 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: else: return None + # Example usage: puzzle = [ ["#", "#", "c", "#", "#", "#", "#"], From d950484da71dc05b4409ef12577307d51872253d Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Fri, 27 Oct 2023 00:10:18 +0530 Subject: [PATCH 06/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 98 +++++++++++++++++++------ 1 file changed, 74 insertions(+), 24 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index cd14deef751e..23513447c55f 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,53 +1,104 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ -from typing import List, Optional +from typing import List +def solve_crossword(puzzle: List[List[str]], words: List[str]) -> List[List[str]]: + + """ + Solve a crossword puzzle by placing words from the provided list into the puzzle. -def solve_crossword( - puzzle: List[List[str]], words: List[str] -) -> Optional[List[List[str]]]: + Args: + puzzle (List[List[str]]): The crossword puzzle grid. + words (List[str]): List of words to place in the puzzle. + + Returns: + Optional[List[List[str]]]: The solved crossword puzzle, or None if no solution is found. + """ rows, cols = len(puzzle), len(puzzle[0]) - def is_valid(word: str, r: int, c: int, direction: str) -> bool: + def is_valid(word: str, row: int, col: int, direction: str) -> bool: + """ + Check if placing a word in a specific direction at a given position is valid. + + Args: + word (str): The word to be placed. + row (int): The starting row position. + col (int): The starting column position. + direction (str): Either "across" or "down". + + Returns: + bool: True if the placement is valid, otherwise False. + """ + if direction == "across": - return c + len(word) <= cols and all( - puzzle[r][c + i] in ("", word[i]) for i in range(len(word)) - ) + return col + len(word) <= cols and all(puzzle[row][col + 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)) - ) + return row + len(word) <= rows and all(puzzle[row + i][col] in ("", word[i]) for i in range(len(word))) - def place_word(word: str, r: int, c: int, direction: str) -> None: + def place_word(word: str, row: int, col: int, direction: str) -> None: + """ + Place a word in the crossword puzzle at a specific position and direction. + + Args: + word (str): The word to be placed. + row (int): The starting row position. + col (int): The starting column position. + direction (str): Either "across" or "down". + + Returns: + None + """ if direction == "across": for i in range(len(word)): - puzzle[r][c + i] = word[i] + puzzle[row][col + i] = word[i] else: # direction == "down" for i in range(len(word)): - puzzle[r + i][c] = word[i] + puzzle[row + i][col] = word[i] - def remove_word(word: str, r: int, c: int, direction: str) -> None: + def remove_word(word: str, row: int, col: int, direction: str) -> None: + """ + Remove a word from the crossword puzzle at a specific position and direction. + + Args: + word (str): The word to be removed. + row (int): The starting row position. + col (int): The starting column position. + direction (str): Either "across" or "down". + + Returns: + None + """ if direction == "across": for i in range(len(word)): - puzzle[r][c + i] = "" + puzzle[row][col + i] = "" else: # direction == "down" for i in range(len(word)): - puzzle[r + i][c] = "" + puzzle[row + i][col] = "" def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: - for r in range(rows): - for c in range(cols): - if puzzle[r][c] == "": + """ + Recursively backtrack to solve the crossword puzzle. + + Args: + puzzle (List[List[str]]): The crossword puzzle grid. + words (List[str]): List of words to place in the puzzle. + + Returns: + bool: True if a solution is found, otherwise False. + """ + for row in range(rows): + for col in range(cols): + if puzzle[row][col] == "": for word in words[:]: for direction in ["across", "down"]: - if is_valid(word, r, c, direction): - place_word(word, r, c, direction) + if is_valid(word, row, col, direction): + place_word(word, row, col, direction) words.remove(word) if not words: return True if backtrack(puzzle, words): return True words.append(word) - remove_word(word, r, c, direction) + remove_word(word, row, col, direction) return False return True @@ -58,7 +109,6 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: else: return None - # Example usage: puzzle = [ ["#", "#", "c", "#", "#", "#", "#"], From 3ec196ddb1b3c0af8e18d1d25cecb2f75b2d3c71 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:40:53 +0000 Subject: [PATCH 07/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 27 +++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 23513447c55f..96db8eebe0a8 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,8 +1,8 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ from typing import List + def solve_crossword(puzzle: List[List[str]], words: List[str]) -> List[List[str]]: - """ Solve a crossword puzzle by placing words from the provided list into the puzzle. @@ -18,32 +18,36 @@ def solve_crossword(puzzle: List[List[str]], words: List[str]) -> List[List[str] def is_valid(word: str, row: int, col: int, direction: str) -> bool: """ Check if placing a word in a specific direction at a given position is valid. - + Args: word (str): The word to be placed. row (int): The starting row position. col (int): The starting column position. direction (str): Either "across" or "down". - + Returns: bool: True if the placement is valid, otherwise False. """ if direction == "across": - return col + len(word) <= cols and all(puzzle[row][col + i] in ("", word[i]) for i in range(len(word))) + return col + len(word) <= cols and all( + puzzle[row][col + i] in ("", word[i]) for i in range(len(word)) + ) else: # direction == "down" - return row + len(word) <= rows and all(puzzle[row + i][col] in ("", word[i]) for i in range(len(word))) + return row + len(word) <= rows and all( + puzzle[row + i][col] in ("", word[i]) for i in range(len(word)) + ) def place_word(word: str, row: int, col: int, direction: str) -> None: """ Place a word in the crossword puzzle at a specific position and direction. - + Args: word (str): The word to be placed. row (int): The starting row position. col (int): The starting column position. direction (str): Either "across" or "down". - + Returns: None """ @@ -57,13 +61,13 @@ def place_word(word: str, row: int, col: int, direction: str) -> None: def remove_word(word: str, row: int, col: int, direction: str) -> None: """ Remove a word from the crossword puzzle at a specific position and direction. - + Args: word (str): The word to be removed. row (int): The starting row position. col (int): The starting column position. direction (str): Either "across" or "down". - + Returns: None """ @@ -77,11 +81,11 @@ def remove_word(word: str, row: int, col: int, direction: str) -> None: def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: """ Recursively backtrack to solve the crossword puzzle. - + Args: puzzle (List[List[str]]): The crossword puzzle grid. words (List[str]): List of words to place in the puzzle. - + Returns: bool: True if a solution is found, otherwise False. """ @@ -109,6 +113,7 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: else: return None + # Example usage: puzzle = [ ["#", "#", "c", "#", "#", "#", "#"], From 82256dae25d047e55ec30952858ca0a84b51a72f Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Fri, 27 Oct 2023 00:22:35 +0530 Subject: [PATCH 08/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 27 +++++++++---------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 96db8eebe0a8..bcfc4824b3f6 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,9 +1,4 @@ -# https://www.geeksforgeeks.org/solve-crossword-puzzle/ -from typing import List - - -def solve_crossword(puzzle: List[List[str]], words: List[str]) -> List[List[str]]: - """ +""" Solve a crossword puzzle by placing words from the provided list into the puzzle. Args: @@ -12,10 +7,14 @@ def solve_crossword(puzzle: List[List[str]], words: List[str]) -> List[List[str] Returns: Optional[List[List[str]]]: The solved crossword puzzle, or None if no solution is found. - """ +""" +from typing import List, Optional + +def solve_crossword(puzzle: List[List[str]], words: List[str]) -> Optional[List[List[str]]]: + rows, cols = len(puzzle), len(puzzle[0]) - def is_valid(word: str, row: int, col: int, direction: str) -> bool: + def is_valid_placement(word: str, row: int, col: int, direction: str) -> bool: """ Check if placing a word in a specific direction at a given position is valid. @@ -28,15 +27,10 @@ def is_valid(word: str, row: int, col: int, direction: str) -> bool: Returns: bool: True if the placement is valid, otherwise False. """ - if direction == "across": - return col + len(word) <= cols and all( - puzzle[row][col + i] in ("", word[i]) for i in range(len(word)) - ) + return col + len(word) <= cols and all(puzzle[row][col + i] in ("", word[i]) for i in range(len(word))) else: # direction == "down" - return row + len(word) <= rows and all( - puzzle[row + i][col] in ("", word[i]) for i in range(len(word)) - ) + return row + len(word) <= rows and all(puzzle[row + i][col] in ("", word[i]) for i in range(len(word))) def place_word(word: str, row: int, col: int, direction: str) -> None: """ @@ -94,7 +88,7 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: if puzzle[row][col] == "": for word in words[:]: for direction in ["across", "down"]: - if is_valid(word, row, col, direction): + if is_valid_placement(word, row, col, direction): place_word(word, row, col, direction) words.remove(word) if not words: @@ -113,7 +107,6 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: else: return None - # Example usage: puzzle = [ ["#", "#", "c", "#", "#", "#", "#"], From f4cd6286fa27af643a3da3f0a31df283c873e532 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:54:23 +0000 Subject: [PATCH 09/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index bcfc4824b3f6..a31c95e61871 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -10,8 +10,10 @@ """ from typing import List, Optional -def solve_crossword(puzzle: List[List[str]], words: List[str]) -> Optional[List[List[str]]]: +def solve_crossword( + puzzle: List[List[str]], words: List[str] +) -> Optional[List[List[str]]]: rows, cols = len(puzzle), len(puzzle[0]) def is_valid_placement(word: str, row: int, col: int, direction: str) -> bool: @@ -28,9 +30,13 @@ def is_valid_placement(word: str, row: int, col: int, direction: str) -> bool: bool: True if the placement is valid, otherwise False. """ if direction == "across": - return col + len(word) <= cols and all(puzzle[row][col + i] in ("", word[i]) for i in range(len(word))) + return col + len(word) <= cols and all( + puzzle[row][col + i] in ("", word[i]) for i in range(len(word)) + ) else: # direction == "down" - return row + len(word) <= rows and all(puzzle[row + i][col] in ("", word[i]) for i in range(len(word))) + return row + len(word) <= rows and all( + puzzle[row + i][col] in ("", word[i]) for i in range(len(word)) + ) def place_word(word: str, row: int, col: int, direction: str) -> None: """ @@ -107,6 +113,7 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: else: return None + # Example usage: puzzle = [ ["#", "#", "c", "#", "#", "#", "#"], From 3684f4495c841ba5f4d1607f606b559bbc209ef1 Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Fri, 27 Oct 2023 00:33:39 +0530 Subject: [PATCH 10/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index a31c95e61871..38e7047c4c6b 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,4 +1,11 @@ -""" +# https://www.geeksforgeeks.org/solve-crossword-puzzle/ +from typing import List, Optional + + +def solve_crossword( + puzzle: List[List[str]], words: List[str] +) -> Optional[List[List[str]]]: + """ Solve a crossword puzzle by placing words from the provided list into the puzzle. Args: @@ -7,13 +14,8 @@ Returns: Optional[List[List[str]]]: The solved crossword puzzle, or None if no solution is found. -""" -from typing import List, Optional - - -def solve_crossword( - puzzle: List[List[str]], words: List[str] -) -> Optional[List[List[str]]]: + """ + rows, cols = len(puzzle), len(puzzle[0]) def is_valid_placement(word: str, row: int, col: int, direction: str) -> bool: @@ -132,3 +134,8 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: print(" ".join(row)) else: print("No solution found.") + +if __name__ == "__main__": + import doctest + + doctest.testmod() From 3bdeefe786926a16f47cbef621b3620f9223709a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 19:04:55 +0000 Subject: [PATCH 11/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 38e7047c4c6b..bab2d5b447cd 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -15,7 +15,7 @@ def solve_crossword( Returns: Optional[List[List[str]]]: The solved crossword puzzle, or None if no solution is found. """ - + rows, cols = len(puzzle), len(puzzle[0]) def is_valid_placement(word: str, row: int, col: int, direction: str) -> bool: From 0571200306ccd4a77ea3d5fb6610771ae536caed Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Fri, 27 Oct 2023 12:29:45 +0530 Subject: [PATCH 12/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 57 ++++++++++++------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index bab2d5b447cd..df3bb5800a27 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,19 +1,16 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ -from typing import List, Optional +from typing import Optional - -def solve_crossword( - puzzle: List[List[str]], words: List[str] -) -> Optional[List[List[str]]]: +def solve_crossword(puzzle: list[list[str]], words: list[str]) -> Optional[list[list[str]]]: """ Solve a crossword puzzle by placing words from the provided list into the puzzle. Args: - puzzle (List[List[str]]): The crossword puzzle grid. - words (List[str]): List of words to place in the puzzle. + puzzle (list[list[str]]): The crossword puzzle grid. + words (list[str]): list of words to place in the puzzle. Returns: - Optional[List[List[str]]]: The solved crossword puzzle, or None if no solution is found. + Optional[list[list[str]]]: The solved crossword puzzle, or None if no solution is found. """ rows, cols = len(puzzle), len(puzzle[0]) @@ -80,13 +77,13 @@ def remove_word(word: str, row: int, col: int, direction: str) -> None: for i in range(len(word)): puzzle[row + i][col] = "" - def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: + def backtrack(puzzle: list[list[str]], words: list[str]) -> bool: """ Recursively backtrack to solve the crossword puzzle. Args: - puzzle (List[List[str]]): The crossword puzzle grid. - words (List[str]): List of words to place in the puzzle. + puzzle (list[list[str]]): The crossword puzzle grid. + words (list[str]): list of words to place in the puzzle. Returns: bool: True if a solution is found, otherwise False. @@ -116,26 +113,28 @@ def backtrack(puzzle: List[List[str]], words: List[str]) -> bool: return None -# Example usage: -puzzle = [ - ["#", "#", "c", "#", "#", "#", "#"], - ["#", "#", "r", "a", "c", "k", "#"], - ["#", "#", "o", "#", "#", "#", "#"], - ["#", "#", "r", "#", "b", "#", "#"], - ["#", "#", "a", "a", "t", "a", "x"], - ["#", "#", "t", "#", "i", "n", "#"], - ["#", "#", "e", "#", "n", "#", "#"], -] -words = ["car", "rack", "bat", "cat", "rat", "in", "tax", "eat"] -solution = solve_crossword(puzzle, words) - -if solution: - for row in solution: - print(" ".join(row)) -else: - print("No solution found.") if __name__ == "__main__": import doctest doctest.testmod() + + + # Example usage: + puzzle = [ + ["#", "#", "c", "#", "#", "#", "#"], + ["#", "#", "r", "a", "c", "k", "#"], + ["#", "#", "o", "#", "#", "#", "#"], + ["#", "#", "r", "#", "b", "#", "#"], + ["#", "#", "a", "a", "t", "a", "x"], + ["#", "#", "t", "#", "i", "n", "#"], + ["#", "#", "e", "#", "n", "#", "#"], + ] + words = ["car", "rack", "bat", "cat", "rat", "in", "tax", "eat"] + solution = solve_crossword(puzzle, words) + + if solution: + for row in solution: + print(" ".join(row)) + else: + print("No solution found.") From 88ee942ad543e5c6031cf4398c76720ff9a32f43 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 07:01:28 +0000 Subject: [PATCH 13/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index df3bb5800a27..043357d91802 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,7 +1,10 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ from typing import Optional -def solve_crossword(puzzle: list[list[str]], words: list[str]) -> Optional[list[list[str]]]: + +def solve_crossword( + puzzle: list[list[str]], words: list[str] +) -> Optional[list[list[str]]]: """ Solve a crossword puzzle by placing words from the provided list into the puzzle. @@ -113,13 +116,11 @@ def backtrack(puzzle: list[list[str]], words: list[str]) -> bool: return None - if __name__ == "__main__": import doctest doctest.testmod() - - + # Example usage: puzzle = [ ["#", "#", "c", "#", "#", "#", "#"], @@ -132,7 +133,7 @@ def backtrack(puzzle: list[list[str]], words: list[str]) -> bool: ] words = ["car", "rack", "bat", "cat", "rat", "in", "tax", "eat"] solution = solve_crossword(puzzle, words) - + if solution: for row in solution: print(" ".join(row)) From 9448cc202c971d13deb89aa36a9acce9e20fcaaa Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Fri, 27 Oct 2023 12:48:11 +0530 Subject: [PATCH 14/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 191 ++++++++---------------- 1 file changed, 61 insertions(+), 130 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 043357d91802..5aebed2dcab5 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,141 +1,72 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ -from typing import Optional - -def solve_crossword( - puzzle: list[list[str]], words: list[str] -) -> Optional[list[list[str]]]: +def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: """ - Solve a crossword puzzle by placing words from the provided list into the puzzle. - - Args: - puzzle (list[list[str]]): The crossword puzzle grid. - words (list[str]): list of words to place in the puzzle. + Check if a word can be placed at the given position. - Returns: - Optional[list[list[str]]]: The solved crossword puzzle, or None if no solution is found. + >>> puzzle = [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] + >>> is_valid(puzzle, 'word', 0, 0) + True """ + for i in range(len(word)): + if row + i >= len(puzzle) or puzzle[row + i][col] != '': + return False + return True - rows, cols = len(puzzle), len(puzzle[0]) - - def is_valid_placement(word: str, row: int, col: int, direction: str) -> bool: - """ - Check if placing a word in a specific direction at a given position is valid. - - Args: - word (str): The word to be placed. - row (int): The starting row position. - col (int): The starting column position. - direction (str): Either "across" or "down". - - Returns: - bool: True if the placement is valid, otherwise False. - """ - if direction == "across": - return col + len(word) <= cols and all( - puzzle[row][col + i] in ("", word[i]) for i in range(len(word)) - ) - else: # direction == "down" - return row + len(word) <= rows and all( - puzzle[row + i][col] in ("", word[i]) for i in range(len(word)) - ) - - def place_word(word: str, row: int, col: int, direction: str) -> None: - """ - Place a word in the crossword puzzle at a specific position and direction. - - Args: - word (str): The word to be placed. - row (int): The starting row position. - col (int): The starting column position. - direction (str): Either "across" or "down". - - Returns: - None - """ - if direction == "across": - for i in range(len(word)): - puzzle[row][col + i] = word[i] - else: # direction == "down" - for i in range(len(word)): - puzzle[row + i][col] = word[i] - - def remove_word(word: str, row: int, col: int, direction: str) -> None: - """ - Remove a word from the crossword puzzle at a specific position and direction. - - Args: - word (str): The word to be removed. - row (int): The starting row position. - col (int): The starting column position. - direction (str): Either "across" or "down". - - Returns: - None - """ - if direction == "across": - for i in range(len(word)): - puzzle[row][col + i] = "" - else: # direction == "down" - for i in range(len(word)): - puzzle[row + i][col] = "" - - def backtrack(puzzle: list[list[str]], words: list[str]) -> bool: - """ - Recursively backtrack to solve the crossword puzzle. - - Args: - puzzle (list[list[str]]): The crossword puzzle grid. - words (list[str]): list of words to place in the puzzle. - - Returns: - bool: True if a solution is found, otherwise False. - """ - for row in range(rows): - for col in range(cols): - if puzzle[row][col] == "": - for word in words[:]: - for direction in ["across", "down"]: - if is_valid_placement(word, row, col, direction): - place_word(word, row, col, direction) - words.remove(word) - if not words: - return True - if backtrack(puzzle, words): - return True - words.append(word) - remove_word(word, row, col, 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 +def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: + """ + Place a word at the given position. + >>> puzzle = [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] + >>> place_word(puzzle, 'word', 0, 0) + >>> puzzle + [['w', '', '', ''], ['o', '', '', ''], ['r', '', '', ''], ['d', '', '', '']] + """ + for i in range(len(word)): + puzzle[row + i][col] = word[i] -if __name__ == "__main__": - import doctest +def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: + """ + Remove a word from the given position. - doctest.testmod() + >>> puzzle = [['w', '', '', ''], ['o', '', '', ''], ['r', '', '', ''], ['d', '', '', '']] + >>> remove_word(puzzle, 'word', 0, 0) + >>> puzzle + [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] + """ + for i in range(len(word)): + puzzle[row + i][col] = '' - # Example usage: - puzzle = [ - ["#", "#", "c", "#", "#", "#", "#"], - ["#", "#", "r", "a", "c", "k", "#"], - ["#", "#", "o", "#", "#", "#", "#"], - ["#", "#", "r", "#", "b", "#", "#"], - ["#", "#", "a", "a", "t", "a", "x"], - ["#", "#", "t", "#", "i", "n", "#"], - ["#", "#", "e", "#", "n", "#", "#"], - ] - words = ["car", "rack", "bat", "cat", "rat", "in", "tax", "eat"] - solution = solve_crossword(puzzle, words) +def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: + """ + Solve the crossword puzzle using backtracking. - if solution: - for row in solution: - print(" ".join(row)) - else: - print("No solution found.") + >>> puzzle = [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] + >>> words = ['word', 'another', 'more', 'last'] + >>> solve_crossword(puzzle, words) + True + """ + for row in range(len(puzzle)): + for col in range(len(puzzle[0])): + if puzzle[row][col] == '': + for word in words: + if is_valid(puzzle, word, row, col): + place_word(puzzle, word, row, col) + words.remove(word) + if solve_crossword(puzzle, words): + return True + words.append(word) + remove_word(puzzle, word, row, col) + return False + return True + +# Replace with your actual puzzle and words +PUZZLE = [['' for _ in range(3)] for _ in range(3)] +WORDS = ['cat', 'dog', 'pig'] + +if solve_crossword(PUZZLE, WORDS): + print('Solution found:') +else: + print('No solution found:') +for row in PUZZLE: + print(' '.join(row)) From 49f6e4de832a5941171f1dd44787fe582d9e2f41 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 07:18:49 +0000 Subject: [PATCH 15/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 5aebed2dcab5..03419a3e896f 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,5 +1,6 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ + def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: """ Check if a word can be placed at the given position. @@ -9,10 +10,11 @@ def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: True """ for i in range(len(word)): - if row + i >= len(puzzle) or puzzle[row + i][col] != '': + if row + i >= len(puzzle) or puzzle[row + i][col] != "": return False return True + def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: """ Place a word at the given position. @@ -25,6 +27,7 @@ def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: for i in range(len(word)): puzzle[row + i][col] = word[i] + def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: """ Remove a word from the given position. @@ -35,7 +38,8 @@ def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] """ for i in range(len(word)): - puzzle[row + i][col] = '' + puzzle[row + i][col] = "" + def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: """ @@ -48,7 +52,7 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: """ for row in range(len(puzzle)): for col in range(len(puzzle[0])): - if puzzle[row][col] == '': + if puzzle[row][col] == "": for word in words: if is_valid(puzzle, word, row, col): place_word(puzzle, word, row, col) @@ -60,13 +64,14 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: return False return True + # Replace with your actual puzzle and words -PUZZLE = [['' for _ in range(3)] for _ in range(3)] -WORDS = ['cat', 'dog', 'pig'] +PUZZLE = [["" for _ in range(3)] for _ in range(3)] +WORDS = ["cat", "dog", "pig"] if solve_crossword(PUZZLE, WORDS): - print('Solution found:') + print("Solution found:") else: - print('No solution found:') + print("No solution found:") for row in PUZZLE: - print(' '.join(row)) + print(" ".join(row)) From 236b159f2f881159d88159c69f6952b809ede1e0 Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Fri, 27 Oct 2023 13:04:01 +0530 Subject: [PATCH 16/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 37 ++++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 03419a3e896f..b695aaf29c4d 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,25 +1,33 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ - def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: """ Check if a word can be placed at the given position. - >>> puzzle = [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] + >>> puzzle = [ + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''] + ... ] >>> is_valid(puzzle, 'word', 0, 0) True """ for i in range(len(word)): - if row + i >= len(puzzle) or puzzle[row + i][col] != "": + if row + i >= len(puzzle) or puzzle[row + i][col] != '': return False return True - def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: """ Place a word at the given position. - >>> puzzle = [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] + >>> puzzle = [ + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''] + ... ] >>> place_word(puzzle, 'word', 0, 0) >>> puzzle [['w', '', '', ''], ['o', '', '', ''], ['r', '', '', ''], ['d', '', '', '']] @@ -27,25 +35,34 @@ def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: for i in range(len(word)): puzzle[row + i][col] = word[i] - def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: """ Remove a word from the given position. - >>> puzzle = [['w', '', '', ''], ['o', '', '', ''], ['r', '', '', ''], ['d', '', '', '']] + >>> puzzle = [ + ... ['w', '', '', ''], + ... ['o', '', '', ''], + ... ['r', '', '', ''], + ... ['d', '', '', ''] + ... ] >>> remove_word(puzzle, 'word', 0, 0) >>> puzzle [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] """ for i in range(len(word)): - puzzle[row + i][col] = "" - + puzzle[row + i][col] = '' def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: """ Solve the crossword puzzle using backtracking. - >>> puzzle = [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] + >>> puzzle = [ + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''] + ... ] + >>> words = ['word', 'another', 'more', 'last'] >>> solve_crossword(puzzle, words) True From 5142ce21f13d77a0e674d738743d20738ad5b81d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 07:36:04 +0000 Subject: [PATCH 17/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index b695aaf29c4d..2f97cd1e8858 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,5 +1,6 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ + def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: """ Check if a word can be placed at the given position. @@ -14,10 +15,11 @@ def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: True """ for i in range(len(word)): - if row + i >= len(puzzle) or puzzle[row + i][col] != '': + if row + i >= len(puzzle) or puzzle[row + i][col] != "": return False return True + def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: """ Place a word at the given position. @@ -35,6 +37,7 @@ def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: for i in range(len(word)): puzzle[row + i][col] = word[i] + def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: """ Remove a word from the given position. @@ -50,7 +53,8 @@ def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] """ for i in range(len(word)): - puzzle[row + i][col] = '' + puzzle[row + i][col] = "" + def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: """ @@ -62,7 +66,7 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: ... ['', '', '', ''], ... ['', '', '', ''] ... ] - + >>> words = ['word', 'another', 'more', 'last'] >>> solve_crossword(puzzle, words) True From e37a7c90e2d47661f36a5ebe985d2e1912a7dc8e Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Fri, 27 Oct 2023 13:14:10 +0530 Subject: [PATCH 18/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 2f97cd1e8858..f4538f2d5503 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -67,7 +67,7 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: ... ['', '', '', ''] ... ] - >>> words = ['word', 'another', 'more', 'last'] + >>> words = ['word', 'four', 'more', 'last'] >>> solve_crossword(puzzle, words) True """ From 77863f63e4a041d832ff8fb94c21ced9f385da14 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 28 Oct 2023 18:58:49 +0200 Subject: [PATCH 19/27] Update backtracking/crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index f4538f2d5503..fa4501b4b4eb 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -70,6 +70,9 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: >>> words = ['word', 'four', 'more', 'last'] >>> solve_crossword(puzzle, words) True + >>> words = ['word', 'four', 'more', 'paragraphs'] + >>> solve_crossword(puzzle, words) + False """ for row in range(len(puzzle)): for col in range(len(puzzle[0])): From ecac1fd10e29f281427c7777e973eecce7f134b0 Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Sat, 28 Oct 2023 22:52:16 +0530 Subject: [PATCH 20/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index fa4501b4b4eb..ebc9f95b0a1a 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -95,7 +95,8 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: if solve_crossword(PUZZLE, WORDS): print("Solution found:") + for row in PUZZLE: + print(" ".join(row)) else: print("No solution found:") -for row in PUZZLE: - print(" ".join(row)) + From 76dd3fe82446a194ebb3aadbfe5230afa46745d5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 28 Oct 2023 17:22:52 +0000 Subject: [PATCH 21/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index ebc9f95b0a1a..240fa3da1ee2 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -99,4 +99,3 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: print(" ".join(row)) else: print("No solution found:") - From 947e09c1a4d77d5946f069f7729b0e8db945df60 Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Sat, 28 Oct 2023 23:44:30 +0530 Subject: [PATCH 22/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 116 +++++++++++++----------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 240fa3da1ee2..4222fcff07e5 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,7 +1,8 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ - -def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: +def is_valid(puzzle: list[list[str]], + word: str, row: int, + col: int, vertical: bool) -> bool: """ Check if a word can be placed at the given position. @@ -11,16 +12,21 @@ def is_valid(puzzle: list[list[str]], word: str, row: int, col: int) -> bool: ... ['', '', '', ''], ... ['', '', '', ''] ... ] - >>> is_valid(puzzle, 'word', 0, 0) + >>> is_valid(puzzle, 'word', 0, 0, True) + True + >>> is_valid(puzzle, 'word', 0, 0, False) True """ for i in range(len(word)): - if row + i >= len(puzzle) or puzzle[row + i][col] != "": - return False + if vertical: + if row + i >= len(puzzle) or puzzle[row + i][col] != "": + return False + else: + if col + i >= len(puzzle[0]) or puzzle[row][col + i] != "": + return False return True - -def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: +def place_word(puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool) -> None: """ Place a word at the given position. @@ -30,15 +36,17 @@ def place_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: ... ['', '', '', ''], ... ['', '', '', ''] ... ] - >>> place_word(puzzle, 'word', 0, 0) + >>> place_word(puzzle, 'word', 0, 0, True) >>> puzzle [['w', '', '', ''], ['o', '', '', ''], ['r', '', '', ''], ['d', '', '', '']] """ for i in range(len(word)): - puzzle[row + i][col] = word[i] - + if vertical: + puzzle[row + i][col] = word[i] + else: + puzzle[row][col + i] = word[i] -def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: +def remove_word(puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool) -> None: """ Remove a word from the given position. @@ -48,54 +56,56 @@ def remove_word(puzzle: list[list[str]], word: str, row: int, col: int) -> None: ... ['r', '', '', ''], ... ['d', '', '', ''] ... ] - >>> remove_word(puzzle, 'word', 0, 0) + >>> remove_word(puzzle, 'word', 0, 0, True) >>> puzzle [['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']] """ for i in range(len(word)): - puzzle[row + i][col] = "" - + if vertical: + puzzle[row + i][col] = "" + else: + puzzle[row][col + i] = "" def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: - """ - Solve the crossword puzzle using backtracking. - - >>> puzzle = [ - ... ['', '', '', ''], - ... ['', '', '', ''], - ... ['', '', '', ''], - ... ['', '', '', ''] - ... ] - - >>> words = ['word', 'four', 'more', 'last'] - >>> solve_crossword(puzzle, words) - True - >>> words = ['word', 'four', 'more', 'paragraphs'] - >>> solve_crossword(puzzle, words) - False - """ - for row in range(len(puzzle)): - for col in range(len(puzzle[0])): - if puzzle[row][col] == "": - for word in words: - if is_valid(puzzle, word, row, col): - place_word(puzzle, word, row, col) - words.remove(word) - if solve_crossword(puzzle, words): - return True - words.append(word) - remove_word(puzzle, word, row, col) - return False - return True - - -# Replace with your actual puzzle and words -PUZZLE = [["" for _ in range(3)] for _ in range(3)] -WORDS = ["cat", "dog", "pig"] + """ + Solve the crossword puzzle using backtracking. + + >>> puzzle = [ + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''] + ... ] + + >>> words = ['word', 'four', 'more', 'last'] + >>> solve_crossword(puzzle, words) + True + >>> words = ['word', 'four', 'more', 'paragraphs'] + >>> solve_crossword(puzzle, words) + False + """ + for row in range(len(puzzle)): + for col in range(len(puzzle[0])): + if puzzle[row][col] == "": + for word in words: + for vertical in [True, False]: + if is_valid(puzzle, word, row, col, vertical): + place_word(puzzle, word, row, col, vertical) + words.remove(word) + if solve_crossword(puzzle, words): + return True + words.append(word) + remove_word(puzzle, word, row, col, vertical) + return False + return True + +PUZZLE = [["" for _ in range(4)] for _ in range(4)] +WORDS = ['word', 'four', 'more', 'paragraph'] if solve_crossword(PUZZLE, WORDS): - print("Solution found:") - for row in PUZZLE: - print(" ".join(row)) + print("Solution found:") + for row in PUZZLE: + print(" ".join(row)) else: - print("No solution found:") + print("No solution found:") + From f211c619f1728868d2eb8c818ee26a5796145879 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 28 Oct 2023 18:15:06 +0000 Subject: [PATCH 23/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/crossword_puzzle_solver.py | 92 ++++++++++++++----------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 4222fcff07e5..2210e0360a2b 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -1,8 +1,9 @@ # https://www.geeksforgeeks.org/solve-crossword-puzzle/ -def is_valid(puzzle: list[list[str]], - word: str, row: int, - col: int, vertical: bool) -> bool: + +def is_valid( + puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool +) -> bool: """ Check if a word can be placed at the given position. @@ -26,7 +27,10 @@ def is_valid(puzzle: list[list[str]], return False return True -def place_word(puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool) -> None: + +def place_word( + puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool +) -> None: """ Place a word at the given position. @@ -46,7 +50,10 @@ def place_word(puzzle: list[list[str]], word: str, row: int, col: int, vertical: else: puzzle[row][col + i] = word[i] -def remove_word(puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool) -> None: + +def remove_word( + puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool +) -> None: """ Remove a word from the given position. @@ -66,46 +73,47 @@ def remove_word(puzzle: list[list[str]], word: str, row: int, col: int, vertical else: puzzle[row][col + i] = "" + def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: - """ - Solve the crossword puzzle using backtracking. - - >>> puzzle = [ - ... ['', '', '', ''], - ... ['', '', '', ''], - ... ['', '', '', ''], - ... ['', '', '', ''] - ... ] - - >>> words = ['word', 'four', 'more', 'last'] - >>> solve_crossword(puzzle, words) - True - >>> words = ['word', 'four', 'more', 'paragraphs'] - >>> solve_crossword(puzzle, words) - False - """ - for row in range(len(puzzle)): - for col in range(len(puzzle[0])): - if puzzle[row][col] == "": - for word in words: - for vertical in [True, False]: - if is_valid(puzzle, word, row, col, vertical): - place_word(puzzle, word, row, col, vertical) - words.remove(word) - if solve_crossword(puzzle, words): - return True - words.append(word) - remove_word(puzzle, word, row, col, vertical) - return False - return True + """ + Solve the crossword puzzle using backtracking. + + >>> puzzle = [ + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''] + ... ] + + >>> words = ['word', 'four', 'more', 'last'] + >>> solve_crossword(puzzle, words) + True + >>> words = ['word', 'four', 'more', 'paragraphs'] + >>> solve_crossword(puzzle, words) + False + """ + for row in range(len(puzzle)): + for col in range(len(puzzle[0])): + if puzzle[row][col] == "": + for word in words: + for vertical in [True, False]: + if is_valid(puzzle, word, row, col, vertical): + place_word(puzzle, word, row, col, vertical) + words.remove(word) + if solve_crossword(puzzle, words): + return True + words.append(word) + remove_word(puzzle, word, row, col, vertical) + return False + return True + PUZZLE = [["" for _ in range(4)] for _ in range(4)] -WORDS = ['word', 'four', 'more', 'paragraph'] +WORDS = ["word", "four", "more", "paragraph"] if solve_crossword(PUZZLE, WORDS): - print("Solution found:") - for row in PUZZLE: - print(" ".join(row)) + print("Solution found:") + for row in PUZZLE: + print(" ".join(row)) else: - print("No solution found:") - + print("No solution found:") From f0239ae7f493d7925470e960980802349c2667c4 Mon Sep 17 00:00:00 2001 From: Khushi Shukla Date: Sun, 29 Oct 2023 00:11:53 +0530 Subject: [PATCH 24/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 2210e0360a2b..5f6aaf834c1f 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -15,6 +15,12 @@ def is_valid( ... ] >>> is_valid(puzzle, 'word', 0, 0, True) True + >>> puzzle = [ + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''] + ... ] >>> is_valid(puzzle, 'word', 0, 0, False) True """ @@ -88,6 +94,12 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: >>> words = ['word', 'four', 'more', 'last'] >>> solve_crossword(puzzle, words) True + >>> puzzle = [ + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''], + ... ['', '', '', ''] + ... ] >>> words = ['word', 'four', 'more', 'paragraphs'] >>> solve_crossword(puzzle, words) False @@ -108,8 +120,8 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: return True -PUZZLE = [["" for _ in range(4)] for _ in range(4)] -WORDS = ["word", "four", "more", "paragraph"] +PUZZLE = [["" for _ in range(3)] for _ in range(3)] +WORDS = ["cat", "dog", "car"] if solve_crossword(PUZZLE, WORDS): print("Solution found:") From ac0f723c52465731d30fc97857c9b7ba2b88a65a Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 28 Oct 2023 23:07:49 +0200 Subject: [PATCH 25/27] Apply suggestions from code review --- backtracking/crossword_puzzle_solver.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 5f6aaf834c1f..6101caafa610 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -50,11 +50,11 @@ def place_word( >>> puzzle [['w', '', '', ''], ['o', '', '', ''], ['r', '', '', ''], ['d', '', '', '']] """ - for i in range(len(word)): + for i, char in enumerate(word): if vertical: - puzzle[row + i][col] = word[i] + puzzle[row + i][col] = char else: - puzzle[row][col + i] = word[i] + puzzle[row][col + i] = char def remove_word( @@ -120,12 +120,13 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: return True -PUZZLE = [["" for _ in range(3)] for _ in range(3)] -WORDS = ["cat", "dog", "car"] +if __name__ == "__main__": + PUZZLE = [[""] * 3] for _ in range(3)] + WORDS = ("cat", "dog", "car") -if solve_crossword(PUZZLE, WORDS): - print("Solution found:") - for row in PUZZLE: - print(" ".join(row)) -else: - print("No solution found:") + if solve_crossword(PUZZLE, WORDS): + print("Solution found:") + for row in PUZZLE: + print(" ".join(row)) + else: + print("No solution found:") From 13794aa5ed463cf9a60c01b63faa98ed6955a86a Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 28 Oct 2023 23:08:48 +0200 Subject: [PATCH 26/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 6101caafa610..9c0f41c2e3f3 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -121,7 +121,7 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: if __name__ == "__main__": - PUZZLE = [[""] * 3] for _ in range(3)] + PUZZLE = [[""] * 3 for _ in range(3)] WORDS = ("cat", "dog", "car") if solve_crossword(PUZZLE, WORDS): From e6bd5990d341a5c19735b385f74ed068e35039d4 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 28 Oct 2023 23:10:01 +0200 Subject: [PATCH 27/27] Update crossword_puzzle_solver.py --- backtracking/crossword_puzzle_solver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backtracking/crossword_puzzle_solver.py b/backtracking/crossword_puzzle_solver.py index 9c0f41c2e3f3..b9c01c4efea9 100644 --- a/backtracking/crossword_puzzle_solver.py +++ b/backtracking/crossword_puzzle_solver.py @@ -122,7 +122,7 @@ def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool: if __name__ == "__main__": PUZZLE = [[""] * 3 for _ in range(3)] - WORDS = ("cat", "dog", "car") + WORDS = ["cat", "dog", "car"] if solve_crossword(PUZZLE, WORDS): print("Solution found:")