Skip to content

Commit

Permalink
Никитин Кирилл - Лабораторная Номер 3 (#418)
Browse files Browse the repository at this point in the history
* lab3 added

* fix

* fix
  • Loading branch information
NikitinKU authored Dec 2, 2024
1 parent 10aee89 commit cc8380e
Show file tree
Hide file tree
Showing 12 changed files with 498 additions and 0 deletions.
12 changes: 12 additions & 0 deletions modules/nikitin_k_lab3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Declare variables for binaries' names
get_filename_component(DIR_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
set(MODULE "${DIR_NAME}")
set(LIBRARY "lib_${MODULE}")
set(TESTS "test_${MODULE}")

# Include directory with public headers
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

# Add all submodules
add_subdirectory(src)
add_subdirectory(test)
45 changes: 45 additions & 0 deletions modules/nikitin_k_lab3/CTestTests.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#############################################
##### Testing
#############################################

set(prefix "${MODULE}")

add_test(
NAME ${prefix}_can_Run
COMMAND ${APPLICATION}
)
set_tests_properties (${prefix}_can_Run PROPERTIES
LABELS "${MODULE}")

add_test(
NAME ${prefix}_can_Print_Help
COMMAND ${APPLICATION} --help
)
set_tests_properties (${prefix}_can_Print_Help PROPERTIES
PASS_REGULAR_EXPRESSION "Usage: ./target [options]*"
LABELS "${MODULE}")

add_test(
NAME ${prefix}_can_initialize
COMMAND ${APPLICATION} --initialize
)
set_tests_properties (${prefix}_can_initialize PROPERTIES
PASS_REGULAR_EXPRESSION "initialized\n"
LABELS "${MODULE}")

add_test(
NAME ${prefix}_is_inside
COMMAND ${APPLICATION} --is_inside 1 1 3
)
set_tests_properties (${prefix}_in_inside PROPERTIES
PASS_REGULAR_EXPRESSION "true\n"
LABELS "${MODULE}")

add_test(
NAME ${prefix}_convert_size
COMMAND ${APPLICATION} --convert_size 1
)
set_tests_properties (${prefix}_convert_size PROPERTIES
PASS_REGULAR_EXPRESSION "1\n"
LABELS "${MODULE}")

14 changes: 14 additions & 0 deletions modules/nikitin_k_lab3/application/Application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2024 Nikitin Kirill

#include <iostream>

#include "include/bisymmetricApp.h"

int main(int argc, const char** argv) {
BysimmetricApp app;
auto output = app.runApp(argc, argv);
for (auto str : output) {
std::cout << str << std::endl;
}
return 0;
}
15 changes: 15 additions & 0 deletions modules/nikitin_k_lab3/application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
set(target ${APPLICATION})

file(GLOB srcs "*.cpp")
set_source_files_properties(${srcs} PROPERTIES
LABELS "${MODULE};Application")

add_executable(${target} ${srcs})
set_target_properties(${target} PROPERTIES
OUTPUT_NAME ${MODULE}
LABELS "${MODULE};Application")

target_link_libraries(${target} ${LIBRARY})
if (UNIX)
target_link_libraries(${target} ${CMAKE_THREAD_LIBS_INIT})
endif (UNIX)
181 changes: 181 additions & 0 deletions modules/nikitin_k_lab3/include/bisymmetric.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright 2024 Nikitin Kirill

#ifndef MODULES_NIKITIN_K_LAB3_INCLUDE_BISYMMETRIC_H_
#define MODULES_NIKITIN_K_LAB3_INCLUDE_BISYMMETRIC_H_

#include <iostream>
#include <vector>

template <typename T>
class BisymmetricMatrix {
private:
std::vector<T> matrix;
int size;
int n;

static int convertIndex(int i1, int j1, int n);

static bool checkBisymmetric(
const std::initializer_list<std::initializer_list<T>>& list);

public:
BisymmetricMatrix() : size(0), n(0) {}

explicit BisymmetricMatrix(int n) : size(convertSize(n)), n(n) {
matrix.resize(convertSize(n), T());
}

explicit BisymmetricMatrix(
const std::initializer_list<std::initializer_list<T>>& list);

static bool isInside(int i, int j, int n);
static int convertSize(int n);
int getN() const { return n; }
void setElement(int i_2d, int j_2d, const T& value);
T getElement(int i_2d, int j_2d) const;
void display() const;
};

#endif // MODULES_NIKITIN_K_LAB3_INCLUDE_BISYMMETRIC_H_

template <typename T>
inline int BisymmetricMatrix<T>::convertSize(int n) {
return ((n + 1) / 2) * ((n + 1) / 2);
}

template <typename T>
inline bool BisymmetricMatrix<T>::isInside(int i, int j, int n) {
int middle = n % 2 == 0 ? n / 2 : (n + 1) / 2;

if (i < middle) {
if (j > i) return false;
} else {
if (j > n - i - 1) return false;
}
return true;
}

template <typename T>
inline int BisymmetricMatrix<T>::convertIndex(int i1, int j1, int n) {
// i1, j1 - original orientation

int i2 = j1; // main diagonal symmetry
int j2 = i1;

int i3 = n - j1 - 1; // minor diagonal symmetry 1
int j3 = n - i1 - 1;

int i4 = n - i1 - 1; // minor diagonal symmetry 2
int j4 = n - j1 - 1;

int i0 = 0; // i,j for the data inside the left central triangle
int j0 = 0;

if (isInside(i1, j1, n)) {
i0 = i1;
j0 = j1;
} else if (isInside(i2, j2, n)) {
i0 = i2;
j0 = j2;
} else if (isInside(i3, j3, n)) {
i0 = i3;
j0 = j3;
} else if (isInside(i4, j4, n)) {
i0 = i4;
j0 = j4;
} else {
return -1;
}

int k = 0;
int side = n;
for (int j = 0; j < j0; j++) {
k += side;
side -= 2;
}
k += i0 - j0;

return k;
}

template <typename T>
inline bool BisymmetricMatrix<T>::checkBisymmetric(
const std::initializer_list<std::initializer_list<T>>& list) {
int n = static_cast<int>(list.size());
std::vector<std::vector<T>> m(n);

int i = 0;
for (const auto& row : list) {
m[i] = std::vector<T>(row);
i++;
}

for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
if (m[i][j] != m[j][i]) return false;

for (int i = 0; i < n; i++)
for (int j = 0; j < n - i; j++)
if (m[i][j] != m[n - j - 1][n - i - 1]) return false;

return true;
}
template <typename T>
inline BisymmetricMatrix<T>::BisymmetricMatrix(
const std::initializer_list<std::initializer_list<T>>& list) {
if (!checkBisymmetric(list)) {
throw std::logic_error("List is not bisymmetric");
}

n = static_cast<int>(list.size());
size = convertSize(n);
matrix.resize(size, T());

int i = 0;
int j = 0;
int k = 0;
int middle = (n % 2 == 0) ? (n / 2) : (n + 1) / 2;

std::vector<std::vector<T>> m(n);

for (const auto& row : list) {
m[i] = std::vector<T>(row);
i++;
}

for (j = 0; j < middle; j++)
for (i = j; i < n - j; i++) {
matrix[k] = m[i][j];
k++;
}
}

template <typename T>
inline void BisymmetricMatrix<T>::setElement(int i_2d, int j_2d,
const T& value) {
if (i_2d < 0 || i_2d > n || j_2d < 0 || j_2d > n) {
throw std::out_of_range("Invalid index");
}
int i_1d = convertIndex(i_2d, j_2d, n);
matrix[i_1d] = value;
}

template <typename T>
inline T BisymmetricMatrix<T>::getElement(int i_2d, int j_2d) const {
if (i_2d < 0 || i_2d > n || j_2d < 0 || j_2d > n) {
throw std::out_of_range("Invalid index");
}
int i_1d = convertIndex(i_2d, j_2d, n);
return matrix[i_1d];
}

template <typename T>
inline void BisymmetricMatrix<T>::display() const {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
int i_1d = convertIndex(i, j, n);
std::cout << matrix[i_1d] << " ";
}
std::cout << "\n";
}
}
22 changes: 22 additions & 0 deletions modules/nikitin_k_lab3/include/bisymmetricApp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 Nikitin Kirill

