diff --git a/01_week/tasks/addition/addition.cpp b/01_week/tasks/addition/addition.cpp index 92872802..dc266f76 100644 --- a/01_week/tasks/addition/addition.cpp +++ b/01_week/tasks/addition/addition.cpp @@ -3,5 +3,7 @@ int64_t Addition(int a, int b) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file + int64_t one = static_cast(a); + int64_t two = static_cast(b); + return one + two; +} diff --git a/01_week/tasks/check_flags/check_flags.cpp b/01_week/tasks/check_flags/check_flags.cpp index 75e7c652..e025a85b 100644 --- a/01_week/tasks/check_flags/check_flags.cpp +++ b/01_week/tasks/check_flags/check_flags.cpp @@ -1,18 +1,45 @@ -#include -#include - - -enum class CheckFlags : uint8_t { - NONE = 0, - TIME = (1 << 0), - DATE = (1 << 1), - USER = (1 << 2), - CERT = (1 << 3), - KEYS = (1 << 4), - DEST = (1 << 5), - ALL = TIME | DATE | USER | CERT | KEYS | DEST -}; - -void PrintCheckFlags(CheckFlags flags) { - throw std::runtime_error{"Not implemented"}; -} +#include +#include + + +enum class CheckFlags : uint8_t { + NONE = 0, + TIME = (1 << 0), + DATE = (1 << 1), + USER = (1 << 2), + CERT = (1 << 3), + KEYS = (1 << 4), + DEST = (1 << 5), + ALL = TIME | DATE | USER | CERT | KEYS | DEST +}; + +void PrintCheckFlags(CheckFlags flags) { + uint8_t value = static_cast(flags); + const uint8_t valid_mask = 0x3F; // 0b00111111 + + if (value & ~valid_mask) { + std::cout << ""; + return; + } + + std::string output = "["; + const char* separator = ""; + + auto add_flag = [&](CheckFlags flag, const char* name) { + if (value & static_cast(flag)) { + output += separator; + output += name; + separator = ","; + } + }; + + add_flag(CheckFlags::TIME, "TIME"); + add_flag(CheckFlags::DATE, "DATE"); + add_flag(CheckFlags::USER, "USER"); + add_flag(CheckFlags::CERT, "CERT"); + add_flag(CheckFlags::KEYS, "KEYS"); + add_flag(CheckFlags::DEST, "DEST"); + + output += "]"; + std::cout << output; +} \ No newline at end of file diff --git a/01_week/tasks/length_lit/length_lit.cpp b/01_week/tasks/length_lit/length_lit.cpp index e69de29b..13f166b4 100644 --- a/01_week/tasks/length_lit/length_lit.cpp +++ b/01_week/tasks/length_lit/length_lit.cpp @@ -0,0 +1,53 @@ +#include + +constexpr double operator "" _ft_to_m(long double value) { + return static_cast(value * 0.3048); +} + +constexpr double operator "" _ft_to_cm(long double value) { + return static_cast(value * 30.48); +} + +constexpr double operator "" _ft_to_in(long double value) { + return static_cast(value * 12.0); +} + +constexpr double operator "" _in_to_m(long double value) { + return static_cast(value * 0.0254); +} + +constexpr double operator "" _in_to_cm(long double value) { + return static_cast(value * 2.54); +} + +constexpr double operator "" _in_to_ft(long double value) { + return static_cast(value / 12.0); +} + +constexpr double operator "" _m_to_ft(long double value) { + return static_cast(value / 0.3048); +} + +constexpr double operator "" _m_to_in(long double value) { + return static_cast(value / 0.0254); +} + +constexpr double operator "" _m_to_cm(long double value) { + return static_cast(value * 100.0); +} + +constexpr double operator "" _cm_to_m(long double value) { + return static_cast(value * 0.01); +} + +constexpr double operator "" _cm_to_ft(long double value) { + return static_cast(value / 30.48); +} + +constexpr double operator "" _cm_to_in(long double value) { + return static_cast(value / 2.54); + +} + + + diff --git a/01_week/tasks/print_bits/print_bits.cpp b/01_week/tasks/print_bits/print_bits.cpp index a48a43c1..ac224958 100644 --- a/01_week/tasks/print_bits/print_bits.cpp +++ b/01_week/tasks/print_bits/print_bits.cpp @@ -1,7 +1,29 @@ -#include -#include - - -void PrintBits(long long value, size_t bytes) { - throw std::runtime_error{"Not implemented"}; -} +#include + +void PrintBits(long long value, size_t bytes) { + if (bytes == 0 || bytes > 8) { + return; + } + + const size_t total_bits = bytes * 8; + unsigned long long unsigned_value = value; + + std::cout << "0b"; + + for (size_t i = 0; i < total_bits; ++i) { + size_t bit_pos = total_bits - 1 - i; + unsigned long long mask = 1ULL << bit_pos; + + if (unsigned_value & mask) { + std::cout << '1'; + } else { + std::cout << '0'; + } + + if ((i + 1) % 4 == 0 && i != total_bits - 1) { + std::cout << "'"; + } + } + + std::cout << '\n'; +} \ No newline at end of file diff --git a/01_week/tasks/quadratic/quadratic.cpp b/01_week/tasks/quadratic/quadratic.cpp index abf7d632..5669bb2d 100644 --- a/01_week/tasks/quadratic/quadratic.cpp +++ b/01_week/tasks/quadratic/quadratic.cpp @@ -1,6 +1,56 @@ -#include - - -void SolveQuadratic(int a, int b, int c) { - throw std::runtime_error{"Not implemented"}; +#include +#include +#include +#include + +void SolveQuadratic(int a, int b, int c) { + std::cout << std::setprecision(6); + + if (a == 0 && b == 0 && c == 0) { + std::cout << "infinite solutions"; + return; + } + + if (a == 0 && b == 0 && c != 0) { + std::cout << "no solutions"; + return; + } + + if (a == 0) { + double root = -static_cast(c) / b; + + if (root == 0.0) root = 0.0; + + std::cout << root; + return; + } + + double discr = static_cast(b) * b - 4.0 * a * c; + + if (discr < 0) { + std::cout << "no solutions"; + return; + } + + if (discr == 0) { + double root = -static_cast(b) / (2.0 * a); + + if (root == 0.0) root = 0.0; + + std::cout << root; + return; + } + + double sqrt_d = std::sqrt(discr); + double root1 = (-static_cast(b) - sqrt_d) / (2.0 * a); + double root2 = (-static_cast(b) + sqrt_d) / (2.0 * a); + + if (root1 > root2) { + std::swap(root1, root2); + } + + if (root1 == 0.0) root1 = 0.0; + if (root2 == 0.0) root2 = 0.0; + + std::cout << root1 << " " << root2; } \ No newline at end of file diff --git a/01_week/tasks/rms/rms.cpp b/01_week/tasks/rms/rms.cpp index 6882f0a9..1e2b0ab4 100644 --- a/01_week/tasks/rms/rms.cpp +++ b/01_week/tasks/rms/rms.cpp @@ -1,7 +1,19 @@ -#include -#include - - -double CalculateRMS(double values[], size_t size) { - throw std::runtime_error{"Not implemented"}; +#include +#include +#include + + + +double CalculateRMS(double values[], size_t size) { + if (values == nullptr || size == 0) { + return 0.0; + } + + double sum = 0.0; + for (size_t i = 0; i < size; ++i) { + sum += values[i] * values[i]; + } + + double sqavg = sum / size; + return std::sqrt(sqavg); } \ 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..9f972792 100644 --- a/02_week/tasks/func_array/func_array.cpp +++ b/02_week/tasks/func_array/func_array.cpp @@ -1,6 +1,15 @@ -#include - - -double ApplyOperations(double a, double b /* other arguments */) { - throw std::runtime_error{"Not implemented"}; +#include + +double ApplyOperations(double a, double b, double (**operations)(double, double), size_t n) { + double total = 0.0; + + if (operations == nullptr || n == 0) { + return total;} + + for (size_t i = 0; i < n; ++i) { + if (operations[i] != nullptr) { + total += operations[i](a, b);} + } + + return total; } \ 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..1d8efa5a 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,22 @@ #include - -/* return_type */ FindLastElement(/* ptr_type */ begin, /* ptr_type */ end, /* func_type */ predicate) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +const int* FindLastElement(const int* begin, const int* end, bool (*predicate)(int)) { + + if (begin == nullptr || end == nullptr || begin > end) { + return end; + } + + const int* last_found = end; + + // Проходим по массиву с конца к началу + const int* current = end; + while (current > begin) { + --current; + if (predicate(*current)) { + last_found = current; + break; + } + } + + return last_found; +} diff --git a/02_week/tasks/longest/longest.cpp b/02_week/tasks/longest/longest.cpp index 04b3c354..1b357730 100644 --- a/02_week/tasks/longest/longest.cpp +++ b/02_week/tasks/longest/longest.cpp @@ -1,6 +1,48 @@ #include +template +CharType* FindLongestSubsequenceImpl(CharType* begin, CharType* end, size_t& count) { + if (begin == nullptr || end == nullptr || begin > end) { + count = 0; + return nullptr; + } + + if (begin == end) { + count = 0; + return nullptr; + } + + CharType* longest_start = begin; + size_t longest_length = 1; + CharType* current_start = begin; + size_t current_length = 1; + + for (CharType* ptr = begin; ptr < end - 1; ++ptr) { + if (*ptr == *(ptr + 1)) { + current_length++; + } else { + if (current_length > longest_length) { + longest_length = current_length; + longest_start = current_start; + } + current_start = ptr + 1; + current_length = 1; + } + } + + if (current_length > longest_length) { + longest_length = current_length; + longest_start = current_start; + } + + count = longest_length; + return longest_start; +} + +const char* FindLongestSubsequence(const char* begin, const char* end, size_t& count) { + return FindLongestSubsequenceImpl(begin, end, count); +} -/* return_type */ FindLongestSubsequence(/* ptr_type */ begin, /* ptr_type */ end, /* type */ count) { - throw std::runtime_error{"Not implemented"}; +char* FindLongestSubsequence(char* begin, char* end, size_t& count) { + return FindLongestSubsequenceImpl(begin, end, count); } diff --git a/02_week/tasks/pretty_array/pretty_array.cpp b/02_week/tasks/pretty_array/pretty_array.cpp index 48eab341..d9f790eb 100644 --- a/02_week/tasks/pretty_array/pretty_array.cpp +++ b/02_week/tasks/pretty_array/pretty_array.cpp @@ -1,6 +1,42 @@ -#include +#include +void PrintArray(const int* begin, const int* end, size_t limit = 0) { + if (begin == end) { + std::cout << "[]\n"; + return; + } -void PrintArray(/* write arguments here */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file + bool forward = (end > begin); + const int* current = begin; + + std::cout << '['; + + size_t count_in_line = 0; + bool first_element = true; + + while (true) { + if (!first_element) { + std::cout << ", "; + } + std::cout << *current; + first_element = false; + count_in_line++; + + const int* next = forward ? current + 1 : current - 1; + bool has_more_elements = (forward && next < end) || (!forward && next > end); + + if (has_more_elements) { + if (limit > 0 && count_in_line == limit) { + std::cout << ", ...\n "; + count_in_line = 0; + first_element = true; + } + } else { + break; + } + + current = next; + } + + std::cout << "]\n"; +} diff --git a/02_week/tasks/swap_ptr/swap_ptr.cpp b/02_week/tasks/swap_ptr/swap_ptr.cpp index 93db625d..fc3e092f 100644 --- a/02_week/tasks/swap_ptr/swap_ptr.cpp +++ b/02_week/tasks/swap_ptr/swap_ptr.cpp @@ -1,6 +1,19 @@ #include +void SwapPtr(int*& a, int*& b) { + int* temp = a; + a = b; + b = temp; +} -void SwapPtr(/* write arguments here */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +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; +} diff --git a/03_week/tasks/data_stats/data_stats.cpp b/03_week/tasks/data_stats/data_stats.cpp index b941c211..67ca4ea9 100644 --- a/03_week/tasks/data_stats/data_stats.cpp +++ b/03_week/tasks/data_stats/data_stats.cpp @@ -1,11 +1,41 @@ -#include - - -struct DataStats { - double avg = 0.0; - double sd = 0.0; -}; - -/* return_type */ CalculateDataStats(/* args */) { - throw std::runtime_error{"Not implemented"}; -} +#include +#include +#include + +struct DataStats { + double avg = 0.0; + double sd = 0.0; +}; + +DataStats CalculateDataStats(const std::vector& data) { + DataStats result; + size_t n = data.size(); + + if (n == 0) { + return result; + } + + double sum = 0.0; + for (int value : data) { + sum += value; + } + + // + result.avg = sum / n; + + if (n == 1) { + + result.sd = 0.0; + return result; + } + + double sum_squared_diff = 0.0; + for (int value : data) { + double diff = value - result.avg; + sum_squared_diff += diff * diff; + } + + result.sd = std::sqrt(sum_squared_diff / n); + + return result; +} \ No newline at end of file diff --git a/03_week/tasks/easy_compare/easy_compare.cpp b/03_week/tasks/easy_compare/easy_compare.cpp index dd5cb7f6..a0c2893b 100644 --- a/03_week/tasks/easy_compare/easy_compare.cpp +++ b/03_week/tasks/easy_compare/easy_compare.cpp @@ -1,16 +1,84 @@ -#include - - -struct Date { - unsigned year; - unsigned month; - unsigned day; -}; - -struct StudentInfo { - size_t id; - char mark; - int score; - unsigned course; - Date birth_date; -}; \ No newline at end of file +#include +#include + +struct Date { + unsigned year; + unsigned month; + unsigned day; + + Date() : year(0), month(0), day(0) {} + + Date(unsigned y, unsigned m, unsigned d) : year(y), month(m), day(d) {} +}; + +struct StudentInfo { + size_t id; + char mark; + int score; + unsigned course; + Date birth_date; +}; + +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); +} + +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 !(rhs < lhs); +} + +bool operator>(const Date& lhs, const Date& rhs) { + return rhs < lhs; +} + +bool operator>=(const Date& lhs, const Date& rhs) { + return !(lhs < rhs); +} + +int mark_priority(char mark) { + switch (mark) { + case 'A': return 5; + case 'B': return 4; + case 'C': return 3; + case 'D': return 2; + case 'Z': return 1; + default: return 0; + } +} + +bool operator==(const StudentInfo& lhs, const StudentInfo& rhs) { + return lhs.mark == rhs.mark && lhs.score == rhs.score; +} + +bool operator!=(const StudentInfo& lhs, const StudentInfo& rhs) { + return !(lhs == rhs); +} + +bool operator<(const StudentInfo& lhs, const StudentInfo& rhs) { + int lhs_priority = mark_priority(lhs.mark); + int rhs_priority = mark_priority(rhs.mark); + + if (lhs_priority != rhs_priority) { + return lhs_priority < rhs_priority; + } + + if (lhs.score != rhs.score) { + return lhs.score < rhs.score; + } + + if (lhs.course != rhs.course) { + return lhs.course > rhs.course; + } + + return lhs.birth_date < rhs.birth_date; +} \ 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..803f9935 100644 --- a/03_week/tasks/enum_operators/enum_operators.cpp +++ b/03_week/tasks/enum_operators/enum_operators.cpp @@ -1,33 +1,88 @@ -#include -#include - -enum class CheckFlags : uint8_t { - NONE = 0, - TIME = (1 << 0), - DATE = (1 << 1), - USER = (1 << 2), - CERT = (1 << 3), - KEYS = (1 << 4), - DEST = (1 << 5), - ALL = TIME | DATE | USER | CERT | KEYS | DEST -}; - -/* return_type */ operator|(/* args */) { - throw std::runtime_error{"Not implemented"}; -} - -/* return_type */ operator&(/* args */) { - throw std::runtime_error{"Not implemented"}; -} - -/* return_type */ operator^(/* args */) { - throw std::runtime_error{"Not implemented"}; -} - -/* return_type */ operator~(/* args */) { - throw std::runtime_error{"Not implemented"}; -} - -/* return_type */ operator<<(/* args */) { - throw std::runtime_error{"Not implemented"}; -} +#include +#include +#include +#include + +enum class CheckFlags : uint8_t { + NONE = 0, + TIME = (1 << 0), + DATE = (1 << 1), + USER = (1 << 2), + CERT = (1 << 3), + KEYS = (1 << 4), + DEST = (1 << 5), + ALL = TIME | DATE | USER | CERT | KEYS | DEST +}; + +constexpr uint8_t MASK = 0x3F; + +inline CheckFlags sanitize(CheckFlags flags) { + return static_cast(static_cast(flags) & MASK); +} + +CheckFlags operator|(CheckFlags lhs, CheckFlags rhs) { + return static_cast( + (static_cast(lhs) | static_cast(rhs)) & MASK); +} + +CheckFlags operator&(CheckFlags lhs, CheckFlags rhs) { + return static_cast( + (static_cast(lhs) & static_cast(rhs)) & MASK); +} + +CheckFlags operator^(CheckFlags lhs, CheckFlags rhs) { + return static_cast( + (static_cast(lhs) ^ static_cast(rhs)) & MASK); +} + +CheckFlags operator~(CheckFlags flags) { + return static_cast( + (~static_cast(flags)) & MASK); +} + +std::ostream& operator<<(std::ostream& os, CheckFlags flags) { + flags = sanitize(flags); + + if (flags == CheckFlags::NONE) { + os << "NONE"; + return os; + } + + bool first = true; + + if ((flags & CheckFlags::TIME) != CheckFlags::NONE) { + os << "TIME"; + first = false; + } + + if ((flags & CheckFlags::DATE) != CheckFlags::NONE) { + if (!first) os << ", "; + os << "DATE"; + first = false; + } + + if ((flags & CheckFlags::USER) != CheckFlags::NONE) { + if (!first) os << ", "; + os << "USER"; + first = false; + } + + if ((flags & CheckFlags::CERT) != CheckFlags::NONE) { + if (!first) os << ", "; + os << "CERT"; + first = false; + } + + if ((flags & CheckFlags::KEYS) != CheckFlags::NONE) { + if (!first) os << ", "; + os << "KEYS"; + first = false; + } + + if ((flags & CheckFlags::DEST) != CheckFlags::NONE) { + if (!first) os << ", "; + os << "DEST"; + } + + return os; +} \ No newline at end of file diff --git a/03_week/tasks/filter/filter.cpp b/03_week/tasks/filter/filter.cpp index 6648cb39..1a570827 100644 --- a/03_week/tasks/filter/filter.cpp +++ b/03_week/tasks/filter/filter.cpp @@ -1,6 +1,23 @@ -#include - - -/* return_type */ Filter(/* args */) { - throw std::runtime_error{"Not implemented"}; +#include + +using Predicate = bool (*)(int); + +void Filter(std::vector& vec, Predicate predicate) { + + if (!predicate) { + return; + } + + size_t write_index = 0; + + for (size_t read_index = 0; read_index < vec.size(); ++read_index) { + if (predicate(vec[read_index])) { + if (write_index != read_index) { + vec[write_index] = vec[read_index]; + } + ++write_index; + } + } + + vec.resize(write_index); } \ 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..93cb29ad 100644 --- a/03_week/tasks/find_all/find_all.cpp +++ b/03_week/tasks/find_all/find_all.cpp @@ -1,6 +1,21 @@ -#include - - -/* return_type */ FindAll(/* args */) { - throw std::runtime_error{"Not implemented"}; +#include + +using Predicate = bool (*)(int); + +std::vector FindAll(const std::vector& vec, Predicate predicate) { + std::vector result; + + if (!predicate) { + return result; + } + + for (size_t i = 0; i < vec.size(); ++i) { + if (predicate(vec[i])) { + result.push_back(i); + } + } + + result.shrink_to_fit(); + + return result; } \ No newline at end of file diff --git a/03_week/tasks/minmax/minmax.cpp b/03_week/tasks/minmax/minmax.cpp index c2869799..3d054f09 100644 --- a/03_week/tasks/minmax/minmax.cpp +++ b/03_week/tasks/minmax/minmax.cpp @@ -1,6 +1,50 @@ -#include - - -/* return_type */ MinMax(/* args */) { - throw std::runtime_error{"Not implemented"}; -} +#include +#include +#include + +std::pair::const_iterator, std::vector::const_iterator> +MinMax(const std::vector& vec) { + if (vec.empty()) { + return {vec.end(), vec.end()}; + } + + auto min_it = vec.begin(); + auto max_it = vec.begin(); + + for (auto it = vec.begin() + 1; it != vec.end(); ++it) { + if (*it < *min_it) { + + min_it = it; + } else if (*it > *max_it) { + + max_it = it; + } else if (*it == *max_it) { + + max_it = it; + } + } + + return {min_it, max_it}; +} + +std::pair::iterator, std::vector::iterator> +MinMax(std::vector& vec) { + if (vec.empty()) { + return {vec.end(), vec.end()}; + } + + auto min_it = vec.begin(); + auto max_it = vec.begin(); + + for (auto it = vec.begin() + 1; it != vec.end(); ++it) { + if (*it < *min_it) { + min_it = it; + } else if (*it > *max_it) { + max_it = it; + } else if (*it == *max_it) { + max_it = it; + } + } + + return {min_it, max_it}; +} \ No newline at end of file diff --git a/03_week/tasks/range/range.cpp b/03_week/tasks/range/range.cpp index d2085495..d83bcb7f 100644 --- a/03_week/tasks/range/range.cpp +++ b/03_week/tasks/range/range.cpp @@ -1,7 +1,34 @@ -#include -#include - - -std::vector Range(int from, int to, int step) { - throw std::runtime_error{"Not implemented"}; -} +#include +#include + +std::vector Range(int from, int to, int step) { + if (step == 0) { + return {}; + } + + if ((step > 0 && from >= to) || (step < 0 && from <= to)) { + return {}; + } + + int n = 0; + if (step > 0) { + n = (to - from - 1) / step + 1; + } else { + n = (to - from + 1) / step + 1; + } + + std::vector result; + result.reserve(n); + + int current = from; + while ((step > 0 && current < to) || (step < 0 && current > to)) { + result.push_back(current); + current += step; + } + + return result; +} + +std::vector Range(int from, int to) { + return Range(from, to, 1); +} \ No newline at end of file diff --git a/03_week/tasks/unique/unique.cpp b/03_week/tasks/unique/unique.cpp index 9d2545bb..343cc49d 100644 --- a/03_week/tasks/unique/unique.cpp +++ b/03_week/tasks/unique/unique.cpp @@ -1,6 +1,25 @@ -#include -#include - -/* return_type */ Unique(/* args */) { - throw std::runtime_error{"Not implemented"}; -} +#include +#include + +std::vector Unique(const std::vector& vec) { + std::vector result; + + if (vec.empty()) { + return result; + } + + result.reserve(vec.size()); + + + result.push_back(vec[0]); + + for (size_t i = 1; i < vec.size(); ++i) { + if (vec[i] != result.back()) { + result.push_back(vec[i]); + } + } + + result.shrink_to_fit(); + + return result; +} \ No newline at end of file diff --git a/04_week/tasks/phasor/phasor.cpp b/04_week/tasks/phasor/phasor.cpp index 3ec1b9ad..55cf7498 100644 --- a/04_week/tasks/phasor/phasor.cpp +++ b/04_week/tasks/phasor/phasor.cpp @@ -1,10 +1,264 @@ - - -struct ExpTag {}; -struct DegTag {}; -struct AlgTag {}; - - -class Phasor { - -}; +#include +#include +#include + +struct ExpTag {}; +struct DegTag {}; +struct AlgTag {}; + +class Phasor { +private: + double real_; + double imag_; + +public: + Phasor() : real_(0.0), imag_(0.0) {} + + Phasor(double magnitude, double phase_rad) { + double mag = std::abs(magnitude); + double phase = phase_rad; + if (magnitude < 0) { + phase += std::numbers::pi; + } + phase = NormalizePhase(phase); + real_ = mag * std::cos(phase); + imag_ = mag * std::sin(phase); + } + + Phasor(double magnitude, double phase_rad, ExpTag) + : Phasor(magnitude, phase_rad) {} + + Phasor(double magnitude, double phase_deg, DegTag) + : Phasor(magnitude, phase_deg * std::numbers::pi / 180.0) {} + + Phasor(double real, double imag, AlgTag) + : real_(real), imag_(imag) { + double mag = Magnitude(); + double phase = Phase(); + real_ = mag * std::cos(phase); + imag_ = mag * std::sin(phase); + } + double Magnitude() const { return std::sqrt(real_ * real_ + imag_ * imag_); } + double Phase() const { return std::atan2(imag_, real_); } + double PhaseDeg() const { return Phase() * 180.0 / std::numbers::pi; } + double Real() const { return real_; } + double Imag() const { return imag_; } + + double Abs() const { return Magnitude(); } + double Angle() const { return Phase(); } + double AngleDeg() const { return PhaseDeg(); } + + void SetPolar(double magnitude, double phase_rad) { + double mag = std::abs(magnitude); + double phase = phase_rad; + if (magnitude < 0) { + phase += std::numbers::pi; + } + phase = NormalizePhase(phase); + real_ = mag * std::cos(phase); + imag_ = mag * std::sin(phase); + } + + void SetCartesian(double real, double imag) { + real_ = real; + imag_ = imag; + } + + Phasor operator+() const { return *this; } + Phasor operator-() const { return Phasor(-real_, -imag_, AlgTag{}); } + + Phasor& operator+=(const Phasor& other) { + real_ += other.real_; + imag_ += other.imag_; + return *this; + } + + Phasor& operator-=(const Phasor& other) { + real_ -= other.real_; + imag_ -= other.imag_; + return *this; + } + + Phasor& operator*=(const Phasor& other) { + double mag = Magnitude() * other.Magnitude(); + double phase = Phase() + other.Phase(); + phase = NormalizePhase(phase); + real_ = mag * std::cos(phase); + imag_ = mag * std::sin(phase); + return *this; + } + + Phasor& operator/=(const Phasor& other) { + double mag = Magnitude() / other.Magnitude(); + double phase = Phase() - other.Phase(); + phase = NormalizePhase(phase); + real_ = mag * std::cos(phase); + imag_ = mag * std::sin(phase); + return *this; + } + + Phasor& operator+=(double scalar) { + real_ += scalar; + return *this; + } + + Phasor& operator-=(double scalar) { + real_ -= scalar; + return *this; + } + + Phasor& operator*=(double scalar) { + if (scalar < 0) { + double mag = Magnitude() * std::abs(scalar); + double phase = Phase() + std::numbers::pi; + phase = NormalizePhase(phase); + real_ = mag * std::cos(phase); + imag_ = mag * std::sin(phase); + } else { + real_ *= scalar; + imag_ *= scalar; + } + return *this; + } + + Phasor& operator/=(double scalar) { + + if (scalar < 0) { + double mag = Magnitude() / std::abs(scalar); + double phase = Phase() + std::numbers::pi; + phase = NormalizePhase(phase); + real_ = mag * std::cos(phase); + imag_ = mag * std::sin(phase); + } else { + real_ /= scalar; + imag_ /= scalar; + } + return *this; + } + + Phasor Conj() const { return Phasor(real_, -imag_, AlgTag{}); } + + Phasor Inv() const { + double mag = Magnitude(); + if (mag == 0.0) { + // , + return Phasor(); + } + double phase = -Phase(); + return Phasor(1.0 / mag, phase); + } + + bool operator==(const Phasor& other) const { + constexpr double EPS = 1e-10; + return std::abs(real_ - other.real_) < EPS && + std::abs(imag_ - other.imag_) < EPS; + } + + bool operator!=(const Phasor& other) const { + return !(*this == other); + } + +private: + static double NormalizePhase(double phase) { + // (-?, ?] + phase = std::fmod(phase, 2 * std::numbers::pi); + if (phase > std::numbers::pi) { + phase -= 2 * std::numbers::pi; + } else if (phase <= -std::numbers::pi) { + phase += 2 * std::numbers::pi; + } + return phase; + } +}; + +Phasor operator+(const Phasor& lhs, const Phasor& rhs) { + Phasor result = lhs; + result += rhs; + return result; +} + +Phasor operator-(const Phasor& lhs, const Phasor& rhs) { + Phasor result = lhs; + result -= rhs; + return result; +} + +Phasor operator*(const Phasor& lhs, const Phasor& rhs) { + Phasor result = lhs; + result *= rhs; + return result; +} + +Phasor operator/(const Phasor& lhs, const Phasor& rhs) { + Phasor result = lhs; + result /= rhs; + return result; +} + +Phasor operator+(const Phasor& phasor, double scalar) { + Phasor result = phasor; + result += scalar; + return result; +} + +Phasor operator+(double scalar, const Phasor& phasor) { + return phasor + scalar; +} + +Phasor operator-(const Phasor& phasor, double scalar) { + Phasor result = phasor; + result -= scalar; + return result; +} + +Phasor operator-(double scalar, const Phasor& phasor) { + return Phasor(scalar, 0.0, AlgTag{}) - phasor; +} + +Phasor operator*(const Phasor& phasor, double scalar) { + Phasor result = phasor; + result *= scalar; + return result; +} + +Phasor operator*(double scalar, const Phasor& phasor) { + return phasor * scalar; +} + +Phasor operator/(const Phasor& phasor, double scalar) { + Phasor result = phasor; + result /= scalar; + return result; +} + +Phasor operator/(double scalar, const Phasor& phasor) { + return Phasor(scalar, 0.0, AlgTag{}) / phasor; +} + +Phasor MakePhasorCartesian(double real, double imag) { + return Phasor(real, imag, AlgTag{}); +} + +Phasor MakePhasorPolar(double magnitude, double phase_rad) { + return Phasor(magnitude, phase_rad); +} + +Phasor MakePhasorPolarDeg(double magnitude, double phase_deg) { + return Phasor(magnitude, phase_deg, DegTag{}); +} + +std::ostream& operator<<(std::ostream& os, const Phasor& phasor) { + // 3 + os.precision(3); + os << std::fixed; + + double mag = phasor.Magnitude(); + double arg_deg = phasor.PhaseDeg(); + double real = phasor.Real(); + double imag = phasor.Imag(); + + os << mag << "*e(j*" << arg_deg << ") [" + << real << " + j*" << imag << "]"; + + return os; +} \ No newline at end of file diff --git a/04_week/tasks/queue/queue.cpp b/04_week/tasks/queue/queue.cpp index 2a9f8493..a3e5167f 100644 --- a/04_week/tasks/queue/queue.cpp +++ b/04_week/tasks/queue/queue.cpp @@ -1,6 +1,145 @@ -#include - - -class Queue { - -}; +#include +#include +#include +#include +#include + +class Queue { +private: + std::vector in_; + std::vector out_; + + void TransferIfNeeded() { + if (out_.empty()) { + while (!in_.empty()) { + out_.push_back(in_.back()); + in_.pop_back(); + } + } + } + +public: + Queue() = default; + + explicit Queue(size_t size) { + in_.reserve(size); + } + + explicit Queue(const std::vector& vec) : in_(vec) {} + + explicit Queue(std::stack s) { + while (!s.empty()) { + out_.push_back(s.top()); + s.pop(); + } + } + + Queue(std::initializer_list il) : in_(il) {} + + Queue(const Queue& other) = default; + + Queue& operator=(const Queue& other) = default; + + Queue(Queue&& other) noexcept = default; + + Queue& operator=(Queue&& other) noexcept = default; + + ~Queue() = default; + + void Push(int value) { + in_.push_back(value); + } + + bool Pop() { + if (Empty()) { + return false; + } + TransferIfNeeded(); + out_.pop_back(); + return true; + } + + int& Front() { + if (Empty()) { + static int dummy; + return dummy; + } + if (out_.empty()) { + return in_.front(); + } + return out_.back(); + } + + const int& Front() const { + if (Empty()) { + static const int dummy = 0; + return dummy; + } + if (out_.empty()) { + return in_.front(); + } + return out_.back(); + } + + int& Back() { + if (Empty()) { + static int dummy; + return dummy; + } + if (in_.empty()) { + return out_.front(); + } + return in_.back(); + } + + const int& Back() const { + if (Empty()) { + static const int dummy = 0; + return dummy; + } + if (in_.empty()) { + return out_.front(); + } + return in_.back(); + } + + bool Empty() const { + return in_.empty() && out_.empty(); + } + + size_t Size() const { + return in_.size() + out_.size(); + } + + void Clear() { + in_.clear(); + out_.clear(); + } + + void Swap(Queue& other) noexcept { + in_.swap(other.in_); + out_.swap(other.out_); + } + + bool operator==(const Queue& other) const { + if (Size() != other.Size()) { + return false; + } + + Queue q1 = *this; + Queue q2 = other; + + while (!q1.Empty() && !q2.Empty()) { + if (q1.Front() != q2.Front()) { + return false; + } + q1.Pop(); + q2.Pop(); + } + return true; + } + + bool operator!=(const Queue& other) const { + return !(*this == other); + } +}; \ 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..53446842 100644 --- a/04_week/tasks/ring_buffer/ring_buffer.cpp +++ b/04_week/tasks/ring_buffer/ring_buffer.cpp @@ -1,6 +1,159 @@ -#include - - -class RingBuffer { - -}; +#include +#include +#include +#include + +class RingBuffer { +private: + std::vector buffer_; + size_t head_ = 0; + size_t tail_ = 0; + size_t size_ = 0; + size_t capacity_ = 0; + + void advance(size_t& index) const { + index = (index + 1) % capacity_; + } + + void ensure_nonzero_capacity(size_t& capacity) { + if (capacity == 0) { + capacity = 1; + } + } + + size_t logical_to_physical(size_t logical_index) const { + return (head_ + logical_index) % capacity_; + } + +public: + explicit RingBuffer(size_t capacity) { + ensure_nonzero_capacity(capacity); + capacity_ = capacity; + buffer_.resize(capacity_); + } + + RingBuffer(size_t capacity, int initial_value) : RingBuffer(capacity) { + size_ = capacity_; + tail_ = 0; // , tail head + std::fill(buffer_.begin(), buffer_.end(), initial_value); + } + + RingBuffer(std::initializer_list init) { + capacity_ = init.size(); + ensure_nonzero_capacity(capacity_); + buffer_.resize(capacity_); + size_ = init.size(); + size_t i = 0; + for (int val : init) { + buffer_[i++] = val; + } + tail_ = size_ == capacity_ ? 0 : size_; + } + + int& operator[](size_t index) { + return buffer_[logical_to_physical(index)]; + } + + const int& operator[](size_t index) const { + return buffer_[logical_to_physical(index)]; + } + + int& Front() { + return size_ == 0 ? buffer_[0] : buffer_[(tail_ + capacity_ - 1) % capacity_]; + } + + const int& Front() const { + return size_ == 0 ? buffer_[0] : buffer_[(tail_ + capacity_ - 1) % capacity_]; + } + + int& Back() { + return size_ == 0 ? buffer_[0] : buffer_[head_]; + } + + const int& Back() const { + return size_ == 0 ? buffer_[0] : buffer_[head_]; + } + + bool Empty() const { return size_ == 0; } + bool Full() const { return size_ == capacity_; } + size_t Size() const { return size_; } + size_t Capacity() const { return capacity_; } + + void Push(int value) { + if (Full()) { + buffer_[tail_] = value; + advance(tail_); + head_ = tail_; + } else { + buffer_[tail_] = value; + advance(tail_); + ++size_; + } + } + + bool TryPush(int value) { + if (Full()) { + return false; + } + Push(value); + return true; + } + + void Pop() { + if (!Empty()) { + advance(head_); + --size_; + } + } + + bool TryPop(int& value) { + if (Empty()) { + return false; + } + value = Back(); + Pop(); + return true; + } + + void Clear() { + head_ = 0; + tail_ = 0; + size_ = 0; + } + + void Resize(size_t new_capacity) { + ensure_nonzero_capacity(new_capacity); + if (new_capacity == capacity_) { + return; + } + + std::vector new_buffer(new_capacity); + size_t elements_to_copy = std::min(size_, new_capacity); + size_t start_index = size_ > new_capacity ? size_ - new_capacity : 0; + + for (size_t i = 0; i < elements_to_copy; ++i) { + new_buffer[i] = (*this)[start_index + i]; + } + + buffer_ = std::move(new_buffer); + capacity_ = new_capacity; + head_ = 0; + size_ = elements_to_copy; + tail_ = size_ % capacity_; + } + + std::vector Vector() const { + std::vector result; + result.reserve(size_); + for (size_t i = 0; i < size_; ++i) { + result.push_back((*this)[i]); + } + return result; + } + + RingBuffer(const RingBuffer&) = default; + RingBuffer& operator=(const RingBuffer&) = default; + RingBuffer(RingBuffer&&) = default; + RingBuffer& operator=(RingBuffer&&) = default; + ~RingBuffer() = default; +}; \ No newline at end of file diff --git a/04_week/tasks/stack/stack.cpp b/04_week/tasks/stack/stack.cpp index 222e4ffc..6bbbabd0 100644 --- a/04_week/tasks/stack/stack.cpp +++ b/04_week/tasks/stack/stack.cpp @@ -1,6 +1,66 @@ -#include - - -class Stack { - -}; +#include + +class Stack { +public: + Stack() = default; + + void Push(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& other) const; + bool operator!=(const Stack& other) const; + +private: + std::vector data_;}; + +void Stack::Push(int value) { + data_.push_back(value); +} + +bool Stack::Pop() { + if (data_.empty()) { + return false; + } + data_.pop_back(); + return true; +} + +int& Stack::Top() { + static int dummy = 0; + return data_.empty() ? dummy : data_.back(); +} + +const int& Stack::Top() const { + static const int dummy = 0; + return data_.empty() ? dummy : 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& other) const { + return data_ == other.data_; +} + +bool Stack::operator!=(const Stack& other) const { + return !(*this == other); +} \ No newline at end of file