From ee3778f0986ffc0438763010e756836b0f6f989d Mon Sep 17 00:00:00 2001 From: Nicholay Shestakov Date: Sat, 22 Nov 2025 11:15:40 +0300 Subject: [PATCH 1/3] Add Graph class with dfs method --- src/iterators/dfs.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/iterators/dfs.py diff --git a/src/iterators/dfs.py b/src/iterators/dfs.py new file mode 100644 index 0000000..6aff15c --- /dev/null +++ b/src/iterators/dfs.py @@ -0,0 +1,38 @@ +class Graph: + def __init__(self, edges: list[tuple[int, int]]): + self.edges = edges + self.vertices = [] + for edge in edges: + if edge[0] not in self.vertices: + self.vertices.append(edge[0]) + if edge[1] not in self.vertices: + self.vertices.append(edge[1]) + + def dfs(self) -> list[int]: + """Depth-first search algorithm. Returns list of visited vertices.""" + vertices_state = { + "white": self.vertices.copy(), + "gray": list(), + "black": list(), + } + visited_vertices_list = [] + + def dfs_step(vertex): + if vertex in vertices_state["white"]: + visited_vertices_list.append(vertex) + vertices_state["white"].remove(vertex) + vertices_state["gray"].append(vertex) + + for edge in self.edges: + if edge[0] == vertex: + dfs_step(edge[1]) + if edge[1] == vertex: + dfs_step(edge[0]) + + vertices_state["gray"].remove(vertex) + vertices_state["black"].append(vertex) + + for vertex in self.vertices: + dfs_step(vertex) + + return visited_vertices_list From a95441f7360fb3d97ac2826148e6d8e8b418b057 Mon Sep 17 00:00:00 2001 From: Nicholay Shestakov Date: Mon, 24 Nov 2025 20:44:07 +0300 Subject: [PATCH 2/3] Add iterator for Graph class --- src/iterators/dfs.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/iterators/dfs.py b/src/iterators/dfs.py index 6aff15c..e0cf9a7 100644 --- a/src/iterators/dfs.py +++ b/src/iterators/dfs.py @@ -36,3 +36,18 @@ def dfs_step(vertex): dfs_step(vertex) return visited_vertices_list + + def __iter__(self): + return _GraphIterable(self.dfs()) + + +class _GraphIterable: + def __init__(self, dfs_vertices_list): + self.dfs_vertices_list = dfs_vertices_list + self.index = 0 + + def __next__(self): + if self.index < len(self.dfs_vertices_list): + self.index += 1 + return self.dfs_vertices_list[self.index - 1] + raise StopIteration From f3a74d7fa33c5ca4a677067e5d6685ca15cd2c70 Mon Sep 17 00:00:00 2001 From: Nicholay Shestakov Date: Mon, 24 Nov 2025 20:44:41 +0300 Subject: [PATCH 3/3] Add tests for Graph class --- tests/dfs_test.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/dfs_test.py diff --git a/tests/dfs_test.py b/tests/dfs_test.py new file mode 100644 index 0000000..655180a --- /dev/null +++ b/tests/dfs_test.py @@ -0,0 +1,63 @@ +from iterators.dfs import Graph +from random import randint + + +def test_method_simple(): + graph = Graph([(1, 2), (2, 4), (5, 3)]) + assert graph.dfs() == [1, 2, 4, 5, 3] + + +def test_iterator_simple(): + graph = Graph([(1, 2), (2, 4), (5, 3)]) + assert list(graph) == [1, 2, 4, 5, 3] + + +def test_method_zero_elements(): + graph = Graph([]) + assert graph.dfs() == [] + + +def test_iterator_zero_elements(): + graph = Graph([]) + assert list(graph) == [] + + +def test_method_edge_to_same_element(): + graph = Graph([(1, 2), (2, 4), (3, 3)]) + assert graph.dfs() == [1, 2, 4, 3] + + +def test_iterator_edge_to_same_element(): + graph = Graph([(1, 2), (2, 4), (3, 3)]) + assert list(graph) == [1, 2, 4, 3] + + +def test_iterator_possibility_of_parallel_working(): + graph = Graph([(1, 2), (2, 4)]) + result = [] + for i in graph: + for j in graph: + result.append((i, j)) + assert result == [ + (1, 1), + (1, 2), + (1, 4), + (2, 1), + (2, 2), + (2, 4), + (4, 1), + (4, 2), + (4, 4), + ] + + +def test_random_correct_vertices(): + random_edges = [ + (randint(-1000, 1000), randint(-1000, 1000)) for _ in range(randint(1, 1000)) + ] + random_edges_vertices_set = set() + for edge in random_edges: + random_edges_vertices_set.add(edge[0]) + random_edges_vertices_set.add(edge[1]) + graph = Graph(random_edges) + assert sorted(graph.dfs()) == sorted(random_edges_vertices_set)