#pragma once

#include <string>
#include <vector>

#include "include/bisymmetric.h"

class BisymmetricApp {
BisymmetricMatrix<int> matrix;
std::vector<std::string> parse(int argc, const char** argv);
void help(std::vector<std::string>& output);
void print(std::vector<std::string>& output);
void initialize(std::vector<std::string>& output);
void convertSize(std::vector<std::string>& output, int elem);
void isInside(std::vector<std::string>& output, int elem1, int elem2,
int elem3);

public:
std::vector<std::string> runApp(int argc, const char** argv);
};
18 changes: 18 additions & 0 deletions modules/nikitin_k_lab3/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
set(target ${LIBRARY})

file(GLOB srcs "*.cpp")
file(GLOB hdrs "../include/*.h")
set_source_files_properties(${srcs} ${hdrs} PROPERTIES
LABELS "${MODULE};Library")

add_library(${target} STATIC ${srcs} ${hdrs})
set_target_properties(${target} PROPERTIES
OUTPUT_NAME ${MODULE}
LABELS "${MODULE};Library")

if (UNIX)
target_link_libraries(${target} ${CMAKE_THREAD_LIBS_INIT})
endif (UNIX)
target_link_libraries(${target} ${LIBRARY_DEPS})

set(LIBRARY_DEPS "${LIBRARY_DEPS};${target}" PARENT_SCOPE)
3 changes: 3 additions & 0 deletions modules/nikitin_k_lab3/src/bisymmetric.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Copyright 2024 Nikitin Kirill

