diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index da17fe10..65fb4b2e 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -29,11 +29,15 @@ jobs: tasks=("addition" "rms" "print_bits" "check_flags" "length_lit" "quadratic" "char_changer" "swap_ptr" "func_array" "longest" "last_of_us" "little_big" "pretty_array" +<<<<<<< HEAD + "data_stats" "unique" "range" "minmax" "find_all" "os_overload" "easy_compare" "filter" "enum_operators") +======= "data_stats" "unique" "range" "minmax" "find_all" "os_overload" "easy_compare" "filter" "enum_operators" "stack" "queue" "ring_buffer" "phasor" "tracer" "string_view" "cow_string" "simple_vector" "unique_ptr" "smart_ptr" "simple_list" ) +>>>>>>> upstream/main declare -i passed_count=0 declare -i failed_count=0 diff --git a/.github/workflows/testing_week_03.yml b/.github/workflows/testing_week_03.yml index 4c5b8fe8..b9ad0497 100644 --- a/.github/workflows/testing_week_03.yml +++ b/.github/workflows/testing_week_03.yml @@ -21,7 +21,7 @@ on: - enum_operators schedule: - - cron: '59 20 19 12 *' # UTC: 20:59 = 23:59 MSK 19 December + - cron: '59 20 18 12 *' # UTC: 20:59 = 23:59 MSK 18 December jobs: test: diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..567609b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/01_week/tasks/addition/addition.cpp b/01_week/tasks/addition/addition.cpp index 92872802..0e2cb82f 100644 --- a/01_week/tasks/addition/addition.cpp +++ b/01_week/tasks/addition/addition.cpp @@ -1,7 +1,7 @@ #include -#include int64_t Addition(int a, int b) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file + + return static_cast(a) + static_cast(b); +} diff --git a/01_week/tasks/char_changer/char_changer.cpp b/01_week/tasks/char_changer/char_changer.cpp index 3a7344d9..3a21d13e 100644 --- a/01_week/tasks/char_changer/char_changer.cpp +++ b/01_week/tasks/char_changer/char_changer.cpp @@ -1,7 +1,45 @@ #include -#include - +#include +#include size_t CharChanger(char array[], size_t size, char delimiter = ' ') { - throw std::runtime_error{"Not implemented"}; -} + size_t w = 0; + auto map_char = [&](char ch) -> char { + unsigned char uc = ch; //в этом месте возникала ошибка, решено использовать unsigner + if (std::isspace(uc)) return delimiter; + if (std::isdigit(uc)) return '*'; + if (std::isalpha(uc)) return (char)std::toupper(uc); + return '_'; }; + size_t r = 0; + while (r < size && array[r] != '\0') { + char current = array[r]; + char mapped = map_char(current); + size_t count = 1; + size_t next = r + 1; + while (next < size && array[next] != '\0') { + char next_char = array[next]; + char mapped_next = map_char(next_char); + if (mapped_next != mapped) break; + if (mapped == '*' || mapped == '_') { + if (current != next_char) break; + } else if (mapped >= 'A' && mapped <= 'Z') { + unsigned char curr_uc = current; + unsigned char next_uc = next_char; + if (std::islower(curr_uc) != std::islower(next_uc)) break; } + count++; + next++;} + unsigned char current_uc = current; + bool is_space_seq = (mapped == delimiter) && std::isspace(current_uc); + if (is_space_seq) { + bool is_letter_delimiter = (delimiter >= 'A' && delimiter <= 'Z'); + if (is_letter_delimiter || w == 0 || array[w - 1] != delimiter) { + array[w++] = delimiter;} + } else { + array[w++] = mapped; + if (count > 1) { + char repeat_char = (count < 10) ? ('0' + count) : '0'; + array[w++] = repeat_char;}} + r += count; } + array[w] = '\0'; + return w; +} \ No newline at end of file diff --git a/01_week/tasks/check_flags/check_flags.cpp b/01_week/tasks/check_flags/check_flags.cpp index 75e7c652..008ab672 100644 --- a/01_week/tasks/check_flags/check_flags.cpp +++ b/01_week/tasks/check_flags/check_flags.cpp @@ -1,5 +1,5 @@ #include -#include +#include enum class CheckFlags : uint8_t { @@ -14,5 +14,26 @@ enum class CheckFlags : uint8_t { }; void PrintCheckFlags(CheckFlags flags) { - throw std::runtime_error{"Not implemented"}; + uint8_t value = static_cast(flags); + uint8_t all = static_cast(CheckFlags::ALL); + if ((value & ~all) != 0) { + return; } + if (value == 0) { + std::cout << "[]"; + return;} + std::cout << "["; + bool first = true; + auto print_flag = [&](CheckFlags f, const char* name) { + if (value & static_cast(f)) { + if (!first) std::cout << ","; + std::cout << name; + first = false;} + }; + print_flag(CheckFlags::TIME, "TIME"); + print_flag(CheckFlags::DATE, "DATE"); + print_flag(CheckFlags::USER, "USER"); + print_flag(CheckFlags::CERT, "CERT"); + print_flag(CheckFlags::KEYS, "KEYS"); + print_flag(CheckFlags::DEST, "DEST"); + std::cout << "]"; } diff --git a/01_week/tasks/length_lit/length_lit.cpp b/01_week/tasks/length_lit/length_lit.cpp index e69de29b..6048477b 100644 --- a/01_week/tasks/length_lit/length_lit.cpp +++ b/01_week/tasks/length_lit/length_lit.cpp @@ -0,0 +1,50 @@ +#include + + +constexpr long double operator"" _ft_to_m(long double v) { + return static_cast(v * 0.3048L); +} + +constexpr long double operator"" _ft_to_in(long double v) { + return static_cast(v * 12.0L); +} + +constexpr long double operator"" _ft_to_cm(long double v) { + return static_cast(v * 30.48L); +} + +constexpr long double operator"" _in_to_ft(long double v) { + return static_cast(v / 12.0L); +} + +constexpr long double operator"" _in_to_m(long double v) { + return static_cast(v * 0.0254L); +} + +constexpr long double operator"" _in_to_cm(long double v) { + return static_cast(v * 2.54L); +} + +constexpr long double operator"" _cm_to_in(long double v) { + return static_cast(v / 2.54L); +} + +constexpr long double operator"" _cm_to_ft(long double v) { + return static_cast(v / 30.48L); +} + +constexpr long double operator"" _cm_to_m(long double v) { + return static_cast(v / 100.0L); +} + +constexpr long double operator"" _m_to_cm(long double v) { + return static_cast(v * 100.0L); +} + +constexpr long double operator"" _m_to_in(long double v) { + return static_cast(v / 0.0254L); +} + +constexpr long double operator"" _m_to_ft(long double v) { + return static_cast(v / 0.3048L); +} diff --git a/01_week/tasks/print_bits/print_bits.cpp b/01_week/tasks/print_bits/print_bits.cpp index a48a43c1..49e619dc 100644 --- a/01_week/tasks/print_bits/print_bits.cpp +++ b/01_week/tasks/print_bits/print_bits.cpp @@ -1,7 +1,17 @@ #include -#include +#include void PrintBits(long long value, size_t bytes) { - throw std::runtime_error{"Not implemented"}; -} + if (bytes == 0 || bytes > 8) + return; + std::cout << "0b"; + size_t total_bits = bytes * 8; + for (size_t i = 0; i < total_bits; ++i) { + size_t bit_index = total_bits - 1 - i; + bool bit = (value >> bit_index) & 1; + std::cout << (bit ? '1' : '0'); + if (i % 4 == 3 && i + 1 < total_bits) + 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..e3af78bc 100644 --- a/01_week/tasks/quadratic/quadratic.cpp +++ b/01_week/tasks/quadratic/quadratic.cpp @@ -1,6 +1,39 @@ -#include +#include +#include void SolveQuadratic(int a, int b, int c) { - throw std::runtime_error{"Not implemented"}; + auto print = [](double x) { + if (std::abs(x) < 1e-9) x = 0; + if (std::abs(x - std::round(x)) < 1e-9) { + std::cout << static_cast(std::round(x)); + } else { + x = std::round(x * 1e6) / 1e6; //округление (тест) + std::cout << x;} + }; + if (a == 0) { + if (b == 0) { + if (c == 0) std::cout << "infinite solutions"; + else std::cout << "no solutions"; + } else { + double x = -static_cast(c) / b; + print(x);} + return;} + double D = static_cast(b) * b - 4.0 * a * c; + if (D < 0) { + std::cout << "no solutions"; + } else if (D == 0) { + double x = -static_cast(b) / (2.0 * a); + print(x); + } else { + double sqrtD = std::sqrt(D); + double x1 = (-b - sqrtD) / (2.0 * a); + double x2 = (-b + sqrtD) / (2.0 * a); + if (x1 > x2) { + double temp = x1; + x1 = x2; + x2 = temp;} + print(x1); + std::cout << " "; + print(x2);} } \ No newline at end of file diff --git a/01_week/tasks/rms/rms.cpp b/01_week/tasks/rms/rms.cpp index 6882f0a9..1f8a5005 100644 --- a/01_week/tasks/rms/rms.cpp +++ b/01_week/tasks/rms/rms.cpp @@ -1,7 +1,13 @@ -#include +#include +#include #include double CalculateRMS(double values[], size_t size) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file + if (size == 0) return 0.0; + if (values == nullptr) return 0.0; + double sum_squares = 0.0; + for (size_t i = 0; i < size; ++i) { + sum_squares += values[i] * values[i];} + return std::sqrt(sum_squares / static_cast(size)); +} diff --git a/02_week/tasks/func_array/func_array.cpp b/02_week/tasks/func_array/func_array.cpp index b327e68d..19f83a79 100644 --- a/02_week/tasks/func_array/func_array.cpp +++ b/02_week/tasks/func_array/func_array.cpp @@ -1,6 +1,12 @@ -#include +#include - -double ApplyOperations(double a, double b /* other arguments */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +double ApplyOperations(double a, double b, double (*operations[])(double, double), size_t size) { + if (size == 0 || operations == nullptr) { + return 0.0;} + double sum = 0.0; + for (size_t i = 0; i < size; ++i) { + if (operations[i] != nullptr) { + sum += operations[i](a, b); + } } + return sum; +} 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..878edc6b 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,12 @@ #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 || !end || begin > end) { + return end;} + const int* result = end; + for (const int* ptr = begin; ptr < end; ++ptr) { + if (predicate(*ptr)) { + result = ptr;} + } + return result; +} diff --git a/02_week/tasks/little_big/little_big.cpp b/02_week/tasks/little_big/little_big.cpp index abe24379..f0eab9ad 100644 --- a/02_week/tasks/little_big/little_big.cpp +++ b/02_week/tasks/little_big/little_big.cpp @@ -1,10 +1,34 @@ +#include +#include #include +void PrintMemory(int value, bool reverse = false) {// Для int + unsigned char* bytes = reinterpret_cast(&value); + std::cout << "0x" << std::uppercase; + if (reverse) { + for (size_t i = sizeof(int); i > 0; --i) { + std::cout << std::hex << std::setw(2) << std::setfill('0') + << static_cast(bytes[i - 1]); } + } else { + for (size_t i = 0; i < sizeof(int); ++i) { + std::cout << std::hex << std::setw(2) << std::setfill('0') + << static_cast(bytes[i]); } + } + std::cout << std::dec << std::endl; +} -void PrintMemory(int /* write arguments here */) { - throw std::runtime_error{"Not implemented"}; +void PrintMemory(double value, bool reverse = false) {// Для double + unsigned char* bytes = reinterpret_cast(&value); + std::cout << "0x" << std::uppercase; + if (reverse) { + for (size_t i = sizeof(double); i > 0; --i) { + std::cout << std::hex << std::setw(2) << std::setfill('0') + << static_cast(bytes[i - 1]); } + } else { + for (size_t i = 0; i < sizeof(double); ++i) { + std::cout << std::hex << std::setw(2) << std::setfill('0') + << static_cast(bytes[i]); } + } + std::cout << std::dec << std::endl; } -void PrintMemory(double /* write arguments here */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file diff --git a/02_week/tasks/longest/longest.cpp b/02_week/tasks/longest/longest.cpp index 04b3c354..124b5cda 100644 --- a/02_week/tasks/longest/longest.cpp +++ b/02_week/tasks/longest/longest.cpp @@ -1,6 +1,32 @@ +#include #include +char* FindLongestSubsequence(char* begin, char* end, size_t& count) { + if (!begin || !end || begin >= end) { + count = 0; + return nullptr; } + char* max_start = begin; + size_t max_len = 1; + char* current_start = begin; + size_t current_len = 1; + for (char* ptr = begin + 1; ptr < end; ++ptr) { + if (*ptr == *(ptr - 1)) { + ++current_len;} + else { + if (current_len > max_len) { + max_len = current_len; + max_start = current_start; + } + current_start = ptr; + current_len = 1;} + } + if (current_len > max_len) { + max_len = current_len; + max_start = current_start;} + count = max_len; + return max_start; +} -/* return_type */ FindLongestSubsequence(/* ptr_type */ begin, /* ptr_type */ end, /* type */ count) { - throw std::runtime_error{"Not implemented"}; +const char* FindLongestSubsequence(const char* begin, const char* end, size_t& count) { //из за ошибки про то, что ожидается изменяемый массив + return FindLongestSubsequence(const_cast(begin), const_cast(end), count); } diff --git a/02_week/tasks/pretty_array/pretty_array.cpp b/02_week/tasks/pretty_array/pretty_array.cpp index 48eab341..5ef7596b 100644 --- a/02_week/tasks/pretty_array/pretty_array.cpp +++ b/02_week/tasks/pretty_array/pretty_array.cpp @@ -1,6 +1,35 @@ -#include +#include +#include - -void PrintArray(/* write arguments here */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +void PrintArray(const int* begin, const int* end, size_t line_limit = 0) { + std::cout << "["; + if (!begin || !end || begin == end) { + std::cout << "]\n"; + return; } + size_t count = 0; + bool first = true; + if (begin < end) { + for (const int* it = begin; it != end; ++it) { + if (!first) std::cout << ", "; + std::cout << *it; + ++count; + first = false; + bool is_last = (it + 1 == end); + if (line_limit > 0 && count == line_limit && !is_last) { + std::cout << ", ...\n "; + count = 0; + first = true; } + }} else { + for (const int* it = begin; it != end; --it) { + if (!first) std::cout << ", "; + std::cout << *it; + ++count; + first = false; + bool is_last = (it - 1 == end - 1); + if (line_limit > 0 && count == line_limit && !is_last) { + std::cout << ", ...\n "; + count = 0; + first = true;}} + } + 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..538688f8 100644 --- a/02_week/tasks/swap_ptr/swap_ptr.cpp +++ b/02_week/tasks/swap_ptr/swap_ptr.cpp @@ -1,6 +1,14 @@ #include - -void SwapPtr(/* write arguments here */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +void SwapPtr(int*& a, int*& b) { + int* temp = a; + a = b; + b = temp;} +void SwapPtr(const int*& a, const int*& b) {//const int* + const int* temp = a; + a = b; + b = temp;} +void SwapPtr(int**& a, int**& b) { //int + 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..e1b531f5 100644 --- a/03_week/tasks/data_stats/data_stats.cpp +++ b/03_week/tasks/data_stats/data_stats.cpp @@ -1,11 +1,21 @@ -#include - +#include +#include struct DataStats { - double avg = 0.0; - double sd = 0.0; -}; + double avg; + double sd;}; -/* return_type */ CalculateDataStats(/* args */) { - throw std::runtime_error{"Not implemented"}; +DataStats CalculateDataStats(const std::vector& data) { + if (data.empty()) { + return {0.0, 0.0};} + double sum = 0.0; + for (int x : data) { + sum += x;} + double mean = sum / data.size(); + double variance_sum = 0.0; + for (int x : data) { + variance_sum += (x - mean) * (x - mean);} + double variance = variance_sum / data.size(); + double stddev = std::sqrt(variance); + return {mean, stddev}; } diff --git a/03_week/tasks/easy_compare/easy_compare.cpp b/03_week/tasks/easy_compare/easy_compare.cpp index dd5cb7f6..92f3a688 100644 --- a/03_week/tasks/easy_compare/easy_compare.cpp +++ b/03_week/tasks/easy_compare/easy_compare.cpp @@ -1,16 +1,46 @@ +#include #include - struct Date { - unsigned year; - unsigned month; - unsigned day; -}; - + unsigned year = 0; + unsigned month = 0; + unsigned day = 0; + Date() = default; + Date(unsigned y, unsigned m, unsigned d) + : year(y), month(m), day(d) {}}; +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);} struct StudentInfo { size_t id; char mark; int score; unsigned course; - Date birth_date; -}; \ No newline at end of file + Date birth_date;}; +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) { + 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; +} diff --git a/03_week/tasks/enum_operators/enum_operators.cpp b/03_week/tasks/enum_operators/enum_operators.cpp index a539be38..bae3d284 100644 --- a/03_week/tasks/enum_operators/enum_operators.cpp +++ b/03_week/tasks/enum_operators/enum_operators.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include enum class CheckFlags : uint8_t { @@ -9,25 +10,57 @@ enum class CheckFlags : uint8_t { CERT = (1 << 3), KEYS = (1 << 4), DEST = (1 << 5), - ALL = TIME | DATE | USER | CERT | KEYS | DEST -}; + ALL = TIME | DATE | USER | CERT | KEYS | DEST}; +CheckFlags operator|(CheckFlags lhs, CheckFlags rhs) { + uint8_t result = + static_cast(lhs) | + static_cast(rhs); + result &= static_cast(CheckFlags::ALL); + return static_cast(result);} +bool operator&(CheckFlags lhs, CheckFlags rhs) { + uint8_t l = static_cast(lhs) & + static_cast(CheckFlags::ALL); + uint8_t r = static_cast(rhs) & + static_cast(CheckFlags::ALL); + if (l == 0 || r == 0) { + return false; } + uint8_t inter = l & r; + return inter == l || inter == r;} +CheckFlags operator^(CheckFlags lhs, CheckFlags rhs) { + uint8_t result = + static_cast(lhs) ^ + static_cast(rhs); -/* 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"}; + result &= static_cast(CheckFlags::ALL); + return static_cast(result);} +CheckFlags operator~(CheckFlags f) { + uint8_t result = ~static_cast(f); + result &= static_cast(CheckFlags::ALL); + return static_cast(result);} +std::ostream& operator<<(std::ostream& os, CheckFlags f) { + uint8_t mask = static_cast(f) & + static_cast(CheckFlags::ALL); + if (mask == 0) { + os << "NONE"; + return os;} + struct FlagName { + CheckFlags flag; + const char* name;}; + static const std::vector flags = { + {CheckFlags::TIME, "TIME"}, + {CheckFlags::DATE, "DATE"}, + {CheckFlags::USER, "USER"}, + {CheckFlags::CERT, "CERT"}, + {CheckFlags::KEYS, "KEYS"}, + {CheckFlags::DEST, "DEST"}}; + bool first = true; + for (const auto& fn : flags) { + if (mask & static_cast(fn.flag)) { + if (!first) { + os << ", "; + } + os << fn.name; + first = false;} + } + return os; } diff --git a/03_week/tasks/filter/filter.cpp b/03_week/tasks/filter/filter.cpp index 6648cb39..1479afb8 100644 --- a/03_week/tasks/filter/filter.cpp +++ b/03_week/tasks/filter/filter.cpp @@ -1,6 +1,13 @@ -#include +#include - -/* return_type */ Filter(/* args */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +void Filter(std::vector& v, bool (*pred)(int)) { + if (pred == nullptr) { + return;} + size_t write = 0; + for (size_t read = 0; read < v.size(); ++read) { + if (pred(v[read])) { + v[write] = v[read]; + ++write;} + } + v.resize(write); +} diff --git a/03_week/tasks/find_all/find_all.cpp b/03_week/tasks/find_all/find_all.cpp index 74f393b2..b4f8a429 100644 --- a/03_week/tasks/find_all/find_all.cpp +++ b/03_week/tasks/find_all/find_all.cpp @@ -1,6 +1,15 @@ +#include #include - -/* return_type */ FindAll(/* args */) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +std::vector FindAll(const std::vector& v, bool (*pred)(int)) { + std::vector result; + if (!pred) { + return result;} + result.reserve(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + if (pred(v[i])) { + result.push_back(i);} + } + result.shrink_to_fit(); + return result; +} diff --git a/03_week/tasks/minmax/minmax.cpp b/03_week/tasks/minmax/minmax.cpp index c2869799..9f95b2fa 100644 --- a/03_week/tasks/minmax/minmax.cpp +++ b/03_week/tasks/minmax/minmax.cpp @@ -1,6 +1,17 @@ +#include +#include #include - -/* return_type */ MinMax(/* args */) { - throw std::runtime_error{"Not implemented"}; +auto MinMax(const std::vector& v) { + if (v.empty()) { + return std::make_pair(v.end(), v.end());} + auto min_it = v.begin(); + auto max_it = v.begin(); + for (auto it = v.begin(); it != v.end(); ++it) { + if (*it < *min_it) { + min_it = it;} + if (*it >= *max_it) { + max_it = it;} + } + return std::make_pair(min_it, max_it); } diff --git a/03_week/tasks/os_overload/os_overload.cpp b/03_week/tasks/os_overload/os_overload.cpp index e473418d..cbdb423f 100644 --- a/03_week/tasks/os_overload/os_overload.cpp +++ b/03_week/tasks/os_overload/os_overload.cpp @@ -1,21 +1,44 @@ -#include +#include #include -#include - struct Coord2D { - int x; - int y; -}; - + int x = 0; + int y = 0; + Coord2D() = default; + Coord2D(int x_, int y_) : x(x_), y(y_) {}}; +std::ostream& operator<<(std::ostream& os, const Coord2D& coord) { + os << "(" << coord.x << ", " << coord.y << ")"; + return os;} struct Circle { Coord2D coord; - unsigned radius; -}; - -using CircleRegion = std::pair; + unsigned int radius = 1; + Circle() = default; + Circle(const Coord2D& c, unsigned int r = 1) : coord(c), radius(r) {} + bool isEmpty() const { return radius == 0; }}; +std::ostream& operator<<(std::ostream& os, const Circle& c) { + if (c.isEmpty()) { + os << "circle[]";} + else { + os << "circle[" << c.coord << ", r = " << c.radius << "]";} + return os;} +struct CircleRegion { + Circle circle; + bool flag = true; // true = '+', false = '-' + CircleRegion(const Circle& c, bool f) : circle(c), flag(f) {} + CircleRegion(const std::pair& p) : circle(p.first), flag(p.second) {}}; +std::ostream& operator<<(std::ostream& os, const CircleRegion& region) { + os << (region.flag ? "+" : "-") << region.circle; + return os;} using CircleRegionList = std::vector; - -/* return_type */ operator<<(/* args */) { - throw std::runtime_error{"Not implemented"}; +std::ostream& operator<<(std::ostream& os, const CircleRegionList& list) { + if (list.empty()) { + os << "{}"; + return os;} + os << "{\n"; + for (size_t i = 0; i < list.size(); ++i) { + os << "\t" << list[i]; + if (i + 1 != list.size()) os << ","; + os << "\n";} + os << "}"; + return os; } diff --git a/03_week/tasks/range/range.cpp b/03_week/tasks/range/range.cpp index d2085495..8abec444 100644 --- a/03_week/tasks/range/range.cpp +++ b/03_week/tasks/range/range.cpp @@ -1,7 +1,27 @@ -#include #include -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 result; + if (step == 0) { + return result;} + if ((from < to && step < 0) || (from > to && step > 0)) { + return result;} + int count = 0; + if (step > 0) { + for (int i = from; i < to; i += step) { + ++count;} + } else { + for (int i = from; i > to; i += step) { + ++count;} + } + result.reserve(count); + if (step > 0) { + for (int i = from; i < to; i += step) { + result.push_back(i);} + } else { + for (int i = from; i > to; i += step) { + result.push_back(i);} + } + return result; } diff --git a/03_week/tasks/unique/unique.cpp b/03_week/tasks/unique/unique.cpp index 9d2545bb..7bed6f7f 100644 --- a/03_week/tasks/unique/unique.cpp +++ b/03_week/tasks/unique/unique.cpp @@ -1,6 +1,15 @@ -#include #include -/* return_type */ Unique(/* args */) { - throw std::runtime_error{"Not implemented"}; +std::vector Unique(const std::vector& values) { + std::vector result; + if (values.empty()) { + return result;} + result.reserve(values.size()); + result.push_back(values[0]); + for (size_t i = 1; i < values.size(); ++i) { + if (values[i] != values[i - 1]) { + result.push_back(values[i]); } + } + result.shrink_to_fit(); + return result; } diff --git a/04_week/CMakeLists.txt b/04_week/CMakeLists.txt index b15ca37c..d56cf274 100644 --- a/04_week/CMakeLists.txt +++ b/04_week/CMakeLists.txt @@ -11,5 +11,5 @@ add_subdirectory(tasks) # Создать исполняемый файл для каждого примера if (BUILD_EXAMPLES_04_WEEK) -# add_example(class_examples ${EXAMPLES_DIR}/class_examples.cpp) -endif() \ No newline at end of file +# add_example(struct_examples ${EXAMPLES_DIR}/struct_examples.cpp) +endif() diff --git a/04_week/tasks/phasor/phasor.cpp b/04_week/tasks/phasor/phasor.cpp index 3ec1b9ad..1c6da90d 100644 --- a/04_week/tasks/phasor/phasor.cpp +++ b/04_week/tasks/phasor/phasor.cpp @@ -1,10 +1,84 @@ - +#include +#include +#include struct ExpTag {}; struct DegTag {}; struct AlgTag {}; - class Phasor { - +private: + double re_; + double im_; +public: + Phasor() : re_(0.0), im_(0.0) {} + Phasor(double mag, double phase_rad) { SetPolar(mag, phase_rad); } + Phasor(double mag, double phase_rad, ExpTag) : Phasor(mag, phase_rad) {} + Phasor(double mag, double phase_deg, DegTag) { + double rad = phase_deg * M_PI / 180.0; + SetPolar(mag, rad);} + Phasor(double real, double imag, AlgTag) : re_(real), im_(imag) {} + void SetPolar(double mag, double phase_rad) { + re_ = mag * std::cos(phase_rad); + im_ = mag * std::sin(phase_rad);} + void SetCartesian(double real, double imag) { re_ = real; im_ = imag; } + double Magnitude() const { return std::hypot(re_, im_); } + double Phase() const { + double angle = std::atan2(im_, re_); + return angle; } + double PhaseDeg() const { + double deg = Phase() * 180.0 / M_PI; + if (deg <= -180.0) deg += 360.0; + else if (deg > 180.0) deg -= 360.0; + return deg;} + double Real() const { return re_; } + double Imag() const { return im_; } + double Abs() const { return Magnitude(); } + double Angle() const { return Phase(); } + double AngleDeg() const { return PhaseDeg(); } + Phasor Conj() const { return Phasor(re_, -im_, AlgTag()); } + Phasor Inv() const { + double mag2 = re_*re_ + im_*im_; + return Phasor(re_/mag2, -im_/mag2, AlgTag());} + Phasor& operator+=(const Phasor& rhs) { re_+=rhs.re_; im_+=rhs.im_; return *this; } + Phasor& operator-=(const Phasor& rhs) { re_-=rhs.re_; im_-=rhs.im_; return *this; } + Phasor& operator*=(const Phasor& rhs) { + double old_re = re_; + re_ = old_re*rhs.re_ - im_*rhs.im_; + im_ = old_re*rhs.im_ + im_*rhs.re_; + return *this;} + Phasor& operator/=(const Phasor& rhs) { + double denom = rhs.re_*rhs.re_ + rhs.im_*rhs.im_; + double old_re = re_; + re_ = (old_re*rhs.re_ + im_*rhs.im_) / denom; + im_ = (im_*rhs.re_ - old_re*rhs.im_) / denom; + return *this;} + Phasor& operator+=(double rhs) { re_+=rhs; return *this; } + Phasor& operator-=(double rhs) { re_-=rhs; return *this; } + Phasor& operator*=(double rhs) { re_*=rhs; im_*=rhs; return *this; } + Phasor& operator/=(double rhs) { re_/=rhs; im_/=rhs; return *this; } + Phasor operator-() const { return Phasor(-re_, -im_, AlgTag()); } }; +inline Phasor operator+(Phasor lhs, const Phasor& rhs){ return lhs+=rhs; } +inline Phasor operator-(Phasor lhs, const Phasor& rhs){ return lhs-=rhs; } +inline Phasor operator*(Phasor lhs, const Phasor& rhs){ return lhs*=rhs; } +inline Phasor operator/(Phasor lhs, const Phasor& rhs){ return lhs/=rhs; } +inline Phasor operator+(Phasor lhs, double rhs){ return lhs+=rhs; } +inline Phasor operator+(double lhs, const Phasor& rhs){ return Phasor(lhs,0,AlgTag())+rhs; } +inline Phasor operator-(Phasor lhs, double rhs){ return lhs-=rhs; } +inline Phasor operator-(double lhs, const Phasor& rhs){ return Phasor(lhs,0,AlgTag())-rhs; } +inline Phasor operator*(Phasor lhs, double rhs){ return lhs*=rhs; } +inline Phasor operator*(double lhs, const Phasor& rhs){ return Phasor(lhs,0,AlgTag())*rhs; } +inline Phasor operator/(Phasor lhs, double rhs){ return lhs/=rhs; } +inline Phasor operator/(double lhs, const Phasor& rhs){ return Phasor(lhs,0,AlgTag())/rhs; } +inline bool operator==(const Phasor& lhs,const Phasor& rhs){ return lhs.Real()==rhs.Real() && lhs.Imag()==rhs.Imag(); } +inline bool operator!=(const Phasor& lhs,const Phasor& rhs){ return !(lhs==rhs); } +inline Phasor MakePhasorCartesian(double r,double i){ return Phasor(r,i,AlgTag()); } +inline Phasor MakePhasorPolar(double m,double p){ return Phasor(m,p,ExpTag()); } +inline Phasor MakePhasorPolarDeg(double m,double d){ return Phasor(m,d,DegTag()); } +inline std::ostream& operator<<(std::ostream& os,const Phasor& p){ + os << std::fixed << std::setprecision(3) + << p.Magnitude() << "*e(j*" << p.PhaseDeg() << ") [" + << p.Real() << " + j*" << p.Imag() << "]"; + return os; +} diff --git a/04_week/tasks/queue/queue.cpp b/04_week/tasks/queue/queue.cpp index 2a9f8493..f02f1994 100644 --- a/04_week/tasks/queue/queue.cpp +++ b/04_week/tasks/queue/queue.cpp @@ -1,6 +1,68 @@ #include - +#include +#include +#include class Queue { - -}; +private: + std::vector inStack_; + std::vector outStack_; + void Transfer() { + if (outStack_.empty()) { + while (!inStack_.empty()) { + outStack_.push_back(inStack_.back()); + inStack_.pop_back();} + } + } +public: + Queue() = default; + Queue(const std::stack& s) { + std::stack temp = s; + while (!temp.empty()) { + inStack_.push_back(temp.top()); + temp.pop();} + std::reverse(inStack_.begin(), inStack_.end());} + Queue(const std::vector& v) : inStack_(v) {} + Queue(std::initializer_list il) : inStack_(il) {} + explicit Queue(size_t capacity) { + inStack_.reserve(capacity); + outStack_.reserve(capacity);} + void Push(int value) { + inStack_.push_back(value);} + bool Pop() { + Transfer(); + if (outStack_.empty()) return false; + outStack_.pop_back(); + return true;} + int& Front() { + Transfer(); + return outStack_.back();} + const int& Front() const { + return const_cast(this)->Front();} + int& Back() { + if (!inStack_.empty()) return inStack_.back(); + Transfer(); + return outStack_.front(); } + const int& Back() const { + return const_cast(this)->Back();} + bool Empty() const { + return inStack_.empty() && outStack_.empty();} + size_t Size() const { + return inStack_.size() + outStack_.size();} + void Clear() { + inStack_.clear(); + outStack_.clear();} + void Swap(Queue& other) { + std::swap(inStack_, other.inStack_); + std::swap(outStack_, other.outStack_);} + bool operator==(const Queue& other) const { + Queue copy1 = *this; + Queue copy2 = other; + while (!copy1.Empty() && !copy2.Empty()) { + if (copy1.Front() != copy2.Front()) return false; + copy1.Pop(); + copy2.Pop();} + return copy1.Empty() && copy2.Empty();} + 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..af9d1828 100644 --- a/04_week/tasks/ring_buffer/ring_buffer.cpp +++ b/04_week/tasks/ring_buffer/ring_buffer.cpp @@ -1,6 +1,92 @@ #include - +#include +#include class RingBuffer { - +private: + std::vector buffer; + size_t start = 0; + size_t end = 0; + size_t count = 0; +public: + RingBuffer(size_t capacity) + : buffer(capacity == 0 ? 1 : capacity), start(0), end(0), count(0) {} + RingBuffer(size_t capacity, int value) + : buffer(capacity == 0 ? 1 : capacity, value), start(0), end(0), count(buffer.size()) {} + RingBuffer(std::initializer_list list) + : buffer(list.size() == 0 ? 1 : list.size()), start(0), end(list.size() % (list.size() == 0 ? 1 : list.size())), count(list.size()) + { + if (!list.size()) { + end = 0; + count = 0; + } else { + size_t i = 0; + for (int v : list) { + buffer[i++] = v;} + } + } + void Push(int value) { + buffer[end] = value; + end = (end + 1) % buffer.size(); + if (count < buffer.size()) { + ++count; + } else { + start = (start + 1) % buffer.size();} + } + bool TryPush(int value) { + if (Full()) return false; + buffer[end] = value; + end = (end + 1) % buffer.size(); + ++count; + return true;} + void Pop() { + if (Empty()) return; + start = (start + 1) % buffer.size(); + --count;} + bool TryPop(int &value) { + if (Empty()) return false; + value = buffer[start]; + start = (start + 1) % buffer.size(); + --count; + return true;} + int& operator[](size_t index) { + return buffer[(start + index) % buffer.size()];} + const int& operator[](size_t index) const { + return buffer[(start + index) % buffer.size()];} + int& Front() { return buffer[(end + buffer.size() - 1) % buffer.size()]; } + const int& Front() const { return buffer[(end + buffer.size() - 1) % buffer.size()]; } + int& Back() { return buffer[start]; } + const int& Back() const { return buffer[start]; } + bool Empty() const { return count == 0; } + bool Full() const { return count == buffer.size(); } + size_t Size() const { return count; } + size_t Capacity() const { return buffer.size(); } + void Clear() { + start = 0; + end = 0; + count = 0;} + void Resize(size_t new_capacity) { + if (new_capacity == 0) new_capacity = 1; + std::vector new_buffer(new_capacity); + size_t new_count = std::min(count, new_capacity); + for (size_t i = 0; i < new_count; ++i) { + new_buffer[i] = (*this)[count - new_count + i];} + buffer = std::move(new_buffer); + start = 0; + count = new_count; + end = new_count % buffer.size();} + std::vector Vector() const { + std::vector result(count); + for (size_t i = 0; i < count; ++i) { + result[i] = (*this)[i];} + return result;} + RingBuffer(const RingBuffer& other) + : buffer(other.buffer), start(other.start), end(other.end), count(other.count) {} + RingBuffer& operator=(const RingBuffer& other) { + if (this != &other) { + buffer = other.buffer; + start = other.start; + end = other.end; + count = other.count;} + return *this;} }; diff --git a/04_week/tasks/stack/stack.cpp b/04_week/tasks/stack/stack.cpp index 222e4ffc..99928186 100644 --- a/04_week/tasks/stack/stack.cpp +++ b/04_week/tasks/stack/stack.cpp @@ -1,6 +1,30 @@ #include - +#include class Stack { - +private: + std::vector data; +public: + void Push(int value) { + data.push_back(value);} + bool Pop() { + if (data.empty()) return false; + data.pop_back(); + return true;} + int& Top() { + return data.back();} + const int& Top() const { + return data.back();} + bool Empty() const { + return data.empty();} + size_t Size() const { + return data.size();} + void Clear() { + data.clear();} + void Swap(Stack& other) { + data.swap(other.data);} + bool operator==(const Stack& other) const { + return data == other.data;} + bool operator!=(const Stack& other) const { + return data != other.data;} }; diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 34d59738..e98789ca 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -1,6 +1,232 @@ #include #include -class CowString { +class CowString +{ +private: + struct Buffer + { + char *data; + size_t size; + size_t ref_count; + Buffer(const char *str, size_t len) + : size(len), ref_count(1) + { + data = new char[len + 1]; + if (len > 0) + { + std::memcpy(data, str, len); + } + data[len] = '\0'; + } + + ~Buffer() + { + delete[] data; + } + }; + + Buffer *buffer_; + + static Buffer *CreateEmptyBuffer() + { + return new Buffer("", 0); + } + + void Release() + { + if (buffer_) + { + if (--buffer_->ref_count == 0) + { + delete buffer_; + } + } + } + + void EnsureUnique() + { + if (buffer_->ref_count > 1) + { + Buffer *new_buf = new Buffer(buffer_->data, buffer_->size); + --buffer_->ref_count; + buffer_ = new_buf; + } + } + +public: + static const size_t npos; + + CowString() + : buffer_(CreateEmptyBuffer()) {} + + CowString(const char *str) + : buffer_(new Buffer(str, std::strlen(str))) {} + + CowString(const std::string &str) + : buffer_(new Buffer(str.c_str(), str.size())) {} + + CowString(const CowString &other) + : buffer_(other.buffer_) + { + ++buffer_->ref_count; + } + + CowString &operator=(const CowString &other) + { + if (this != &other) + { + Release(); + buffer_ = other.buffer_; + ++buffer_->ref_count; + } + return *this; + } + + CowString(CowString &&other) noexcept + : buffer_(other.buffer_) + { + other.buffer_ = CreateEmptyBuffer(); + } + + CowString &operator=(CowString &&other) noexcept + { + if (this != &other) + { + Release(); + buffer_ = other.buffer_; + other.buffer_ = CreateEmptyBuffer(); + } + return *this; + } + + ~CowString() + { + Release(); + } + + size_t Size() const + { + return buffer_->size; + } + + bool Empty() const + { + return buffer_->size == 0; + } + + const char *ToCstr() const + { + return buffer_->data; + } + + std::string ToString() const + { + return std::string(buffer_->data, buffer_->size); + } + + const char &operator[](size_t index) const + { + return buffer_->data[index]; + } + + operator const char *() const + { + return buffer_->data; + } + + char &operator[](size_t index) + { + EnsureUnique(); + return buffer_->data[index]; + } + + CowString &Append(const char *str) + { + size_t add_len = std::strlen(str); + if (add_len == 0) + { + return *this; + } + + EnsureUnique(); + + size_t new_size = buffer_->size + add_len; + char *new_data = new char[new_size + 1]; + + std::memcpy(new_data, buffer_->data, buffer_->size); + std::memcpy(new_data + buffer_->size, str, add_len); + new_data[new_size] = '\0'; + + delete[] buffer_->data; + buffer_->data = new_data; + buffer_->size = new_size; + + return *this; + } + + CowString &Append(const std::string &str) + { + return Append(str.c_str()); + } + + CowString Substr(size_t pos = 0, size_t len = npos) const + { + if (pos >= buffer_->size) + { + return CowString(); + } + + size_t max_len = buffer_->size - pos; + size_t real_len = (len == npos || len > max_len) + ? max_len + : len; + + return CowString(std::string(buffer_->data + pos, real_len)); + } + + void Clear() + { + if (buffer_->size == 0 && buffer_->ref_count == 1) + { + return; + } + + EnsureUnique(); + + delete[] buffer_->data; + buffer_->data = new char[1]; + buffer_->data[0] = '\0'; + buffer_->size = 0; + } + + size_t Find(const char *str) const + { + if (std::strlen(str) == 0) + { + return 0; + } + + const char *found = std::strstr(buffer_->data, str); + if (!found) + { + return npos; + } + + return static_cast(found - buffer_->data); + } + + size_t Find(char ch) const + { + const char *found = std::strchr(buffer_->data, ch); + if (!found) + { + return npos; + } + + return static_cast(found - buffer_->data); + } }; + +const size_t CowString::npos = static_cast(-1); diff --git a/05_week/tasks/simple_vector/README.md b/05_week/tasks/simple_vector/README.md index d3913644..23190e69 100644 --- a/05_week/tasks/simple_vector/README.md +++ b/05_week/tasks/simple_vector/README.md @@ -60,8 +60,7 @@ - Устройство вектора обсуждалось в конце третьей лекции - Для поддержки range-based for необходимы методы `begin`, `end` или внешние функции `begin`, `end`, принимающие заданную коллекцию, поэтому допустимо, чтобы они не - соответствовали стайлгайду. Если не хочется нарушать стайлгайд, то методы класса - могут быть с большой буквы, но внешние функции должны быть с маленькой + - Для совместимости с алгоритмами стандартной библиотеки **STL** может потребоваться `swap`, ситуация аналогичная, но поскольку требуется внутри класса `Swap`, достаточно реализовать внешнюю функцию, вызывающую метод `Swap` контейнера diff --git a/05_week/tasks/simple_vector/simple_vector.cpp b/05_week/tasks/simple_vector/simple_vector.cpp index 9b2ea971..268af7a1 100644 --- a/05_week/tasks/simple_vector/simple_vector.cpp +++ b/05_week/tasks/simple_vector/simple_vector.cpp @@ -1,5 +1,189 @@ +#include +#include + +class SimpleVector +{ +private: + int *data_; + size_t size_; + size_t capacity_; + + void Reallocate(size_t new_capacity) + { + int *new_data = new int[new_capacity]; + for (size_t i = 0; i < size_; ++i) + { + new_data[i] = data_[i]; + } + delete[] data_; + data_ = new_data; + capacity_ = new_capacity; + } + +public: + SimpleVector() + : data_(nullptr), size_(0), capacity_(0) {} + + explicit SimpleVector(size_t size) + : data_(new int[size]()), size_(size), capacity_(size) {} + + SimpleVector(size_t size, int value) + : data_(new int[size]), size_(size), capacity_(size) + { + for (size_t i = 0; i < size_; ++i) + { + data_[i] = value; + } + } + + SimpleVector(std::initializer_list init) + : data_(new int[init.size()]), size_(init.size()), capacity_(init.size()) + { + std::copy(init.begin(), init.end(), data_); + } + + SimpleVector(const SimpleVector &other) + : data_(new int[other.size_]), size_(other.size_), capacity_(other.size_) + { + for (size_t i = 0; i < size_; ++i) + { + data_[i] = other.data_[i]; + } + } + SimpleVector(SimpleVector &&other) noexcept + : data_(other.data_), size_(other.size_), capacity_(other.capacity_) + { + other.data_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + } + SimpleVector &operator=(const SimpleVector &other) + { + if (this != &other) + { + SimpleVector temp(other); + Swap(temp); + } + return *this; + } + SimpleVector &operator=(SimpleVector &&other) noexcept + { + if (this != &other) + { + delete[] data_; + data_ = other.data_; + size_ = other.size_; + capacity_ = other.capacity_; + other.data_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + } + return *this; + } + ~SimpleVector() + { + delete[] data_; + } + void Swap(SimpleVector &other) noexcept + { + std::swap(data_, other.data_); + std::swap(size_, other.size_); + std::swap(capacity_, other.capacity_); + } + friend void swap(SimpleVector &lhs, SimpleVector &rhs) noexcept + { + lhs.Swap(rhs); + } + int &operator[](size_t index) { return data_[index]; } + const int &operator[](size_t index) const { return data_[index]; } + size_t Size() const { return size_; } + size_t Capacity() const { return capacity_; } + bool Empty() const { return size_ == 0; } + const int *Data() const { return data_; } + void PushBack(int value) + { + if (size_ == capacity_) + { + size_t new_capacity = (capacity_ == 0) ? 1 : capacity_ * 2; + Reallocate(new_capacity); + } + data_[size_++] = value; + } + void PopBack() + { + if (size_ > 0) + --size_; + } + int *Insert(const int *pos, int value) + { + if (pos < data_ || pos > data_ + size_) + return data_ + size_; + + size_t index = pos - data_; + if (size_ == capacity_) + { + size_t new_capacity = (capacity_ == 0) ? 1 : capacity_ * 2; + Reallocate(new_capacity); + } + + for (size_t i = size_; i > index; --i) + data_[i] = data_[i - 1]; + + data_[index] = value; + ++size_; + return data_ + index; + } + int *Erase(const int *pos) + { + if (pos < data_ || pos >= data_ + size_) + return data_ + size_; + + size_t index = pos - data_; + for (size_t i = index; i + 1 < size_; ++i) + data_[i] = data_[i + 1]; + + --size_; + return data_ + index; + } + void Clear() { size_ = 0; } + void Resize(size_t new_size, int value = 0) + { + if (new_size <= size_) + { + size_ = new_size; + return; + } + if (new_size > capacity_) + Reallocate(new_size); + + for (size_t i = size_; i < new_size; ++i) + data_[i] = value; + + size_ = new_size; + } + void Reserve(size_t new_capacity) + { + if (new_capacity > capacity_) + Reallocate(new_capacity); + } + int *begin() { return data_; } + int *end() { return data_ + size_; } + const int *begin() const { return data_; } + const int *end() const { return data_ + size_; } + bool operator==(const SimpleVector &other) const + { + if (size_ != other.size_) + return false; + for (size_t i = 0; i < size_; ++i) + if (data_[i] != other.data_[i]) + return false; + return true; + } + + bool operator!=(const SimpleVector &other) const + { + return !(*this == other); + } -class SimpleVector { -}; \ No newline at end of file diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 438c4536..848d7c22 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -1,7 +1,86 @@ #include #include +class StringView +{ +public: + inline static const size_t npos = static_cast(-1); -class StringView { +private: + const char *data_; + size_t size_; +public: + StringView() : data_(nullptr), size_(0) {} + StringView(const std::string &str, size_t pos = 0, size_t len = npos) + { + if (pos >= str.size()) + { + data_ = nullptr; + size_ = 0; + return; + } + + size_t real_len = (len == npos || pos + len > str.size()) ? str.size() - pos : len; + + data_ = str.data() + pos; + size_ = real_len; + } + StringView(const char *str) : data_(str), size_(str ? std::strlen(str) : 0) {} + StringView(const char *str, size_t len) : data_(str), size_(str ? len : 0) {} + const char &operator[](size_t index) const { return data_[index]; } + const char *Data() const { return data_; } + const char &Front() const { return data_[0]; } + const char &Back() const { return data_[size_ - 1]; } + size_t Size() const { return size_; } + size_t Length() const { return size_; } + bool Empty() const { return size_ == 0; } + void RemovePrefix(size_t n) + { + if (n > size_) + n = size_; + data_ += n; + size_ -= n; + } + void RemoveSuffix(size_t n) + { + if (n > size_) + n = size_; + size_ -= n; + } + StringView Substr(size_t pos, size_t len = npos) const + { + if (pos >= size_) + return StringView(); + + size_t real_len = (len == npos || pos + len > size_) ? size_ - pos : len; + return StringView(data_ + pos, real_len); + } + size_t Find(char ch, size_t pos = 0) const + { + if (pos >= size_) + return npos; + + for (size_t i = pos; i < size_; ++i) + { + if (data_[i] == ch) + return i; + } + return npos; + } + size_t Find(StringView sv, size_t pos = 0) const + { + if (sv.size_ == 0) + return (pos <= size_) ? pos : npos; + if (sv.size_ > size_ || pos >= size_) + return npos; + + for (size_t i = pos; i + sv.size_ <= size_; ++i) + { + if (std::memcmp(data_ + i, sv.data_, sv.size_) == 0) + return i; + } + return npos; + } + std::string ToString() const { return std::string(data_, size_); } }; \ No newline at end of file diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index 2ccfb417..3e27f5cd 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -1,6 +1,90 @@ +#include #include +class Tracer +{ +public: + Tracer() : id_(++count), name_("obj_" + std::to_string(id_)) + { + ++default_ctor; + ++alive; + } -class Tracer { + explicit Tracer(const std::string &s) + : id_(++count), name_(s + "_" + std::to_string(id_)) + { + ++str_ctor; + ++alive; + } + Tracer(const Tracer &other) + : id_(++count), name_(other.name_) + { + ++copy_ctor; + ++alive; + } + + Tracer(Tracer &&other) noexcept + : id_(++count), name_(std::move(other.name_)) + { + ++move_ctor; + ++alive; + } + + Tracer &operator=(const Tracer &other) + { + if (this != &other) + { + name_ = other.name_; + ++copy_assign; + } + return *this; + } + + Tracer &operator=(Tracer &&other) noexcept + { + if (this != &other) + { + name_ = std::move(other.name_); + ++move_assign; + } + return *this; + } + + ~Tracer() + { + ++dtor; + --alive; + } + + int Id() const { return id_; } + const std::string &Name() const { return name_; } + const char *Data() const { return name_.data(); } + + static void ResetStats() + { + count = 0; + alive = 0; + default_ctor = 0; + str_ctor = 0; + copy_ctor = 0; + move_ctor = 0; + copy_assign = 0; + move_assign = 0; + dtor = 0; + } + + inline static int count = 0; + inline static int alive = 0; + inline static int default_ctor = 0; + inline static int str_ctor = 0; + inline static int copy_ctor = 0; + inline static int move_ctor = 0; + inline static int copy_assign = 0; + inline static int move_assign = 0; + inline static int dtor = 0; + +private: + int id_; + std::string name_; }; \ No newline at end of file diff --git a/06_week/tasks/simple_list/simple_list.cpp b/06_week/tasks/simple_list/simple_list.cpp index e97b2a81..9785e4f1 100644 --- a/06_week/tasks/simple_list/simple_list.cpp +++ b/06_week/tasks/simple_list/simple_list.cpp @@ -1,5 +1,194 @@ #include +#include +#include -class SimpleList { +class SimpleList +{ +private: + struct Node + { + std::string value; + Node *prev; + Node *next; -}; \ No newline at end of file + Node(const std::string &v) : value(v), prev(nullptr), next(nullptr) {} + Node(std::string &&v) : value(std::move(v)), prev(nullptr), next(nullptr) {} + }; + Node *head_; + Node *tail_; + size_t size_; + +private: + void Link(Node *position, Node *newNode) + { + newNode->next = position; + newNode->prev = position->prev; + if (position->prev) + position->prev->next = newNode; + else + head_ = newNode; + + position->prev = newNode; + ++size_; + } + void Unlink(Node *node) + { + if (!node) + return; + + if (node->prev) + node->prev->next = node->next; + else + head_ = node->next; + + if (node->next) + node->next->prev = node->prev; + else + tail_ = node->prev; + + delete node; + --size_; + } + +public: + SimpleList() : head_(nullptr), tail_(nullptr), size_(0) {} + SimpleList(const SimpleList &other) : head_(nullptr), tail_(nullptr), size_(0) + { + Node *current = other.head_; + while (current) + { + PushBack(current->value); + current = current->next; + } + } + SimpleList(SimpleList &&other) noexcept : head_(nullptr), tail_(nullptr), size_(0) + { + Swap(other); + } + ~SimpleList() + { + Clear(); + } + void Swap(SimpleList &other) noexcept + { + std::swap(head_, other.head_); + std::swap(tail_, other.tail_); + std::swap(size_, other.size_); + } + size_t Size() const { return size_; } + bool Empty() const { return size_ == 0; } + void PushBack(const std::string &value) + { + Node *node = new Node(value); + if (!tail_) + head_ = tail_ = node; + else + { + node->prev = tail_; + tail_->next = node; + tail_ = node; + } + ++size_; + } + void PushBack(std::string &&value) + { + Node *node = new Node(std::move(value)); + if (!tail_) + head_ = tail_ = node; + else + { + node->prev = tail_; + tail_->next = node; + tail_ = node; + } + ++size_; + } + void PushFront(const std::string &value) + { + Node *node = new Node(value); + if (!head_) + head_ = tail_ = node; + else + { + node->next = head_; + head_->prev = node; + head_ = node; + } + ++size_; + } + void PushFront(std::string &&value) + { + Node *node = new Node(std::move(value)); + if (!head_) + head_ = tail_ = node; + else + { + node->next = head_; + head_->prev = node; + head_ = node; + } + ++size_; + } + void PopBack() + { + if (!Empty()) + Unlink(tail_); + } + void PopFront() + { + if (!Empty()) + Unlink(head_); + } + std::string &Back() + { + if (Empty()) + throw std::out_of_range("List is empty"); + return tail_->value; + } + const std::string &Back() const + { + if (Empty()) + throw std::out_of_range("List is empty"); + return tail_->value; + } + std::string &Front() + { + if (Empty()) + throw std::out_of_range("List is empty"); + return head_->value; + } + const std::string &Front() const + { + if (Empty()) + throw std::out_of_range("List is empty"); + return head_->value; + } + void Clear() + { + while (!Empty()) + PopFront(); + } + SimpleList &operator=(const SimpleList &other) + { + if (this != &other) + { + SimpleList tmp(other); + Swap(tmp); + } + return *this; + } + SimpleList &operator=(SimpleList &&other) noexcept + { + if (this != &other) + { + Clear(); + Swap(other); + } + return *this; + } +}; + +inline void Swap(SimpleList &a, SimpleList &b) noexcept +{ + a.Swap(b); +} \ No newline at end of file diff --git a/06_week/tasks/smart_ptr/smart_ptr.cpp b/06_week/tasks/smart_ptr/smart_ptr.cpp index 05de4dc8..2ec371cc 100644 --- a/06_week/tasks/smart_ptr/smart_ptr.cpp +++ b/06_week/tasks/smart_ptr/smart_ptr.cpp @@ -1,10 +1,196 @@ #include +#include +#include +struct Block +{ + std::string *ptr; + size_t shared_count; + size_t weak_count; + explicit Block(std::string *p) + : ptr(p), shared_count(1), weak_count(0) {} +}; +class SharedPtr; +class WeakPtr; +class SharedPtr +{ +private: + std::string *ptr_; + Block *block_; + void Release() + { + if (!block_) + return; + --block_->shared_count; + if (block_->shared_count == 0) + { + delete block_->ptr; + block_->ptr = nullptr; -class SharedPtr { + if (block_->weak_count == 0) + delete block_; + } + block_ = nullptr; + ptr_ = nullptr; + } +public: + SharedPtr() : ptr_(nullptr), block_(nullptr) {} + explicit SharedPtr(std::string *ptr) + : ptr_(ptr) + { + if (ptr) + block_ = new Block(ptr); + else + block_ = nullptr; + } + SharedPtr(std::string *ptr, Block *block) + : ptr_(ptr), block_(block) + { + if (block_) + ++block_->shared_count; + } + SharedPtr(const SharedPtr &other) + : ptr_(other.ptr_), block_(other.block_) + { + if (block_) + ++block_->shared_count; + } + SharedPtr(SharedPtr &&other) noexcept + : ptr_(other.ptr_), block_(other.block_) + { + other.ptr_ = nullptr; + other.block_ = nullptr; + } + ~SharedPtr() { Release(); } + SharedPtr &operator=(const SharedPtr &other) + { + if (this != &other) + { + Release(); + ptr_ = other.ptr_; + block_ = other.block_; + if (block_) + ++block_->shared_count; + } + return *this; + } + SharedPtr &operator=(SharedPtr &&other) noexcept + { + if (this != &other) + { + Release(); + ptr_ = other.ptr_; + block_ = other.block_; + other.ptr_ = nullptr; + other.block_ = nullptr; + } + return *this; + } + std::string &operator*() const { return *ptr_; } + std::string *operator->() const { return ptr_; } + std::string *Get() const { return ptr_; } + void Reset(std::string *new_ptr = nullptr) + { + Release(); + if (new_ptr) + { + block_ = new Block(new_ptr); + ptr_ = new_ptr; + } + } + void Swap(SharedPtr &other) + { + std::swap(ptr_, other.ptr_); + std::swap(block_, other.block_); + } + size_t UseCount() const { return block_ ? block_->shared_count : 0; } + explicit operator bool() const { return ptr_ != nullptr; } + Block *GetBlock() const { return block_; } }; +class WeakPtr +{ +private: + Block *block_; + void Release() + { + if (!block_) + return; + + --block_->weak_count; + if (block_->shared_count == 0 && block_->weak_count == 0) + delete block_; -class WeakPtr { + block_ = nullptr; + } -}; \ No newline at end of file +public: + WeakPtr() : block_(nullptr) {} + WeakPtr(const SharedPtr &shared) : block_(shared.GetBlock()) + { + if (block_) + ++block_->weak_count; + } + WeakPtr(const WeakPtr &other) : block_(other.block_) + { + if (block_) + ++block_->weak_count; + } + WeakPtr(WeakPtr &&other) noexcept : block_(other.block_) + { + other.block_ = nullptr; + } + ~WeakPtr() { Release(); } + WeakPtr &operator=(const WeakPtr &other) + { + if (this != &other) + { + Release(); + block_ = other.block_; + if (block_) + ++block_->weak_count; + } + return *this; + } + WeakPtr &operator=(WeakPtr &&other) noexcept + { + if (this != &other) + { + Release(); + block_ = other.block_; + other.block_ = nullptr; + } + return *this; + } + WeakPtr &operator=(const SharedPtr &shared) + { + Release(); + block_ = shared.GetBlock(); + if (block_) + ++block_->weak_count; + return *this; + } + void Reset() + { + Release(); + } + void Swap(WeakPtr &other) + { + std::swap(block_, other.block_); + } + size_t UseCount() const { return block_ ? block_->shared_count : 0; } + bool Expired() const { return !block_ || block_->shared_count == 0; } + SharedPtr Lock() const + { + if (Expired()) + return SharedPtr(); + return SharedPtr(block_->ptr, block_); + } +}; +template +SharedPtr MakeShared(T &&value) +{ + return SharedPtr(new std::string(std::forward(value))); +} +void Swap(SharedPtr &a, SharedPtr &b) { a.Swap(b); } +void Swap(WeakPtr &a, WeakPtr &b) { a.Swap(b); } \ No newline at end of file diff --git a/06_week/tasks/unique_ptr/unique_ptr.cpp b/06_week/tasks/unique_ptr/unique_ptr.cpp index db8729ad..b04ba670 100644 --- a/06_week/tasks/unique_ptr/unique_ptr.cpp +++ b/06_week/tasks/unique_ptr/unique_ptr.cpp @@ -1,6 +1,75 @@ #include +#include +class UniquePtr +{ +private: + std::string *ptr_; -class UniquePtr { - -}; \ No newline at end of file +public: + UniquePtr() : ptr_(nullptr) {} + explicit UniquePtr(std::string *ptr) : ptr_(ptr) {} + UniquePtr(const UniquePtr &) = delete; + UniquePtr &operator=(const UniquePtr &) = delete; + UniquePtr(UniquePtr &&other) noexcept : ptr_(other.ptr_) + { + other.ptr_ = nullptr; + } + UniquePtr &operator=(UniquePtr &&other) noexcept + { + if (this != &other) + { + delete ptr_; + ptr_ = other.ptr_; + other.ptr_ = nullptr; + } + return *this; + } + ~UniquePtr() + { + delete ptr_; + } + std::string &operator*() const + { + return *ptr_; + } + std::string *operator->() const + { + return ptr_; + } + std::string *Get() const + { + return ptr_; + } + std::string *Release() + { + std::string *temp = ptr_; + ptr_ = nullptr; + return temp; + } + void Reset(std::string *new_ptr = nullptr) + { + if (ptr_ != new_ptr) + { + delete ptr_; + ptr_ = new_ptr; + } + } + void Swap(UniquePtr &other) + { + std::swap(ptr_, other.ptr_); + } + explicit operator bool() const + { + return ptr_ != nullptr; + } +}; +template +UniquePtr MakeUnique(T &&value) +{ + return UniquePtr(new std::string(std::forward(value))); +} +void Swap(UniquePtr &lhs, UniquePtr &rhs) +{ + lhs.Swap(rhs); +} \ No newline at end of file diff --git a/addition.cpp b/addition.cpp new file mode 100644 index 00000000..b185d50b --- /dev/null +++ b/addition.cpp @@ -0,0 +1,5 @@ +#include + +int64_t Addition(int a, int b) { + return static_cast(a) + static_cast(b); +} diff --git a/grading/deadlines.json b/grading/deadlines.json index ed835db7..0452158a 100644 --- a/grading/deadlines.json +++ b/grading/deadlines.json @@ -68,48 +68,50 @@ "data_stats": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Статистика данных" }, "unique": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Уникальные элементы" }, "range": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Диапазон элементов" }, "minmax": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Минимум и максимум" }, "find_all": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Найти все элементы" }, "os_overload": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Перегрузка оператора вывода" }, "easy_compare": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Оператор сравнения" }, "filter": { "max_score": 100, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Фильтрация данных" }, "enum_operators": { "max_score": 200, - "deadline": "2025-12-19 23:59", + "deadline": "2025-12-18 23:59", "description": "Переопределение побитовых операторов" +<<<<<<< HEAD +======= }, "stack": { @@ -168,5 +170,6 @@ "max_score": 400, "deadline": "2026-02-23 23:59", "description": "Двусвязный список (упрощенный)" +>>>>>>> upstream/main } } \ No newline at end of file