From 7201e9f11ca79b43ecab09fd3f1155fc47c77432 Mon Sep 17 00:00:00 2001 From: Saptadeep Banerjee <69459134+imSanko@users.noreply.github.com> Date: Sun, 1 Oct 2023 15:16:28 +0530 Subject: [PATCH 1/3] Adding the Fibonacci_heap in the DSA>Heap section --- data_structures/heap/fibonacci_heap.py | 98 ++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 data_structures/heap/fibonacci_heap.py diff --git a/data_structures/heap/fibonacci_heap.py b/data_structures/heap/fibonacci_heap.py new file mode 100644 index 000000000000..12c5099d61cc --- /dev/null +++ b/data_structures/heap/fibonacci_heap.py @@ -0,0 +1,98 @@ +class FibonacciNode: + def __init__(self, key): + self.key = key + self.children = [] + self.marked = False + self.degree = 0 + self.parent = None + +class FibonacciHeap: + def __init__(self): + self.trees = [] + self.least = None + self.count = 0 + + def insert(self, key): + new_node = FibonacciNode(key) + self.trees.append(new_node) + self.count += 1 + + if self.least is None or key < self.least.key: + self.least = new_node + + def extract_min(self): + if self.count == 0: + raise ValueError("Heap is empty") + + min_node = self.least + self.trees.remove(min_node) + + for child in min_node.children: + child.parent = None + self.trees.append(child) + + self.count -= 1 + + if self.least is min_node: + self.least = None + for node in self.trees: + if self.least is None or node.key < self.least.key: + self.least = node + + self.consolidate() + + return min_node.key + + def consolidate(self): + degree_counts = [0] * len(self.trees) + + for node in self.trees: + degree_counts[node.degree] += 1 + + new_trees = [] + for i in range(len(degree_counts)): + while degree_counts[i] > 1: + degree_counts[i] -= 1 + + node1 = self.trees.pop() + node2 = self.trees.pop() + + if node1.key < node2.key: + new_node = node1 + new_node.children.append(node2) + else: + new_node = node2 + new_node.children.append(node1) + + new_node.degree += 1 + new_trees.append(new_node) + + self.trees = new_trees + + def decrease_key(self, node, new_key): + if new_key > node.key: + raise ValueError("New key must be less than or equal to old key") + + node.key = new_key + + if node == self.least: + self.least = node + + while node.parent is not None and node.key < node.parent.key: + self.cut(node) + self.cascading_cut(node.parent) + + def cut(self, node): + node.parent.children.remove(node) + node.parent = None + self.trees.append(node) + + node.degree = 0 + node.marked = False + + def cascading_cut(self, node): + if node.marked: + self.cut(node) + + if node.parent is not None: + node.parent.marked = True From 7d9658bf9e35f66cdd17cea24560a904e3b2c0c9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 09:49:22 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- data_structures/heap/fibonacci_heap.py | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/heap/fibonacci_heap.py b/data_structures/heap/fibonacci_heap.py index 12c5099d61cc..db377ca13f41 100644 --- a/data_structures/heap/fibonacci_heap.py +++ b/data_structures/heap/fibonacci_heap.py @@ -6,6 +6,7 @@ def __init__(self, key): self.degree = 0 self.parent = None + class FibonacciHeap: def __init__(self): self.trees = [] From 3e0190382429f26e18ab5f36c900a39596b8deb8 Mon Sep 17 00:00:00 2001 From: Saptadeep Banerjee <69459134+imSanko@users.noreply.github.com> Date: Sun, 1 Oct 2023 16:01:41 +0530 Subject: [PATCH 3/3] Added New Rat Maze in Backtracking --- backtracking/rat_in_maze.py | 48 +++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/backtracking/rat_in_maze.py b/backtracking/rat_in_maze.py index 7bde886dd558..54e254b87cc3 100644 --- a/backtracking/rat_in_maze.py +++ b/backtracking/rat_in_maze.py @@ -60,7 +60,7 @@ def solve_maze(maze: list[list[int]]) -> bool: False """ size = len(maze) - # We need to create solution object to save path. + # We need to create a solution object to save the path. solutions = [[0 for _ in range(size)] for _ in range(size)] solved = run_maze(maze, 0, 0, solutions) if solved: @@ -74,41 +74,43 @@ def run_maze(maze: list[list[int]], i: int, j: int, solutions: list[list[int]]) """ This method is recursive starting from (i, j) and going in one of four directions: up, down, left, right. - If a path is found to destination it returns True otherwise it returns False. + If a path is found to the destination, it returns True; otherwise, it returns False. Parameters: maze(2D matrix) : maze - i, j : coordinates of matrix + i, j : coordinates of the matrix solutions(2D matrix) : solutions Returns: - Boolean if path is found True, Otherwise False. + Boolean if the path is found, True; Otherwise, False. """ size = len(maze) - # Final check point. + # Final checkpoint. if i == j == (size - 1): solutions[i][j] = 1 return True - lower_flag = (not i < 0) and (not j < 0) # Check lower bounds - upper_flag = (i < size) and (j < size) # Check upper bounds + # Check bounds + if ( + i >= 0 + and j >= 0 + and i < size + and j < size + and solutions[i][j] == 0 + and maze[i][j] == 1 + ): + solutions[i][j] = 1 - if lower_flag and upper_flag: - # check for already visited and block points. - block_flag = (not solutions[i][j]) and (not maze[i][j]) - if block_flag: - # check visited - solutions[i][j] = 1 + # Explore in four directions: up, down, left, right + if ( + run_maze(maze, i + 1, j, solutions) + or run_maze(maze, i, j + 1, solutions) + or run_maze(maze, i - 1, j, solutions) + or run_maze(maze, i, j - 1, solutions) + ): + return True - # check for directions - if ( - run_maze(maze, i + 1, j, solutions) - or run_maze(maze, i, j + 1, solutions) - or run_maze(maze, i - 1, j, solutions) - or run_maze(maze, i, j - 1, solutions) - ): - return True + # If none of the directions lead to a solution, backtrack by marking the current position as 0 + solutions[i][j] = 0 - solutions[i][j] = 0 - return False return False