#include "include/bisymmetric.h"
75 changes: 75 additions & 0 deletions modules/nikitin_k_lab3/src/bisymmetricApp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2024 Nikitin Kirill

#include "include/bisymmetricApp.h"

std::vector<std::string> BisymmetricApp::runApp(int argc, const char** argv) {
std::vector<std::string> output;
auto args = parse(argc, argv);
int argsSize = static_cast<int>(args.size());
for (int i = 0; i < argsSize; i++) {
auto arg = args[i];
if (arg == "--help") {
help(output);
} else if (arg == "--convert_size") {
convertSize(output, std::stoi(args[i + 1]));
i++;
} else if (arg == "--print") {
print(output);
} else if (arg == "--is_inside") {
if (i + 3 > argsSize) {
output.push_back("Error: insufficient arguments");
} else {
isInside(output, std::stoi(args[i + 1]), std::stoi(args[i + 2]),
std::stoi(args[i + 3]));
i += 3;
}
} else {
output.push_back("Error:");
output.push_back("unrecognized command-line option.");
output.push_back("Run --help for all supported options");
break;
}
}
return output;
}

std::vector<std::string> BisymmetricApp::parse(int argc, const char** argv) {
std::vector<std::string> input;
for (int i = 1; i < argc; i++) {
const char* ptr = argv[i];
std::string str(ptr);
input.push_back(str);
}
return input;
}

void BisymmetricApp::help(std::vector<std::string>& output) {
output.push_back("Usage: ./target [options]");
output.push_back("Optinos:");
output.push_back(" --print");
output.push_back(" --initialize");
output.push_back(" --convert_size");
output.push_back(" --is_inside");
output.push_back(" --help");
output.push_back("Notion: you can use the same option several times");
}

void BisymmetricApp::print(std::vector<std::string>& output) {
output.push_back("1,2,3\n4,5,6\n7,8,9");
}

void BisymmetricApp::isInside(std::vector<std::string>& output, int elem1,
int elem2, int elem3) {
bool res = matrix.isInside(elem1, elem2, elem3);
output.push_back((res ? "true" : "false"));
}

void BisymmetricApp::convertSize(std::vector<std::string>& output, int elem1) {
int res = matrix.convertSize(elem1);
output.push_back(std::to_string(res));
}

void BisymmetricApp::initialize(std::vector<std::string>& output) {
matrix = BisymmetricMatrix<int>({{1, 4, 7}, {2, 5, 8}, {3, 6, 9}});
output.push_back("initialized");
}
Loading

0 comments on commit cc8380e

Please sign in to comment.