diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..07438f34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +build/ +.vs/ +CMakeLists.txt.user +CMakeSettings.json +CMakeUserPresets.json +.vscode/ +*.out \ No newline at end of file diff --git a/01_week/tasks/addition/addition.cpp b/01_week/tasks/addition/addition.cpp index 92872802..892776ac 100644 --- a/01_week/tasks/addition/addition.cpp +++ b/01_week/tasks/addition/addition.cpp @@ -3,5 +3,6 @@ int64_t Addition(int a, int b) { - throw std::runtime_error{"Not implemented"}; + int64_t res = static_cast(a) + b; //явно преобразуем одно из слагаемых в int64_t + return res; } \ No newline at end of file diff --git a/01_week/tasks/char_changer/char_changer.cpp b/01_week/tasks/char_changer/char_changer.cpp index 3a7344d9..c467d660 100644 --- a/01_week/tasks/char_changer/char_changer.cpp +++ b/01_week/tasks/char_changer/char_changer.cpp @@ -1,7 +1,64 @@ #include -#include +#include -size_t CharChanger(char array[], size_t size, char delimiter = ' ') { - throw std::runtime_error{"Not implemented"}; +size_t CharChanger(char array[], size_t size, char delimiter = ' '){ + //Массив для подстановки кол-ва повторений + char intToChar[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + //Индексы + size_t i = 0; + size_t j = 1; + size_t k = 0; + + int reps = 1; // кол-во повторений символа + while(j < size){ + // Если есть повторы, то сначала считаются они + if(array[i] == array[j]){ + ++reps; + j++; + continue; + } + + array[k] = array[i]; + //Если повторы были, то записывается число + if(reps != 1 && array[i] != ' '){ + array[k+1] = reps < 10 ? intToChar[reps] : intToChar[0]; + } + + //Проверка, что это символ алфавита и он в нижнем регистре + if(char c = array[k]; std::isalpha(c) && std::islower(c)){ + array[k] = std::toupper(c); + } + //Отдельно обрабатываются пробелы + else if(array[k] == ' '){ + array[k] = delimiter; + ++k; + i = j++; + reps = 1; + continue; + } + //Замена цифр + else if(std::isdigit(array[k])){ + array[k] = '*'; + } + //Замена остальных символов + else if(!(std::isalpha(array[k]))){ + array[k] = '_'; + } + + //Сдвигаем индексы в зависимости от повторов + if(reps == 1){ + ++k; + } + else if(reps != 1){ + k+= 2; + reps = 1; + } + i = j++; + } + + //В конце добавляется нуль-терминатор + array[k] = '\0'; + + return k; } diff --git a/01_week/tasks/check_flags/check_flags.cpp b/01_week/tasks/check_flags/check_flags.cpp index 75e7c652..a6cf373b 100644 --- a/01_week/tasks/check_flags/check_flags.cpp +++ b/01_week/tasks/check_flags/check_flags.cpp @@ -1,6 +1,10 @@ #include #include - +#include +#include +#include +#include +#include enum class CheckFlags : uint8_t { NONE = 0, @@ -14,5 +18,54 @@ enum class CheckFlags : uint8_t { }; void PrintCheckFlags(CheckFlags flags) { - throw std::runtime_error{"Not implemented"}; + //Хэш-таблица для быстрого преобразования uint8_t -> string + std::unordered_map flagStr = { + {0b00000001,"TIME"}, + {0b00000010,"DATE"}, + {0b00000100,"USER"}, + {0b00001000,"CERT"}, + {0b00010000,"KEYS"}, + {0b00100000,"DEST"} + }; + + //Вектор с результатом работы функции + std::vector result = {"["}; + //Резервирование места под элементы, чтобы не было лишних реаллокаций + result.reserve(16); + + + if(flags == CheckFlags::NONE){ + std::cout << "[]"; + return; + } + else if(flags == CheckFlags::ALL) + { + std::cout << "[TIME,DATE,USER,CERT,KEYS,DEST]"; + return; + } + //Если флаг больше ALL значит он выходит из диапазона значений флагов + else if(static_cast(flags) > static_cast(CheckFlags::ALL)) + { + std::cout << ""; + return; + } + //В остальных случаях флаги перебираются и добавляюся в вектор если присутствуют + else + { + for(uint8_t flag = 1; flag < static_cast(CheckFlags::ALL); flag *= 2){ + if(static_cast(flags) & flag){ + result.push_back(flagStr[flag]); + result.push_back(","); + } + } + } + + + result.pop_back(); //Убираем лишнюю запятую + result.push_back("]"); + + //Вывод результата + for(auto& elem : result){ + std::cout << elem; + } } diff --git a/01_week/tasks/length_lit/length_lit.cpp b/01_week/tasks/length_lit/length_lit.cpp index e69de29b..c19e3409 100644 --- a/01_week/tasks/length_lit/length_lit.cpp +++ b/01_week/tasks/length_lit/length_lit.cpp @@ -0,0 +1,59 @@ +//Футы в дюймы +constexpr double operator""_ft_to_in(long double ft) { + return ft * 12.0; +} + +//Футы в сантиметры +constexpr double operator""_ft_to_cm(long double ft) { + return ft * 30.48; +} + +//Футы в метры +constexpr double operator""_ft_to_m(long double ft) { + return ft * 0.3048; +} + +//Дюймы в футы +constexpr double operator""_in_to_ft(long double in) { + return in / 12.0; +} + +//Дюймы в сантиметры +constexpr double operator""_in_to_cm(long double in) { + return in * 2.54; +} + +//Дюймы в метры +constexpr double operator""_in_to_m(long double in) { + return in * 0.0254; +} + +//Сантиметры в футы +constexpr double operator""_cm_to_ft(long double cm) { + return cm / 30.48; +} + +//Сантиметры в дюймы +constexpr double operator""_cm_to_in(long double cm) { + return cm / 2.54; +} + +//Сантиметры в метры +constexpr double operator""_cm_to_m(long double cm) { + return cm * 0.01; +} + +//Метры в футы +constexpr double operator""_m_to_ft(long double m) { + return m / 0.3048; +} + +//Метры в дюймы +constexpr double operator""_m_to_in(long double m) { + return m / 0.0254; +} + +//Метры в сантиметры +constexpr double operator""_m_to_cm(long double m) { + return m * 100; +} \ No newline at end of file diff --git a/01_week/tasks/print_bits/print_bits.cpp b/01_week/tasks/print_bits/print_bits.cpp index a48a43c1..cc297058 100644 --- a/01_week/tasks/print_bits/print_bits.cpp +++ b/01_week/tasks/print_bits/print_bits.cpp @@ -1,7 +1,22 @@ #include -#include - +#include +#include void PrintBits(long long value, size_t bytes) { - throw std::runtime_error{"Not implemented"}; + size_t bitLen = 8 * bytes; + std::vector bits(bitLen); + + for(size_t i = 0; i < bitLen; ++i){ + bits[bitLen-i-1] = value % 2 == 0 ? '0' : '1'; + value = value >> 1; + } + + std::cout << "0b"; + for(size_t i = 0; i < bitLen; ++i){ + std::cout << bits[i]; + if((i+1) % 4 == 0 && (i+1) != bitLen){ + std::cout << '\''; + } + } + std::cout << "\n"; } diff --git a/01_week/tasks/quadratic/quadratic.cpp b/01_week/tasks/quadratic/quadratic.cpp index abf7d632..25661e64 100644 --- a/01_week/tasks/quadratic/quadratic.cpp +++ b/01_week/tasks/quadratic/quadratic.cpp @@ -1,6 +1,39 @@ -#include - +#include +#include +#include void SolveQuadratic(int a, int b, int c) { - throw std::runtime_error{"Not implemented"}; + //Установка точности вывода в 6 символов + std::cout << std::setprecision(6); + + double eps = 1e-3; // Погрешность при сравнении double + double x1{0}, x2{0}; + long long d = static_cast(b) * b - 4 * static_cast(a) * c; + if(d < 0){ + std::cout << "no solutions"; + } + else if(a == 0 && b == 0 && c != 0){ + std::cout << "no solutions"; + } + else if(a != 0){ + x1 = (-b + sqrt(d)) / (2*a); + x2 = (-b - sqrt(d)) / (2*a); + + if((x1 - x2) < eps){ + std::cout << x1; + } + else{ + if(x1 > x2){ + std::swap(x1, x2); + } + std::cout << x1 << " " << x2; + } + } + else if(a == 0 && b == 0 && c == 0){ + std::cout << "infinite solutions"; + } + else if(b != 0){ + x1 = -c / static_cast(b); + std::cout << x1; + } } \ No newline at end of file diff --git a/01_week/tasks/rms/rms.cpp b/01_week/tasks/rms/rms.cpp index 6882f0a9..7e699a1f 100644 --- a/01_week/tasks/rms/rms.cpp +++ b/01_week/tasks/rms/rms.cpp @@ -1,7 +1,16 @@ -#include +#include #include +#include double CalculateRMS(double values[], size_t size) { - throw std::runtime_error{"Not implemented"}; + if(values == nullptr || size == 0){ + return 0.0; + } + + double res {0.0}; + for(size_t i = 0; i < size; ++i){ + res += values[i]*values[i]; + } + return sqrt(res/size); } \ No newline at end of file diff --git a/02_week/tasks/func_array/func_array.cpp b/02_week/tasks/func_array/func_array.cpp index b327e68d..a91456b6 100644 --- a/02_week/tasks/func_array/func_array.cpp +++ b/02_week/tasks/func_array/func_array.cpp @@ -1,6 +1,13 @@ -#include +#include -double ApplyOperations(double a, double b /* other arguments */) { - throw std::runtime_error{"Not implemented"}; +double ApplyOperations(double a, double b, double (**functions)(double, double), size_t size) { + if(size == 0) return 0.0; + + double res{}; + for(size_t i = 0; i < size; ++i){ + res += functions[i] == nullptr ? 0.0 : functions[i](a, b); + } + + return res; } \ No newline at end of file diff --git a/02_week/tasks/last_of_us/last_of_us.cpp b/02_week/tasks/last_of_us/last_of_us.cpp index c7bf1a25..549a4a71 100644 --- a/02_week/tasks/last_of_us/last_of_us.cpp +++ b/02_week/tasks/last_of_us/last_of_us.cpp @@ -1,6 +1,9 @@ -#include +const int* FindLastElement(const int* begin, const int* end, bool (*predicate)(int)) { + if(begin == nullptr || end == nullptr || begin > end) return end; -/* return_type */ FindLastElement(/* ptr_type */ begin, /* ptr_type */ end, /* func_type */ predicate) { - throw std::runtime_error{"Not implemented"}; + for(int* current = const_cast(end-1); current != begin-1; --current){ + if(predicate(*current)) return current; + } + return end; } \ No newline at end of file diff --git a/02_week/tasks/little_big/little_big.cpp b/02_week/tasks/little_big/little_big.cpp index abe24379..269fc5a4 100644 --- a/02_week/tasks/little_big/little_big.cpp +++ b/02_week/tasks/little_big/little_big.cpp @@ -1,10 +1,47 @@ -#include +#include +#include +#include - -void PrintMemory(int /* write arguments here */) { - throw std::runtime_error{"Not implemented"}; +void PrintMemory(int num, bool inverse = false) { + const size_t size = sizeof(int); + auto ptr = reinterpret_cast(&num); + + std::cout << "0x"; + + if (inverse) { + // little-endian + for (size_t i = size - 1; i < size; --i) { + std::cout << std::uppercase << std::hex << std::setw(2) << std::setfill('0') + << static_cast(ptr[i]); + } + } else { + // big-endian + for (size_t i = 0; i < size; ++i) { + std::cout << std::uppercase << std::hex << std::setw(2) << std::setfill('0') + << static_cast(ptr[i]); + } + } + std::cout << std::endl; } -void PrintMemory(double /* write arguments here */) { - throw std::runtime_error{"Not implemented"}; +void PrintMemory(double num, bool inverse = false) { + const size_t size = sizeof(double); + auto ptr = reinterpret_cast(&num); + + std::cout << "0x"; + + if (inverse) { + //little-endian + for (size_t i = size - 1; i < size; --i) { + std::cout << std::uppercase << std::hex << std::setw(2) << std::setfill('0') + << static_cast(ptr[i]); + } + } else { + // big-endian + for (size_t i = 0; i < size; ++i) { + std::cout << std::uppercase << std::hex << std::setw(2) << std::setfill('0') + << static_cast(ptr[i]); + } + } + std::cout << std::endl; } \ No newline at end of file diff --git a/02_week/tasks/longest/longest.cpp b/02_week/tasks/longest/longest.cpp index 04b3c354..be0b6d97 100644 --- a/02_week/tasks/longest/longest.cpp +++ b/02_week/tasks/longest/longest.cpp @@ -1,6 +1,25 @@ -#include +#include -/* return_type */ FindLongestSubsequence(/* ptr_type */ begin, /* ptr_type */ end, /* type */ count) { - throw std::runtime_error{"Not implemented"}; +char* FindLongestSubsequence(const char* begin, const char* end, size_t& count) { + char* res{nullptr}; + count = 0; + + if(begin == nullptr || end == nullptr) return nullptr; + + size_t curLen{1}; + const char* curBegin{begin}; + for(const char* curent = begin; curent < end; ++curent){ + if(curent+1 != end && *curent == *(curent+1)){ + curBegin = curLen == 1 ? curent : curBegin; + ++curLen; + continue; + } + + res = count < curLen ? const_cast(curBegin) : res; + count = count < curLen ? curLen : count; + curLen = 1; + } + + return res; } diff --git a/02_week/tasks/pretty_array/pretty_array.cpp b/02_week/tasks/pretty_array/pretty_array.cpp index 48eab341..6553ea1b 100644 --- a/02_week/tasks/pretty_array/pretty_array.cpp +++ b/02_week/tasks/pretty_array/pretty_array.cpp @@ -1,6 +1,39 @@ -#include +#include -void PrintArray(/* write arguments here */) { - throw std::runtime_error{"Not implemented"}; +void PrintArray(const int* begin, const int* end, size_t limit = 0) { + if(begin == nullptr || end == nullptr){ + std::cout << "[]\n"; + return; + } + + std::cout << "["; + if(begin < end){ + size_t i = 1; + for(const int* curent = begin; curent < end; ++curent){ + if(limit != 0 && i > limit){ + std::cout << "...\n " << *curent << (curent+1 == end ? "" : ", "); + i = 1; + } + else{ + std::cout << *curent << (curent+1 == end ? "" : ", "); + } + ++i; + } + } + else{ + size_t i = 1; + for(const int* curent = begin; curent > end; --curent){ + if(limit != 0 && i > limit){ + std::cout << "...\n " << *curent << (curent-1 == end ? "" : ", "); + i = 1; + } + else{ + std::cout << *curent << (curent-1 == end ? "" : ", "); + } + ++i; + } + } + + std::cout << "]\n"; } \ No newline at end of file diff --git a/02_week/tasks/swap_ptr/swap_ptr.cpp b/02_week/tasks/swap_ptr/swap_ptr.cpp index 93db625d..eb56cb6e 100644 --- a/02_week/tasks/swap_ptr/swap_ptr.cpp +++ b/02_week/tasks/swap_ptr/swap_ptr.cpp @@ -1,6 +1,18 @@ -#include +void SwapPtr(int*& a, int*& b) { + int* tmp = a; + a = b; + b = tmp; +} -void SwapPtr(/* write arguments here */) { - throw std::runtime_error{"Not implemented"}; +void SwapPtr(const int*& a, const int*& b) { + const int* temp = a; + a = b; + b = temp; +} + +void SwapPtr(int**& a, int**& b) { + int** temp = a; + a = b; + b = temp; } \ No newline at end of file diff --git a/03_week/tasks/data_stats/data_stats.cpp b/03_week/tasks/data_stats/data_stats.cpp index b941c211..e9079c62 100644 --- a/03_week/tasks/data_stats/data_stats.cpp +++ b/03_week/tasks/data_stats/data_stats.cpp @@ -1,4 +1,5 @@ -#include +#include +#include struct DataStats { @@ -6,6 +7,21 @@ struct DataStats { double sd = 0.0; }; -/* return_type */ CalculateDataStats(/* args */) { - throw std::runtime_error{"Not implemented"}; +DataStats CalculateDataStats(const std::vector& data) { + DataStats res {0.0, 0.0}; + size_t size = 0; + + if(data.empty()) return res; + + for(int elem : data){ + res.avg += elem; + res.sd += static_cast(elem) * elem; + ++size; + } + res.avg /= size; + res.sd /= size; + res.sd -= res.avg * res.avg; + res.sd = sqrt(res.sd); + + return res; } diff --git a/03_week/tasks/easy_compare/easy_compare.cpp b/03_week/tasks/easy_compare/easy_compare.cpp index dd5cb7f6..268d39fc 100644 --- a/03_week/tasks/easy_compare/easy_compare.cpp +++ b/03_week/tasks/easy_compare/easy_compare.cpp @@ -1,16 +1,63 @@ -#include - struct Date { - unsigned year; - unsigned month; - unsigned day; + unsigned year = 0; + unsigned month = 0; + unsigned day = 0; }; struct StudentInfo { - size_t id; - char mark; - int score; - unsigned course; + size_t id = 0; + char mark = 'Z'; + int score = 0; + unsigned course = 0; Date birth_date; -}; \ No newline at end of file +}; + + +bool operator<(const Date& lhs, const Date& rhs){ + return std::tie(lhs.year, lhs.month, lhs.day) < std::tie(rhs.year, rhs.month, rhs.day); +} + +bool operator==(const Date& lhs, const Date& rhs){ + return std::tie(lhs.year, lhs.month, lhs.day) == std::tie(rhs.year, rhs.month, rhs.day); +} + +bool operator<=(const Date& lhs, const Date& rhs){ + return lhs < rhs || lhs == rhs; +} + +bool operator>(const Date& lhs, const Date& rhs){ + return rhs <= lhs; +} + +bool operator>=(const Date& lhs, const Date& rhs){ + return lhs > rhs || lhs == rhs;; +} + +bool operator<(const StudentInfo& lhs, const StudentInfo& rhs){ + if(lhs.mark != rhs.mark){ + return lhs.mark > rhs.mark; + } + if(lhs.score != rhs.score){ + return lhs.score < rhs.score; + } + if(lhs.course != rhs.course){ + return lhs.course > rhs.course; + } + if(lhs.birth_date != rhs.birth_date){ + return lhs.birth_date < rhs.birth_date; + } + return false; +} + +bool operator==(const StudentInfo& lhs, const StudentInfo& rhs){ + return std::tie(lhs.mark, lhs. score) == std::tie(rhs.mark, rhs. score); +} + +bool operator<=(const StudentInfo& lhs, const StudentInfo& rhs){ + return lhs < rhs || lhs == rhs; +} + +bool operator>(const StudentInfo& lhs, const StudentInfo& rhs){ + return rhs <= lhs; +} \ No newline at end of file diff --git a/03_week/tasks/enum_operators/enum_operators.cpp b/03_week/tasks/enum_operators/enum_operators.cpp index a539be38..7b67d072 100644 --- a/03_week/tasks/enum_operators/enum_operators.cpp +++ b/03_week/tasks/enum_operators/enum_operators.cpp @@ -1,4 +1,4 @@ -#include +#include #include enum class CheckFlags : uint8_t { @@ -12,22 +12,58 @@ enum class CheckFlags : uint8_t { ALL = TIME | DATE | USER | CERT | KEYS | DEST }; -/* return_type */ operator|(/* args */) { - throw std::runtime_error{"Not implemented"}; +CheckFlags operator|(const CheckFlags& lhs, const CheckFlags& rhs) { + uint8_t res = static_cast(lhs) | static_cast(rhs); + res = res & static_cast(CheckFlags::ALL); + return static_cast(res); } -/* return_type */ operator&(/* args */) { - throw std::runtime_error{"Not implemented"}; +bool operator&(const CheckFlags& lhs, const CheckFlags& rhs) { + uint8_t all_uint8 = static_cast(CheckFlags::ALL); + uint8_t lhs_uint8 = static_cast(lhs) & all_uint8; + uint8_t rhs_uint8 = static_cast(rhs) & all_uint8; + if(lhs_uint8 == 0 || rhs_uint8 == 0) return false; + if(((lhs_uint8 & rhs_uint8) == lhs_uint8) || ((lhs_uint8 & rhs_uint8) == rhs_uint8)) return true; + return false; } -/* return_type */ operator^(/* args */) { - throw std::runtime_error{"Not implemented"}; +CheckFlags operator^(const CheckFlags& lhs, const CheckFlags& rhs) { + uint8_t all_uint8 = static_cast(CheckFlags::ALL); + uint8_t lhs_uint8 = static_cast(lhs) & all_uint8; + uint8_t rhs_uint8 = static_cast(rhs) & all_uint8; + return static_cast(lhs_uint8 ^ rhs_uint8); } -/* return_type */ operator~(/* args */) { - throw std::runtime_error{"Not implemented"}; +CheckFlags operator~(const CheckFlags& flags) { + return static_cast(~(static_cast(flags)) & static_cast(CheckFlags::ALL)); } -/* return_type */ operator<<(/* args */) { - throw std::runtime_error{"Not implemented"}; +std::ostream& operator<<(std::ostream& os, const CheckFlags& flags) { + //Хэш-таблица для быстрого преобразования uint8_t -> string + std::unordered_map flagStr = { + {0b00000001,"TIME"}, + {0b00000010,"DATE"}, + {0b00000100,"USER"}, + {0b00001000,"CERT"}, + {0b00010000,"KEYS"}, + {0b00100000,"DEST"} + }; + + //Вектор с результатом работы функции + std::vector result; + //Резервирование места под элементы, чтобы не было лишних реаллокаций + result.reserve(16); + + for(uint8_t flag = 1; flag < static_cast(CheckFlags::ALL); flag *= 2){ + if(static_cast(flags) & flag){ + result.push_back( !result.empty() ? ", " : ""); + result.push_back(flagStr[flag]); + } + } + + for(auto& elem : result) os << elem; + + if(result.empty()) os << "NONE"; + + return os; } diff --git a/03_week/tasks/filter/filter.cpp b/03_week/tasks/filter/filter.cpp index 6648cb39..aee625ac 100644 --- a/03_week/tasks/filter/filter.cpp +++ b/03_week/tasks/filter/filter.cpp @@ -1,6 +1,15 @@ -#include +#include - -/* return_type */ Filter(/* args */) { - throw std::runtime_error{"Not implemented"}; +void Filter(std::vector& data, bool (*predicate)(int)) { + size_t i{0}; + size_t j{0}; + size_t size{data.size()}; + if(predicate == nullptr) return; + while(j < size){ + if(predicate(data[j])){ + data[i++] = data[j]; + } + ++j; + } + data.resize(i); } \ No newline at end of file diff --git a/03_week/tasks/find_all/find_all.cpp b/03_week/tasks/find_all/find_all.cpp index 74f393b2..af0e8339 100644 --- a/03_week/tasks/find_all/find_all.cpp +++ b/03_week/tasks/find_all/find_all.cpp @@ -1,6 +1,12 @@ -#include +#include - -/* return_type */ FindAll(/* args */) { - throw std::runtime_error{"Not implemented"}; +std::vector FindAll(const std::vector& data, bool(*predicat)(int)){ + std::vector res; + if(predicat != nullptr){ + res.reserve(data.size() / 2); + for(size_t i = 0; i < data.size(); ++i){ + if(predicat(data[i])) res.push_back(i); + } + } + return res; } \ No newline at end of file diff --git a/03_week/tasks/minmax/minmax.cpp b/03_week/tasks/minmax/minmax.cpp index c2869799..18bef7ff 100644 --- a/03_week/tasks/minmax/minmax.cpp +++ b/03_week/tasks/minmax/minmax.cpp @@ -1,6 +1,20 @@ -#include +#include +#include +#include - -/* return_type */ MinMax(/* args */) { - throw std::runtime_error{"Not implemented"}; +std::pair::const_iterator, std::vector::const_iterator> MinMax(const std::vector& data){ + auto res = std::make_pair(data.end(), data.end()); + int Min{std::numeric_limits::max()}; + int Max{std::numeric_limits::min()}; + for(auto it = data.begin(); it != data.end(); ++it){ + if(*it < Min){ + Min = *it; + res.first = it; + } + if(*it >= Max){ + Max = *it; + res.second = it; + } + } + return res; } diff --git a/03_week/tasks/os_overload/os_overload.cpp b/03_week/tasks/os_overload/os_overload.cpp index e473418d..f1605031 100644 --- a/03_week/tasks/os_overload/os_overload.cpp +++ b/03_week/tasks/os_overload/os_overload.cpp @@ -1,21 +1,39 @@ -#include #include #include struct Coord2D { - int x; - int y; + int x = 0; + int y = 0; }; struct Circle { Coord2D coord; - unsigned radius; + unsigned radius = 1; }; using CircleRegion = std::pair; using CircleRegionList = std::vector; -/* return_type */ operator<<(/* args */) { - throw std::runtime_error{"Not implemented"}; +std::ostream& operator<<(std::ostream& os, const Coord2D& coord) { + return os << "(" << coord.x << ", " << coord.y << ")"; +} + +std::ostream& operator<<(std::ostream& os, const Circle& circle) { + if(circle.radius == 0) return os << "circle[]"; + return os << "circle[" << circle.coord << ", r = " << circle.radius <<"]"; +} + +std::ostream& operator<<(std::ostream& os, const CircleRegion& circReg) { + if(circReg.second) return os << "+" << circReg.first; + return os << "-" << circReg.first; +} + +std::ostream& operator<<(std::ostream& os, const CircleRegionList& regList) { + if(regList.empty()) return os << "{}"; + os << "{\n\t" << regList[0]; + for(auto it = ++regList.begin(); it != regList.end(); ++it){ + os << ",\n\t" << *it; + } + return os << "\n}"; } diff --git a/03_week/tasks/range/range.cpp b/03_week/tasks/range/range.cpp index d2085495..938fe335 100644 --- a/03_week/tasks/range/range.cpp +++ b/03_week/tasks/range/range.cpp @@ -1,7 +1,36 @@ -#include #include +// -11 -1 1 = -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 +// -1 -11 -1 +// 15 20 2 = 15 17 19 +// 15 20 1 = 15 16 17 18 19 -std::vector Range(int from, int to, int step) { - throw std::runtime_error{"Not implemented"}; + +std::vector Range(int from, int to, int step = 1) { + std::vector res; + + // Определение валидности аргументов + if(from > to && step > 0) return res; + if(from < to && step < 0) return res; + if(step == 0) return res; + + // Определение размера + size_t size = std::abs(to - from) % std::abs(step) == 0 ? + std::abs(to - from) / std::abs(step) : + std::abs(to - from) / std::abs(step) + 1; + res.reserve(size); + + if(from < to){ + for(int i = from; i < to; i += step){ + res.push_back(i); + } + } + else{ + for(int i = from; i > to; i += step){ + res.push_back(i); + } + } + + + return res; } diff --git a/03_week/tasks/unique/unique.cpp b/03_week/tasks/unique/unique.cpp index 9d2545bb..f98dbd18 100644 --- a/03_week/tasks/unique/unique.cpp +++ b/03_week/tasks/unique/unique.cpp @@ -1,6 +1,14 @@ -#include #include -/* return_type */ Unique(/* args */) { - throw std::runtime_error{"Not implemented"}; +std::vector Unique(const std::vector& data) { + std::vector res; + if(data.empty()) return res; + + res.reserve(data.size()); + res.push_back(data[0]); + for(auto el : data){ + if(res.back() != el) res.push_back(el); + } + res.shrink_to_fit(); + return res; } diff --git a/04_week/CMakeLists.txt b/04_week/CMakeLists.txt index b15ca37c..0f8cd779 100644 --- a/04_week/CMakeLists.txt +++ b/04_week/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.14) # Минимальная требуемая версия CMake project(04_week) # Необходим для инициализации cmake + set(CMAKE_CXX_STANDARD 20) # Версия стандарта C++ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Гарантирует использование указанной версии стандарта diff --git a/04_week/tasks/phasor/phasor.cpp b/04_week/tasks/phasor/phasor.cpp index 3ec1b9ad..89baf65e 100644 --- a/04_week/tasks/phasor/phasor.cpp +++ b/04_week/tasks/phasor/phasor.cpp @@ -1,4 +1,11 @@ +#include +#include +#include +namespace { + constexpr double eps_ = 1e-12; + constexpr double pi_ = std::numbers::pi; +} struct ExpTag {}; struct DegTag {}; @@ -6,5 +13,201 @@ struct AlgTag {}; class Phasor { +public: + Phasor() = default; + Phasor(double mag, double phase); + Phasor(double mag, double phase, ExpTag) : Phasor(mag, phase) {}; + Phasor(double mag, double phase, DegTag); + Phasor(double re, double im, AlgTag); + void SetPolar(double mag, double phase); + void SetCartesian(double re, double im); + double Magnitude() const; + double Phase() const; + double PhaseDeg() const; + double Abs() const; + double Angle() const; + double AngleDeg() const; + double Real() const; + double Imag() const; + + Phasor Conj() const; + Phasor Inv() const; + + +private: + double mag_{0.0}; + double phase_{0.0}; + + // Методы для поддержания инварианта класса + void PhaseNormalize(); }; + +void Phasor::PhaseNormalize(){ + phase_ -= mag_ >= 0 ? 0 : pi_; + phase_ = phase_ - 2 * pi_ * floor((phase_ + pi_ - eps_) / (2 * pi_)); +} + +Phasor::Phasor(double mag, double phase) : mag_(mag), phase_(phase) { + PhaseNormalize(); +} + +Phasor::Phasor(double mag, double phase, DegTag) : mag_(mag), phase_((pi_ / 180.0) * phase){ + PhaseNormalize(); +} + +Phasor::Phasor(double re, double im, AlgTag) { + mag_ = sqrt(re * re + im * im); + phase_ = atan2(im, re); + PhaseNormalize(); +} + +void Phasor::SetPolar(double mag, double phase){ + mag_ = mag; + phase_ = phase; + PhaseNormalize(); +} + +void Phasor::SetCartesian(double re, double im){ + mag_ = sqrt(re * re + im * im); + phase_ = atan2(im, re); + PhaseNormalize(); +} +double Phasor::Magnitude() const { + return abs(mag_); +} + +double Phasor::Phase() const { + return phase_; +} + +double Phasor::PhaseDeg() const { + return (180.0 / pi_) * phase_; +} + +double Phasor::Abs() const { + return Magnitude(); +} + +double Phasor::Angle() const { + return Phase(); +} + +double Phasor::AngleDeg() const { + return PhaseDeg(); +} + +double Phasor::Real() const { + return abs(mag_) * cos(phase_); +} + +double Phasor::Imag() const { + return abs(mag_) * sin(phase_); +} + +Phasor Phasor::Conj() const { + return Phasor(Real(), -Imag(), AlgTag{}); +} +Phasor Phasor::Inv() const { + return Phasor(1 / Magnitude(), -Phase()); +} + +bool operator==(const Phasor& lhs, const Phasor& rhs){ + return (abs(lhs.Magnitude() - rhs.Magnitude()) < eps_) && + (abs(lhs.Phase() - rhs.Phase()) < eps_); +} + +bool operator!=(const Phasor& lhs, const Phasor& rhs){ + return !(lhs == rhs); +} + +Phasor operator+(const Phasor& lhs, const Phasor& rhs){ + return Phasor(lhs.Real() + rhs.Real(), lhs.Imag() + rhs.Imag(), AlgTag{}); +} +Phasor operator-(const Phasor& lhs, const Phasor& rhs){ + return Phasor(lhs.Real() - rhs.Real(), lhs.Imag() - rhs.Imag(), AlgTag{}); +} +Phasor operator*(const Phasor& lhs, const Phasor& rhs){ + return Phasor(lhs.Magnitude() * rhs.Magnitude(), lhs.Phase() + rhs.Phase()); +} +Phasor operator/(const Phasor& lhs, const Phasor& rhs){ + return Phasor(lhs.Magnitude() / rhs.Magnitude(), lhs.Phase() - rhs.Phase()); +} + +Phasor operator+(const Phasor& lhs, const double rhs){ + return Phasor(lhs.Real() + rhs, lhs.Imag(), AlgTag{}); +} +Phasor operator-(const Phasor& lhs, const double rhs){ + return Phasor(lhs.Real() - rhs, lhs.Imag(), AlgTag{}); +} +Phasor operator*(const Phasor& lhs, const double rhs){ + return Phasor(lhs.Magnitude() * rhs, lhs.Phase()); +} +Phasor operator/(const Phasor& lhs, const double rhs){ + return Phasor(lhs.Magnitude() / rhs, lhs.Phase()); +} + +Phasor operator+(const double lhs, const Phasor& rhs){ + return Phasor(lhs + rhs.Real(), rhs.Imag(), AlgTag{}); +} +Phasor operator-(const double lhs, const Phasor& rhs){ + return Phasor(lhs - rhs.Real(), -rhs.Imag(), AlgTag{}); +} +Phasor operator*(const double lhs, const Phasor& rhs){ + return Phasor(lhs * rhs.Magnitude(), rhs.Phase()); +} +Phasor operator/(const double lhs, const Phasor& rhs){ + return Phasor(lhs / rhs.Magnitude(), -rhs.Phase()); +} + +Phasor operator-(const Phasor& phasor){ + return Phasor(-(phasor.Magnitude()), phasor.Phase()); +} + +Phasor& operator+=(Phasor& lhs, const Phasor& rhs){ + lhs.SetCartesian(lhs.Real() + rhs.Real(), lhs.Imag() + rhs.Imag()); + return lhs; +} +Phasor& operator-=(Phasor& lhs, const Phasor& rhs){ + lhs.SetCartesian(lhs.Real() - rhs.Real(), lhs.Imag() - rhs.Imag()); + return lhs; +} +Phasor& operator*=(Phasor& lhs, const Phasor& rhs){ + lhs.SetPolar(lhs.Magnitude() * rhs.Magnitude(), lhs.Phase() + rhs.Phase()); + return lhs; +} +Phasor& operator/=(Phasor& lhs, const Phasor& rhs){ + lhs.SetPolar(lhs.Magnitude() / rhs.Magnitude(), lhs.Phase() - rhs.Phase()); + return lhs; +} + +Phasor& operator+=(Phasor& lhs, const double rhs){ + lhs.SetCartesian(lhs.Real() + rhs, lhs.Imag()); + return lhs; +} +Phasor& operator-=(Phasor& lhs, const double rhs){ + lhs.SetCartesian(lhs.Real() - rhs, lhs.Imag()); + return lhs; +} +Phasor& operator*=(Phasor& lhs, const double rhs){ + lhs.SetPolar(lhs.Magnitude() * rhs, lhs.Phase()); + return lhs; +} +Phasor& operator/=(Phasor& lhs, const double rhs){ + lhs.SetPolar(lhs.Magnitude() / rhs, lhs.Phase()); + return lhs; +} + +std::ostream& operator<<(std::ostream& os, const Phasor& p){ + return os << std::fixed << p.Abs() << "*e(j*" << p.AngleDeg() << ") " << "[" << p.Real() << " + j*" << p.Imag() << "]"; +} + +Phasor MakePhasorCartesian(double re, double im){ + return Phasor{re, im, AlgTag{}}; +} +Phasor MakePhasorPolar(double mag, double phase){ + return Phasor{mag, phase}; +} +Phasor MakePhasorPolarDeg(double mag, double phase){ + return Phasor{mag, phase, DegTag{}}; +} \ No newline at end of file diff --git a/04_week/tasks/queue/queue.cpp b/04_week/tasks/queue/queue.cpp index 2a9f8493..6236c2fd 100644 --- a/04_week/tasks/queue/queue.cpp +++ b/04_week/tasks/queue/queue.cpp @@ -1,6 +1,110 @@ #include +#include +#include class Queue { +public: + Queue(std::stack& stack); + Queue(const std::vector& vec); + Queue(const std::initializer_list list); + Queue(size_t size); + Queue() = default; + void Push(int value); + bool Pop(); + int& Front(); + int& Back(); + const int& Front() const; + const int& Back() const; + bool Empty() const; + size_t Size() const; + void Clear(); + void Swap(Queue& other); + bool operator==(const Queue& rhs) const; + bool operator!=(const Queue& rhs) const; +private: + std::vector in_; + std::vector out_; }; + + +Queue::Queue(std::stack& stack) { + out_.reserve(stack.size() * 1.2); + while(!(stack.empty())){ + out_.push_back(stack.top()); + stack.pop(); + } +} +Queue::Queue(const std::vector& vec) { + out_.reserve(vec.size() * 1.5); + out_.insert(out_.end(), vec.rbegin(), vec.rend()); +} +Queue::Queue(std::initializer_list list) { + out_.reserve(list.size() * 1.5); + for(auto it = std::rbegin(list); it != std::rend(list); ++it){ + out_.push_back(*it); + } +} +Queue::Queue(size_t size) { + out_.reserve(size); + in_.reserve(size); +} + +void Queue::Push(int value){ + in_.push_back(value); +} +bool Queue::Pop(){ + if(in_.empty() && out_.empty()) return false; + if(out_.empty() && !(in_.empty())){ + while(!(in_.empty())){ + out_.push_back(in_.back()); + in_.pop_back(); + } + } + out_.pop_back(); + return true; +} +int& Queue::Front() { + if(out_.empty()) return in_.front(); + return out_.back(); +} +int& Queue::Back() { + if(in_.empty()) return out_.front(); + return in_.back(); +} +const int& Queue::Front() const { + if(out_.empty()) return in_.front(); + return out_.back(); +} +const int& Queue::Back() const { + if(in_.empty()) return out_.front(); + return in_.back(); +} +bool Queue::Empty() const { + if(in_.empty() && out_.empty()) return true; + return false; +} +size_t Queue::Size() const { + return in_.size() + out_.size(); +} +void Queue::Clear() { + in_.clear(); + out_.clear(); +} +void Queue::Swap(Queue& other) { + in_.swap(other.in_); + out_.swap(other.out_); +} + +bool Queue::operator==(const Queue& rhs) const { + std::vector tmp_lhs(this->in_.rbegin(), this->in_.rend()); + tmp_lhs.insert(tmp_lhs.end(), this->out_.begin(), this->out_.end()); + std::vector tmp_rhs(rhs.in_.rbegin(), rhs.in_.rend()); + tmp_rhs.insert(tmp_rhs.end(), rhs.out_.begin(), rhs.out_.end()); + + return tmp_lhs == tmp_rhs; +} +bool Queue::operator!=(const Queue& rhs) const { + return !(*this == rhs); +} \ No newline at end of file diff --git a/04_week/tasks/ring_buffer/ring_buffer.cpp b/04_week/tasks/ring_buffer/ring_buffer.cpp index e2b57ba2..d95ad3aa 100644 --- a/04_week/tasks/ring_buffer/ring_buffer.cpp +++ b/04_week/tasks/ring_buffer/ring_buffer.cpp @@ -1,6 +1,194 @@ #include +#include class RingBuffer { +public: + RingBuffer() = default; + // + RingBuffer(size_t size); + RingBuffer(size_t capacity, int value); + RingBuffer(const std::initializer_list list); + // Добавляет элемент в буфер, может перезаписывать + void Push(int value); + // Пытается добавить элемент без перезаписи, true - успех + bool TryPush(int value); + // Убирает самый старый элемент из буфера + void Pop(); + // Пытается извлечь самый старый элемент и возвращает убранное значение через параметр метода + bool TryPop(int& poped); + // Обеспечивает доступ на запись и чтение к самому новому элементу буфера + int& Front(); + // Обеспечивает доступ на запись и чтение к самому старому элементу буфера + int& Back(); + // Обеспечивает доступ на запись и чтение к самому новому элементу буфера + const int& Front() const; + // Обеспечивает доступ на запись и чтение к самому старому элементу буфера + const int& Back() const; + // Возвращает результат проверки буфера на отсутствие элементов + bool Empty() const; + // Возвращает результат проверки буфера на заполненность + bool Full() const; + // Возвращает количество элементов в буфере + size_t Size() const; + // Возвращает размер буфера + size_t Capacity() const; + // Очищает буфер, позиции начала и конца соответствуют нулевому элементу + void Clear(); + // Изменяет вместимость буфера + void Resize(size_t size); + // Возвращает `std::vector` - линейное представление буфера + std::vector Vector() const; + // Доступ по индексу + int& operator[](size_t index); + const int& operator[](size_t index) const; +private: + std::vector data_ = {-1}; + // Кол-во элементов в буфере + size_t size_ = 0; + // Итератор на последний элемент + std::vector::iterator end_ = data_.end(); + std::vector::iterator begin_ = data_.begin(); }; + +RingBuffer::RingBuffer(size_t size) : data_(size + 1), size_(0), end_(data_.begin()), begin_(data_.begin()) { + begin_ += size + 1 >= 2 ? 1 : 0; +} + +RingBuffer::RingBuffer(size_t size, int value) : data_(size+1, value), size_(size), end_(data_.end() - 1), begin_(data_.begin()) { + if(size == 0){ + data_.push_back(value); + size_ = 1; + end_ = data_.end() - 1; + begin_ = end_; + } + begin_ += size + 1 >= 2 ? 1 : 0; +} + +RingBuffer::RingBuffer(const std::initializer_list list) : size_(list.size()), end_(data_.begin()), begin_(data_.begin()) { + data_.insert(data_.end(), list.begin(), list.end()); + end_ = data_.end() - 1; + begin_ = data_.begin() + 1; +} + +void RingBuffer::Push(int value) { + if(end_ + 1 == data_.end()){ + end_ = data_.begin() + 1; + *end_ = value; + } + else *(++end_) = value; + + if(begin_ != end_ || size_ == 0){ + ++size_; + return; + } + if(size_ != 1){ + begin_ = begin_ + 1 == data_.end() ? data_.begin() + 1 : begin_ + 1; + } +} +bool RingBuffer::TryPush(int value) { + if(size_ == data_.size() - 1){ + return false; + } + else *(++end_) = value; + + if(begin_ != end_ || size_ == 0){ + ++size_; + return true; + } + if(size_ != 1){ + begin_ = begin_ + 1 == data_.end() ? data_.begin() + 1 : begin_ + 1; + } + return true; +} +void RingBuffer::Pop() { + if(size_ == 0) return; + --size_; + begin_ = begin_ + 1 == data_.end() ? data_.begin() + 1 : begin_ + 1; +} +bool RingBuffer::TryPop(int& poped) { + if(size_ == 0) return false; + --size_; + poped = *begin_; + begin_ = begin_ + 1 == data_.end() ? data_.begin() + 1 : begin_ + 1; + return true; +} + +int& RingBuffer::Front() { + return *end_; +} +int& RingBuffer::Back() { + return *begin_; +} +const int& RingBuffer::Front() const { + return *end_; +} +const int& RingBuffer::Back() const { + return *begin_; +} +bool RingBuffer::Empty() const { + return size_ == 0 ? true : false; +} +bool RingBuffer::Full() const { + if(data_.size() == 1) return false; + return data_.size() - 1 == size_ ? true : false; +} +size_t RingBuffer::Size() const { + return size_; +} +size_t RingBuffer::Capacity() const { + return data_.size() != 1 ? data_.size() - 1 : 1; +} +void RingBuffer::Clear() { + size_ = 0; + end_ = data_.begin(); + begin_ = data_.begin() + 1; +} +void RingBuffer::Resize(size_t size) { + if(size == size_) return; + if(size == 0) { + Clear(); + size_ = 1; + return; + } + std::vector New = Vector(); + if(size < size_){ + data_ = std::vector(New.end() - size, New.end()); + data_.insert(data_.begin(), 0); + } + else{ + New.insert(New.begin(), 0); + New.resize(size + 1); + data_ = New; + } + + size_ = size < size_ ? size : size_; + begin_ = data_.begin() + 1; + end_ = begin_ + size_ - 1; +} +std::vector RingBuffer::Vector() const { + std::vector res; + res.reserve(size_); + std::vector::const_iterator it = begin_; + while(true){ + res.push_back(*it); + if(it == end_) break; + if(it + 1 == data_.end()) it = data_.begin() + 1; + else ++it; + } + return res; +} + +int& RingBuffer::operator[](size_t index) { + if(size_t dif = data_.end() - begin_; dif <= index){ + return *(data_.begin() + index - dif + 1); + } + return *(begin_ + index); +} +const int& RingBuffer::operator[](size_t index) const { + if(size_t dif = data_.end() - begin_; dif <= index){ + return *(data_.begin() + index - dif + 1); + } + return *(begin_ + index); +} \ No newline at end of file diff --git a/04_week/tasks/stack/stack.cpp b/04_week/tasks/stack/stack.cpp index 222e4ffc..1254ca8f 100644 --- a/04_week/tasks/stack/stack.cpp +++ b/04_week/tasks/stack/stack.cpp @@ -2,5 +2,53 @@ class Stack { +public: + Stack() = default; + void Push(const int value); + bool Pop(); + int& Top(); + const int& Top() const; + bool Empty() const; + size_t Size() const; + void Clear(); + void Swap(Stack& other); + bool operator==(const Stack& rhs) const; + bool operator!=(const Stack& rhs) const; +private: + std::vector data_; }; + +void Stack::Push(const int value) { + data_.push_back(value); +} +bool Stack::Pop() { + if(data_.empty()) return false; + data_.pop_back(); + return true; +} +int& Stack::Top() { + return data_.back(); +} +const int& Stack::Top() const { + return data_.back(); +} +bool Stack::Empty() const { + return data_.empty(); +} +size_t Stack::Size() const { + return data_.size(); +} +void Stack::Clear() { + data_.clear(); +} +void Stack::Swap(Stack& other) { + data_.swap(other.data_); +} + +bool Stack::operator==(const Stack& rhs) const { + return data_ == rhs.data_; +} +bool Stack::operator!=(const Stack& rhs) const { + return data_ != rhs.data_; +}