From f23a69567b9a959afbbf48ad497f07bfaa62131f Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 15:11:02 +0000 Subject: [PATCH 01/33] docs(graph_view): Add readme about the task --- additional_tasks/graph_view/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 additional_tasks/graph_view/README.md diff --git a/additional_tasks/graph_view/README.md b/additional_tasks/graph_view/README.md new file mode 100644 index 0000000..1ef8d9b --- /dev/null +++ b/additional_tasks/graph_view/README.md @@ -0,0 +1,10 @@ +# Задача на перевод одного и того же графа в его различные представления + +В качестве возможных вариантов хранения графа используются: + +1. Матрица смежности, основанная на двумерном bool векторе +2. Лист смежности, основанный на двумерном size_t векторе +3. Лист смежности, основанных на векторе из unordered_set (то есть без повторения вершин) +4. Список вершин, основанный на векторе пар + +Перевод осуществляется из любого представления в любое. \ No newline at end of file From 116457d7ed44f07b023b3c2a7e72e2710c3248e8 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:02:20 +0000 Subject: [PATCH 02/33] chore(graph_view): Add default CMake file --- additional_tasks/graph_view/CMakeLists.txt | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 additional_tasks/graph_view/CMakeLists.txt diff --git a/additional_tasks/graph_view/CMakeLists.txt b/additional_tasks/graph_view/CMakeLists.txt new file mode 100644 index 0000000..d903dc4 --- /dev/null +++ b/additional_tasks/graph_view/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.10) + +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) +string(REPLACE " " "_" PROJECT_NAME ${PROJECT_NAME}) +project(${PROJECT_NAME} C CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +file(GLOB_RECURSE source_list "src/*.cpp" "src/*.hpp") +file(GLOB_RECURSE lib_source_list "../lib/src/*.cpp" "../lib/src/*.hpp") +file(GLOB_RECURSE main_source_list "src/main.cpp") +file(GLOB_RECURSE test_source_list "src/*.cpp") +file(GLOB_RECURSE test_list "src/*test.cpp") + +list(REMOVE_ITEM test_source_list ${main_source_list}) +list(REMOVE_ITEM source_list ${test_list}) + +include_directories(${PROJECT_NAME} PUBLIC src) +include_directories(${PROJECT_NAME} PUBLIC ../lib/src) + +add_executable(${PROJECT_NAME} ${source_list} ${lib_source_list}) + +# Locate GTest +enable_testing() +find_package(GTest REQUIRED) +include_directories(${GTEST_INCLUDE_DIRS}) + +# Link runTests with what we want to test and the GTest and pthread library +add_executable(${PROJECT_NAME}_tests ${test_source_list}) +target_link_libraries( + ${PROJECT_NAME}_tests + GTest::gtest_main +) + +include(GoogleTest) +gtest_discover_tests(${PROJECT_NAME}_tests) From 5b6ab528ca3e3c9ea7d1710852abd0a7fde07c8e Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:03:26 +0000 Subject: [PATCH 03/33] feat(graph_view): Add operator<< for default structures --- .../graph_view/src/container_couts.h | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 additional_tasks/graph_view/src/container_couts.h diff --git a/additional_tasks/graph_view/src/container_couts.h b/additional_tasks/graph_view/src/container_couts.h new file mode 100644 index 0000000..567eab2 --- /dev/null +++ b/additional_tasks/graph_view/src/container_couts.h @@ -0,0 +1,54 @@ +#ifndef CONTAINER_COUTS_H +#define CONTAINER_COUTS_H + +#include +#include +#include +#include + +template +std::ostream& operator<< (std::ostream& ost, std::pair& v) +{ + ost << '[' << v.first << "," << v.second << ']'; + return ost; +} + +template +std::ostream& operator<< (std::ostream& ost, const std::vector& v) +{ + ost << '['; + if(!v.empty()) + { + auto it = v.begin(); + ost << *it; + ++it; + while(it != v.end()) + { + ost << ',' << *it; + ++it; + } + } + ost << ']'; + return ost; +} + +template +std::ostream& operator<< (std::ostream& ost, const std::unordered_set& v) +{ + ost << '{'; + if(!v.empty()) + { + auto it = v.begin(); + ost << *it; + ++it; + while(it != v.end()) + { + ost << ',' << *it; + ++it; + } + } + ost << '}'; + return ost; +} + +#endif // CONTAINER_COUTS_H \ No newline at end of file From dbb1c521cb478f2c24be257994ae17a02920b06f Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:04:28 +0000 Subject: [PATCH 04/33] feat(graph_view): Add declarations of main classes --- additional_tasks/graph_view/src/graph_view.h | 138 +++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 additional_tasks/graph_view/src/graph_view.h diff --git a/additional_tasks/graph_view/src/graph_view.h b/additional_tasks/graph_view/src/graph_view.h new file mode 100644 index 0000000..3364159 --- /dev/null +++ b/additional_tasks/graph_view/src/graph_view.h @@ -0,0 +1,138 @@ +#ifndef GRAPH_VIEWS_H +#define GRAPH_VIEWS_H + +#include +#include +#include +#include + +class Adjacency_matrix; +class Adjacency_list_vec; +class Adjacency_list_unordered_set; +class Edge_list; + +class Adjacency_matrix +{ +private: + std::vector> data_; +public: + Adjacency_matrix(const size_t size) : data_(size, std::vector(size, 0)) {} + Adjacency_matrix(const std::vector> data) : data_{data} {} + + const std::vector& operator[] (const size_t index) const { return data_[index]; } + std::vector& operator[] (const size_t index) { return data_[index]; } + + friend std::ostream& operator<< (std::ostream &ost, Adjacency_matrix& matrix); + + Adjacency_matrix& operator= (const Adjacency_list_vec& vec_list); + Adjacency_matrix& operator= (const Adjacency_list_unordered_set& list_unord); + Adjacency_matrix& operator= (const Edge_list& edge_list); + + size_t size() const { return data_.size(); } + + const std::vector>::iterator begin() { return data_.begin(); } + const std::vector>::iterator end() { return data_.end(); } + + std::vector> get_matrix() const { return data_; } + void load_matrix(const std::vector> new_data) { data_ = new_data; }; +}; + +class Adjacency_list_vec +{ +private: + std::vector> data_; +public: + Adjacency_list_vec(const size_t size) : data_(size) {} + Adjacency_list_vec(const std::vector> data) : data_{data} {} + + const std::vector& operator[] (const size_t index) const { return data_[index]; } + std::vector& operator[] (const size_t index) { return data_[index]; } + + friend std::ostream& operator<< (std::ostream &ost, Adjacency_list_vec& list_vec); + + bool operator() (const size_t parent, const size_t child) const{ + const std::vector& vec = data_[parent]; + return std::find(vec.begin(), vec.end(), child) != vec.end(); + } + + // add edge between node parent and child + void add_edge(const size_t parent, const size_t child) { data_[parent].push_back(child); } + size_t size() const { return data_.size(); } + + Adjacency_list_vec& operator= (const Adjacency_matrix& matrix); + Adjacency_list_vec& operator= (const Adjacency_list_unordered_set& list); + Adjacency_list_vec& operator= (const Edge_list& list); + + const std::vector>::iterator begin() { return data_.begin(); } + const std::vector>::iterator end() { return data_.end(); } + + std::vector> get_list() const { return data_; } + void load_list(const std::vector> new_data) { data_ = new_data; }; +}; + +class Adjacency_list_unordered_set +{ +private: + std::vector> data_; +public: + Adjacency_list_unordered_set(const size_t size) : data_(size) {} + Adjacency_list_unordered_set(const std::vector> data) : data_{data} {} + + const std::unordered_set& operator[] (const size_t index) const { return data_[index]; } + std::unordered_set& operator[] (const size_t index) { return data_[index]; } + + friend std::ostream& operator<< (std::ostream &ost, Adjacency_list_unordered_set& list_unord_set); + bool operator() (const size_t parent, const size_t child){ + const std::unordered_set& unord_set = data_[parent]; + return std::find(unord_set.begin(), unord_set.end(), child) != unord_set.end(); + } + + // add edge between node parent and child + void add_edge(const size_t parent, const size_t child) { data_[parent].insert(child); } + size_t size() const { return data_.size(); } + + Adjacency_list_unordered_set& operator= (const Adjacency_matrix& matrix); + Adjacency_list_unordered_set& operator= (const Adjacency_list_vec& list); + Adjacency_list_unordered_set& operator= (const Edge_list& list); + + + const std::vector>::iterator begin() { return data_.begin(); } + const std::vector>::iterator end() { return data_.end(); } + + std::vector> get_list() const { return data_; } + void load_list(const std::vector> new_data) { data_ = new_data; }; +}; + +class Edge_list +{ +private: + std::vector> data_; +public: + Edge_list(const size_t size) : data_(size) {} + Edge_list(const std::vector> data) : data_{data} {} + + friend std::ostream& operator<< (std::ostream &ost, Edge_list& edge_list); + bool operator() (const std::pair edge) { return std::find(data_.begin(), data_.end(), edge) != data_.end(); } + bool operator() (const size_t parent, const size_t child) { + std::pair edge(parent, child); + return std::find(data_.begin(), data_.end(), edge) != data_.end(); + } + + // add edge between node parent and child + void add_edge(const size_t parent, const size_t child) { data_.push_back(std::pair (parent, child)); } + void add_edge(const std::pair edge) { data_.push_back(edge); } + size_t size() const { return data_.size(); } + const std::pair& operator[] (const size_t index) const { return data_[index]; } + + Edge_list& operator= (const Adjacency_matrix& matrix); + Edge_list& operator= (const Adjacency_list_vec& list); + Edge_list& operator= (const Adjacency_list_unordered_set& list); + + const std::vector>::iterator begin() { return data_.begin(); } + const std::vector>::iterator end() { return data_.end(); } + + std::vector> get_list() const { return data_; } + void load_list(const std::vector> new_data) { data_ = new_data; }; +}; + +#endif // GRAPH_VIEWS_H From 70deeefb29ef149f33c8b43520d754caeb0f080e Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:05:36 +0000 Subject: [PATCH 05/33] feat(graph_view): Add operators= and << for view classes --- .../graph_view/src/graph_view.cpp | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 additional_tasks/graph_view/src/graph_view.cpp diff --git a/additional_tasks/graph_view/src/graph_view.cpp b/additional_tasks/graph_view/src/graph_view.cpp new file mode 100644 index 0000000..cd74bd7 --- /dev/null +++ b/additional_tasks/graph_view/src/graph_view.cpp @@ -0,0 +1,183 @@ +#include "graph_view.h" +#include "container_couts.h" + +Adjacency_matrix& Adjacency_matrix::operator= (const Adjacency_list_vec& vec_list) +{ + data_.clear(); + data_.resize(vec_list.size(), std::vector(vec_list.size())); + for (size_t vec_index = 0; vec_index < vec_list.size(); vec_index++) + for (size_t index = 0; index < vec_list[vec_index].size(); index++) + data_[vec_index][vec_list[vec_index][index]] = vec_list[vec_index][index] || vec_list[vec_index][index] == 0 ? true : false; + return *this; +} + +Adjacency_matrix& Adjacency_matrix::operator= (const Adjacency_list_unordered_set& unord_list) +{ + data_.clear(); + data_.resize(unord_list.size(), std::vector(unord_list.size())); + for (size_t vec_index = 0; vec_index < unord_list.size(); vec_index++) + for (size_t elem : unord_list[vec_index]) + data_[vec_index][elem] = elem || elem == 0 ? true : false; + return *this; +} + +Adjacency_matrix& Adjacency_matrix::operator= (const Edge_list& edge_list) +{ + data_.clear(); + size_t max_vertex{0}; + for (size_t index = 0; index < edge_list.size(); index++) + { + std::pair pair = edge_list[index]; + size_t parent = pair.first; + size_t child = pair.second; + max_vertex = std::max(max_vertex, std::max(parent, child) + 1); + } + + data_.resize(max_vertex, std::vector(max_vertex)); + + for (size_t index = 0; index < edge_list.size(); index++) + { + std::pair pair = edge_list[index]; + size_t parent = pair.first; + size_t child = pair.second; + size_t max_vertex = std::max(parent, child) + 1; + data_[parent][child] = child || child == 0 ? true : false; + } + return *this; +} + + + + +Adjacency_list_vec& Adjacency_list_vec::operator= (const Adjacency_matrix& matrix) +{ + data_.clear(); + data_.resize(matrix.size()); + for (size_t vertex = 0; vertex < matrix.size(); vertex++) + for (size_t index = 0; index < matrix.size(); index++) + if(matrix[vertex][index]) data_[vertex].push_back(index); + return *this; +} + +Adjacency_list_vec& Adjacency_list_vec::operator= (const Adjacency_list_unordered_set& list) +{ + Adjacency_matrix matrix(3); + matrix = list; + *this = matrix; + return *this; +} + +Adjacency_list_vec& Adjacency_list_vec::operator= (const Edge_list& list) +{ + data_.clear(); + size_t max_vertex{0}; + for (size_t index = 0; index < list.size(); index++) + { + std::pair pair = list[index]; + size_t parent = pair.first; + size_t child = pair.second; + max_vertex = std::max(max_vertex, std::max(parent, child) + 1); + } + data_.resize(max_vertex); + for (size_t index = 0; index < list.size(); index++) + { + std::pair pair = list[index]; + size_t parent = pair.first; + size_t child = pair.second; + data_[parent].push_back(child); + } + return *this; +} + + + + +Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Adjacency_matrix& matrix) +{ + data_.clear(); + data_.resize(matrix.size()); + for (size_t vertex = 0; vertex < matrix.size(); vertex++) + for (size_t index = 0; index < matrix.size(); index++) + if(matrix[vertex][index]) data_[vertex].insert(index); + return *this; +} + +Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Adjacency_list_vec& list) +{ + Adjacency_matrix matrix(3); + matrix = list; + *this = matrix; + return *this; +} + +Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Edge_list& list) +{ + Adjacency_matrix matrix(3); + matrix = list; + *this = matrix; + return *this; +} + + + + +Edge_list& Edge_list::operator= (const Adjacency_matrix& matrix) +{ + data_.clear(); + for (size_t vertex = 0; vertex < matrix.size(); vertex++) + for (size_t index = 0; index < matrix.size(); index++) + if(matrix[vertex][index]) data_.push_back(std::pair (vertex, index)); + return *this; +} + +Edge_list& Edge_list::operator= (const Adjacency_list_vec& list) +{ + data_.clear(); + for(size_t parent = 0; parent < list.size(); parent++) + { + for(size_t child : list[parent]) + data_.push_back(std::pair(parent, child)); + } + return *this; +} + +Edge_list& Edge_list::operator= (const Adjacency_list_unordered_set& list) +{ + Adjacency_matrix matrix(3); + matrix = list; + *this = matrix; + return *this; +} + + + + + +std::ostream& operator<< (std::ostream& ost, Adjacency_matrix& matrix) +{ + for (auto& vec : matrix.data_) + std::cout << vec << std::endl; + return ost; +} + +std::ostream& operator<< (std::ostream& ost, Adjacency_list_vec& list_vec) +{ + size_t i = 0; + for (auto& vec : list_vec.data_) + std::cout << i++ << ":" << vec << std::endl; + return ost; +} + +std::ostream& operator<< (std::ostream& ost, Adjacency_list_unordered_set& list_unord_set) +{ + for (auto& unord_set : list_unord_set.data_) + std::cout << unord_set << std::endl; + return ost; +} + +std::ostream& operator<< (std::ostream& ost, Edge_list& edge_list) +{ + for (auto& pair : edge_list.data_) + std::cout << pair << std::endl; + return ost; +} From 1b8a6bd28b164fa9783b1d72c14afbe7badf0eaa Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:17:19 +0000 Subject: [PATCH 06/33] chore(graph_view): Rename .h to .hpp --- .../graph_view/src/{container_couts.h => container_couts.hpp} | 0 additional_tasks/graph_view/src/{graph_view.h => graph_view.hpp} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename additional_tasks/graph_view/src/{container_couts.h => container_couts.hpp} (100%) rename additional_tasks/graph_view/src/{graph_view.h => graph_view.hpp} (100%) diff --git a/additional_tasks/graph_view/src/container_couts.h b/additional_tasks/graph_view/src/container_couts.hpp similarity index 100% rename from additional_tasks/graph_view/src/container_couts.h rename to additional_tasks/graph_view/src/container_couts.hpp diff --git a/additional_tasks/graph_view/src/graph_view.h b/additional_tasks/graph_view/src/graph_view.hpp similarity index 100% rename from additional_tasks/graph_view/src/graph_view.h rename to additional_tasks/graph_view/src/graph_view.hpp From 487621b6bbe95b19b9b492b899ac9045c320424b Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:18:40 +0000 Subject: [PATCH 07/33] chore(graph_view): Change include from .h to .hpp --- additional_tasks/graph_view/src/graph_view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/additional_tasks/graph_view/src/graph_view.cpp b/additional_tasks/graph_view/src/graph_view.cpp index cd74bd7..74b0f3c 100644 --- a/additional_tasks/graph_view/src/graph_view.cpp +++ b/additional_tasks/graph_view/src/graph_view.cpp @@ -1,5 +1,5 @@ -#include "graph_view.h" -#include "container_couts.h" +#include "graph_view.hpp" +#include "container_couts.hpp" Adjacency_matrix& Adjacency_matrix::operator= (const Adjacency_list_vec& vec_list) { From bd3d21f0f8d046f3612c5def992aa7c6c4fafbdc Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:19:11 +0000 Subject: [PATCH 08/33] chore(graph_view): Add default main.cpp file --- additional_tasks/graph_view/src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 additional_tasks/graph_view/src/main.cpp diff --git a/additional_tasks/graph_view/src/main.cpp b/additional_tasks/graph_view/src/main.cpp new file mode 100644 index 0000000..9ec81e0 --- /dev/null +++ b/additional_tasks/graph_view/src/main.cpp @@ -0,0 +1,3 @@ +#include + +int main() { return 0; } \ No newline at end of file From 44fc6dbbeed28e2089582893a45db1c766f4d6b1 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:19:33 +0000 Subject: [PATCH 09/33] test(graph_view): Add tests for view classes --- additional_tasks/graph_view/src/test.cpp | 216 +++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 additional_tasks/graph_view/src/test.cpp diff --git a/additional_tasks/graph_view/src/test.cpp b/additional_tasks/graph_view/src/test.cpp new file mode 100644 index 0000000..54d75c5 --- /dev/null +++ b/additional_tasks/graph_view/src/test.cpp @@ -0,0 +1,216 @@ +#include + +#include "graph_view.hpp" + +using namespace testing; + +TEST(Graphs_view_test_system, Adjacency_matrix_base) +{ + Adjacency_matrix x(5); + x[0][1] = 1; + ASSERT_EQ(x[2][3], 0); + ASSERT_EQ(x[0][1], 1); + Adjacency_matrix y(std::vector> { + {0,1,1,0,1,0}, + {1,1,1,0,0,0}, + {0,0,1,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}}); + ASSERT_EQ(y[0][3], 0); + ASSERT_EQ(y[1][1], 1); +} + +TEST(Graphs_view_test_system, Adjacency_matrix_convertion) +{ + Adjacency_matrix matrix_1(3); + Adjacency_matrix matrix_2(3); + Adjacency_matrix matrix_3(3); + Adjacency_list_unordered_set unord_set_list(std::vector>{ + {1,2,4}, + {0,1,2,2}, + {2}, + {}, + {}, + {}, + }); + Adjacency_list_vec vec_list(std::vector>{ + {1,2,4}, + {0,1,2,2}, + {2}, + {}, + {}, + {}, + }); + Edge_list edge_list(std::vector> + {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); + + matrix_1 = vec_list; + std::vector> result_vec{ + {0,1,1,0,1,0}, + {1,1,1,0,0,0}, + {0,0,1,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}}; + ASSERT_EQ(matrix_1.get_matrix(), result_vec); + + matrix_2 = unord_set_list; + ASSERT_EQ(matrix_2.get_matrix(), result_vec); + + matrix_3 = edge_list; + result_vec = std::vector>{ + {0,1,1,0,1}, + {1,1,1,0,0}, + {0,0,1,0,0}, + {0,0,0,0,0}, + {0,0,0,0,0}}; + ASSERT_EQ(matrix_3.get_matrix(), result_vec); +} + +TEST(Graphs_view_test_system, Adjacency_list_vec_convertion) +{ + Adjacency_matrix matrix(std::vector>{ + {0,1,1,0,1,0}, + {0,1,1,0,0,0}, + {0,0,1,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}}); + Adjacency_list_vec vec_list_1(3); + vec_list_1 = matrix; + std::vector> result_vec{ + {1,2,4}, + {1,2}, + {2}, + {}, + {}, + {}}; + ASSERT_EQ(vec_list_1.get_list(), result_vec); + + Adjacency_list_vec vec_list_2(3); + Adjacency_list_unordered_set unord_set_list( + std::vector>{ + {1,2,4}, + {0,1,2,2}, + {2}, + {}, + {}, + {}}); + vec_list_2 = unord_set_list; + result_vec = std::vector>{ + {1,2,4}, + {0,1,2}, + {2}, + {}, + {}, + {}}; + ASSERT_EQ(vec_list_2.get_list(), result_vec); + + Adjacency_list_vec vec_list_3(3); + Edge_list edge_list(std::vector> + {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); + vec_list_3 = edge_list; + result_vec = std::vector>{ + {1,2,4}, + {0,1,2,2}, + {2}, + {}, + {}}; + ASSERT_EQ(vec_list_3.get_list(), result_vec); +} + +TEST(Graphs_view_test_system, Adjacency_list_unordered_set_convertion) +{ + Adjacency_list_unordered_set unord_set_list_1(3); + + Adjacency_matrix matrix(std::vector>{ + {0,1,1,0,1,0}, + {0,1,1,0,0,0}, + {0,0,1,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}}); + unord_set_list_1 = matrix; + std::vector> result_unord_set{ + {1,2,4}, + {1,2}, + {2}, + {}, + {}, + {}}; + ASSERT_EQ(unord_set_list_1.get_list(), result_unord_set); + + Adjacency_list_unordered_set unord_set_list_2(3); + Adjacency_list_vec vec_list(std::vector>{ + {1,2,4}, + {0,1,2,2}, + {2}, + {}, + {}, + {}}); + unord_set_list_2 = vec_list; + result_unord_set = std::vector>{ + {1,2,4}, + {0,1,2}, + {2}, + {}, + {}, + {}}; + ASSERT_EQ(unord_set_list_2.get_list(), result_unord_set); + + Adjacency_list_unordered_set unord_set_list_3(3); + Edge_list edge_list(std::vector> + {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); + unord_set_list_3 = edge_list; + result_unord_set = std::vector>{ + {1,2,4}, + {0,1,2}, + {2}, + {}, + {}}; + ASSERT_EQ(unord_set_list_3.get_list(), result_unord_set); +} + +TEST(Graphs_view_test_system, Edge_list_convertion) +{ + Adjacency_matrix matrix(std::vector>{ + {0,1,1,0,1,0}, + {0,1,1,0,0,0}, + {0,0,1,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}, + {0,0,0,0,0,0}}); + Edge_list edge_list_1(3); + edge_list_1 = matrix; + std::vector> result_list( + {{0,1},{0,2},{0,4},{1,1},{1,2},{2,2}}); + ASSERT_EQ(edge_list_1.get_list(), result_list); + + Adjacency_list_vec vec_list = (std::vector>{ + {1,2,4}, + {0,1,2,2}, + {2}, + {}, + {}, + {}}); + Edge_list edge_list_2(3); + edge_list_2 = vec_list; + result_list = std::vector>( + {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); + ASSERT_EQ(edge_list_2.get_list(), result_list); + + Adjacency_list_unordered_set unord_set_list( + std::vector>{ + {1,2,4}, + {0,1,2,2}, + {2}, + {}, + {}, + {}}); + Edge_list edge_list_3(3); + edge_list_3 = unord_set_list; + result_list = std::vector>( + {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{2,2}}); + ASSERT_EQ(edge_list_3.get_list(), result_list); +} From 97f229debbaa430bff5cc23eec096fdc05de7848 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Sun, 12 Nov 2023 16:16:48 +0000 Subject: [PATCH 10/33] feat(topology_sort): Add Vertex class for graph --- task_01/src/topology_sort.hpp | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/task_01/src/topology_sort.hpp b/task_01/src/topology_sort.hpp index 6f70f09..864875c 100644 --- a/task_01/src/topology_sort.hpp +++ b/task_01/src/topology_sort.hpp @@ -1 +1,38 @@ #pragma once + +#include +#include + +/* +Taryan algotirthm is used there: https://ru.wikipedia.org/wiki/Топологическая_сортировка +In these interpreatation all vertices can be: + 1) "white" (if not visited) + 2) "black" (if visited) + 3) "gray" (if gone in but not gone out) +*/ + +namespace Colour +{ + std::string white = "white"; + std::string gray = "gray"; + std::string black = "black"; +} + +class Vertex +{ + /* Struct of a vertex in a graph */ + + public: + Vertex(Vertex* parent = nullptr): + _parent{parent} {} + + Vertex* get_parent() {return _parent; }; + std::vector get_children() {return _children; }; + + void add_child(Vertex* children) {_children.push_back(children); }; + + private: + Vertex* _parent = nullptr; + std::vector _children; + std::string _colour = Colour::white; // possbile colours are "white", "gray" and "'black" +} From bf9ff2102b58b0986d1c772ca3e5271831424ed2 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Sun, 12 Nov 2023 17:21:50 +0000 Subject: [PATCH 11/33] feat(vertex): Add number field for Vertex class --- task_01/src/topology_sort.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/task_01/src/topology_sort.hpp b/task_01/src/topology_sort.hpp index 864875c..9fc76ee 100644 --- a/task_01/src/topology_sort.hpp +++ b/task_01/src/topology_sort.hpp @@ -23,8 +23,8 @@ class Vertex /* Struct of a vertex in a graph */ public: - Vertex(Vertex* parent = nullptr): - _parent{parent} {} + Vertex(size_t number, Vertex* parent = nullptr): + _parent{parent}, _number{number} {} Vertex* get_parent() {return _parent; }; std::vector get_children() {return _children; }; @@ -32,6 +32,7 @@ class Vertex void add_child(Vertex* children) {_children.push_back(children); }; private: + size_t _number; Vertex* _parent = nullptr; std::vector _children; std::string _colour = Colour::white; // possbile colours are "white", "gray" and "'black" From 0e185bf15befd009863b0683921aaaf8bf72e89f Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Sun, 12 Nov 2023 17:24:27 +0000 Subject: [PATCH 12/33] feat(vertex): Change namespace to enum --- task_01/src/topology_sort.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/task_01/src/topology_sort.hpp b/task_01/src/topology_sort.hpp index 9fc76ee..37099c4 100644 --- a/task_01/src/topology_sort.hpp +++ b/task_01/src/topology_sort.hpp @@ -11,12 +11,12 @@ In these interpreatation all vertices can be: 3) "gray" (if gone in but not gone out) */ -namespace Colour +enum Colour { - std::string white = "white"; - std::string gray = "gray"; - std::string black = "black"; -} + WHITE, + GRAY, + BLACK, +}; class Vertex { @@ -35,5 +35,6 @@ class Vertex size_t _number; Vertex* _parent = nullptr; std::vector _children; - std::string _colour = Colour::white; // possbile colours are "white", "gray" and "'black" -} + Colour _colour = WHITE; // possbile colours are "white", "gray" and "'black" +}; + From c0bb076ba8137ba7036cdbbe40e24641fa9f7a57 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Sun, 12 Nov 2023 17:25:07 +0000 Subject: [PATCH 13/33] feat(vertex): Add method to change Vertex --- task_01/src/topology_sort.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/task_01/src/topology_sort.hpp b/task_01/src/topology_sort.hpp index 37099c4..af8f073 100644 --- a/task_01/src/topology_sort.hpp +++ b/task_01/src/topology_sort.hpp @@ -27,9 +27,10 @@ class Vertex _parent{parent}, _number{number} {} Vertex* get_parent() {return _parent; }; - std::vector get_children() {return _children; }; + std::vector get_children() { return _children; }; - void add_child(Vertex* children) {_children.push_back(children); }; + void add_child(Vertex* children) { _children.push_back(children); }; + void change_colour(Colour new_colour) { this->_colour = new_colour; }; private: size_t _number; From b5df347eef482532bc045c681889982e4b1c4cc2 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Sun, 12 Nov 2023 17:28:07 +0000 Subject: [PATCH 14/33] feat(topology_sort): Add Graph class --- task_01/src/topology_sort.cpp | 19 +++++++++++++++++++ task_01/src/topology_sort.hpp | 14 ++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/task_01/src/topology_sort.cpp b/task_01/src/topology_sort.cpp index e53f670..b4515f9 100644 --- a/task_01/src/topology_sort.cpp +++ b/task_01/src/topology_sort.cpp @@ -1 +1,20 @@ +#include + #include "topology_sort.hpp" + +void Graph::add_element(Vertex* parent) +{ + Vertex v = Vertex(this->_cur_number, parent); + this->_cur_number++; +} + +std::vector Graph::topology_sort() +{ + if (this->_roots.empty()) + throw std::runtime_error("Graph is empty. Nothing to sort"); + + // for(Vertex* root : this->_roots) + // { + // root. + // } +} diff --git a/task_01/src/topology_sort.hpp b/task_01/src/topology_sort.hpp index af8f073..5ece9f7 100644 --- a/task_01/src/topology_sort.hpp +++ b/task_01/src/topology_sort.hpp @@ -39,3 +39,17 @@ class Vertex Colour _colour = WHITE; // possbile colours are "white", "gray" and "'black" }; +class Graph +{ + public: + Graph(bool root=false){ + if (root) + this->_roots.push_back(new Vertex(this->_cur_number++)); + } + + void add_element(Vertex* parent=nullptr); // add new element to the graph + std::vector topology_sort(); // get sorted vertices + private: + std::vector _roots; // vector with all roots in graph + size_t _cur_number = 1; // number of last added vertex +}; From 7446f0b2dc5eea1a843e4b95fd5834e2b3ead3a4 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Sun, 26 Nov 2023 14:39:16 +0000 Subject: [PATCH 15/33] style: Change classes' and functions' names --- .../graph_view/src/container_couts.hpp | 5 +- .../graph_view/src/graph_view.cpp | 40 ++++----- .../graph_view/src/graph_view.hpp | 88 +++++++++---------- additional_tasks/graph_view/src/test.cpp | 76 ++++++++-------- 4 files changed, 103 insertions(+), 106 deletions(-) diff --git a/additional_tasks/graph_view/src/container_couts.hpp b/additional_tasks/graph_view/src/container_couts.hpp index 567eab2..ce38f1e 100644 --- a/additional_tasks/graph_view/src/container_couts.hpp +++ b/additional_tasks/graph_view/src/container_couts.hpp @@ -1,5 +1,4 @@ -#ifndef CONTAINER_COUTS_H -#define CONTAINER_COUTS_H +#pragma #include #include @@ -50,5 +49,3 @@ std::ostream& operator<< (std::ostream& ost, const std::unordered_set& v) ost << '}'; return ost; } - -#endif // CONTAINER_COUTS_H \ No newline at end of file diff --git a/additional_tasks/graph_view/src/graph_view.cpp b/additional_tasks/graph_view/src/graph_view.cpp index 74b0f3c..bbb5dbb 100644 --- a/additional_tasks/graph_view/src/graph_view.cpp +++ b/additional_tasks/graph_view/src/graph_view.cpp @@ -1,7 +1,7 @@ #include "graph_view.hpp" #include "container_couts.hpp" -Adjacency_matrix& Adjacency_matrix::operator= (const Adjacency_list_vec& vec_list) +AdjacencyMatrix& AdjacencyMatrix::operator= (const AdjacencyListVec& vec_list) { data_.clear(); data_.resize(vec_list.size(), std::vector(vec_list.size())); @@ -11,7 +11,7 @@ Adjacency_matrix& Adjacency_matrix::operator= (const Adjacency_list_vec& vec_lis return *this; } -Adjacency_matrix& Adjacency_matrix::operator= (const Adjacency_list_unordered_set& unord_list) +AdjacencyMatrix& AdjacencyMatrix::operator= (const AdjacencyListUnorderedSet& unord_list) { data_.clear(); data_.resize(unord_list.size(), std::vector(unord_list.size())); @@ -21,7 +21,7 @@ Adjacency_matrix& Adjacency_matrix::operator= (const Adjacency_list_unordered_se return *this; } -Adjacency_matrix& Adjacency_matrix::operator= (const Edge_list& edge_list) +AdjacencyMatrix& AdjacencyMatrix::operator= (const EdgeList& edge_list) { data_.clear(); size_t max_vertex{0}; @@ -49,7 +49,7 @@ Adjacency_matrix& Adjacency_matrix::operator= (const Edge_list& edge_list) -Adjacency_list_vec& Adjacency_list_vec::operator= (const Adjacency_matrix& matrix) +AdjacencyListVec& AdjacencyListVec::operator= (const AdjacencyMatrix& matrix) { data_.clear(); data_.resize(matrix.size()); @@ -59,15 +59,15 @@ Adjacency_list_vec& Adjacency_list_vec::operator= (const Adjacency_matrix& matri return *this; } -Adjacency_list_vec& Adjacency_list_vec::operator= (const Adjacency_list_unordered_set& list) +AdjacencyListVec& AdjacencyListVec::operator= (const AdjacencyListUnorderedSet& list) { - Adjacency_matrix matrix(3); + AdjacencyMatrix matrix(3); matrix = list; *this = matrix; return *this; } -Adjacency_list_vec& Adjacency_list_vec::operator= (const Edge_list& list) +AdjacencyListVec& AdjacencyListVec::operator= (const EdgeList& list) { data_.clear(); size_t max_vertex{0}; @@ -92,7 +92,7 @@ Adjacency_list_vec& Adjacency_list_vec::operator= (const Edge_list& list) -Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Adjacency_matrix& matrix) +AdjacencyListUnorderedSet& AdjacencyListUnorderedSet::operator= (const AdjacencyMatrix& matrix) { data_.clear(); data_.resize(matrix.size()); @@ -102,17 +102,17 @@ Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Adj return *this; } -Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Adjacency_list_vec& list) +AdjacencyListUnorderedSet& AdjacencyListUnorderedSet::operator= (const AdjacencyListVec& list) { - Adjacency_matrix matrix(3); + AdjacencyMatrix matrix(3); matrix = list; *this = matrix; return *this; } -Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Edge_list& list) +AdjacencyListUnorderedSet& AdjacencyListUnorderedSet::operator= (const EdgeList& list) { - Adjacency_matrix matrix(3); + AdjacencyMatrix matrix(3); matrix = list; *this = matrix; return *this; @@ -121,7 +121,7 @@ Adjacency_list_unordered_set& Adjacency_list_unordered_set::operator= (const Edg -Edge_list& Edge_list::operator= (const Adjacency_matrix& matrix) +EdgeList& EdgeList::operator= (const AdjacencyMatrix& matrix) { data_.clear(); for (size_t vertex = 0; vertex < matrix.size(); vertex++) @@ -130,7 +130,7 @@ Edge_list& Edge_list::operator= (const Adjacency_matrix& matrix) return *this; } -Edge_list& Edge_list::operator= (const Adjacency_list_vec& list) +EdgeList& EdgeList::operator= (const AdjacencyListVec& list) { data_.clear(); for(size_t parent = 0; parent < list.size(); parent++) @@ -141,9 +141,9 @@ Edge_list& Edge_list::operator= (const Adjacency_list_vec& list) return *this; } -Edge_list& Edge_list::operator= (const Adjacency_list_unordered_set& list) +EdgeList& EdgeList::operator= (const AdjacencyListUnorderedSet& list) { - Adjacency_matrix matrix(3); + AdjacencyMatrix matrix(3); matrix = list; *this = matrix; return *this; @@ -153,14 +153,14 @@ Edge_list& Edge_list::operator= (const Adjacency_list_unordered_set& list) -std::ostream& operator<< (std::ostream& ost, Adjacency_matrix& matrix) +std::ostream& operator<< (std::ostream& ost, AdjacencyMatrix& matrix) { for (auto& vec : matrix.data_) std::cout << vec << std::endl; return ost; } -std::ostream& operator<< (std::ostream& ost, Adjacency_list_vec& list_vec) +std::ostream& operator<< (std::ostream& ost, AdjacencyListVec& list_vec) { size_t i = 0; for (auto& vec : list_vec.data_) @@ -168,14 +168,14 @@ std::ostream& operator<< (std::ostream& ost, Adjacency_list_vec& list_vec) return ost; } -std::ostream& operator<< (std::ostream& ost, Adjacency_list_unordered_set& list_unord_set) +std::ostream& operator<< (std::ostream& ost, AdjacencyListUnorderedSet& list_unord_set) { for (auto& unord_set : list_unord_set.data_) std::cout << unord_set << std::endl; return ost; } -std::ostream& operator<< (std::ostream& ost, Edge_list& edge_list) +std::ostream& operator<< (std::ostream& ost, EdgeList& edge_list) { for (auto& pair : edge_list.data_) std::cout << pair << std::endl; diff --git a/additional_tasks/graph_view/src/graph_view.hpp b/additional_tasks/graph_view/src/graph_view.hpp index 3364159..5b90ba7 100644 --- a/additional_tasks/graph_view/src/graph_view.hpp +++ b/additional_tasks/graph_view/src/graph_view.hpp @@ -6,49 +6,49 @@ #include #include -class Adjacency_matrix; -class Adjacency_list_vec; -class Adjacency_list_unordered_set; -class Edge_list; +class AdjacencyMatrix; +class AdjacencyListVec; +class AdjacencyListUnorderedSet; +class EdgeList; -class Adjacency_matrix +class AdjacencyMatrix { private: std::vector> data_; public: - Adjacency_matrix(const size_t size) : data_(size, std::vector(size, 0)) {} - Adjacency_matrix(const std::vector> data) : data_{data} {} + AdjacencyMatrix(const size_t size) : data_(size, std::vector(size, 0)) {} + AdjacencyMatrix(const std::vector> data) : data_{data} {} const std::vector& operator[] (const size_t index) const { return data_[index]; } std::vector& operator[] (const size_t index) { return data_[index]; } - friend std::ostream& operator<< (std::ostream &ost, Adjacency_matrix& matrix); + friend std::ostream& operator<< (std::ostream &ost, AdjacencyMatrix& matrix); - Adjacency_matrix& operator= (const Adjacency_list_vec& vec_list); - Adjacency_matrix& operator= (const Adjacency_list_unordered_set& list_unord); - Adjacency_matrix& operator= (const Edge_list& edge_list); + AdjacencyMatrix& operator= (const AdjacencyListVec& vec_list); + AdjacencyMatrix& operator= (const AdjacencyListUnorderedSet& list_unord); + AdjacencyMatrix& operator= (const EdgeList& edge_list); size_t size() const { return data_.size(); } const std::vector>::iterator begin() { return data_.begin(); } const std::vector>::iterator end() { return data_.end(); } - std::vector> get_matrix() const { return data_; } - void load_matrix(const std::vector> new_data) { data_ = new_data; }; + std::vector> GetMatrix() const { return data_; } + void LoadMatrix(const std::vector> new_data) { data_ = new_data; }; }; -class Adjacency_list_vec +class AdjacencyListVec { private: std::vector> data_; public: - Adjacency_list_vec(const size_t size) : data_(size) {} - Adjacency_list_vec(const std::vector> data) : data_{data} {} + AdjacencyListVec(const size_t size) : data_(size) {} + AdjacencyListVec(const std::vector> data) : data_{data} {} const std::vector& operator[] (const size_t index) const { return data_[index]; } std::vector& operator[] (const size_t index) { return data_[index]; } - friend std::ostream& operator<< (std::ostream &ost, Adjacency_list_vec& list_vec); + friend std::ostream& operator<< (std::ostream &ost, AdjacencyListVec& list_vec); bool operator() (const size_t parent, const size_t child) const{ const std::vector& vec = data_[parent]; @@ -56,62 +56,62 @@ class Adjacency_list_vec } // add edge between node parent and child - void add_edge(const size_t parent, const size_t child) { data_[parent].push_back(child); } + void AddEdge(const size_t parent, const size_t child) { data_[parent].push_back(child); } size_t size() const { return data_.size(); } - Adjacency_list_vec& operator= (const Adjacency_matrix& matrix); - Adjacency_list_vec& operator= (const Adjacency_list_unordered_set& list); - Adjacency_list_vec& operator= (const Edge_list& list); + AdjacencyListVec& operator= (const AdjacencyMatrix& matrix); + AdjacencyListVec& operator= (const AdjacencyListUnorderedSet& list); + AdjacencyListVec& operator= (const EdgeList& list); const std::vector>::iterator begin() { return data_.begin(); } const std::vector>::iterator end() { return data_.end(); } - std::vector> get_list() const { return data_; } - void load_list(const std::vector> new_data) { data_ = new_data; }; + std::vector> GetList() const { return data_; } + void LoadList(const std::vector> new_data) { data_ = new_data; }; }; -class Adjacency_list_unordered_set +class AdjacencyListUnorderedSet { private: std::vector> data_; public: - Adjacency_list_unordered_set(const size_t size) : data_(size) {} - Adjacency_list_unordered_set(const std::vector> data) : data_{data} {} + AdjacencyListUnorderedSet(const size_t size) : data_(size) {} + AdjacencyListUnorderedSet(const std::vector> data) : data_{data} {} const std::unordered_set& operator[] (const size_t index) const { return data_[index]; } std::unordered_set& operator[] (const size_t index) { return data_[index]; } - friend std::ostream& operator<< (std::ostream &ost, Adjacency_list_unordered_set& list_unord_set); + friend std::ostream& operator<< (std::ostream &ost, AdjacencyListUnorderedSet& list_unord_set); bool operator() (const size_t parent, const size_t child){ const std::unordered_set& unord_set = data_[parent]; return std::find(unord_set.begin(), unord_set.end(), child) != unord_set.end(); } // add edge between node parent and child - void add_edge(const size_t parent, const size_t child) { data_[parent].insert(child); } + void AddEdge(const size_t parent, const size_t child) { data_[parent].insert(child); } size_t size() const { return data_.size(); } - Adjacency_list_unordered_set& operator= (const Adjacency_matrix& matrix); - Adjacency_list_unordered_set& operator= (const Adjacency_list_vec& list); - Adjacency_list_unordered_set& operator= (const Edge_list& list); + AdjacencyListUnorderedSet& operator= (const AdjacencyMatrix& matrix); + AdjacencyListUnorderedSet& operator= (const AdjacencyListVec& list); + AdjacencyListUnorderedSet& operator= (const EdgeList& list); const std::vector>::iterator begin() { return data_.begin(); } const std::vector>::iterator end() { return data_.end(); } - std::vector> get_list() const { return data_; } - void load_list(const std::vector> new_data) { data_ = new_data; }; + std::vector> GetList() const { return data_; } + void LoadList(const std::vector> new_data) { data_ = new_data; }; }; -class Edge_list +class EdgeList { private: std::vector> data_; public: - Edge_list(const size_t size) : data_(size) {} - Edge_list(const std::vector> data) : data_{data} {} + EdgeList(const size_t size) : data_(size) {} + EdgeList(const std::vector> data) : data_{data} {} - friend std::ostream& operator<< (std::ostream &ost, Edge_list& edge_list); + friend std::ostream& operator<< (std::ostream &ost, EdgeList& edge_list); bool operator() (const std::pair edge) { return std::find(data_.begin(), data_.end(), edge) != data_.end(); } bool operator() (const size_t parent, const size_t child) { std::pair edge(parent, child); @@ -119,20 +119,20 @@ class Edge_list } // add edge between node parent and child - void add_edge(const size_t parent, const size_t child) { data_.push_back(std::pair (parent, child)); } - void add_edge(const std::pair edge) { data_.push_back(edge); } + void AddEdge(const size_t parent, const size_t child) { data_.push_back(std::pair (parent, child)); } + void AddEdge(const std::pair edge) { data_.push_back(edge); } size_t size() const { return data_.size(); } const std::pair& operator[] (const size_t index) const { return data_[index]; } - Edge_list& operator= (const Adjacency_matrix& matrix); - Edge_list& operator= (const Adjacency_list_vec& list); - Edge_list& operator= (const Adjacency_list_unordered_set& list); + EdgeList& operator= (const AdjacencyMatrix& matrix); + EdgeList& operator= (const AdjacencyListVec& list); + EdgeList& operator= (const AdjacencyListUnorderedSet& list); const std::vector>::iterator begin() { return data_.begin(); } const std::vector>::iterator end() { return data_.end(); } - std::vector> get_list() const { return data_; } - void load_list(const std::vector> new_data) { data_ = new_data; }; + std::vector> GetList() const { return data_; } + void LoadList(const std::vector> new_data) { data_ = new_data; }; }; #endif // GRAPH_VIEWS_H diff --git a/additional_tasks/graph_view/src/test.cpp b/additional_tasks/graph_view/src/test.cpp index 54d75c5..76bcbfb 100644 --- a/additional_tasks/graph_view/src/test.cpp +++ b/additional_tasks/graph_view/src/test.cpp @@ -6,11 +6,11 @@ using namespace testing; TEST(Graphs_view_test_system, Adjacency_matrix_base) { - Adjacency_matrix x(5); + AdjacencyMatrix x(5); x[0][1] = 1; ASSERT_EQ(x[2][3], 0); ASSERT_EQ(x[0][1], 1); - Adjacency_matrix y(std::vector> { + AdjacencyMatrix y(std::vector> { {0,1,1,0,1,0}, {1,1,1,0,0,0}, {0,0,1,0,0,0}, @@ -23,10 +23,10 @@ TEST(Graphs_view_test_system, Adjacency_matrix_base) TEST(Graphs_view_test_system, Adjacency_matrix_convertion) { - Adjacency_matrix matrix_1(3); - Adjacency_matrix matrix_2(3); - Adjacency_matrix matrix_3(3); - Adjacency_list_unordered_set unord_set_list(std::vector>{ + AdjacencyMatrix matrix_1(3); + AdjacencyMatrix matrix_2(3); + AdjacencyMatrix matrix_3(3); + AdjacencyListUnorderedSet unord_set_list(std::vector>{ {1,2,4}, {0,1,2,2}, {2}, @@ -34,7 +34,7 @@ TEST(Graphs_view_test_system, Adjacency_matrix_convertion) {}, {}, }); - Adjacency_list_vec vec_list(std::vector>{ + AdjacencyListVec vec_list(std::vector>{ {1,2,4}, {0,1,2,2}, {2}, @@ -42,7 +42,7 @@ TEST(Graphs_view_test_system, Adjacency_matrix_convertion) {}, {}, }); - Edge_list edge_list(std::vector> + EdgeList edge_list(std::vector> {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); matrix_1 = vec_list; @@ -53,10 +53,10 @@ TEST(Graphs_view_test_system, Adjacency_matrix_convertion) {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}}; - ASSERT_EQ(matrix_1.get_matrix(), result_vec); + ASSERT_EQ(matrix_1.GetMatrix(), result_vec); matrix_2 = unord_set_list; - ASSERT_EQ(matrix_2.get_matrix(), result_vec); + ASSERT_EQ(matrix_2.GetMatrix(), result_vec); matrix_3 = edge_list; result_vec = std::vector>{ @@ -65,19 +65,19 @@ TEST(Graphs_view_test_system, Adjacency_matrix_convertion) {0,0,1,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}; - ASSERT_EQ(matrix_3.get_matrix(), result_vec); + ASSERT_EQ(matrix_3.GetMatrix(), result_vec); } TEST(Graphs_view_test_system, Adjacency_list_vec_convertion) { - Adjacency_matrix matrix(std::vector>{ + AdjacencyMatrix matrix(std::vector>{ {0,1,1,0,1,0}, {0,1,1,0,0,0}, {0,0,1,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}}); - Adjacency_list_vec vec_list_1(3); + AdjacencyListVec vec_list_1(3); vec_list_1 = matrix; std::vector> result_vec{ {1,2,4}, @@ -86,10 +86,10 @@ TEST(Graphs_view_test_system, Adjacency_list_vec_convertion) {}, {}, {}}; - ASSERT_EQ(vec_list_1.get_list(), result_vec); + ASSERT_EQ(vec_list_1.GetList(), result_vec); - Adjacency_list_vec vec_list_2(3); - Adjacency_list_unordered_set unord_set_list( + AdjacencyListVec vec_list_2(3); + AdjacencyListUnorderedSet unord_set_list( std::vector>{ {1,2,4}, {0,1,2,2}, @@ -105,10 +105,10 @@ TEST(Graphs_view_test_system, Adjacency_list_vec_convertion) {}, {}, {}}; - ASSERT_EQ(vec_list_2.get_list(), result_vec); + ASSERT_EQ(vec_list_2.GetList(), result_vec); - Adjacency_list_vec vec_list_3(3); - Edge_list edge_list(std::vector> + AdjacencyListVec vec_list_3(3); + EdgeList edge_list(std::vector> {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); vec_list_3 = edge_list; result_vec = std::vector>{ @@ -117,14 +117,14 @@ TEST(Graphs_view_test_system, Adjacency_list_vec_convertion) {2}, {}, {}}; - ASSERT_EQ(vec_list_3.get_list(), result_vec); + ASSERT_EQ(vec_list_3.GetList(), result_vec); } TEST(Graphs_view_test_system, Adjacency_list_unordered_set_convertion) { - Adjacency_list_unordered_set unord_set_list_1(3); + AdjacencyListUnorderedSet unord_set_list_1(3); - Adjacency_matrix matrix(std::vector>{ + AdjacencyMatrix matrix(std::vector>{ {0,1,1,0,1,0}, {0,1,1,0,0,0}, {0,0,1,0,0,0}, @@ -139,10 +139,10 @@ TEST(Graphs_view_test_system, Adjacency_list_unordered_set_convertion) {}, {}, {}}; - ASSERT_EQ(unord_set_list_1.get_list(), result_unord_set); + ASSERT_EQ(unord_set_list_1.GetList(), result_unord_set); - Adjacency_list_unordered_set unord_set_list_2(3); - Adjacency_list_vec vec_list(std::vector>{ + AdjacencyListUnorderedSet unord_set_list_2(3); + AdjacencyListVec vec_list(std::vector>{ {1,2,4}, {0,1,2,2}, {2}, @@ -157,10 +157,10 @@ TEST(Graphs_view_test_system, Adjacency_list_unordered_set_convertion) {}, {}, {}}; - ASSERT_EQ(unord_set_list_2.get_list(), result_unord_set); + ASSERT_EQ(unord_set_list_2.GetList(), result_unord_set); - Adjacency_list_unordered_set unord_set_list_3(3); - Edge_list edge_list(std::vector> + AdjacencyListUnorderedSet unord_set_list_3(3); + EdgeList edge_list(std::vector> {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); unord_set_list_3 = edge_list; result_unord_set = std::vector>{ @@ -169,38 +169,38 @@ TEST(Graphs_view_test_system, Adjacency_list_unordered_set_convertion) {2}, {}, {}}; - ASSERT_EQ(unord_set_list_3.get_list(), result_unord_set); + ASSERT_EQ(unord_set_list_3.GetList(), result_unord_set); } TEST(Graphs_view_test_system, Edge_list_convertion) { - Adjacency_matrix matrix(std::vector>{ + AdjacencyMatrix matrix(std::vector>{ {0,1,1,0,1,0}, {0,1,1,0,0,0}, {0,0,1,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}}); - Edge_list edge_list_1(3); + EdgeList edge_list_1(3); edge_list_1 = matrix; std::vector> result_list( {{0,1},{0,2},{0,4},{1,1},{1,2},{2,2}}); - ASSERT_EQ(edge_list_1.get_list(), result_list); + ASSERT_EQ(edge_list_1.GetList(), result_list); - Adjacency_list_vec vec_list = (std::vector>{ + AdjacencyListVec vec_list = (std::vector>{ {1,2,4}, {0,1,2,2}, {2}, {}, {}, {}}); - Edge_list edge_list_2(3); + EdgeList edge_list_2(3); edge_list_2 = vec_list; result_list = std::vector>( {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{1,2},{2,2}}); - ASSERT_EQ(edge_list_2.get_list(), result_list); + ASSERT_EQ(edge_list_2.GetList(), result_list); - Adjacency_list_unordered_set unord_set_list( + AdjacencyListUnorderedSet unord_set_list( std::vector>{ {1,2,4}, {0,1,2,2}, @@ -208,9 +208,9 @@ TEST(Graphs_view_test_system, Edge_list_convertion) {}, {}, {}}); - Edge_list edge_list_3(3); + EdgeList edge_list_3(3); edge_list_3 = unord_set_list; result_list = std::vector>( {{0,1},{0,2},{0,4},{1,0},{1,1},{1,2},{2,2}}); - ASSERT_EQ(edge_list_3.get_list(), result_list); + ASSERT_EQ(edge_list_3.GetList(), result_list); } From fa5b00a22ce59515bbfec6ea8efc4181ef29837e Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:12:00 +0000 Subject: [PATCH 16/33] fix(CMake): Fix bug with lUtil --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06c6f26..cc9a45a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(homeworks) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/sandbox) +#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/sandbox) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/additional_tasks) From b2d1c2de82d4819ace9c70e695f899cb17942a46 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:12:25 +0000 Subject: [PATCH 17/33] feat(sort): Add topology sort --- task_01/src/test.cpp | 16 +++++++++- task_01/src/topology_sort.cpp | 58 ++++++++++++++++++++++++++++++----- task_01/src/topology_sort.hpp | 34 +++++++++++--------- 3 files changed, 84 insertions(+), 24 deletions(-) diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index ef5a86a..149fbc0 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -4,5 +4,19 @@ #include "topology_sort.hpp" TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] + Vertex v0(0); + Vertex v1(1); + Vertex v2(2); + Vertex v3(3); + AddEdge(&v1, &v0); + AddEdge(&v2, &v0); + AddEdge(&v3, &v0); + + Graph graph; + graph.AddRoot(&v1); + graph.AddRoot(&v2); + graph.AddRoot(&v3); + + std::vector answer = {1, 0, 2, 3}; + ASSERT_EQ(graph.TopologySort(), answer); } diff --git a/task_01/src/topology_sort.cpp b/task_01/src/topology_sort.cpp index b4515f9..4e046df 100644 --- a/task_01/src/topology_sort.cpp +++ b/task_01/src/topology_sort.cpp @@ -2,19 +2,61 @@ #include "topology_sort.hpp" -void Graph::add_element(Vertex* parent) +void Graph::AddRoot(Vertex* root) { - Vertex v = Vertex(this->_cur_number, parent); - this->_cur_number++; + this->_roots.push_back(root); } -std::vector Graph::topology_sort() +void Graph::AddElement(int number, std::vector parents) +{ + if (parents.empty()) + throw std::runtime_error("Vertex has no parents"); + + Vertex v = Vertex(number, parents); +} + +std::vector Graph::TopologySort() { if (this->_roots.empty()) throw std::runtime_error("Graph is empty. Nothing to sort"); - // for(Vertex* root : this->_roots) - // { - // root. - // } + std::vector result; + for(Vertex* root : this->_roots) + { + root->ChangeColour(GRAY); + std::vector current_sorting = this->_TopologySort(root); + root->ChangeColour(BLACK); + result.push_back(root->GetNumber()); + result.insert(result.end(), current_sorting.begin(), current_sorting.end()); + } + return result; } + +std::vector Graph::_TopologySort(Vertex* root) +{ + std::vector result; + + for (Vertex* vertex : root->GetChildren()) + { + Colour vertex_colour = vertex->GetColour(); + if(vertex_colour == WHITE) + { + vertex->ChangeColour(GRAY); + std::vector current_sorting = this->_TopologySort(vertex); + vertex->ChangeColour(BLACK); + result.push_back(vertex->GetNumber()); + result.insert(result.end(), current_sorting.begin(), current_sorting.end()); + } + else if (vertex_colour == BLACK) + continue; + else if (vertex_colour == GRAY) + throw std::runtime_error("There is a cycle in the graph"); + } + return result; +} + +void AddEdge(Vertex* root, Vertex* child) +{ + child->AddParent(root); + root->AddChild(child); +} \ No newline at end of file diff --git a/task_01/src/topology_sort.hpp b/task_01/src/topology_sort.hpp index 5ece9f7..e58af00 100644 --- a/task_01/src/topology_sort.hpp +++ b/task_01/src/topology_sort.hpp @@ -23,18 +23,21 @@ class Vertex /* Struct of a vertex in a graph */ public: - Vertex(size_t number, Vertex* parent = nullptr): - _parent{parent}, _number{number} {} + Vertex(int number, std::vector parents = std::vector()): + _parents{parents}, _number{number} {} - Vertex* get_parent() {return _parent; }; - std::vector get_children() { return _children; }; + std::vector GetParents() {return _parents; } + std::vector GetChildren() { return _children; } + Colour GetColour() { return _colour; } + int GetNumber() { return _number; } - void add_child(Vertex* children) { _children.push_back(children); }; - void change_colour(Colour new_colour) { this->_colour = new_colour; }; + void AddChild(Vertex* children) { _children.push_back(children); } + void ChangeColour(Colour new_colour) { this->_colour = new_colour; } + void AddParent(Vertex* parent) { _parents.push_back(parent); } private: - size_t _number; - Vertex* _parent = nullptr; + int _number; + std::vector _parents; std::vector _children; Colour _colour = WHITE; // possbile colours are "white", "gray" and "'black" }; @@ -42,14 +45,15 @@ class Vertex class Graph { public: - Graph(bool root=false){ - if (root) - this->_roots.push_back(new Vertex(this->_cur_number++)); - } + Graph() = default; - void add_element(Vertex* parent=nullptr); // add new element to the graph - std::vector topology_sort(); // get sorted vertices + void AddRoot(Vertex* root); // add new root to the graph + void AddElement(int number, std::vector parents); // add new element to the graph + std::vector TopologySort(); // get sorted vertices private: + std::vector _TopologySort(Vertex* vertex); // recursion of topology sort for this vertex std::vector _roots; // vector with all roots in graph - size_t _cur_number = 1; // number of last added vertex + // size_t _cur_number = 1; // number of last added vertex }; + +void AddEdge(Vertex* root, Vertex* child); \ No newline at end of file From 35e517548dffe1d0573cbf232e003cbf75bf72b4 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:17:48 +0000 Subject: [PATCH 18/33] feat(task_2): Add initial files --- task_02/src/algorithm.cpp | 1 + task_02/src/algorithm.hpp | 1 + 2 files changed, 2 insertions(+) create mode 100644 task_02/src/algorithm.cpp create mode 100644 task_02/src/algorithm.hpp diff --git a/task_02/src/algorithm.cpp b/task_02/src/algorithm.cpp new file mode 100644 index 0000000..470c262 --- /dev/null +++ b/task_02/src/algorithm.cpp @@ -0,0 +1 @@ +#include "algorithm.hpp" \ No newline at end of file diff --git a/task_02/src/algorithm.hpp b/task_02/src/algorithm.hpp new file mode 100644 index 0000000..7b9637e --- /dev/null +++ b/task_02/src/algorithm.hpp @@ -0,0 +1 @@ +#pragma once \ No newline at end of file From 1b8a92a127e1b9a8f89ba62e56d8ec025c088580 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:29:40 +0000 Subject: [PATCH 19/33] feat(task_2): Add class of graph --- task_02/src/graph.hpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 task_02/src/graph.hpp diff --git a/task_02/src/graph.hpp b/task_02/src/graph.hpp new file mode 100644 index 0000000..e6554a0 --- /dev/null +++ b/task_02/src/graph.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + + +class AdjacencyListVec +{ +private: + std::vector> data_; +public: + AdjacencyListVec(const size_t size) : data_(size) {} + AdjacencyListVec(const std::vector> data) : data_{data} {} + + const std::vector& operator[] (const size_t index) const { return data_[index]; } + std::vector& operator[] (const size_t index) { return data_[index]; } + + bool operator() (const size_t parent, const size_t child) const{ + const std::vector& vec = data_[parent]; + return std::find(vec.begin(), vec.end(), child) != vec.end(); + } + + // add edge between node parent and child + void AddEdge(const size_t parent, const size_t child) { data_[parent].push_back(child); } + size_t size() const { return data_.size(); } + + const std::vector>::iterator begin() { return data_.begin(); } + const std::vector>::iterator end() { return data_.end(); } + + std::vector> GetList() const { return data_; } + void LoadList(const std::vector> new_data) { data_ = new_data; }; +}; \ No newline at end of file From 2198fcbd41dd3a19ee7999559f406b6aa8f01bb6 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 1 Dec 2023 19:05:13 +0000 Subject: [PATCH 20/33] feat(task_3): Add class graph and algorithms --- task_02/src/graph.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ task_02/src/graph.hpp | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 task_02/src/graph.cpp diff --git a/task_02/src/graph.cpp b/task_02/src/graph.cpp new file mode 100644 index 0000000..e475f6e --- /dev/null +++ b/task_02/src/graph.cpp @@ -0,0 +1,42 @@ +#include "graph.hpp" + +void Graph::Dfs(int vertex, int parent) +{ + timer_++; + tin_[vertex] = timer_; + ret_[vertex] = tin_[vertex]; + size_t children = 0; + for (auto to : data_[vertex]) + { + if (to == parent) + continue; + if (used_[to]) + ret_[vertex] = std::min(ret_[vertex], tin_[to]); + else + { + Dfs(to, vertex); + ret_[vertex] = std::min(ret_[vertex], ret_[to]); + children += 1; // for root case + if (ret_[to] == tin_[to]) + bridges_.push_back(std::pair (vertex, to)); + if (ret_[to] >= tin_[vertex] and parent != -1) + dots_.push_back(vertex); + } + if (parent == -1 && children > 1) + dots_.push_back(vertex); + } +} + +std::vector FindRouters(Graph& g) +{ + if (g.empty()) + g.FindBridgesAndDots(); + return g.GetDotes(); +} + +std::vector> FindWires(Graph& g) +{ + if (g.empty()) + g.FindBridgesAndDots(); + return g.GetBridges(); +} diff --git a/task_02/src/graph.hpp b/task_02/src/graph.hpp index e6554a0..3e4a051 100644 --- a/task_02/src/graph.hpp +++ b/task_02/src/graph.hpp @@ -3,19 +3,29 @@ #include -class AdjacencyListVec +class Graph { private: - std::vector> data_; + std::vector> data_; + size_t timer_; + std::vector tin_; // times of enter in vertex + std::vector ret_; // ret_[v] = min(tin_[v], tin_[u]), where u - vertex before v (it can be not reacheable from v) + std::vector used_; // visited vertexes + + std::vector dots_; // joint points + std::vector> bridges_; + + void Dfs(int vertex, int parent=-1); + public: - AdjacencyListVec(const size_t size) : data_(size) {} - AdjacencyListVec(const std::vector> data) : data_{data} {} + Graph(const size_t size) : data_(size) {} + Graph(const std::vector> data) : data_{data} {} const std::vector& operator[] (const size_t index) const { return data_[index]; } - std::vector& operator[] (const size_t index) { return data_[index]; } + std::vector& operator[] (const size_t index) { return data_[index]; } bool operator() (const size_t parent, const size_t child) const{ - const std::vector& vec = data_[parent]; + const std::vector& vec = data_[parent]; return std::find(vec.begin(), vec.end(), child) != vec.end(); } @@ -23,9 +33,18 @@ class AdjacencyListVec void AddEdge(const size_t parent, const size_t child) { data_[parent].push_back(child); } size_t size() const { return data_.size(); } - const std::vector>::iterator begin() { return data_.begin(); } - const std::vector>::iterator end() { return data_.end(); } + const std::vector>::iterator begin() { return data_.begin(); } + const std::vector>::iterator end() { return data_.end(); } - std::vector> GetList() const { return data_; } + std::vector> GetList() const { return data_; } void LoadList(const std::vector> new_data) { data_ = new_data; }; -}; \ No newline at end of file + + void FindBridgesAndDots() { Dfs(0); }; + std::vector> GetBridges() { return bridges_; }; + std::vector GetDotes() { return dots_; }; + + bool empty() { return data_.empty(); }; +}; + +std::vector FindRouters(Graph& g); +std::vector> FindWires(Graph& g); \ No newline at end of file From 34466835589b386c0c53e93c93a108b095a8f24d Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 1 Dec 2023 19:05:33 +0000 Subject: [PATCH 21/33] chore(tasl_3): Delete unnecessary files --- task_02/src/algorithm.cpp | 1 - task_02/src/algorithm.hpp | 1 - 2 files changed, 2 deletions(-) delete mode 100644 task_02/src/algorithm.cpp delete mode 100644 task_02/src/algorithm.hpp diff --git a/task_02/src/algorithm.cpp b/task_02/src/algorithm.cpp deleted file mode 100644 index 470c262..0000000 --- a/task_02/src/algorithm.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "algorithm.hpp" \ No newline at end of file diff --git a/task_02/src/algorithm.hpp b/task_02/src/algorithm.hpp deleted file mode 100644 index 7b9637e..0000000 --- a/task_02/src/algorithm.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once \ No newline at end of file From 6bb638d1c8fdd94e7ef4b59fc26164b480548853 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Wed, 3 Jan 2024 09:57:31 +0000 Subject: [PATCH 22/33] fix(task_2): Change int to size_t, fix used_ --- task_02/src/graph.cpp | 15 ++++++++------- task_02/src/graph.hpp | 36 +++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/task_02/src/graph.cpp b/task_02/src/graph.cpp index e475f6e..20c54fd 100644 --- a/task_02/src/graph.cpp +++ b/task_02/src/graph.cpp @@ -1,10 +1,11 @@ #include "graph.hpp" -void Graph::Dfs(int vertex, int parent) +void Graph::Dfs(size_t vertex, size_t parent) { timer_++; tin_[vertex] = timer_; ret_[vertex] = tin_[vertex]; + used_[vertex] = true; size_t children = 0; for (auto to : data_[vertex]) { @@ -18,25 +19,25 @@ void Graph::Dfs(int vertex, int parent) ret_[vertex] = std::min(ret_[vertex], ret_[to]); children += 1; // for root case if (ret_[to] == tin_[to]) - bridges_.push_back(std::pair (vertex, to)); + bridges_.push_back(std::pair (vertex, to)); if (ret_[to] >= tin_[vertex] and parent != -1) dots_.push_back(vertex); } - if (parent == -1 && children > 1) + if (parent == -1 && children > 1) // it's root dots_.push_back(vertex); } } -std::vector FindRouters(Graph& g) +std::vector FindRouters(Graph& g) { - if (g.empty()) + if (g.Empty()) g.FindBridgesAndDots(); return g.GetDotes(); } -std::vector> FindWires(Graph& g) +std::vector> FindWires(Graph& g) { - if (g.empty()) + if (g.Empty()) g.FindBridgesAndDots(); return g.GetBridges(); } diff --git a/task_02/src/graph.hpp b/task_02/src/graph.hpp index 3e4a051..948ca3a 100644 --- a/task_02/src/graph.hpp +++ b/task_02/src/graph.hpp @@ -1,31 +1,33 @@ #pragma once #include +#include class Graph { private: - std::vector> data_; + std::vector> data_; size_t timer_; std::vector tin_; // times of enter in vertex std::vector ret_; // ret_[v] = min(tin_[v], tin_[u]), where u - vertex before v (it can be not reacheable from v) std::vector used_; // visited vertexes - std::vector dots_; // joint points - std::vector> bridges_; + std::vector dots_; // articulation points + std::vector> bridges_; - void Dfs(int vertex, int parent=-1); + void Dfs(size_t vertex, size_t parent=-1); + bool calculation_done = false; // if dots and bridges have already found public: - Graph(const size_t size) : data_(size) {} - Graph(const std::vector> data) : data_{data} {} + Graph(const size_t size) : data_(size), tin_(size), ret_(size), used_(size) {} + Graph(const std::vector> data) : data_{data}, tin_(data.size()), ret_(data.size()), used_(data.size()) {} - const std::vector& operator[] (const size_t index) const { return data_[index]; } - std::vector& operator[] (const size_t index) { return data_[index]; } + std::vector operator[] (const size_t index) const { return data_[index]; } + // check if edge exist between parent and child bool operator() (const size_t parent, const size_t child) const{ - const std::vector& vec = data_[parent]; + const std::vector& vec = data_[parent]; return std::find(vec.begin(), vec.end(), child) != vec.end(); } @@ -33,18 +35,18 @@ class Graph void AddEdge(const size_t parent, const size_t child) { data_[parent].push_back(child); } size_t size() const { return data_.size(); } - const std::vector>::iterator begin() { return data_.begin(); } - const std::vector>::iterator end() { return data_.end(); } + const std::vector>::iterator begin() { return data_.begin(); } + const std::vector>::iterator end() { return data_.end(); } - std::vector> GetList() const { return data_; } + std::vector> GetList() const { return data_; } void LoadList(const std::vector> new_data) { data_ = new_data; }; void FindBridgesAndDots() { Dfs(0); }; - std::vector> GetBridges() { return bridges_; }; - std::vector GetDotes() { return dots_; }; + std::vector> GetBridges() { return bridges_; }; + std::vector GetDotes() { return dots_; }; - bool empty() { return data_.empty(); }; + bool Empty() { return !calculation_done; }; }; -std::vector FindRouters(Graph& g); -std::vector> FindWires(Graph& g); \ No newline at end of file +std::vector FindRouters(Graph& g); +std::vector> FindWires(Graph& g); \ No newline at end of file From a65ed0f2552887a22ff56b3e115527b6eb81a7da Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Wed, 3 Jan 2024 09:57:43 +0000 Subject: [PATCH 23/33] test(task 2): Add tests --- task_02/src/test.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index 5e11617..be06910 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,6 +1,30 @@ #include +#include "graph.hpp" +#include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(Routers, Simple) { + Graph g(6); + g.AddEdge(0, 1); + g.AddEdge(1, 2); + g.AddEdge(2, 0); + g.AddEdge(2, 3); + g.AddEdge(3, 4); + g.AddEdge(4, 5); + g.AddEdge(5, 3); + std::vector answer = {3, 2}; + ASSERT_EQ(FindRouters(g), answer); // Stack [] } + +TEST(Bridges, Simple) { + Graph g(6); + g.AddEdge(0, 1); + g.AddEdge(1, 2); + g.AddEdge(2, 0); + g.AddEdge(2, 3); + g.AddEdge(3, 4); + g.AddEdge(4, 5); + g.AddEdge(5, 3); + std::vector> answer = {std::pair{2, 3}}; + ASSERT_EQ(FindWires(g), answer); // Stack [] +} \ No newline at end of file From c0f455179c436e5a65b9d7975a2a8d8a54fd9d54 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:49:26 +0000 Subject: [PATCH 24/33] feat(task_3): Add solution of task 3 --- task_03/src/algo.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++ task_03/src/algo.hpp | 34 ++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 task_03/src/algo.cpp create mode 100644 task_03/src/algo.hpp diff --git a/task_03/src/algo.cpp b/task_03/src/algo.cpp new file mode 100644 index 0000000..7a12a77 --- /dev/null +++ b/task_03/src/algo.cpp @@ -0,0 +1,95 @@ +#include "algo.hpp" + +// Bellman-Ford algorithm to find shortest path from source to all other vertices +std::vector Graph::BellmanFord(int source) { + std::vector distance(vertex_count, INF); + distance[source] = 0; + + // Relax all edges |V| - 1 times + for (int i = 0; i < vertex_count - 1; ++i) { + for (const auto& edge : edges) { + int u = edge.source; + int v = edge.destination; + int w = edge.weight; + if (distance[u] != INF && distance[u] + w < distance[v]) { + distance[v] = distance[u] + w; + } + } + } + + // Check for negative-weight cycles + for (const auto& edge : edges) { + int u = edge.source; + int v = edge.destination; + int w = edge.weight; + if (distance[u] != INF && distance[u] + w < distance[v]) { + std::cout << "Graph contains negative-weight cycle!\n"; + return {}; + } + } + + return distance; +} + +// Dijkstra's algorithm to find shortest path from given source vertex to all other vertices +std::vector Graph::Dijkstra(int source) { + std::vector distance(vertex_count, INF); + distance[source] = 0; + + auto compare = [](const std::pair& a, const std::pair& b) { + return a.second > b.second; + }; + std::priority_queue, std::vector>, decltype(compare)> pq(compare); + pq.push({source, 0}); + + while (!pq.empty()) { + int u = pq.top().first; + pq.pop(); + + for (const auto& edge : edges) { + if (edge.source == u) { + int v = edge.destination; + int w = edge.weight; + if (distance[u] != INF && distance[u] + w < distance[v]) { + distance[v] = distance[u] + w; + pq.push({v, distance[v]}); + } + } + } + } + + return distance; +} + +// Johnson's algorithm to find shortest paths between all pairs of vertices +std::vector> Graph::JohnsonsAlgorithm() { + // Add an extra vertex with zero-weight edges to all other vertices + for (int i = 0; i < vertex_count; ++i) + edges.push_back({vertex_count, i, 0}); + + // Run Bellman-Ford algorithm from the extra vertex + std::vector phi = BellmanFord(vertex_count); + + std::vector> distance_matrix(vertex_count, std::vector(vertex_count, INF)); + + // Re-weight the edges + for (auto& edge : edges) { + int u = edge.source; + int v = edge.destination; + int w = edge.weight; + if (phi[u] != INF && phi[u] != INF) { + edge.weight = w + phi[u] - phi[v]; + } + } + + // Run Dijkstra's algorithm for every vertex + for (int i = 0; i < vertex_count; ++i) { + std::vector distance = Dijkstra(i); + for (int j = 0; j < vertex_count; ++j) { + if (distance[j] != INF) + distance_matrix[i][j] = distance[j] + phi[j] - phi[i]; + } + } + + return distance_matrix; +} \ No newline at end of file diff --git a/task_03/src/algo.hpp b/task_03/src/algo.hpp new file mode 100644 index 0000000..8481f75 --- /dev/null +++ b/task_03/src/algo.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include +#include + +#define INF std::numeric_limits::max() + +// Structure to represent a weighted edge +struct Edge { + int source; + int destination; + int weight; +}; + +// Graph class +class Graph { +private: + int vertex_count; // Number of vertices + std::vector edges; // Vector to store graph edges + +public: + Graph(int V) : vertex_count(V) {} + + // Add an edge to the graph + void AddEdge(int source, int destination, int weight) { + edges.push_back({source, destination, weight}); + } + + std::vector BellmanFord(int source); + std::vector Dijkstra(int source); + std::vector> JohnsonsAlgorithm(); +}; From 793cba830c1747dcd57dea376a2e4bd469592a19 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:49:42 +0000 Subject: [PATCH 25/33] test(task_3): Add a test for task 3 --- task_03/src/test.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index 5e11617..4b29173 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,6 +1,25 @@ - #include +#include "algo.hpp" + +#define INF std::numeric_limits::max() + +TEST(JohnsonTest, Simple) { + Graph graph(5); + graph.AddEdge(0, 1, 5); // Add an edge from vertex 0 to vertex 1 with weight 5 + graph.AddEdge(0, 3, 3); // Add an edge from vertex 0 to vertex 3 with weight 3 + graph.AddEdge(1, 2, 2); // Add an edge from vertex 1 to vertex 2 with weight 2 + graph.AddEdge(2, 3, 6); // Add an edge from vertex 2 to vertex 3 with weight 6 + graph.AddEdge(3, 4, 4); // Add an edge from vertex 3 to vertex 4 with weight 4 + graph.AddEdge(4, 1, 1); // Add an edge from vertex 4 to vertex 1 with weight 1 + + std::vector> expected_distances = { + {0, 5, 7, 3, 7}, + {INF, 0, 2, 8, 12}, + {INF, 11, 0, 6, 10}, + {INF, 5, 7, 0, 4}, + {INF, 1, 3, 9, 0} + }; -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} + std::vector> distances = graph.JohnsonsAlgorithm(); + ASSERT_EQ(distances, expected_distances); +} \ No newline at end of file From cfb0ae2764efa23d8f8149e24bb7ff66df0a3cde Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:56:41 +0000 Subject: [PATCH 26/33] feat(task_4): Add solution of task 4 --- task_04/src/dijkstra.cpp | 41 ++++++++++++++++++++++++++++++++++++++++ task_04/src/dijkstra.hpp | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 task_04/src/dijkstra.cpp create mode 100644 task_04/src/dijkstra.hpp diff --git a/task_04/src/dijkstra.cpp b/task_04/src/dijkstra.cpp new file mode 100644 index 0000000..10debf8 --- /dev/null +++ b/task_04/src/dijkstra.cpp @@ -0,0 +1,41 @@ +#include "dijkstra.hpp" + +// Dijkstra's algorithm to find shortest path from given source vertex to all other vertices +std::vector Graph::Dijkstra_(int source) { + std::vector distance(vertex_count, INF); + distance[source] = 0; + + auto compare = [](const std::pair& a, const std::pair& b) { + return a.second > b.second; + }; + std::priority_queue, std::vector>, decltype(compare)> pq(compare); + pq.push({source, 0}); + + while (!pq.empty()) { + int u = pq.top().first; + pq.pop(); + + for (const auto& edge : edges) { + if (edge.source == u) { + int v = edge.destination; + int w = edge.weight; + if (distance[u] != INF && distance[u] + w < distance[v]) { + distance[v] = distance[u] + w; + pq.push({v, distance[v]}); + } + } + } + } + + return distance; +} + +std::vector> Graph::Dijkstra() +{ + std::vector> distance_matrix(vertex_count, std::vector(vertex_count, INF)); + + for (int i = 0; i < vertex_count; ++i) + distance_matrix[i] = Dijkstra_(i); + + return distance_matrix; +} \ No newline at end of file diff --git a/task_04/src/dijkstra.hpp b/task_04/src/dijkstra.hpp new file mode 100644 index 0000000..55a336c --- /dev/null +++ b/task_04/src/dijkstra.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include +#include + +#define INF std::numeric_limits::max() + +// Structure to represent a weighted edge +struct Edge { + int source; + int destination; + int weight; +}; + +// Graph class +class Graph { +private: + int vertex_count; // Number of vertices + std::vector edges; // Vector to store graph edges + std::vector Dijkstra_(int source); + +public: + Graph(int V) : vertex_count(V) {} + + // Add an edge to the graph + void AddEdge(int source, int destination, int weight) { + edges.push_back({source, destination, weight}); + } + + std::vector> Dijkstra(); +}; \ No newline at end of file From 7fafab2bc1f5691b43b0098f447ca0bf125dbf4d Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:56:58 +0000 Subject: [PATCH 27/33] test(task_4): Add a test for task 4 --- task_04/src/test.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 5e11617..ea23354 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,6 +1,23 @@ - +#include "dijkstra.hpp" #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(Dijkstra, Simple) { + Graph graph(5); + graph.AddEdge(0, 1, 5); // Add an edge from vertex 0 to vertex 1 with weight 5 + graph.AddEdge(0, 3, 3); // Add an edge from vertex 0 to vertex 3 with weight 3 + graph.AddEdge(1, 2, 2); // Add an edge from vertex 1 to vertex 2 with weight 2 + graph.AddEdge(2, 3, 6); // Add an edge from vertex 2 to vertex 3 with weight 6 + graph.AddEdge(3, 4, 4); // Add an edge from vertex 3 to vertex 4 with weight 4 + graph.AddEdge(4, 1, 1); // Add an edge from vertex 4 to vertex 1 with weight 1 + + std::vector> expected_distances = { + {0, 5, 7, 3, 7}, + {INF, 0, 2, 8, 12}, + {INF, 11, 0, 6, 10}, + {INF, 5, 7, 0, 4}, + {INF, 1, 3, 9, 0} + }; + + std::vector> distances = graph.Dijkstra(); + ASSERT_EQ(distances, expected_distances); } From 03f624425f2bee44c9ecf006756201460d56a3f9 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 5 Jan 2024 10:08:38 +0000 Subject: [PATCH 28/33] feat(task 4): Add solution of task 4 --- task_05/src/rmq.hpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 task_05/src/rmq.hpp diff --git a/task_05/src/rmq.hpp b/task_05/src/rmq.hpp new file mode 100644 index 0000000..1ea4ed2 --- /dev/null +++ b/task_05/src/rmq.hpp @@ -0,0 +1,23 @@ +#include + +class RMQ +{ + private: + std::vector> data_; + public: + RMQ(std::vector input) : data_(std::__lg(input.size() + 1), std::vector(input.size())) + { + const size_t n = input.size(); + std::copy(input.begin(), input.end(), data_[0].begin()); + + for (int l = 0; l < std::__lg(n); l++) + for (int i = 0; i + (2 << l) <= n; i++) + data_[l+1][i] = std::min(data_[l][i], data_[l][i + (1 << l)]); + } + + int rmq(const size_t l, const size_t r) const + { + const size_t power_2 = std::__lg(r - l); + return std::min(data_[power_2][l], data_[power_2][r - (1 << power_2) + 1]); + } +}; From 0ab9b3c5b79e774a34517882121bac354a4bff9c Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 5 Jan 2024 10:08:53 +0000 Subject: [PATCH 29/33] test(task 4): Add tests for task 4 --- task_05/src/test.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617..30ee568 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,12 @@ - +#include "rmq.hpp" #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(RMQ, Simple) { + std::vector data{0, 2, 3, 5, 1, 4, 7}; + RMQ rmq(data); + ASSERT_EQ(rmq.rmq(1, 4), 1); + ASSERT_EQ(rmq.rmq(0, 5), 0); + ASSERT_EQ(rmq.rmq(1, 6), 1); + ASSERT_EQ(rmq.rmq(5, 6), 4); + ASSERT_EQ(rmq.rmq(4, 4), 1); } From f84e6e20330d9ac0dab16f6a2b7bcba2a35a1564 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:31:00 +0000 Subject: [PATCH 30/33] feat(task 6): Add solution of task 6 --- task_06/src/lca.hpp | 85 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 task_06/src/lca.hpp diff --git a/task_06/src/lca.hpp b/task_06/src/lca.hpp new file mode 100644 index 0000000..a67cf3a --- /dev/null +++ b/task_06/src/lca.hpp @@ -0,0 +1,85 @@ +#pragma once + + +#include +#include +#include + +using namespace std; + +// Class to represent the binary tree +class BinaryTree { + int n; // Number of nodes in the tree + vector parent; // Parent array to store the parent of each node + vector depth; // Depth array to store the depth of each node + vector> sparse_table; // Sparse table to store the LCA information + +public: + BinaryTree(int nodes) { + n = nodes; + parent.resize(n); + depth.resize(n); + sparse_table.resize(n, vector(log2(n) + 1)); + + // Initialize parent array with -1 + for (int i = 0; i < n; i++) { + parent[i] = -1; + } + } + + // Function to add an edge between two nodes + void AddEdge(int child, int par) { + parent[child] = par; + } + + // Function to initialize the sparse table + void InitSparseTable() { + for (int i = 0; i < n; i++) { + sparse_table[i][0] = parent[i]; + } + + for (int j = 1; (1 << j) < n; j++) { + for (int i = 0; i < n; i++) { + if (sparse_table[i][j - 1] != -1) { + sparse_table[i][j] = sparse_table[sparse_table[i][j - 1]][j - 1]; + } + } + } + } + + // Function to find the LCA of two nodes using the sparse table + int findLCA(int u, int v) { + if (depth[u] < depth[v]) { + swap(u, v); + } + + int maxDepth = log2(depth[u]) + 1; + + for (int i = maxDepth - 1; i >= 0; i--) { + if (depth[u] - (1 << i) >= depth[v]) { + u = sparse_table[u][i]; + } + } + + if (u == v) { + return u; + } + + for (int i = maxDepth - 1; i >= 0; i--) { + if (sparse_table[u][i] != -1 && sparse_table[u][i] != sparse_table[v][i]) { + u = sparse_table[u][i]; + v = sparse_table[v][i]; + } + } + + return parent[u]; + } + + // Function to calculate the depth of each node + void CalculateDepths(int node, int d) { + depth[node] = d; + for (int child = 0; child < n; child++) + if (parent[child] == node) + CalculateDepths(child, d + 1); + } +}; From 9c76975224fc524b799a5ab7bcff9b404332f2d0 Mon Sep 17 00:00:00 2001 From: ShatunovEvgeniy <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:31:18 +0000 Subject: [PATCH 31/33] test(task 6): Add a test for task 6 --- task_06/src/test.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617..da0ae92 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,19 @@ - +#include "lca.hpp" #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(LCA, Simple) { + BinaryTree tree(7); + tree.AddEdge(1, 0); + tree.AddEdge(2, 0); + tree.AddEdge(3, 1); + tree.AddEdge(4, 1); + tree.AddEdge(5, 4); + tree.AddEdge(6, 4); + + tree.CalculateDepths(0, 0); // Calculate the depth of each node + tree.InitSparseTable(); // Initialize the sparse table + + int u = 5; + int v = 6; + ASSERT_EQ(tree.findLCA(u, v), 4); // Stack [] } From 2e5da2bd188c4537d8f3854b476647980244feb8 Mon Sep 17 00:00:00 2001 From: Shatunov Evgeny <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:19:02 +0300 Subject: [PATCH 32/33] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 39762f8..b31b40e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1 @@ # Домашнее задание для 2 семестра алгоритмов и структур данных - -### Для удобства можно пользоваться папкой lib, все файлы из этой папки будут подключаться к любой задаче - -### Можно получить дополнительные баллы, если добавить интересные текстовые задачи. Необходимы текст задачи, решение и тесты. - -### Можно получить дополнительные баллы, если добавить теорию в папку doc. Делается в отдельном ПР From 3531f4c9f54878a01ba09e26444484cdb9d2d9e2 Mon Sep 17 00:00:00 2001 From: Shatunov Evgeny <118297183+ShatunovEvgeniy@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:19:18 +0300 Subject: [PATCH 33/33] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b31b40e..8b13789 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Домашнее задание для 2 семестра алгоритмов и структур данных +