From ffa67381aa43cdcb0cef1c9c3ecbb5905a035bbc Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Mon, 2 Oct 2023 23:14:54 +0530 Subject: [PATCH 01/26] Create dijkstra_algorithm.py --- greedy_methods/dijkstra_algorithm.py | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 greedy_methods/dijkstra_algorithm.py diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py new file mode 100644 index 000000000000..6e1d8b0ccabc --- /dev/null +++ b/greedy_methods/dijkstra_algorithm.py @@ -0,0 +1,51 @@ +import heapq + +def dijkstra(graph, start): + """ + Shortest path from a starting to all other nodes in a weighted graph + + Args: + graph (dict): Representing the weighted graph in {node: {neighbor: weight}} + start (str): The starting node. + + Returns: + dict: Containing the shortest distance from the start node to all other nodes. + For unreachable nodes, the distance is set to float('inf'). + + Example: + >>> graph = { + ... 'A': {'B': 1, 'C': 4}, + ... 'B': {'A': 1, 'C': 2, 'D': 5}, + ... 'C': {'A': 4, 'B': 2, 'D': 1}, + ... 'D': {'B': 5, 'C': 1}, + ... } + >>> dijkstra(graph, 'A') + {'A': 0, 'B': 1, 'C': 3, 'D': 4} + """ + distances = {node: float('inf') for node in graph} + distances[start] = 0 + priority_queue = [(0, start)] + + while priority_queue: + current_distance, current_node = heapq.heappop(priority_queue) + + if current_distance > distances[current_node]: + continue + + for neighbor, weight in graph[current_node].items(): + distance = current_distance + weight + + if distance < distances[neighbor]: + distances[neighbor] = distance + heapq.heappush(priority_queue, (distance, neighbor)) + + return distances + +if __name__ == "__main__": + import doctest + res = doctest.testmod() + + if res.failed == 0: + print("All tests passed!") + else: + print(f"{res.failed} test(s) failed.") From 6a04fce87611d9818a3dc8924e9c2d4ac4718581 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:50:18 +0000 Subject: [PATCH 02/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- greedy_methods/dijkstra_algorithm.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py index 6e1d8b0ccabc..05d5fe86fb03 100644 --- a/greedy_methods/dijkstra_algorithm.py +++ b/greedy_methods/dijkstra_algorithm.py @@ -1,5 +1,6 @@ import heapq + def dijkstra(graph, start): """ Shortest path from a starting to all other nodes in a weighted graph @@ -22,7 +23,7 @@ def dijkstra(graph, start): >>> dijkstra(graph, 'A') {'A': 0, 'B': 1, 'C': 3, 'D': 4} """ - distances = {node: float('inf') for node in graph} + distances = {node: float("inf") for node in graph} distances[start] = 0 priority_queue = [(0, start)] @@ -41,8 +42,10 @@ def dijkstra(graph, start): return distances + if __name__ == "__main__": import doctest + res = doctest.testmod() if res.failed == 0: From 8faba2488bdd1547593a1eef5f6655d6e34589e7 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Mon, 2 Oct 2023 23:25:18 +0530 Subject: [PATCH 03/26] Update dijkstra_algorithm.py --- greedy_methods/dijkstra_algorithm.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py index 05d5fe86fb03..ed458bc27d18 100644 --- a/greedy_methods/dijkstra_algorithm.py +++ b/greedy_methods/dijkstra_algorithm.py @@ -1,12 +1,12 @@ import heapq +from typing import Dict, Union - -def dijkstra(graph, start): +def dijkstra(graph:Dict[str, Dict[str, int]], start: str)->Dict[str, Union[int, float]]: """ - Shortest path from a starting to all other nodes in a weighted graph + Find the shortest path from a starting node to all other nodes in a weighted graph. Args: - graph (dict): Representing the weighted graph in {node: {neighbor: weight}} + graph (dict): Representing the weighted graph in {node: {neighbor: weight}}. start (str): The starting node. Returns: @@ -23,7 +23,7 @@ def dijkstra(graph, start): >>> dijkstra(graph, 'A') {'A': 0, 'B': 1, 'C': 3, 'D': 4} """ - distances = {node: float("inf") for node in graph} + distances = {node: float('inf') for node in graph} distances[start] = 0 priority_queue = [(0, start)] @@ -42,13 +42,11 @@ def dijkstra(graph, start): return distances - if __name__ == "__main__": import doctest + result = doctest.testmod() - res = doctest.testmod() - - if res.failed == 0: + if result.failed == 0: print("All tests passed!") else: - print(f"{res.failed} test(s) failed.") + print(f"{result.failed} test(s) failed.") From 8521a6b6c15ede2de4efa4575c2a9d637bd79efd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:55:51 +0000 Subject: [PATCH 04/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- greedy_methods/dijkstra_algorithm.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py index ed458bc27d18..3c9e0b9fd04f 100644 --- a/greedy_methods/dijkstra_algorithm.py +++ b/greedy_methods/dijkstra_algorithm.py @@ -1,7 +1,10 @@ import heapq from typing import Dict, Union -def dijkstra(graph:Dict[str, Dict[str, int]], start: str)->Dict[str, Union[int, float]]: + +def dijkstra( + graph: Dict[str, Dict[str, int]], start: str +) -> Dict[str, Union[int, float]]: """ Find the shortest path from a starting node to all other nodes in a weighted graph. @@ -23,7 +26,7 @@ def dijkstra(graph:Dict[str, Dict[str, int]], start: str)->Dict[str, Union[int, >>> dijkstra(graph, 'A') {'A': 0, 'B': 1, 'C': 3, 'D': 4} """ - distances = {node: float('inf') for node in graph} + distances = {node: float("inf") for node in graph} distances[start] = 0 priority_queue = [(0, start)] @@ -42,8 +45,10 @@ def dijkstra(graph:Dict[str, Dict[str, int]], start: str)->Dict[str, Union[int, return distances + if __name__ == "__main__": import doctest + result = doctest.testmod() if result.failed == 0: From e0da2c3f1c2f184208de1db26fe4adc67eeb0c6d Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Mon, 2 Oct 2023 23:29:13 +0530 Subject: [PATCH 05/26] Update dijkstra_algorithm.py --- greedy_methods/dijkstra_algorithm.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py index 3c9e0b9fd04f..a3afc246f720 100644 --- a/greedy_methods/dijkstra_algorithm.py +++ b/greedy_methods/dijkstra_algorithm.py @@ -1,10 +1,7 @@ import heapq -from typing import Dict, Union +from typing import Union - -def dijkstra( - graph: Dict[str, Dict[str, int]], start: str -) -> Dict[str, Union[int, float]]: +def dijkstra(graph:dict[str, dict[str, int]], start: str)->dict[str, Union[int, float]]: """ Find the shortest path from a starting node to all other nodes in a weighted graph. @@ -26,7 +23,7 @@ def dijkstra( >>> dijkstra(graph, 'A') {'A': 0, 'B': 1, 'C': 3, 'D': 4} """ - distances = {node: float("inf") for node in graph} + distances = {node: float('inf') for node in graph} distances[start] = 0 priority_queue = [(0, start)] @@ -45,10 +42,8 @@ def dijkstra( return distances - if __name__ == "__main__": import doctest - result = doctest.testmod() if result.failed == 0: From 934272eb19a1fb875ee838984cb28d36cfa3389d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:59:46 +0000 Subject: [PATCH 06/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- greedy_methods/dijkstra_algorithm.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py index a3afc246f720..16dc711246ab 100644 --- a/greedy_methods/dijkstra_algorithm.py +++ b/greedy_methods/dijkstra_algorithm.py @@ -1,7 +1,10 @@ import heapq from typing import Union -def dijkstra(graph:dict[str, dict[str, int]], start: str)->dict[str, Union[int, float]]: + +def dijkstra( + graph: dict[str, dict[str, int]], start: str +) -> dict[str, Union[int, float]]: """ Find the shortest path from a starting node to all other nodes in a weighted graph. @@ -23,7 +26,7 @@ def dijkstra(graph:dict[str, dict[str, int]], start: str)->dict[str, Union[int, >>> dijkstra(graph, 'A') {'A': 0, 'B': 1, 'C': 3, 'D': 4} """ - distances = {node: float('inf') for node in graph} + distances = {node: float("inf") for node in graph} distances[start] = 0 priority_queue = [(0, start)] @@ -42,8 +45,10 @@ def dijkstra(graph:dict[str, dict[str, int]], start: str)->dict[str, Union[int, return distances + if __name__ == "__main__": import doctest + result = doctest.testmod() if result.failed == 0: From c2e477159f61776317134d7800b156bd1fae029e Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Mon, 2 Oct 2023 23:34:58 +0530 Subject: [PATCH 07/26] Update dijkstra_algorithm.py --- greedy_methods/dijkstra_algorithm.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py index 16dc711246ab..5dd2e3cf95cc 100644 --- a/greedy_methods/dijkstra_algorithm.py +++ b/greedy_methods/dijkstra_algorithm.py @@ -3,8 +3,7 @@ def dijkstra( - graph: dict[str, dict[str, int]], start: str -) -> dict[str, Union[int, float]]: + graph: dict[str, dict[str, int]], start: str) -> dict[str, Union[int, float]]: """ Find the shortest path from a starting node to all other nodes in a weighted graph. From df722eb54e714ca18a53a5c3dcbf2352dd34c11a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:05:33 +0000 Subject: [PATCH 08/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- greedy_methods/dijkstra_algorithm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py index 5dd2e3cf95cc..16dc711246ab 100644 --- a/greedy_methods/dijkstra_algorithm.py +++ b/greedy_methods/dijkstra_algorithm.py @@ -3,7 +3,8 @@ def dijkstra( - graph: dict[str, dict[str, int]], start: str) -> dict[str, Union[int, float]]: + graph: dict[str, dict[str, int]], start: str +) -> dict[str, Union[int, float]]: """ Find the shortest path from a starting node to all other nodes in a weighted graph. From 2888c8b728ea971cfae659821f97a14d969313b9 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Tue, 3 Oct 2023 00:16:24 +0530 Subject: [PATCH 09/26] Delete greedy_methods/dijkstra_algorithm.py --- greedy_methods/dijkstra_algorithm.py | 57 ---------------------------- 1 file changed, 57 deletions(-) delete mode 100644 greedy_methods/dijkstra_algorithm.py diff --git a/greedy_methods/dijkstra_algorithm.py b/greedy_methods/dijkstra_algorithm.py deleted file mode 100644 index 16dc711246ab..000000000000 --- a/greedy_methods/dijkstra_algorithm.py +++ /dev/null @@ -1,57 +0,0 @@ -import heapq -from typing import Union - - -def dijkstra( - graph: dict[str, dict[str, int]], start: str -) -> dict[str, Union[int, float]]: - """ - Find the shortest path from a starting node to all other nodes in a weighted graph. - - Args: - graph (dict): Representing the weighted graph in {node: {neighbor: weight}}. - start (str): The starting node. - - Returns: - dict: Containing the shortest distance from the start node to all other nodes. - For unreachable nodes, the distance is set to float('inf'). - - Example: - >>> graph = { - ... 'A': {'B': 1, 'C': 4}, - ... 'B': {'A': 1, 'C': 2, 'D': 5}, - ... 'C': {'A': 4, 'B': 2, 'D': 1}, - ... 'D': {'B': 5, 'C': 1}, - ... } - >>> dijkstra(graph, 'A') - {'A': 0, 'B': 1, 'C': 3, 'D': 4} - """ - distances = {node: float("inf") for node in graph} - distances[start] = 0 - priority_queue = [(0, start)] - - while priority_queue: - current_distance, current_node = heapq.heappop(priority_queue) - - if current_distance > distances[current_node]: - continue - - for neighbor, weight in graph[current_node].items(): - distance = current_distance + weight - - if distance < distances[neighbor]: - distances[neighbor] = distance - heapq.heappush(priority_queue, (distance, neighbor)) - - return distances - - -if __name__ == "__main__": - import doctest - - result = doctest.testmod() - - if result.failed == 0: - print("All tests passed!") - else: - print(f"{result.failed} test(s) failed.") From 1de4cb5ea8b61d4a00779b9bd389f8ca95f5ddaf Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Tue, 3 Oct 2023 00:24:27 +0530 Subject: [PATCH 10/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 73 +++++++++++++++++------------ 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index fd644230449c..4247d48fb151 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -1,34 +1,47 @@ -# Check whether Graph is Bipartite or Not using DFS - - -# A Bipartite Graph is a graph whose vertices can be divided into two independent sets, -# U and V such that every edge (u, v) either connects a vertex from U to V or a vertex -# from V to U. In other words, for every edge (u, v), either u belongs to U and v to V, -# or u belongs to V and v to U. We can also say that there is no edge that connects -# vertices of same set. -def check_bipartite_dfs(graph): - visited = [False] * len(graph) - color = [-1] * len(graph) - - def dfs(v, c): - visited[v] = True - color[v] = c - for u in graph[v]: - if not visited[u]: - dfs(u, 1 - c) - - for i in range(len(graph)): - if not visited[i]: - dfs(i, 0) - - for i in range(len(graph)): - for j in graph[i]: - if color[i] == color[j]: +from collections import defaultdict + + +def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: + """ + Check whether a graph is Bipartite or not using Depth-First Search (DFS). + + A Bipartite Graph is a graph whose vertices can be divided into two independent + sets, U and V such that every edge (u, v) either connects a vertex from + U to V or a vertex from V to U. In other words, for every edge (u, v), + either u belongs to U and v to V, or u belongs to V and v to U. There is + no edge that connects vertices of the same set. + + Args: + graph (DefaultDict[int, List[int]]): An adjacency list representing the graph. + + Returns: + bool: True if the graph is Bipartite, False otherwise. + + Examples: + >>> graph1=defaultdict(list,{0:[1, 3],1:[0, 2],2:[1, 3],3:[0,2], 4:[]}) + >>> is_bipartite(graph1) + True + + >>> graph2 = defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}) + >>> is_bipartite(graph2) + False + """ + def dfs(node, color): + vis[node] = color + for nbor in graph[node]: + if vis[nbor] == color or (vis[nbor] == -1 and not dfs(nbor, 1 - color)): return False + return True - return True + vis = defaultdict(lambda: -1) + return all(not (vis[node] == -1 and not dfs(node, 0)) for node in graph) -# Adjacency list of graph -graph = {0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: []} -print(check_bipartite_dfs(graph)) +if __name__ == "__main__": + import doctest + result = doctest.testmod() + + if result.failed == 0: + print("All tests passed!") + else: + print(f"{result.failed} test(s) failed.") From 5857640c22add280fd2bbdec70ad61465dd4aea1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:59:58 +0000 Subject: [PATCH 11/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- graphs/check_bipartite_graph_dfs.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 4247d48fb151..003247f26949 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -26,6 +26,7 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: >>> is_bipartite(graph2) False """ + def dfs(node, color): vis[node] = color for nbor in graph[node]: @@ -37,8 +38,10 @@ def dfs(node, color): return all(not (vis[node] == -1 and not dfs(node, 0)) for node in graph) + if __name__ == "__main__": import doctest + result = doctest.testmod() if result.failed == 0: From 4d4bb3e85a2f6218d5498affa8710b6bcda55e45 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Tue, 3 Oct 2023 00:38:50 +0530 Subject: [PATCH 12/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 003247f26949..2c85789e3e35 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -18,7 +18,7 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: bool: True if the graph is Bipartite, False otherwise. Examples: - >>> graph1=defaultdict(list,{0:[1, 3],1:[0, 2],2:[1, 3],3:[0,2], 4:[]}) + >>> graph1=defaultdict(list,{0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: []}) >>> is_bipartite(graph1) True @@ -26,7 +26,6 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: >>> is_bipartite(graph2) False """ - def dfs(node, color): vis[node] = color for nbor in graph[node]: @@ -34,14 +33,12 @@ def dfs(node, color): return False return True - vis = defaultdict(lambda: -1) + vis: defaultdict[int, int] = defaultdict(lambda: -1) return all(not (vis[node] == -1 and not dfs(node, 0)) for node in graph) - if __name__ == "__main__": import doctest - result = doctest.testmod() if result.failed == 0: From 307388b28d74ccb9f290108b2523299dc781c4a0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:09:24 +0000 Subject: [PATCH 13/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- graphs/check_bipartite_graph_dfs.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 2c85789e3e35..7d6f0e7c7695 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -26,6 +26,7 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: >>> is_bipartite(graph2) False """ + def dfs(node, color): vis[node] = color for nbor in graph[node]: @@ -37,8 +38,10 @@ def dfs(node, color): return all(not (vis[node] == -1 and not dfs(node, 0)) for node in graph) + if __name__ == "__main__": import doctest + result = doctest.testmod() if result.failed == 0: From b7522ba3a24f21a4d9cb928b139a377c6cd5472f Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Wed, 4 Oct 2023 23:28:03 +0530 Subject: [PATCH 14/26] Update graphs/check_bipartite_graph_dfs.py Co-authored-by: Christian Clauss --- graphs/check_bipartite_graph_dfs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 7d6f0e7c7695..26924e0ed4eb 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -12,7 +12,7 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: no edge that connects vertices of the same set. Args: - graph (DefaultDict[int, List[int]]): An adjacency list representing the graph. + graph: An adjacency list representing the graph. Returns: bool: True if the graph is Bipartite, False otherwise. From 8f46b7f6911f4c2fb087533748d518821dad35bd Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Wed, 4 Oct 2023 23:29:46 +0530 Subject: [PATCH 15/26] Update graphs/check_bipartite_graph_dfs.py Co-authored-by: Christian Clauss --- graphs/check_bipartite_graph_dfs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 26924e0ed4eb..53a1c25393ba 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -15,7 +15,7 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: graph: An adjacency list representing the graph. Returns: - bool: True if the graph is Bipartite, False otherwise. + True if there is no edge that connects vertices of the same set, False otherwise. Examples: >>> graph1=defaultdict(list,{0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: []}) From 81d6e002075b2bac07876f150dbab8c5b0f7baae Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Wed, 4 Oct 2023 23:31:18 +0530 Subject: [PATCH 16/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 53a1c25393ba..bf5bfa9df963 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -15,7 +15,7 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: graph: An adjacency list representing the graph. Returns: - True if there is no edge that connects vertices of the same set, False otherwise. + True if there's no edge that connects vertices of the same set, False otherwise. Examples: >>> graph1=defaultdict(list,{0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: []}) From 2f62202d3091486f69b34c87563073ab9dfefa86 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Wed, 4 Oct 2023 23:34:04 +0530 Subject: [PATCH 17/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index bf5bfa9df963..b08d8814f16a 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -27,16 +27,16 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: False """ - def dfs(node, color): + def dpthfrst(node, color): vis[node] = color for nbor in graph[node]: - if vis[nbor] == color or (vis[nbor] == -1 and not dfs(nbor, 1 - color)): + if vis[nbor] == color or (vis[nbor] == -1 and not dpthfrst(nbor, 1 - color)): return False return True vis: defaultdict[int, int] = defaultdict(lambda: -1) - return all(not (vis[node] == -1 and not dfs(node, 0)) for node in graph) + return all(not (vis[node] == -1 and not dpthfrst(node, 0)) for node in graph) if __name__ == "__main__": From 55a384eb1b712ada030dbfbdd85dced80fbbfd56 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:05:30 +0000 Subject: [PATCH 18/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- graphs/check_bipartite_graph_dfs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index b08d8814f16a..cfcf1454a70c 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -30,7 +30,9 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: def dpthfrst(node, color): vis[node] = color for nbor in graph[node]: - if vis[nbor] == color or (vis[nbor] == -1 and not dpthfrst(nbor, 1 - color)): + if vis[nbor] == color or ( + vis[nbor] == -1 and not dpthfrst(nbor, 1 - color) + ): return False return True From 74b0d5b85d3176645566f839a1cb5cbf2d522379 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Wed, 4 Oct 2023 23:38:47 +0530 Subject: [PATCH 19/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index cfcf1454a70c..fa195bcec554 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -27,18 +27,13 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: False """ - def dpthfrst(node, color): + def dpth(node, color): vis[node] = color - for nbor in graph[node]: - if vis[nbor] == color or ( - vis[nbor] == -1 and not dpthfrst(nbor, 1 - color) - ): - return False - return True + return any(vis[nbor] == color or (vis[nbor] == -1 and not dpth(nbor, 1 - color)) for nbor in graph[node]) vis: defaultdict[int, int] = defaultdict(lambda: -1) - return all(not (vis[node] == -1 and not dpthfrst(node, 0)) for node in graph) + return all(not (vis[node] == -1 and not dpth(node, 0)) for node in graph) if __name__ == "__main__": From 10a5d0e4b01b82094c800d2d9b058a767e6569b0 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Wed, 4 Oct 2023 23:41:13 +0530 Subject: [PATCH 20/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index fa195bcec554..3d0102bcd235 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -27,9 +27,9 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: False """ - def dpth(node, color): - vis[node] = color - return any(vis[nbor] == color or (vis[nbor] == -1 and not dpth(nbor, 1 - color)) for nbor in graph[node]) + def dpth(node, col): + vis[node] = col + return any(vis[nbor]==col or (vis[nbor]==-1 and not dpth(nbor,1-col)) for nbor in graph[node]) vis: defaultdict[int, int] = defaultdict(lambda: -1) From afd7c07c61e298652a52ff4ca31b91c95022ca34 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:12:48 +0000 Subject: [PATCH 21/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- graphs/check_bipartite_graph_dfs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 3d0102bcd235..4084cac7a915 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -29,7 +29,10 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: def dpth(node, col): vis[node] = col - return any(vis[nbor]==col or (vis[nbor]==-1 and not dpth(nbor,1-col)) for nbor in graph[node]) + return any( + vis[nbor] == col or (vis[nbor] == -1 and not dpth(nbor, 1 - col)) + for nbor in graph[node] + ) vis: defaultdict[int, int] = defaultdict(lambda: -1) From 9b949a03b6272958134e354f7632ca20c9b8e5a8 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Wed, 4 Oct 2023 23:57:14 +0530 Subject: [PATCH 22/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 4084cac7a915..e6f6de7c4ac9 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -18,7 +18,7 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: True if there's no edge that connects vertices of the same set, False otherwise. Examples: - >>> graph1=defaultdict(list,{0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: []}) + >>> graph1 = defaultdict(list,{0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: []}) >>> is_bipartite(graph1) True From 779ccf0b6307b86a04cb6517545a443685740b18 Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Thu, 5 Oct 2023 00:03:49 +0530 Subject: [PATCH 23/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index e6f6de7c4ac9..0a42ce5d1dd3 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -1,7 +1,7 @@ from collections import defaultdict -def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: +def is_bipartite(gph: defaultdict[int, list[int]]) -> bool: """ Check whether a graph is Bipartite or not using Depth-First Search (DFS). @@ -18,12 +18,12 @@ def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: True if there's no edge that connects vertices of the same set, False otherwise. Examples: - >>> graph1 = defaultdict(list,{0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: []}) - >>> is_bipartite(graph1) + >>> gph1 = defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4], 3: [1], 4: [2]}) + >>> is_bipartite(gph1) True - >>> graph2 = defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}) - >>> is_bipartite(graph2) + >>> gph2 = defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}) + >>> is_bipartite(gph2) False """ @@ -31,12 +31,12 @@ def dpth(node, col): vis[node] = col return any( vis[nbor] == col or (vis[nbor] == -1 and not dpth(nbor, 1 - col)) - for nbor in graph[node] + for nbor in gph[node] ) vis: defaultdict[int, int] = defaultdict(lambda: -1) - return all(not (vis[node] == -1 and not dpth(node, 0)) for node in graph) + return all(not (vis[node] == -1 and not dpth(node, 0)) for node in gph) if __name__ == "__main__": From 6d5ed2ae88d123cd0bfc730de77b150a467564bc Mon Sep 17 00:00:00 2001 From: Pronay Debnath Date: Thu, 5 Oct 2023 00:59:40 +0530 Subject: [PATCH 24/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 0a42ce5d1dd3..bdfddee6128f 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -20,11 +20,11 @@ def is_bipartite(gph: defaultdict[int, list[int]]) -> bool: Examples: >>> gph1 = defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4], 3: [1], 4: [2]}) >>> is_bipartite(gph1) - True + False >>> gph2 = defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}) >>> is_bipartite(gph2) - False + True """ def dpth(node, col): From 272d92404d806d87db1a16431bb8293c773d19e9 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 5 Oct 2023 17:35:31 +0200 Subject: [PATCH 25/26] Let's use self-documenting variable names This is complex code so let's use self-documenting function and variable names to help readers to understand. We should not shorten names to simplify the code formatting but use understandable name and leave to code formatting to psf/black. I am not sure if `nbor` was supposed to be `neighbour`. ;-) --- graphs/check_bipartite_graph_dfs.py | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index bdfddee6128f..09a9064a00e5 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -1,6 +1,61 @@ from collections import defaultdict +def is_bipartite(graph: defaultdict[int, list[int]]) -> bool: + """ + Check whether a graph is Bipartite or not using Depth-First Search (DFS). + + A Bipartite Graph is a graph whose vertices can be divided into two independent + sets, U and V such that every edge (u, v) either connects a vertex from + U to V or a vertex from V to U. In other words, for every edge (u, v), + either u belongs to U and v to V, or u belongs to V and v to U. There is + no edge that connects vertices of the same set. + + Args: + graph: An adjacency list representing the graph. + + Returns: + True if there's no edge that connects vertices of the same set, False otherwise. + + Examples: + >>> is_bipartite( + ... defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4], 3: [1], 4: [2]}) + ... ) + False + >>> is_bipartite(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]})) + True + """ + + def depth_first_search(node: int, color: int) -> bool: + visited[node] = color + return any( + visited[neighbour] == color + or ( + visited[neighbour] == -1 + and not depth_first_search(neighbour, 1 - color) + ) + for neighbour in graph[node] + ) + + visited: defaultdict[int, int] = defaultdict(lambda: -1) + + return all( + not (visited[node] == -1 and not depth_first_search(node, 0)) for node in graph + ) + + +if __name__ == "__main__": + import doctest + + result = doctest.testmod() + + if result.failed: + print(f"{result.failed} test(s) failed.") + else: + print("All tests passed!") +from collections import defaultdict + + def is_bipartite(gph: defaultdict[int, list[int]]) -> bool: """ Check whether a graph is Bipartite or not using Depth-First Search (DFS). From 498438bac43458ae2d4b969458c314a801dfd022 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 5 Oct 2023 17:39:22 +0200 Subject: [PATCH 26/26] Update check_bipartite_graph_dfs.py --- graphs/check_bipartite_graph_dfs.py | 50 ----------------------------- 1 file changed, 50 deletions(-) diff --git a/graphs/check_bipartite_graph_dfs.py b/graphs/check_bipartite_graph_dfs.py index 09a9064a00e5..b13a9eb95afb 100644 --- a/graphs/check_bipartite_graph_dfs.py +++ b/graphs/check_bipartite_graph_dfs.py @@ -53,53 +53,3 @@ def depth_first_search(node: int, color: int) -> bool: print(f"{result.failed} test(s) failed.") else: print("All tests passed!") -from collections import defaultdict - - -def is_bipartite(gph: defaultdict[int, list[int]]) -> bool: - """ - Check whether a graph is Bipartite or not using Depth-First Search (DFS). - - A Bipartite Graph is a graph whose vertices can be divided into two independent - sets, U and V such that every edge (u, v) either connects a vertex from - U to V or a vertex from V to U. In other words, for every edge (u, v), - either u belongs to U and v to V, or u belongs to V and v to U. There is - no edge that connects vertices of the same set. - - Args: - graph: An adjacency list representing the graph. - - Returns: - True if there's no edge that connects vertices of the same set, False otherwise. - - Examples: - >>> gph1 = defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4], 3: [1], 4: [2]}) - >>> is_bipartite(gph1) - False - - >>> gph2 = defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}) - >>> is_bipartite(gph2) - True - """ - - def dpth(node, col): - vis[node] = col - return any( - vis[nbor] == col or (vis[nbor] == -1 and not dpth(nbor, 1 - col)) - for nbor in gph[node] - ) - - vis: defaultdict[int, int] = defaultdict(lambda: -1) - - return all(not (vis[node] == -1 and not dpth(node, 0)) for node in gph) - - -if __name__ == "__main__": - import doctest - - result = doctest.testmod() - - if result.failed == 0: - print("All tests passed!") - else: - print(f"{result.failed} test(s) failed.")