Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ include(cmake/function.cmake) # подхватываем функции,
# и для создания исполняемого проекта в отдельные функции

add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example

add_subdirectory(lib_DSU)
add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main

option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO)
Expand Down
1 change: 1 addition & 0 deletions lib_DSU/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create_project_lib(DSU)
Empty file added lib_DSU/DSU.cpp
Empty file.
47 changes: 47 additions & 0 deletions lib_DSU/DSU.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class DSU {
int* _parent;
int* _rank;
size_t _size;

public:

DSU(size_t size) : _size(size) {
_parent = new int[size];
_rank = new int[size];
for (int i = 0; i < size; i++) {
_parent[i] = i;
_rank[i] = 0;
}
}

~DSU() {
delete[] _parent;
delete[] _rank;
}

int find(int x) {
if (x < 0 || x >= _size) return -1;
if (_parent[x] != x) {
_parent[x] = find(_parent[x]);
}
return _parent[x];
}

void unite(int x, int y) {
int rootX = find(x);
int rootY = find(y);

if (rootX == rootY || rootX == -1 || rootY == -1) return;

if (_rank[rootX] < _rank[rootY]) {
_parent[rootX] = rootY;
}
else if (_rank[rootX] > _rank[rootY]) {
_parent[rootY] = rootX;
}
else {
_parent[rootY] = rootX;
_rank[rootX]++;
}
}
};
97 changes: 67 additions & 30 deletions main/main.cpp
Original file line number Diff line number Diff line change
@@ -1,37 +1,74 @@
// Copyright 2024 Marina Usova

#define EASY_EXAMPLE
#ifdef EASY_EXAMPLE


#include <iostream>
#include <iomanip>
#include "../lib_easy_example/easy_example.h"
#include "DSU.h"
#include <vector>

int main() {
int a, b;
float result;

a = 1; b = 4;

try {
result = division(a, b);
std::cout << a << " / " << b << " = "
<< std::setprecision(2) << result << std::endl;
} catch (std::exception err) {
std::cerr << err.what() << std::endl;
}

a = 1; b = 0;

try {
result = division(a, b);
std::cout << a << " / " << b << " = "
<< std::setprecision(2) << result << std::endl;
} catch (std::exception err) {
std::cerr << err.what() << std::endl;
}

return 0;
int countIslands(std::vector<std::vector<int>>& grid) {
if (grid.empty() || grid[0].empty()) return 0;

int rows = grid.size();
int cols = grid[0].size();

DSU dsu(rows * cols);

int directions[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] == 1) {
int currentIndex = i * cols + j;

for (int k = 0; k < 4; k++) {
int newRow = i + directions[k][0];
int newCol = j + directions[k][1];

if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols && grid[newRow][newCol] == 1) {
int neighborIndex = newRow * cols + newCol;
dsu.unite(currentIndex, neighborIndex);
}
}
}
}
}

int totalCells = rows * cols;
bool* seen = new bool[totalCells];
for (int i = 0; i < totalCells; i++) {
seen[i] = false;
}

int count = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] == 1) {
int index = i * cols + j;
int root = dsu.find(index);
if (root != -1 && !seen[root]) {
seen[root] = true;
count++;
}
}
}
}

delete[] seen;
return count;
}

#endif // EASY_EXAMPLE
int main() {
std::vector<std::vector<int>> grid = {
{0, 1, 0, 0, 1},
{0, 1, 1, 0, 1},
{1, 1, 0, 1, 1},
{0, 0, 0, 0, 1},
{1, 0, 1, 1, 1}
};

int islandsCount = countIslands(grid);
std::cout << "Number of islands: " << islandsCount << std::endl;

return 0;
}
56 changes: 56 additions & 0 deletions tests/test_DSU.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <gtest/gtest.h>
#include "DSU.h"




TEST(DSUTest, BasicUnion) {
DSU dsu(10);
dsu.unite(0, 1);
EXPECT_EQ(dsu.find(0), dsu.find(1));

dsu.unite(2, 3);
EXPECT_EQ(dsu.find(2), dsu.find(3));

EXPECT_NE(dsu.find(0), dsu.find(2));
EXPECT_NE(dsu.find(1), dsu.find(3));
}

TEST(DSUTest, TransitiveUnion) {
DSU dsu(10);
dsu.unite(0, 1);
dsu.unite(1, 2);

EXPECT_EQ(dsu.find(0), dsu.find(1));
EXPECT_EQ(dsu.find(1), dsu.find(2));
EXPECT_EQ(dsu.find(0), dsu.find(2));
}

TEST(DSUTest, MultipleUnions) {
DSU dsu(10);
dsu.unite(0, 1);
dsu.unite(2, 3);
dsu.unite(0, 2);

EXPECT_EQ(dsu.find(0), dsu.find(1));
EXPECT_EQ(dsu.find(0), dsu.find(2));
EXPECT_EQ(dsu.find(0), dsu.find(3));
}

TEST(DSUTest, SelfUnion) {
DSU dsu(10);
int original_root = dsu.find(5);
dsu.unite(5, 5);
EXPECT_EQ(dsu.find(5), original_root);
}


TEST(DSUTest, RankTest) {
DSU small_dsu(3);

small_dsu.unite(0, 1);
small_dsu.unite(0, 2);

EXPECT_EQ(small_dsu.find(0), small_dsu.find(1));
EXPECT_EQ(small_dsu.find(0), small_dsu.find(2));
}
50 changes: 6 additions & 44 deletions tests/test_easy_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,11 @@

#include <gtest/gtest.h>
#include "../lib_easy_example/easy_example.h"

#define EPSILON 0.000001

TEST(TestEasyExampleLib, can_div) {
// Arrange
int x = 10;
int y = 2;

// Act & Assert
ASSERT_NO_THROW(division(x, y));
}

TEST(TestEasyExampleLib, can_div_correctly) {
// Arrange
int x = 6;
int y = 2;

// Act
int actual_result = division(x, y);

// Assert
int expected_result = 3;
EXPECT_EQ(expected_result, actual_result);
}

TEST(TestEasyExampleLib, can_div_correctly_with_remainder) {
// Arrange
int x = 5;
int y = 4;

// Act
float actual_result = division(x, y);

// Assert
float expected_result = 1.25;
EXPECT_NEAR(expected_result, actual_result, EPSILON);
}

TEST(TestEasyExampleLib, throw_when_try_div_by_zero) {
// Arrange
int x = 10;
int y = 0;

// Act & Assert
ASSERT_ANY_THROW(division(x, y));
}