diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 81e15bd..ed26906 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -1 +1,31 @@ #include "util.hpp" + +std::vector Smaller(double elem, const std::vector& input) { + std::vector smaller{}; + for (auto i : input) { + if (i < elem) { + smaller.push_back(i); + } + } + return smaller; +} + +std::vector Bigger(double elem, const std::vector& input) { + std::vector bigger{}; + for (auto i : input) { + if (i > elem) { + bigger.push_back(i); + } + } + return bigger; +} + +std::vector Eq(double elem, const std::vector& input) { + std::vector eq{}; + for (auto i : input) { + if (i == elem) { + eq.push_back(i); + } + } + return eq; +} \ No newline at end of file diff --git a/lib/src/util.hpp b/lib/src/util.hpp index e69de29..f76a723 100644 --- a/lib/src/util.hpp +++ b/lib/src/util.hpp @@ -0,0 +1,7 @@ +#include + +std::vector Smaller(double elem, const std::vector& input); + +std::vector Bigger(double elem, const std::vector& input); + +std::vector Eq(double elem, const std::vector& input); \ No newline at end of file diff --git a/task_01/src/task.cpp b/task_01/src/task.cpp new file mode 100644 index 0000000..c688469 --- /dev/null +++ b/task_01/src/task.cpp @@ -0,0 +1,23 @@ +#include "task.hpp" + +#include + +std::pair SearchNumbers(int search_num, + const std::vector& data) { + if (data.size() <= 1) { + throw std::invalid_argument("vector is too small"); + } + size_t bottom{0}; + size_t top{data.size() - 1}; + while (bottom != top) { + if (data[bottom] + data[top] == search_num) { + std::pair ans{data[bottom], data[top]}; + return ans; + } else if (data[bottom] + data[top] > search_num) { + --top; + } else { + ++bottom; + } + } + throw std::invalid_argument("no suitable pair"); +} \ No newline at end of file diff --git a/task_01/src/task.hpp b/task_01/src/task.hpp new file mode 100644 index 0000000..ca04052 --- /dev/null +++ b/task_01/src/task.hpp @@ -0,0 +1,4 @@ +#include +#include + +std::pair SearchNumbers(int search_num, const std::vector& data); \ No newline at end of file diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index 87cef73..173ac81 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,5 +1,48 @@ #include -TEST(Test, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} \ No newline at end of file +#include "task.hpp" + +TEST(Task1, Simple) { + std::vector data{1, 3, 4, 4, 7, 11}; + std::pair ans{3, 7}; + ASSERT_EQ(SearchNumbers(10, data), ans); +} + +TEST(Task1, FirstAndLast) { + std::vector data{1, 2, 3, 4, 5, 99}; + std::pair ans{1, 99}; + ASSERT_EQ(SearchNumbers(100, data), ans); +} + +TEST(Task1, Negative) { + std::vector data{-5, -3, 0, 1, 2, 8}; + std::pair ans{-3, 8}; + ASSERT_EQ(SearchNumbers(5, data), ans); +} + +TEST(Task1, Simple2) { + std::vector data{10, 11, 12, 13, 14, 15}; + std::pair ans{10, 15}; + ASSERT_EQ(SearchNumbers(25, data), ans); +} + +TEST(Task1, SmallVector) { + std::vector data{1, 2}; + std::pair ans{1, 2}; + ASSERT_EQ(SearchNumbers(3, data), ans); +} + +TEST(Task1, NoPair) { + std::vector data{1, 2, 3, 4, 5}; + ASSERT_THROW(SearchNumbers(100, data), std::invalid_argument); +} + +TEST(Task1, Empty) { + std::vector data; + ASSERT_THROW(SearchNumbers(10, data), std::invalid_argument); +} + +TEST(Task1, SingleElementVector) { + std::vector data{5}; + ASSERT_THROW(SearchNumbers(5, data), std::invalid_argument); +} diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0e4393b..7601116 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,3 +1,5 @@ #include -int main() { return 0; } +#include "stack.hpp" + +int main() {} \ No newline at end of file diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp deleted file mode 100644 index 8ca8990..0000000 --- a/task_02/src/stack.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stack.hpp" - -#include - -void Stack::Push(int value) { data_.push(value); } - -int Stack::Pop() { - auto result = data_.top(); - data_.pop(); - return result; -} - -void MinStack::Push(int value) { data_.push_back(value); } - -int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); - return result; -} - -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 138ec40..b47652b 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -1,23 +1,128 @@ #pragma once -#include -#include +#include +#include +struct EmptyStackError : std::exception { + using std::exception::exception; +}; + +template +struct Node { + T value; + Node* prev = nullptr; +}; + +template class Stack { public: - void Push(int value); - int Pop(); + Stack(){}; + ~Stack() { + while (head != nullptr) { + Node* old_head = head; + head = head->prev; + delete old_head; + } + } + void Push(T value); + T Pop(); private: - std::stack data_; + Node* head = nullptr; }; +template + requires(std::totally_ordered) class MinStack { public: - void Push(int value); - int Pop(); - int GetMin(); + MinStack(){}; + ~MinStack() { + while (head != nullptr) { + Node* old_head = head; + Node* old_head_min = head_min; + + head = head->prev; + head_min = head_min->prev; + + delete old_head; + delete old_head_min; + } + } + void Push(T value); + T Pop(); + T const GetMin(); private: - std::vector data_; + Node* head = nullptr; + Node* head_min = nullptr; }; + +template +void Stack::Push(T value) { + if (!head) { + head = new Node; + head->value = value; + } else { + Node* new_head = new Node; + new_head->prev = head; + new_head->value = value; + head = new_head; + } +} + +template +T Stack::Pop() { + if (head == nullptr) { + throw EmptyStackError(); + } + Node* del_node = head; + T val = head->value; + head = head->prev; + delete del_node; + return val; +} + +template + requires(std::totally_ordered) +void MinStack::Push(T value) { + if (!head) { + head = new Node; + head->value = value; + head_min = new Node; + head_min->value = value; + } else { + Node* new_head = new Node; + Node* new_head_min = new Node; + new_head->prev = head; + new_head->value = value; + new_head_min->prev = head_min; + new_head_min->value = std::min(head_min->value, value); + head = new_head; + head_min = new_head_min; + } +} + +template + requires(std::totally_ordered) +T MinStack::Pop() { + if (!head || !head_min) { + throw EmptyStackError(); + } + Node* del_node = head; + Node* del_node_min = head_min; + T val = head->value; + head = head->prev; + head_min = head_min->prev; + delete del_node; + delete del_node_min; + return val; +} + +template + requires(std::totally_ordered) +T const MinStack::GetMin() { + if (!head_min) { + throw EmptyStackError(); + } + return head_min->value; +} \ No newline at end of file diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index 54e7ce9..989d0ed 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,42 +1,97 @@ #include -#include +#include #include "stack.hpp" TEST(StackTest, Simple) { - Stack stack; - stack.Push(1); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] + Stack stack{}; + stack.Push(1); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] + ASSERT_EQ(stack.Pop(), 2); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] + ASSERT_EQ(stack.Pop(), 2); // [1] + stack.Push(3); // [1, 3] + ASSERT_EQ(stack.Pop(), 3); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] } TEST(MinStackTest, Simple) { - MinStack stack; - stack.Push(1); // Stack [1] + MinStack stack{}; + stack.Push(1); // [1] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] + ASSERT_EQ(stack.Pop(), 2); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] + ASSERT_EQ(stack.Pop(), 2); // [1] + stack.Push(3); // [1, 3] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] + ASSERT_EQ(stack.Pop(), 3); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] +} + +TEST(PopErrorTest, EmptyStackErrorTest) { + MinStack minstack{}; + ASSERT_THROW(minstack.Pop(), EmptyStackError); + MinStack minstack2{}; + minstack2.Push(6); + minstack2.Pop(); + ASSERT_THROW(minstack2.GetMin(), EmptyStackError); + Stack stack{}; + stack.Push(2); + stack.Pop(); + ASSERT_THROW(stack.Pop(), EmptyStackError); +} + +TEST(MinStackTest, Double) { + MinStack minstack{}; + minstack.Push(3.3); + ASSERT_EQ(minstack.GetMin(), 3.3); + minstack.Push(-0.7); + minstack.Push(4.8); + ASSERT_EQ(minstack.GetMin(), -0.7); + ASSERT_EQ(minstack.Pop(), 4.8); + ASSERT_EQ(minstack.GetMin(), -0.7); + ASSERT_EQ(minstack.Pop(), -0.7); + ASSERT_EQ(minstack.GetMin(), 3.3); +} + +TEST(MinStackTest, String) { // сравнивает алфавитно + MinStack minstack{}; + minstack.Push("bb"); + minstack.Push("r"); + ASSERT_EQ(minstack.GetMin(), "bb"); + minstack.Push("aaat"); + ASSERT_EQ(minstack.GetMin(), "aaat"); + ASSERT_EQ(minstack.Pop(), "aaat"); + ASSERT_EQ(minstack.GetMin(), "bb"); + ASSERT_EQ(minstack.Pop(), "r"); + ASSERT_EQ(minstack.Pop(), "bb"); +} + +TEST(MinStackTest, Vector) { // поэлементно + MinStack> minstack{}; + std::vector a{3, 2}; + minstack.Push(a); + std::vector b{5}; + minstack.Push(b); + ASSERT_EQ(minstack.GetMin(), a); + std::vector c{-4, 8, 9}; + minstack.Push(c); + ASSERT_EQ(minstack.GetMin(), c); + ASSERT_EQ(minstack.Pop(), c); + ASSERT_EQ(minstack.GetMin(), a); + ASSERT_EQ(minstack.Pop(), b); + ASSERT_EQ(minstack.Pop(), a); } \ No newline at end of file diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp new file mode 100644 index 0000000..7e5093c --- /dev/null +++ b/task_03/src/days_before_hot.cpp @@ -0,0 +1,26 @@ +#include "days_before_hot.hpp" + +struct TemperatureWithDayIndex { + double temperature; + int day_index; +}; + +std::vector DaysBeforeHot(std::vector temperatures) { + std::vector days_before_hot(temperatures.size()); + std::stack hotter_temperatures{}; + int size = temperatures.size() - 1; + for (int i{size}; i >= 0; --i) { + while (!(hotter_temperatures.empty()) && + (hotter_temperatures.top().temperature <= temperatures[i])) { + hotter_temperatures.pop(); + } + if (hotter_temperatures.empty()) { + days_before_hot[i] = 0; + } else { + days_before_hot[i] = hotter_temperatures.top().day_index - i; + } + TemperatureWithDayIndex day{temperatures[i], i}; + hotter_temperatures.push(day); + } + return days_before_hot; +} \ No newline at end of file diff --git a/task_03/src/days_before_hot.hpp b/task_03/src/days_before_hot.hpp new file mode 100644 index 0000000..ba5196f --- /dev/null +++ b/task_03/src/days_before_hot.hpp @@ -0,0 +1,4 @@ +#include +#include + +std::vector DaysBeforeHot(std::vector temperatures); \ No newline at end of file diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index 0e4393b..8e89d61 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,3 +1,4 @@ -#include -int main() { return 0; } +#include "days_before_hot.hpp" + +int main() {} diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index ef5a86a..ae3eecc 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,8 +1,40 @@ #include -#include "topology_sort.hpp" +#include "days_before_hot.hpp" -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(first_test, ints) { + std::vector temp{5, 7, 5, 3, 10, 0, 2, -1, 3}; + std::vector ans{1, 3, 2, 1, 0, 1, 2, 1, 0}; + ASSERT_EQ(DaysBeforeHot(temp), ans); } + +TEST(second_test, doubles) { + std::vector temp{5.1, 7.656, 5.0, 3, 10, -729.3, 2, -1.4, 3.2}; + std::vector ans{1, 3, 2, 1, 0, 1, 2, 1, 0}; + ASSERT_EQ(DaysBeforeHot(temp), ans); +} + +TEST(third_test, no_hot) { + std::vector temp{5, 4.7, 4.3, 3, 2, 1.3}; + std::vector ans{0, 0, 0, 0, 0, 0}; + ASSERT_EQ(DaysBeforeHot(temp), ans); +} + +TEST(fourth_test, four) { + std::vector temp{5, 4, 3, 2, 1, 10}; + std::vector ans{5, 4, 3, 2, 1, 0}; + ASSERT_EQ(DaysBeforeHot(temp), ans); +} + +TEST(fifth_test, one_number) { + std::vector temp{1}; + std::vector ans{0}; + ASSERT_EQ(DaysBeforeHot(temp), ans); +} + +TEST(sixth_test, same_values) { + std::vector temp{1, 1, 2, 2, 5, 1, 7}; + std::vector ans{2, 1, 2, 1, 2, 1, 0}; + ASSERT_EQ(DaysBeforeHot(temp), ans); +} \ No newline at end of file diff --git a/task_03/src/topology_sort.cpp b/task_03/src/topology_sort.cpp deleted file mode 100644 index e53f670..0000000 --- a/task_03/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_03/src/topology_sort.hpp b/task_03/src/topology_sort.hpp deleted file mode 100644 index 6f70f09..0000000 --- a/task_03/src/topology_sort.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/task_04/src/fish_days.cpp b/task_04/src/fish_days.cpp new file mode 100644 index 0000000..09cd3f2 --- /dev/null +++ b/task_04/src/fish_days.cpp @@ -0,0 +1,30 @@ +#include "fish_days.hpp" + +std::vector calculate_fish_days(int N, int K, + const std::vector& prices) { + if (prices.empty()) return {}; + + std::vector purchases(N, 0); + int min_price_day = 0; + double min_price = prices[0]; + ++purchases[0]; + + for (int i = 1; i < N; ++i) { + if (prices[i] <= min_price) { // если новый минимум + min_price = prices[i]; + min_price_day = i; + } else if (min_price_day <= i - K) { // если минимум устарел + min_price = prices[i - K + 1]; + min_price_day = i - K + 1; + for (int j = i - K + 2; j <= i; + ++j) { // пересчёт минимума в окне [i-K+1, i] + if (prices[j] <= min_price) { + min_price = prices[j]; + min_price_day = j; + } + } + } + ++purchases[min_price_day]; + } + return purchases; +} \ No newline at end of file diff --git a/task_04/src/fish_days.hpp b/task_04/src/fish_days.hpp new file mode 100644 index 0000000..b944cff --- /dev/null +++ b/task_04/src/fish_days.hpp @@ -0,0 +1,3 @@ +#include +std::vector calculate_fish_days(int N, int K, + const std::vector& prices); \ No newline at end of file diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 5e11617..c70d557 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,6 +1,50 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "fish_days.hpp" + +TEST(FishDays, OneDay) { + std::vector expected = {1}; + ASSERT_EQ(calculate_fish_days(1, 1, {5.0}), expected); +} + +TEST(FishDays, CheapFishWeek) { + std::vector prices = {5, 5, 1, 5, 5, 5, 5}; + std::vector expected = {1, 1, 3, 0, 0, 1, 1}; + ASSERT_EQ(calculate_fish_days(7, 3, prices), expected); +} + +TEST(FishDays, AllAtOne) { + std::vector prices = {8, 9, 10, 15, 20}; + std::vector expected = {5, 0, 0, 0, 0}; + ASSERT_EQ(calculate_fish_days(5, 5, prices), expected); +} + +TEST(FishDays, EveryDay) { + std::vector prices = {10, 8, 6, 4, 2}; + std::vector expected = {1, 1, 1, 1, 1}; + ASSERT_EQ(calculate_fish_days(5, 2, prices), expected); } + +TEST(FishDays, AnotherEveryDay) { + std::vector prices(10, 5.0); + std::vector expected(10, 1); + ASSERT_EQ(calculate_fish_days(10, 3, prices), expected); +} + +TEST(FishDays, Empty) { + std::vector expected; + ASSERT_EQ(calculate_fish_days(0, 3, {}), expected); +} + +TEST(FishDays, K_is_One) { + std::vector prices = {3, 1, 4, 1, 5}; + std::vector expected = {1, 1, 1, 1, 1}; + ASSERT_EQ(calculate_fish_days(5, 1, prices), expected); +} + +TEST(FishDays, Simple) { + std::vector prices = {7, 3, 8, 2, 5, 1, 9}; + std::vector expected = {1, 2, 0, 2, 0, 2, 0}; + ASSERT_EQ(calculate_fish_days(7, 4, prices), expected); +} \ No newline at end of file diff --git a/task_05/src/quick_sort.cpp b/task_05/src/quick_sort.cpp new file mode 100644 index 0000000..3c039ae --- /dev/null +++ b/task_05/src/quick_sort.cpp @@ -0,0 +1,26 @@ +#include "quick_sort.hpp" + +#include +#include + +static void QuickSortInplace(std::vector& arr, int left, int right) { + if (left >= right) return; + double pivot = arr[right]; + int i = left; + for (int j = left; j < right; ++j) { + if (arr[j] < pivot) { + std::swap(arr[i], arr[j]); + ++i; + } + } + std::swap(arr[i], arr[right]); + QuickSortInplace(arr, left, i - 1); + QuickSortInplace(arr, i + 1, right); +} + +// обертка +std::vector QuickSort(const std::vector& input) { + std::vector arr = input; + if (!arr.empty()) QuickSortInplace(arr, 0, arr.size() - 1); + return arr; +} \ No newline at end of file diff --git a/task_05/src/quick_sort.hpp b/task_05/src/quick_sort.hpp new file mode 100644 index 0000000..1080cb2 --- /dev/null +++ b/task_05/src/quick_sort.hpp @@ -0,0 +1,3 @@ +#include + +std::vector QuickSort(const std::vector& input); \ No newline at end of file diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617..cc7719b 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,42 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "quick_sort.hpp" + +TEST(QuickSort, Simple) { + std::vector vec{5.0, 6.3, 5.0, 1, -7.3, 3.3, 2.1, 2.1}; + std::vector ans{-7.3, 1, 2.1, 2.1, 3.3, 5, 5, 6.3}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Simple2) { + std::vector vec{0.001, 0.008, 0.004, 0.006, 0.007, 0.007}; + std::vector ans{0.001, 0.004, 0.006, 0.007, 0.007, 0.008}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Same) { + std::vector vec{4.2, 4.2, 4.2, 4.2, 4.2}; + std::vector ans{4.2, 4.2, 4.2, 4.2, 4.2}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Already) { + std::vector vec{-2.2, -1.1, 0, 3.3}; + std::vector ans{-2.2, -1.1, 0, 3.3}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Decrease) { + std::vector vec{9.9, 7.7, 5.5, 1.1, -0.7}; + std::vector ans{-0.7, 1.1, 5.5, 7.7, 9.9}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Empty) { + std::vector vec{}; + std::vector ans{}; + ASSERT_EQ(QuickSort(vec), ans); } diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 0e4393b..46aa64d 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,3 +1,5 @@ #include +#include "search_statistic.hpp" + int main() { return 0; } diff --git a/task_06/src/search_statistic.cpp b/task_06/src/search_statistic.cpp new file mode 100644 index 0000000..5de4ad4 --- /dev/null +++ b/task_06/src/search_statistic.cpp @@ -0,0 +1,24 @@ +#include "search_statistic.hpp" + +#include + +double SearchNStatistics(const std::vector& input, int order) { + if (input.empty() || order >= input.size() || order < 0) { + throw std::invalid_argument("invalid data"); + } + double elem = input[0]; + std::vector smaller{Smaller(elem, input)}; + if (smaller.size() == order) { + return elem; + } else if (smaller.size() > order) { + return SearchNStatistics(smaller, order); + } + std::vector eq{Eq(elem, input)}; + order -= smaller.size(); + if (eq.size() > order) { + return elem; + } + order -= eq.size(); + std::vector bigger{Bigger(elem, input)}; + return SearchNStatistics(bigger, order); +} \ No newline at end of file diff --git a/task_06/src/search_statistic.hpp b/task_06/src/search_statistic.hpp new file mode 100644 index 0000000..ccb8453 --- /dev/null +++ b/task_06/src/search_statistic.hpp @@ -0,0 +1,3 @@ +#include "../../lib/src/util.hpp" + +double SearchNStatistics(const std::vector& input, int order); \ No newline at end of file diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617..792ba97 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,47 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "search_statistic.hpp" + +TEST(SearchNStatistics, Simple) { + std::vector v = {5, 3, 1, 4, 2}; + ASSERT_EQ(SearchNStatistics(v, 0), 1); + ASSERT_EQ(SearchNStatistics(v, 2), 3); + ASSERT_EQ(SearchNStatistics(v, 4), 5); +} + +TEST(SearchNStatistics, Same) { + std::vector v = {1, 1, 1, 1, 1, 3}; + ASSERT_EQ(SearchNStatistics(v, 2), 1); + ASSERT_EQ(SearchNStatistics(v, 0), 1); + ASSERT_EQ(SearchNStatistics(v, 5), 3); +} + +TEST(SearchNStatistics, Empty) { + std::vector v; + EXPECT_THROW(SearchNStatistics(v, 0), std::invalid_argument); +} + +TEST(SearchNStatistics, OrderException) { + std::vector v = {42.0}; + EXPECT_THROW(SearchNStatistics(v, 1), std::invalid_argument); +} + +TEST(SearchNStatistics, InvalidOrder) { + std::vector v = {42.0}; + EXPECT_THROW(SearchNStatistics(v, -3), std::invalid_argument); } + +TEST(SearchNStatistics, Sorted) { + std::vector v = {0, 1, 2, 3, 4, 5, 6, 7}; + EXPECT_EQ(SearchNStatistics(v, 0), 0); + EXPECT_EQ(SearchNStatistics(v, 3), 3); + EXPECT_EQ(SearchNStatistics(v, 6), 6); +} + +TEST(SearchNStatistics, NegativeNumbers) { + std::vector v = {-5, -1, -3, -2, -4}; + EXPECT_EQ(SearchNStatistics(v, 0), -5); + EXPECT_EQ(SearchNStatistics(v, 2), -3); + EXPECT_EQ(SearchNStatistics(v, 4), -1); +} \ No newline at end of file diff --git a/task_07/src/avl_tree.cpp b/task_07/src/avl_tree.cpp new file mode 100644 index 0000000..cf4536f --- /dev/null +++ b/task_07/src/avl_tree.cpp @@ -0,0 +1,208 @@ +#include "avl_tree.hpp" + +#include + +AvlTree::Node* AvlTree::Search(int search_key) const { + Node* cur = head; + while (cur != nullptr) { + if (cur->key == search_key) { + return cur; + } else if (search_key < cur->key) { + cur = cur->left_child; + } else if (search_key > cur->key) { + cur = cur->right_child; + } + } + return nullptr; +} + +void AvlTree::Add(int new_key, int data) { + Node* new_node = new Node(new_key, data); + if (head == nullptr) { + head = new_node; + return; + } + Node* par = nullptr; + Node* cur = head; + + while (cur != nullptr) { + par = cur; + if (cur->key == new_key) { + std::cout << "the key is already exist\n"; + delete new_node; + return; + } else if (new_key < cur->key) { + cur = cur->left_child; + } else if (new_key > cur->key) { + cur = cur->right_child; + } + } + + if (new_key < par->key) { + par->left_child = new_node; + } + if (new_key > par->key) { + par->right_child = new_node; + } + new_node->parent = par; + + while (new_node != nullptr) { + new_node = Balance(new_node)->parent; + } +} + +AvlTree::Node* AvlTree::SearchMin(Node* cur) const { + while (cur->left_child != nullptr) { + cur = cur->left_child; + } + return cur; +} + +void AvlTree::Del(int del_key) { + Node* del_par = nullptr; + Node* del_node = head; + + while (del_node != nullptr) { + if (del_node->key == del_key) { + break; + } + del_par = del_node; + if (del_key < del_node->key) { + del_node = del_node->left_child; + } else if (del_key > del_node->key) { + del_node = del_node->right_child; + } + } + if (del_node == nullptr) { + return; + } + + Node* new_n; + + if (del_node->right_child == nullptr) { + new_n = del_node->left_child; + if (del_par == nullptr) { + head = del_node->left_child; + } else if (del_node == del_par->left_child) { + del_par->left_child = del_node->left_child; + } else { + del_par->right_child = del_node->left_child; + } + if (del_node->left_child != nullptr) { + del_node->left_child->parent = del_par; + } + delete del_node; + } else { + new_n = SearchMin(del_node->right_child); + if (new_n == del_node->right_child) { // это прямой правый ребенок + new_n->left_child = del_node->left_child; + } else { + new_n->parent->left_child = new_n->right_child; + if (new_n->right_child != nullptr) { + new_n->right_child->parent = new_n->parent; + } + new_n->right_child = del_node->right_child; + new_n->left_child = del_node->left_child; + del_node->right_child->parent = new_n; + } + new_n->parent = del_par; + if (del_node->left_child != nullptr) { + del_node->left_child->parent = new_n; + } + if (del_par != nullptr) { + if (del_node == del_par->left_child) { + del_par->left_child = new_n; + } else { + del_par->right_child = new_n; + } + } else { + head = new_n; + } + delete del_node; + } + Node* balancing = (new_n) ? new_n : del_par; + while (balancing != nullptr) { + balancing = Balance(balancing)->parent; + } +} + +AvlTree::AvlTree(std::vector> key_values) { + for (int i = 0; i < key_values.size(); ++i) { + Add(key_values[i].first, key_values[i].second); + } +} + +AvlTree::Node* AvlTree::Balance(Node* old_par) { + UpdateHeight(old_par); + int diff{GetDifference(old_par)}; + if (diff > 1) { + if (GetDifference(old_par->left_child) > 0) { + return LeftLeftImbalance(old_par); + } else { + return LeftRightImbalance(old_par); + } + } else if (diff < -1) { + if (GetDifference(old_par->right_child) < 0) { + return RightRightImbalance(old_par); + } else { + return RightLeftImbalance(old_par); + } + } + return old_par; +} + +AvlTree::Node* AvlTree::LeftLeftImbalance(Node* old_par) { + Node* new_par{old_par->left_child}; + if (old_par->parent) { + if (old_par->parent->left_child == old_par) { + old_par->parent->left_child = new_par; + } else { + old_par->parent->right_child = new_par; + } + } + new_par->parent = old_par->parent; + old_par->left_child = new_par->right_child; + if (new_par->right_child) new_par->right_child->parent = old_par; + old_par->parent = new_par; + new_par->right_child = old_par; + UpdateHeight(old_par); + UpdateHeight(new_par); + if (old_par == head) { + head = new_par; + } + return new_par; +} + +AvlTree::Node* AvlTree::RightRightImbalance(Node* old_par) { + Node* new_par{old_par->right_child}; + if (old_par->parent) { + if (old_par->parent->right_child == old_par) { + old_par->parent->right_child = new_par; + } else { + old_par->parent->left_child = new_par; + } + } + new_par->parent = old_par->parent; + old_par->right_child = new_par->left_child; + if (new_par->left_child) new_par->left_child->parent = old_par; + old_par->parent = new_par; + new_par->left_child = old_par; + UpdateHeight(old_par); + UpdateHeight(new_par); + if (old_par == head) { + head = new_par; + } + return new_par; +} + +AvlTree::Node* AvlTree::LeftRightImbalance(Node* old_par) { + Node* new_par = RightRightImbalance(old_par->left_child); + new_par = LeftLeftImbalance(old_par); + return new_par; +} + +AvlTree::Node* AvlTree::RightLeftImbalance(Node* old_par) { + Node* new_par = LeftLeftImbalance(old_par->right_child); + new_par = RightRightImbalance(old_par); + return new_par; +} \ No newline at end of file diff --git a/task_07/src/avl_tree.hpp b/task_07/src/avl_tree.hpp new file mode 100644 index 0000000..2eaf47a --- /dev/null +++ b/task_07/src/avl_tree.hpp @@ -0,0 +1,118 @@ +#include +#include + +class AvlTree { + public: + AvlTree(){}; + AvlTree(std::vector> key_values); + int operator[](int key) { + Node* node{Search(key)}; + if (node == nullptr) { + throw std::out_of_range("dont exist"); + } else { + return node->data; + } + } + + bool operator==(const AvlTree& other) const { + if (this == &other) { + return true; + } + if (head == nullptr && other.head == nullptr) { + return true; + } + if (head == nullptr || other.head == nullptr) { + return false; + } + for (auto it = begin(), it_other = other.begin(); + it != end() && it_other != other.end(); ++it, ++it_other) { + if (*it != *it_other) { + return false; + } + } + return true; + } + bool operator!=(const AvlTree& other) const { return !(*this == other); } + + void Del(int del_key); + void Add(int new_key, int data); + + private: + struct Node { + int key; + int data; + Node* parent = nullptr; + Node* left_child = nullptr; + Node* right_child = nullptr; + int height = 1; + Node(int key, int data) : key(key), data(data) {} + }; + Node* head = nullptr; + Node* Search(int key) const; + Node* SearchMin(Node* cur) const; + Node* SearchSuccessor(Node* cur) const; + + int GetHeight(Node* node) { + if (node) { + UpdateHeight(node); + return node->height; + } + return 0; + } + + int GetDifference(Node* node) { + if (node) { + return (GetHeight(node->left_child) - GetHeight(node->right_child)); + } + return 0; + } + + void UpdateHeight(Node* node) { + if (node) { + node->height = 1 + std::max(GetHeight(node->left_child), + GetHeight(node->right_child)); + } + } + + Node* Balance(Node* old_par); + Node* LeftLeftImbalance(Node* old_par); + Node* RightRightImbalance(Node* old_par); + Node* LeftRightImbalance(Node* old_par); + Node* RightLeftImbalance(Node* old_par); + + public: + friend std::ostream& operator<<(std::ostream& os, const AvlTree& tree); + class Iterator { + public: + Iterator(Node* node, const AvlTree& tree) + : current_node(node), tree(tree){}; + + std::pair operator*() const { + if (!current_node) { + throw std::out_of_range("dont exist"); + } + return {current_node->key, current_node->data}; + } + + Iterator& operator++() { + current_node = tree.SearchSuccessor(current_node); + return *this; + } + + bool operator==(const Iterator& other) const { + return current_node == other.current_node; + } + + bool operator!=(const Iterator& other) const { + return current_node != other.current_node; + } + + private: + Node* current_node; + const AvlTree& tree; + }; + Iterator begin() const { + return Iterator(head ? SearchMin(head) : nullptr, *this); + } + Iterator end() const { return Iterator(nullptr, *this); } +}; \ No newline at end of file diff --git a/task_07/src/print_tree.cpp b/task_07/src/print_tree.cpp new file mode 100644 index 0000000..310f2d9 --- /dev/null +++ b/task_07/src/print_tree.cpp @@ -0,0 +1,35 @@ +#include + +#include "avl_tree.hpp" + +std::ostream& operator<<(std::ostream& os, const AvlTree& tree) { + os << "{"; + bool first_elem = true; + for (const auto& [key, value] : tree) { + if (!first_elem) { + os << ", "; + } + os << "(" << key << ", " << value << ")"; + first_elem = false; + } + os << "}"; + return os; +} + +AvlTree::Node* AvlTree::SearchSuccessor(Node* cur) const { + if (cur == nullptr) { + return nullptr; + } + if (cur->right_child != nullptr) { + return SearchMin(cur->right_child); + } else { + Node* parent = cur->parent; + while (parent != nullptr && + cur == parent->right_child) { // пока я не левый ребенок или не + // корень в конце + cur = parent; + parent = parent->parent; + } + return parent; + } +} \ No newline at end of file diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617..0ffce4c 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,134 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "avl_tree.hpp" + +TEST(AvlTest, Simple) { + std::vector> pairs{std::pair{5, 5}, + std::pair{3, 4}, + std::pair{9, 9}}; + AvlTree tree{pairs}; + ASSERT_EQ(tree[5], 5); + ASSERT_EQ(tree[3], 4); + ASSERT_EQ(tree[9], 9); + EXPECT_THROW({ int a{tree[2]}; }, std::out_of_range); +} + +TEST(AvlTest, AddDel) { + std::vector> pairs{std::pair{5, 5}, + std::pair{3, 4}, + std::pair{9, 9}}; + AvlTree tree{pairs}; + tree.Add(7, 1); + ASSERT_EQ(tree[7], 1); + tree.Del(5); + tree.Del(3); + tree.Add(3, 0); + ASSERT_EQ(tree[3], 0); + EXPECT_THROW({ int a{tree[5]}; }, std::out_of_range); +} + +TEST(AvlCoutTest, Simple) { + std::vector> pairs{std::pair{5, 5}, + std::pair{3, 4}, + std::pair{9, 9}}; + AvlTree tree{pairs}; + tree.Add(7, 1); + + std::ostringstream oss; + oss << tree; + std::string expected = "{(3, 4), (5, 5), (7, 1), (9, 9)}"; + EXPECT_EQ(oss.str(), expected); +} + +TEST(AvlCoutTest, Simple2) { + AvlTree tree; + tree.Add(3, 30); + tree.Add(1, 10); + tree.Add(4, 40); + tree.Add(2, 20); + + std::ostringstream oss; + oss << tree; + std::string expected = "{(1, 10), (2, 20), (3, 30), (4, 40)}"; + EXPECT_EQ(oss.str(), expected); +} + +TEST(AvlCoutTest, EmptyTreeOutput) { + AvlTree empty_tree; + std::ostringstream oss; + oss << empty_tree; + EXPECT_EQ(oss.str(), "{}"); +} + +TEST(AvlCoutTest, SingleElement) { + AvlTree tree; + tree.Add(5, 6); + std::ostringstream oss; + oss << tree; + EXPECT_EQ(oss.str(), "{(5, 6)}"); +} + +TEST(AvlIteratorTest, IterationOrder) { + std::vector> pairs{{5, 5}, {3, 3}, {7, 7}, {2, 2}, + {4, 4}, {6, 6}, {8, 8}}; + AvlTree tree(pairs); + + std::vector> result; + for (const auto& kv : tree) { + result.push_back(kv); + } + + std::vector> expected{{2, 2}, {3, 3}, {4, 4}, {5, 5}, + {6, 6}, {7, 7}, {8, 8}}; + + EXPECT_EQ(result, expected); +} + +TEST(AvlIteratorTest, EmptyTree) { + AvlTree empty_tree; + std::vector> result; + for (const auto& kv : empty_tree) { + result.push_back(kv); + } + EXPECT_TRUE(result.empty()); +} + +TEST(AvlIteratorTest, SingleElement) { + AvlTree tree; + tree.Add(5, 6); + std::vector> result; + for (const auto& kv : tree) { + result.push_back(kv); + } + EXPECT_EQ(result.size(), 1); + EXPECT_EQ(result[0].first, 5); + EXPECT_EQ(result[0].second, 6); } + +TEST(AvlIteratorTest, MixedOperations) { + AvlTree tree; + tree.Add(5, 5); + tree.Add(3, 3); + tree.Add(7, 7); + + std::vector> result; + for (const auto& kv : tree) { + result.push_back(kv); + } + + std::vector> expected{{3, 3}, {5, 5}, {7, 7}}; + + EXPECT_EQ(result, expected); + + tree.Del(3); + + result.clear(); + for (const auto& kv : tree) { + result.push_back(kv); + } + + expected = {{5, 5}, {7, 7}}; + + EXPECT_EQ(result, expected); +} \ No newline at end of file diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp new file mode 100644 index 0000000..dad2087 --- /dev/null +++ b/task_08/src/hash_table.cpp @@ -0,0 +1,95 @@ +#include "hash_table.hpp" + +int HashTable::SecondHashFunc(const std::string& key) { return 1; } + +int HashTable::FirstHashFunc(const std::string& key) { + return base_hasher(key); +} + +int HashTable::HashFunc(const std::string& key, int iteration) { + return (FirstHashFunc(key) + iteration * SecondHashFunc(key)) % array.size(); +} + +HashTable::HashTable(size_t size) { + std::vector vec(size); + array = vec; +} + +HashTable::HashTable() { + std::vector vec(20); + array = vec; +} + +HashTable::HashTable(const std::vector>& input) { + std::vector vec(input.size() * 3); + array = vec; + for (const auto& elem : input) { + Add(elem.first, elem.second); + } +} + +int HashTable::FindIndex(const std::string& key) { + for (int i{0}; i < array.size(); ++i) { + int index{HashFunc(key, i)}; + if (array[index].condition == Condition::Empty) { + return -1; + } + if (array[index].condition == Condition::Full && array[index].key == key) { + return index; + } + } + return -1; +} + +void HashTable::Del(const std::string& del_key) { + int index = FindIndex(del_key); + if (index == -1) { + throw HashTableError("key do not exist"); + } + array[index].condition = Condition::Cleared; + full_elements -= 1; + return; +} + +int HashTable::Get(const std::string& key) { + int index = FindIndex(key); + if (index == -1) { + throw HashTableError("key do not exist"); + } + return array[index].value; +} + +void HashTable::Add(const std::string& new_key, int new_value) { + int index = FindIndex(new_key); + if (index != -1) { + array[index].value = new_value; + return; + } + if (full_elements > array.size() / 2) { + UpdateArray(); + } + for (int i{0}; i < array.size(); ++i) { + index = HashFunc(new_key, i); + if (array[index].condition == Condition::Empty || + array[index].condition == Condition::Cleared) { + array[index].key = new_key; + array[index].value = new_value; + array[index].condition = Condition::Full; + full_elements += 1; + return; + } + } + throw HashTableError("full table"); +} + +void HashTable::UpdateArray() { + std::vector old_array = std::move(array); + std::vector new_array(old_array.size() * 2); + array = new_array; + full_elements = 0; + for (const auto& elem : old_array) { + if (elem.condition == Condition::Full) { + Add(elem.key, elem.value); + } + } +} \ No newline at end of file diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp new file mode 100644 index 0000000..27d8505 --- /dev/null +++ b/task_08/src/hash_table.hpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +struct HashTableError : std::runtime_error { + using std::runtime_error::runtime_error; +}; +enum class Condition { Empty, Full, Cleared }; + +struct HashTable { + public: + HashTable(); + HashTable(size_t size); + HashTable(const std::vector>& input); + void Add(const std::string& new_key, int new_value); + void Del(const std::string& del_key); + int Get(const std::string& key); + + private: + struct Element { + public: + Condition condition = Condition::Empty; + std::string key; + int value; + }; + std::vector array; + std::hash base_hasher; + int full_elements = 0; + void UpdateArray(); + int FindIndex(const std::string& key); // находит, если существует + // если нет такого, возвращает -1 + int FirstHashFunc(const std::string& num); + int SecondHashFunc(const std::string& num); + int HashFunc(const std::string& num, int iteration); +}; \ No newline at end of file diff --git a/task_08/src/main.cpp b/task_08/src/main.cpp index 0e4393b..0aadcf2 100644 --- a/task_08/src/main.cpp +++ b/task_08/src/main.cpp @@ -1,3 +1,5 @@ #include +#include "hash_table.hpp" + int main() { return 0; } diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617..9cdc7ec 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,74 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "hash_table.hpp" + +TEST(HashTableTest, Simple) { + HashTable hash_table; + hash_table.Add("f", 5); + hash_table.Add("a", -1); + hash_table.Add("b", 4); + ASSERT_EQ(hash_table.Get("b"), 4); + ASSERT_EQ(hash_table.Get("b"), 4); + ASSERT_EQ(hash_table.Get("a"), -1); + ASSERT_EQ(hash_table.Get("f"), 5); +} + +TEST(HashTableTest, ExceptionLen) { + ASSERT_THROW(HashTable hash_table(-1), std::length_error); +} + +TEST(HashTableTest, ExceptionGet) { + HashTable hash_table; + hash_table.Add("f", 5); + ASSERT_THROW(hash_table.Get("ff"), HashTableError); + hash_table.Add("qw", 8); + ASSERT_EQ(hash_table.Get("f"), 5); + hash_table.Del("f"); + ASSERT_THROW(hash_table.Get("f"), HashTableError); +} + +TEST(HashTableTest, ExceptionDel) { + HashTable hash_table; + hash_table.Add("f", 5); + ASSERT_THROW(hash_table.Del("ff"), HashTableError); +} + +TEST(HashTableTest, ChangeValue) { + HashTable hash_table; + hash_table.Add("42", 42); + ASSERT_EQ(hash_table.Get("42"), 42); + hash_table.Add("42", -42); + ASSERT_EQ(hash_table.Get("42"), -42); +} + +TEST(HashTableTest, RehashingWorks) { + HashTable hash_table(1); + hash_table.Add("one", 1); + hash_table.Add("two", 2); + hash_table.Add("three", 3); + hash_table.Add("four", 4); + + ASSERT_EQ(hash_table.Get("one"), 1); + ASSERT_EQ(hash_table.Get("two"), 2); + ASSERT_EQ(hash_table.Get("three"), 3); + ASSERT_EQ(hash_table.Get("four"), 4); } + +TEST(HashTableTest, ConstructorVector) { + std::vector> data = { + {"a", 1}, {"b", 2}, {"c", 3}}; + HashTable hash_table(data); + + ASSERT_EQ(hash_table.Get("a"), 1); + ASSERT_EQ(hash_table.Get("b"), 2); + ASSERT_EQ(hash_table.Get("c"), 3); +} + +TEST(HashTableTest, AddAfterDel) { + HashTable hash_table; + hash_table.Add("d", 13); + hash_table.Del("d"); + hash_table.Add("d", 0); + ASSERT_EQ(hash_table.Get("d"), 0); +} \ No newline at end of file diff --git a/task_09/src/task.cpp b/task_09/src/task.cpp new file mode 100644 index 0000000..d3fd1b3 --- /dev/null +++ b/task_09/src/task.cpp @@ -0,0 +1,52 @@ +#include "task.hpp" + +#include + +std::vector IsThereSortedColumns( + const std::vector>& matrix, + const std::vector>& l_and_r) { + std::vector> prefixes_from_bools{BuildPrefixes(matrix)}; + std::vector ans{}; + for (auto pair : l_and_r) { + size_t l = pair.first; + size_t r = pair.second; + if (l >= matrix.size() || r >= matrix.size() || l > r) { + throw std::runtime_error("l or r is wrong"); + } + if (l == r) { + ans.push_back(true); + continue; + } + bool is_found{false}; + for (int j{0}; j < matrix[0].size(); ++j) { + if (prefixes_from_bools[r][j] - prefixes_from_bools[l][j] == + static_cast(r - l)) { + is_found = true; + break; + } + } + ans.push_back(is_found); + } + return ans; +} + +std::vector> BuildPrefixes( + const std::vector>& matrix) { + if (matrix.size() == 0) { + throw std::runtime_error("empty matrix"); + } + size_t columns_num = matrix[0].size(); + for (int i{0}; i < matrix.size(); ++i) { + if (matrix[i].size() != columns_num) { + throw std::runtime_error("rows should have same size"); + } + } + std::vector> p(matrix.size(), + std::vector(columns_num, 0)); + for (int i{1}; i < matrix.size(); ++i) { + for (int j{0}; j < columns_num; ++j) { + p[i][j] = p[i - 1][j] + (matrix[i - 1][j] <= matrix[i][j] ? 1 : 0); + } + } + return p; +} diff --git a/task_09/src/task.hpp b/task_09/src/task.hpp new file mode 100644 index 0000000..f8582f0 --- /dev/null +++ b/task_09/src/task.hpp @@ -0,0 +1,9 @@ +#include +#include + +std::vector IsThereSortedColumns( + const std::vector>& matrix, + const std::vector>& l_and_r); + +std::vector> BuildPrefixes( + const std::vector>& matrix); \ No newline at end of file diff --git a/task_09/src/test.cpp b/task_09/src/test.cpp index a42caa4..288e6d6 100644 --- a/task_09/src/test.cpp +++ b/task_09/src/test.cpp @@ -1,23 +1,55 @@ #include -#include - -TEST(CanReachNonDecreasingSegment, 1) { - // ASSERT_EQ(SolveFunction(5, 4, 6, - // std::vector>{{1, 2, 3, 5}, - // {3, 1, 3, 2}, - // {4, 5, 2, 3}, - // {5, 5, 3, 2}, - // {4, 4, 3, 4}}, - // std::vector>{ - // {1, 1}, {2, 5}, {4, 5}, {3, 5}, {1, 3}, {1, - // 5}}), - // (std::vector{"Yes", "No", "Yes", "Yes", "Yes", - // "No"})); +#include "task.hpp" + +TEST(IsThereSortedColumns, Simple) { + std::vector> matrix{{1, 0, 3}, {2, 2, 3}, {1, 0, 2}}; + std::vector> pairs{{0, 2}, {1, 1}, {0, 1}}; + std::vector ans{false, true, true}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); +} + +TEST(IsThereSortedColumns, EmptyMatrix) { + std::vector> matrix; + std::vector> pairs{{0, 0}}; + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} + +TEST(IsThereSortedColumns, WrongRows) { + std::vector> matrix{{1, 2, 3}, {8, 9}}; + std::vector> pairs{{0, 0}}; + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} + +TEST(IsThereSortedColumns, SingleRow) { + std::vector> matrix{{1, 2, 3}}; + std::vector> pairs{{0, 0}}; + std::vector ans{true}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); +} + +TEST(IsThereSortedColumns, OneColumnSorted) { + std::vector> matrix{{5, 1, 3}, {6, 0, 2}, {7, 0, 4}}; + std::vector> pairs{{0, 2}}; + std::vector ans{true}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); } -TEST(CanReachNonDecreasingSegment, 2) { - // ASSERT_EQ(SolveFunction(1, 1, 1, std::vector>{{1, 1}}, - // std::vector>{{1, 1}}), - // (std::vector{"Yes"})); +TEST(IsThereSortedColumns, NoSortedColumns) { + std::vector> matrix{{3, 2, 7}, {2, 3, 5}, {1, 2, 0}}; + std::vector> pairs{{0, 2}, {2, 2}, {1, 2}}; + std::vector ans{false, true, false}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); } + +TEST(IsThereSortedColumns, InvalidRange) { + std::vector> matrix{{1, 2}, {3, 4}}; + std::vector> pairs{{1, 0}}; // l > r + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} + +TEST(IsThereSortedColumns, InvalidRange2) { + std::vector> matrix{{1, 2}, {3, 4}}; + std::vector> pairs{{0, 2}}; // r >= matrix.size() + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} \ No newline at end of file