From 11cfa5493e8b746eb6afe8c2efc641781f717456 Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:14:33 +0000 Subject: [PATCH 1/9] finished task_02 --- task_02/src/stack.cpp | 41 +++++++++++++++++++++++++++++++++-------- task_02/src/stack.hpp | 13 +++++++++---- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp index 8ca89902..31809103 100644 --- a/task_02/src/stack.cpp +++ b/task_02/src/stack.cpp @@ -1,21 +1,46 @@ #include "stack.hpp" #include +#include -void Stack::Push(int value) { data_.push(value); } +void Stack::Push(int value) { + Node* new_top = new Node(); + new_top->value = value; + if (top == nullptr) { + top = new_top; + } else { + new_top->prev = top; + top = new_top; + } +} int Stack::Pop() { - auto result = data_.top(); - data_.pop(); + if (top == nullptr) { + throw std::out_of_range("Stack is out of elements"); + } + int result = top->value; + top = top->prev; return result; } -void MinStack::Push(int value) { data_.push_back(value); } +void MinStack::Push(int value) { + Stack::Push(value); + + Node* new_min_top = new Node(); + if (min_top == nullptr) { + new_min_top->value = value; + min_top = new_min_top; + } else { + new_min_top->value = std::min(value, min_top->value); + new_min_top->prev = min_top; + min_top = new_min_top; + } +} int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); - return result; + int a = Stack::Pop(); + min_top = min_top->prev; + return a; } -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file +int MinStack::GetMin() { return min_top->value; } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 138ec40f..c0d2d621 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -1,23 +1,28 @@ #pragma once -#include #include class Stack { public: + struct Node { + int value; + Node* prev = nullptr; + }; + void Push(int value); int Pop(); private: - std::stack data_; + Node* top = nullptr; }; -class MinStack { +class MinStack : public Stack { public: void Push(int value); int Pop(); int GetMin(); private: - std::vector data_; + Node* top = nullptr; + Node* min_top = nullptr; }; From 570459bf5fd560dce43017fee22c3107695c3b5f Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:50:14 +0000 Subject: [PATCH 2/9] task_03 finished --- task_03/src/test.cpp | 19 ++++++++++++++++++- task_03/src/topology_sort.cpp | 28 ++++++++++++++++++++++++++++ task_03/src/topology_sort.hpp | 4 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index ef5a86ae..bd46a048 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,8 +1,25 @@ #include +#include + #include "topology_sort.hpp" TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] + ASSERT_EQ(find_higher_temp({0, 2, 6, 4, 8, 4, 6, 0, 3, -3, -2, -6, 1}), + std::vector({1, 1, 2, 1, 0, 1, 0, 1, 0, 1, 2, 1, 0})); + ASSERT_EQ(find_higher_temp({0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0}), + std::vector({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0})); + ASSERT_EQ(find_higher_temp({0, 1, -1, 0, 1, -1, 0, 1}), + std::vector({1, 0, 1, 1, 0, 1, 1, 0})); + ASSERT_EQ(find_higher_temp({1}), std::vector({0})); + ASSERT_EQ(find_higher_temp({-1, -1, -1, -3, -3, -3, -2, -2, -2, 0, 0, 0}), + std::vector({9, 8, 7, 3, 2, 1, 3, 2, 1, 0, 0, 0})); + ASSERT_EQ(find_higher_temp({0, 0, 0, 0, 0, 0, 0}), + std::vector({0, 0, 0, 0, 0, 0, 0})); + ASSERT_EQ(find_higher_temp({}), + std::vector({})); + ASSERT_EQ(find_higher_temp({1, 5, 2, 3, 4, 0}), + std::vector({1, 0, 1, 1, 0, 0})); + } diff --git a/task_03/src/topology_sort.cpp b/task_03/src/topology_sort.cpp index e53f670c..0ccc7c36 100644 --- a/task_03/src/topology_sort.cpp +++ b/task_03/src/topology_sort.cpp @@ -1 +1,29 @@ #include "topology_sort.hpp" + +#include +#include +#include + +std::vector find_higher_temp(std::vector temp_list) { + if (temp_list.size() == 0) { + return {}; + } + + std::vector ans_vect = std::vector(temp_list.size(), 0); + std::stack day_stack; + + for (int i_day = temp_list.size() - 1; i_day >= 0; i_day--) { + while (!day_stack.empty()) { + if (temp_list[day_stack.top()] <= temp_list[i_day]) { + day_stack.pop(); + } else { + break; + } + } + if (!day_stack.empty()) { + ans_vect[i_day] = day_stack.top() - i_day; + } + day_stack.push(i_day); + } + return ans_vect; +} \ No newline at end of file diff --git a/task_03/src/topology_sort.hpp b/task_03/src/topology_sort.hpp index 6f70f09b..64beba1b 100644 --- a/task_03/src/topology_sort.hpp +++ b/task_03/src/topology_sort.hpp @@ -1 +1,5 @@ #pragma once + +#include + +std::vector find_higher_temp(std::vector temp_vect); \ No newline at end of file From d3c7d74035741165b00c24c48cbe1c03e6fdb5e0 Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:16:12 +0000 Subject: [PATCH 3/9] task_04 finished --- task_04/src/bin_heap.cpp | 103 +++++++++++++++++++++++++++++++++++++++ task_04/src/bin_heap.hpp | 29 +++++++++++ task_04/src/test.cpp | 35 +++++++++++-- 3 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 task_04/src/bin_heap.cpp create mode 100644 task_04/src/bin_heap.hpp diff --git a/task_04/src/bin_heap.cpp b/task_04/src/bin_heap.cpp new file mode 100644 index 00000000..01ae95ee --- /dev/null +++ b/task_04/src/bin_heap.cpp @@ -0,0 +1,103 @@ +#include "bin_heap.hpp" + +#include + +BinHeap::BinHeap() { + heap = {}; + size = 0; +} + +BinHeap::BinHeap(std::vector list) { + heap = list; + size = list.size(); + heapify(); +} + +std::vector BinHeap::get_heap() { return heap; } + +void BinHeap::swap(int i, int j) { + if (i >= size or i < 0 or j >= size or j < 0) { + throw std::range_error("swap: indexes must be in range"); + } + + int i_val = heap[i]; + heap[i] = heap[j]; + heap[j] = i_val; +} + +void BinHeap::swap(int i, char key) { + if (key != 'l' and key != 'r') { + throw std::invalid_argument("swap: Key must be 'l' or 'r'"); + } + + if (key == 'l') { + swap(i, i * 2 + 1); + } + if (key == 'r') { + swap(i, i * 2 + 2); + } +} + +void BinHeap::heapify() { + for (int i = size / 2 - 1; i >= 0; i--) { + heapify(i); + } +} + +void BinHeap::heapify(int i) { + if (i >= size or i < 0) { + return; + } + + int l = 2 * i + 1; + int r = 2 * i + 2; + int largest = i; + if (l < size and heap[l] > heap[largest]) { + largest = l; + } + if (r < size and heap[r] > heap[largest]) { + largest = r; + } + if (largest != i) { + swap(i, largest); + heapify(largest); + } +} + +void BinHeap::insert_key_value(int key, int value) { + if (key >= size or key < 0) { + throw std::range_error("insert_key_value: index must be in range"); + } + + if (value <= heap[key]) { + heap[key] = value; + heapify(key); + + } else { + heap[key] = value; + for (int i = key; i > 0 and heap[i] > heap[(i - 1) / 2]; i = (i - 1) / 2) { + swap(i, (i - 1) / 2); + } + } +} + +void BinHeap::push_value(int value) { + size++; + heap.push_back(std::numeric_limits::lowest()); + insert_key_value(size - 1, value); +} + +int BinHeap::pop_max() { + if (size < 1) { + throw std::length_error("pop_max: heap is empty"); + } + + int max_value = heap[0]; + heap[0] = heap[size - 1]; + heap.pop_back(); + size -= 1; + + heapify(0); + + return max_value; +} diff --git a/task_04/src/bin_heap.hpp b/task_04/src/bin_heap.hpp new file mode 100644 index 00000000..1ab5b6df --- /dev/null +++ b/task_04/src/bin_heap.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +class BinHeap { + public: + std::vector heap; + int size; + + BinHeap(); + BinHeap(std::vector list); + + std::vector get_heap(); + + void insert_key_value(int key, int value); + void push_value(int value); + int pop_max(); + + private: + void swap(int i, int j); // heap[i] <-> heap[j] + void swap( + int i, + char key); // swaps heap[i] with his left ('l') or right ('r') child + + void heapify(); // make whole heap a binary heap + void heapify(int i); // fix heap to be a binart heap (at 'i') +}; diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 5e11617e..5f74e253 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,6 +1,35 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "bin_heap.hpp" + +TEST(BinHeap, Simple) { + BinHeap heap1({1, 2, 3, 4, 5, 6, 7}); + ASSERT_EQ(heap1.get_heap(), std::vector({7, 5, 6, 4, 2, 1, 3})); + heap1.push_value(8); + heap1.push_value(3); + heap1.push_value(3); + ASSERT_EQ(heap1.pop_max(), 8); + heap1.insert_key_value(0, 11); + ASSERT_EQ(heap1.pop_max(), 11); + heap1.insert_key_value(7, 20); + ASSERT_EQ(heap1.pop_max(), 20); + ASSERT_EQ(heap1.get_heap(), std::vector({6, 5, 3, 4, 3, 1, 3})); + heap1.insert_key_value(4, -13); + heap1.insert_key_value(4, 7); + ASSERT_EQ(heap1.get_heap(), std::vector({7, 6, 3, 4, 5, 1, 3})); + + BinHeap heap2({0}); + ASSERT_EQ(heap2.pop_max(), 0); + ASSERT_ANY_THROW(heap2.pop_max()); + heap2.push_value(13); + heap2.push_value(13); + heap2.push_value(13); + heap2.push_value(14); + heap2.push_value(13); + heap2.push_value(13); + heap2.insert_key_value(0, 13); + ASSERT_EQ(heap2.pop_max(), 13); + ASSERT_EQ(heap2.get_heap(), std::vector({13, 13, 13, 13, 13})); } From 7e202aeafe49a4249322e15fa9329f434bbd1850 Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:14:15 +0000 Subject: [PATCH 4/9] task_05 --- task_04/src/bin_heap.cpp | 1 + task_05/src/sorts.cpp | 127 +++++++++++++++++++++++++++++++++++++++ task_05/src/sorts.hpp | 25 ++++++++ task_05/src/test.cpp | 63 ++++++++++++++++++- 4 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 task_05/src/sorts.cpp create mode 100644 task_05/src/sorts.hpp diff --git a/task_04/src/bin_heap.cpp b/task_04/src/bin_heap.cpp index 01ae95ee..8222a8e1 100644 --- a/task_04/src/bin_heap.cpp +++ b/task_04/src/bin_heap.cpp @@ -2,6 +2,7 @@ #include + BinHeap::BinHeap() { heap = {}; size = 0; diff --git a/task_05/src/sorts.cpp b/task_05/src/sorts.cpp new file mode 100644 index 00000000..bf7d38d1 --- /dev/null +++ b/task_05/src/sorts.cpp @@ -0,0 +1,127 @@ +#include "sorts.hpp" + +#include +#include + +void SORT::swap(std::vector &A, int i, int j) { + int i_val = A[i]; + A[i] = A[j]; + A[j] = i_val; +} + +void SORT::heapify(std::vector &A, int h_size, int i) { + int l = 2 * i + 1; + int r = 2 * i + 2; + int largest = i; + if (l < h_size and A[l] > A[largest]) { + largest = l; + } + if (r < h_size and A[r] > A[largest]) { + largest = r; + } + if (largest != i) { + swap(A, i, largest); + heapify(A, h_size, largest); + } +} + +void SORT::heapsort(std::vector &list) { + // build_heap + + int h_size = list.size(); + for (int i = h_size / 2 - 1; i >= 0; i--) { + heapify(list, h_size, i); + } + + for (int i = h_size - 1; i >= 0; i--) { + swap(list, 0, i); + h_size--; + heapify(list, h_size, 0); + } +} + +std::vector SORT::heapsorted(std::vector list) { + heapsort(list); + return list; +} + +int SORT::partition(std::vector &A, int start, int end) { + int pivot = A[end]; + + int swapIndex = start; + + for (int i = start; i < end; i++) { + if (A[i] <= pivot) { + swap(A, i, swapIndex); + swapIndex++; + } + } + + swap(A, swapIndex, end); + + return swapIndex; +} + +void SORT::quicksort(std::vector &list) { + quicksort(list, 0, list.size() - 1); +} + +void SORT::quicksort(std::vector &list, int start, int end) { + if (start >= end) { + return; + } + + int pivot = partition(list, start, end); + + quicksort(list, start, pivot - 1); + + quicksort(list, pivot + 1, end); +} + +std::vector SORT::quicksorted(std::vector list) { + quicksort(list); + return list; +} + +void SORT::sort_and_merge(std::vector &A, int start, int end) { + if (start >= end) { + throw std::range_error( + "sort_and_merge: start of a vector must be before an end"); + } + + int mid = (start + end) / 2; + std::vector left(A.begin() + start, A.begin() + mid + 1); + std::vector right(A.begin() + mid + 1, A.begin() + end + 1); + + int L = 0; + int R = 0; + for (int i = start; i <= end; i++) { + if (!(mid + 1 + R <= end) or (left[L] <= right[R] and start + L <= mid)) { + A[i] = left[L]; + L++; + } else { + A[i] = right[R]; + R++; + } + } +} + +void SORT::mergesort(std::vector &list) { + mergesort(list, 0, list.size() - 1); +} + +void SORT::mergesort(std::vector &list, int start, int end) { + if (start >= end) { + return; + } + + int mid = (start + end) / 2; + mergesort(list, start, mid); + mergesort(list, mid + 1, end); + sort_and_merge(list, start, end); +} + +std::vector SORT::mergesorted(std::vector list) { + mergesort(list); + return list; +} \ No newline at end of file diff --git a/task_05/src/sorts.hpp b/task_05/src/sorts.hpp new file mode 100644 index 00000000..1ffa0e45 --- /dev/null +++ b/task_05/src/sorts.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +class SORT { + public: + SORT(){}; + + void heapsort(std::vector &list); + std::vector heapsorted(std::vector list); + + void quicksort(std::vector &list); + void quicksort(std::vector &list, int start, int end); + std::vector quicksorted(std::vector list); + + void mergesort(std::vector &list); + void mergesort(std::vector &list, int start, int end); + std::vector mergesorted(std::vector list); + + private: + void swap(std::vector &A, int i, int j); + void heapify(std::vector &A, int h_size, int i); + int partition(std::vector &A, int start, int end); + void sort_and_merge(std::vector &A, int start, int end); +}; diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617e..60037372 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,65 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "sorts.hpp" + +TEST(Sorts, Simple) { + SORT sort; + + std::vector temp; + + std::vector list1 = {1, 2, 6, 5, 3, 4}; + std::vector list2 = {0, 5, 0, -1, -2, -3, 10, 7}; + std::vector list3 = {}; + std::vector list4 = {0}; + + // HEAPSORT + // ----------------------------------------------------------------- + ASSERT_EQ(sort.heapsorted(list1), std::vector({1, 2, 3, 4, 5, 6})); + ASSERT_EQ(list1, std::vector({1, 2, 6, 5, 3, 4})); + + temp = list2; + sort.heapsort(temp); + ASSERT_EQ(temp, std::vector({-3, -2, -1, 0, 0, 5, 7, 10})); + ASSERT_EQ(list2, std::vector({0, 5, 0, -1, -2, -3, 10, 7})); + + ASSERT_EQ(sort.heapsorted(list3), std::vector()); + ASSERT_EQ(list3, std::vector({})); + + sort.heapsort(list4); + ASSERT_EQ(list4, std::vector({0})); + + // QUICK SORT + // ----------------------------------------------------------------- + ASSERT_EQ(sort.quicksorted(list1), std::vector({1, 2, 3, 4, 5, 6})); + ASSERT_EQ(list1, std::vector({1, 2, 6, 5, 3, 4})); + + temp = list2; + sort.quicksort(temp); + ASSERT_EQ(temp, std::vector({-3, -2, -1, 0, 0, 5, 7, 10})); + ASSERT_EQ(list2, std::vector({0, 5, 0, -1, -2, -3, 10, 7})); + + ASSERT_EQ(sort.quicksorted(list3), std::vector()); + ASSERT_EQ(list3, std::vector({})); + + sort.quicksort(list4); + ASSERT_EQ(list4, std::vector({0})); + + // MERGE SORT + // ----------------------------------------------------------------- + ASSERT_EQ(sort.mergesorted(list1), std::vector({1, 2, 3, 4, 5, 6})); + ASSERT_EQ(list1, std::vector({1, 2, 6, 5, 3, 4})); + + temp = list2; + sort.mergesort(temp); + ASSERT_EQ(temp, std::vector({-3, -2, -1, 0, 0, 5, 7, 10})); + ASSERT_EQ(list2, std::vector({0, 5, 0, -1, -2, -3, 10, 7})); + + ASSERT_EQ(sort.mergesorted(list3), std::vector()); + ASSERT_EQ(list3, std::vector({})); + + sort.mergesort(list4); + ASSERT_EQ(list4, std::vector({0})); } From 64bec26f36567d61f7919e438a80dcaa38561910 Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:43:20 +0000 Subject: [PATCH 5/9] task_06 --- task_06/src/n_statistic.cpp | 51 +++++++++++++++++++++++++++++++++++++ task_06/src/n_statistic.hpp | 9 +++++++ task_06/src/test.cpp | 34 +++++++++++++++++++++++-- 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 task_06/src/n_statistic.cpp create mode 100644 task_06/src/n_statistic.hpp diff --git a/task_06/src/n_statistic.cpp b/task_06/src/n_statistic.cpp new file mode 100644 index 00000000..ceebbcf2 --- /dev/null +++ b/task_06/src/n_statistic.cpp @@ -0,0 +1,51 @@ +#include "n_statistic.hpp" + +#include + +int findNstat(std::vector list, int n) { + if (list.size() == 0) { + throw std::length_error("findNstat: empty vector given"); + } + + if (n >= list.size() or n < 0) { + throw std::out_of_range("findNstat: n must be in range of given vector"); + } + + int start = 0; + int end = list.size() - 1; + + while (true) { + int mid = partition(list, start, end); + + if (mid == n) { + return list[mid]; + } else if (n < mid) { + end = mid - 1; + } else { + start = mid; + } + } +} + +void swap(std::vector &A, int i, int j) { + int i_val = A[i]; + A[i] = A[j]; + A[j] = i_val; +} + +int partition(std::vector &A, int start, int end) { + int pivot = A[end]; + + int swapIndex = start; + + for (int i = start; i < end; i++) { + if (A[i] <= pivot) { + swap(A, i, swapIndex); + swapIndex++; + } + } + + swap(A, swapIndex, end); + + return swapIndex; +} \ No newline at end of file diff --git a/task_06/src/n_statistic.hpp b/task_06/src/n_statistic.hpp new file mode 100644 index 00000000..e462d251 --- /dev/null +++ b/task_06/src/n_statistic.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +int findNstat(std::vector list, int n); + +void swap(std::vector &A, int i, int j); + +int partition(std::vector &A, int start, int end); \ No newline at end of file diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617e..8924ee14 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,36 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "n_statistic.hpp" + +TEST(N_th_Statistic, Simple) { + std::vector temp; + + std::vector list1 = {1, 2, 6, 5, 3, 4}; + std::vector list2 = {0, 5, 0, -1, -2, -3, 10, 7}; + std::vector list3 = {}; + std::vector list4 = {0}; + + // HEAPSORT + // ----------------------------------------------------------------- + ASSERT_EQ(findNstat(list1, 3), 4); + ASSERT_EQ(list1, std::vector({1, 2, 6, 5, 3, 4})); + + ASSERT_EQ(findNstat(list1, 1), 2); + ASSERT_EQ(findNstat(list1, list1.size() - 1), 6); + ASSERT_EQ(list1, std::vector({1, 2, 6, 5, 3, 4})); + + ASSERT_EQ(findNstat(list2, 2), -1); + ASSERT_EQ(list2, std::vector({0, 5, 0, -1, -2, -3, 10, 7})); + ASSERT_EQ(findNstat(list2, 7), 10); + ASSERT_THROW(findNstat(list2, 10), std::out_of_range); + ASSERT_EQ(findNstat(list2, 4), 0); + + ASSERT_THROW(findNstat(list3, 4), std::length_error); + ASSERT_THROW(findNstat(list3, 0), std::length_error); + + ASSERT_EQ(findNstat(list4, 0), 0); + ASSERT_THROW(findNstat(list4, 1), std::out_of_range); } From c1f51a7dab46807a8d9d94a08aa00113d2842ccb Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:07:13 +0000 Subject: [PATCH 6/9] task_07 --- task_07/src/AVL_tree.cpp | 131 +++++++++++++++++++++++++++++++++++++++ task_07/src/AVL_tree.hpp | 35 +++++++++++ task_07/src/test.cpp | 29 ++++++++- 3 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 task_07/src/AVL_tree.cpp create mode 100644 task_07/src/AVL_tree.hpp diff --git a/task_07/src/AVL_tree.cpp b/task_07/src/AVL_tree.cpp new file mode 100644 index 00000000..588a9e09 --- /dev/null +++ b/task_07/src/AVL_tree.cpp @@ -0,0 +1,131 @@ +#include "AVL_tree.hpp" + +void AVL_tree::push(int value) { root = insert(root, value); } + +void AVL_tree::pop(int value) { root = remove(root, value); } + +bool AVL_tree::contains(int value) { + Node* node = find(root, value); + if (node == nullptr) { + return false; + } + if (node->value == value) { + return true; + } + throw std::logic_error("contains: unreachable error"); +} + +unsigned int AVL_tree::height(Node* node) { + if (node == nullptr) { + return 0; + } + return node->height; +} + +int AVL_tree::balance_coeff(Node* node) { + return height(node->right) - height(node->left); +} + +void AVL_tree::update_height(Node* node) { + unsigned int height_l = height(node->left); + unsigned int height_r = height(node->right); + node->height = std::max(height_l, height_r) + 1; +} + +AVL_tree::Node* AVL_tree::rotate_right(Node* node) { + Node* l_node = node->left; + node->left = l_node->right; + l_node->right = node; + update_height(node); + update_height(l_node); + return l_node; +} + +AVL_tree::Node* AVL_tree::rotate_left(Node* node) { + Node* r_node = node->right; + node->right = r_node->left; + r_node->left = node; + update_height(node); + update_height(r_node); + return r_node; +} + +AVL_tree::Node* AVL_tree::balance(Node* node) { + update_height(node); + if (balance_coeff(node) == 2) { + if (balance_coeff(node->right) < 0) { + node->right = rotate_right(node->right); + } + return rotate_left(node); + } + if (balance_coeff(node) == -2) { + if (balance_coeff(node->left) > 0) { + node->left = rotate_left(node->left); + } + return rotate_right(node); + } + return node; +} + +AVL_tree::Node* AVL_tree::insert(Node* node, int val) { + if (node == nullptr) { + return new Node(val); + } + if (val < node->value) { + node->left = insert(node->left, val); + } else { + node->right = insert(node->right, val); + } + return balance(node); +} + +AVL_tree::Node* AVL_tree::find_min(Node* node) { + if (node->left == nullptr) { + return node; + } + return find_min(node->left); +} + +AVL_tree::Node* AVL_tree::remove_min(Node* node) { + if (node->left == nullptr) return node->right; + node->left = remove_min(node->left); + return balance(node); +} + +AVL_tree::Node* AVL_tree::find(Node* node, int val) { + if (node == nullptr) { + return nullptr; + } + if (val < node->value) { + return find(node->left, val); + } + if (val > node->value) { + return find(node->right, val); + } + return node; +} + +AVL_tree::Node* AVL_tree::remove(Node* node, int val) { + if (node == nullptr) { + return 0; + } + if (val < node->value) { + node->left = remove(node->left, val); + return balance(node); + } else if (val > node->value) { + node->right = remove(node->right, val); + return balance(node); + } else { + Node* l_node = node->left; + Node* r_node = node->right; + delete node; + + if (r_node == nullptr) { + return l_node; + } + Node* min_node = find_min(r_node); + min_node->right = remove_min(r_node); + min_node->left = l_node; + return balance(min_node); + } +} \ 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 00000000..db58d673 --- /dev/null +++ b/task_07/src/AVL_tree.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +class AVL_tree { + public: + void push(int value); + void pop(int value); + bool contains(int value); + + struct Node { + int value; + unsigned int height = 1; + + Node* left = nullptr; + Node* right = nullptr; + Node(int val) : value{val} {}; + }; + + private: + Node* root = nullptr; + + unsigned int height(Node* node); + int balance_coeff(Node* node); + void update_height(Node* node); + Node* rotate_right(Node* node); + Node* rotate_left(Node* node); + Node* balance(Node* node); + Node* insert(Node* node, int val); + Node* find_min(Node* node); + Node* remove_min(Node* node); + Node* find(Node* node, int val); + Node* remove(Node* node, int val); +}; \ No newline at end of file diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617e..49f3c6e3 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,31 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "AVL_tree.hpp" + +TEST(avlTree, Simple) { + AVL_tree tree; + + ASSERT_EQ(tree.contains(0), false); + ASSERT_EQ(tree.contains(-24124), false); + + tree.push(1); + tree.push(123); + tree.push(-1); + tree.push(1); + + ASSERT_EQ(tree.contains(-1), true); + ASSERT_EQ(tree.contains(0), false); + + ASSERT_EQ(tree.contains(1), true); + tree.pop(1); + ASSERT_EQ(tree.contains(1), true); + tree.pop(1); + ASSERT_EQ(tree.contains(1), false); + tree.pop(1); + + ASSERT_EQ(tree.contains(1), false); + ASSERT_EQ(tree.contains(123), true); + ASSERT_EQ(tree.contains(-1), true); + ASSERT_EQ(tree.contains(1), false); } From 2e3576a2302c81cf08f44b381b361b173e27df99 Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:04:08 +0000 Subject: [PATCH 7/9] task_08 --- task_08/src/hash_table.cpp | 125 +++++++++++++++++++++++++++++++++++++ task_08/src/hash_table.hpp | 40 ++++++++++++ task_08/src/test.cpp | 25 +++++++- 3 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 task_08/src/hash_table.cpp create mode 100644 task_08/src/hash_table.hpp diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp new file mode 100644 index 00000000..09e210b5 --- /dev/null +++ b/task_08/src/hash_table.cpp @@ -0,0 +1,125 @@ +#include "hash_table.hpp" + +#include + +int HashFunctionHorner(const std::string& s, int table_size, const int key) { + int hash_result = 0; + for (int i = 0; i <= s.size(); ++i) { + hash_result = (key * hash_result + s[i]) % table_size; + } + hash_result = (hash_result * 2 + 1) % table_size; + return hash_result; +} + +int HashTable::HashFunction1(const std::string& s, int table_size) { + return HashFunctionHorner(s, table_size, table_size - 1); +} + +int HashTable::HashFunction2(const std::string& s, int table_size) { + return HashFunctionHorner(s, table_size, table_size + 1); +} + +HashTable::HashTable() + : size{0}, + buffer_size{default_size}, + cells_in_use{0}, + list{std::vector(default_size, nullptr)} {} + +HashTable::~HashTable() { + for (int i = 0; i < buffer_size; ++i) { + if (list[i] != nullptr) { + delete list[i]; + } + } +} + +bool HashTable::Add(const str& value) { + if (size + 1 > int(rehash_size * buffer_size)) { + Increase_Size(); + } else if (cells_in_use > 2 * size) { + Rehash(); + } + + int pos_h = HashFunction1(value, buffer_size); + int step_h = HashFunction2(value, buffer_size); + + for (int i = 0; (list[pos_h] != nullptr) and i < buffer_size; i++) { + if (list[pos_h]->value == value and list[pos_h]->state) { + return false; // value already in table + } + if (!list[pos_h]->state) { // first pos that is empty (node was deleted) + list[pos_h]->state = true; + list[pos_h]->value = value; + size++; + return true; + } + pos_h = (pos_h + step_h) % buffer_size; + } + list[pos_h] = new Node(value); + cells_in_use++; + size++; + return true; +} + +bool HashTable::Remove(const str& value) { + int pos_h = HashFunction1(value, buffer_size); + int step_h = HashFunction2(value, buffer_size); + + for (int i = 0; (list[pos_h] != nullptr) and i < buffer_size; i++) { + if (list[pos_h]->value == value and list[pos_h]->state) { + list[pos_h]->state = false; + size--; + return true; + } + pos_h = (pos_h + step_h) % buffer_size; + } + return false; +} + +bool HashTable::Find(const str& value) { + int pos_h = HashFunction1(value, buffer_size); + int step_h = HashFunction2(value, buffer_size); + for (int i = 0; (list[pos_h] != nullptr) and i < buffer_size; i++) { + if (list[pos_h]->value == value and list[pos_h]->state) { + return true; + } + pos_h = (pos_h + step_h) % buffer_size; + } + return false; +} + +void HashTable::Increase_Size() { + int past_buffer_size = buffer_size; + buffer_size *= 2; + cells_in_use = 0; + size = 0; + + std::vector list2(buffer_size, nullptr); + std::swap(list, list2); + + for (int i = 0; i < past_buffer_size; ++i) { + if (list2[i] != nullptr) { + if (list2[i]->state) { + Add(list2[i]->value); + } + delete list2[i]; + } + } +} + +void HashTable::Rehash() { + cells_in_use = 0; + size = 0; + + std::vector list2(buffer_size, nullptr); + std::swap(list, list2); + + for (int i = 0; i < buffer_size; i++) { + if (list2[i] != nullptr) { + if (list2[i]->state) { + Add(list2[i]->value); + } + delete list2[i]; + } + } +} \ 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 00000000..54060761 --- /dev/null +++ b/task_08/src/hash_table.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +using str = std::string; + +int HashFunctionHorner(const str& s, int table_size, const int key); + +class HashTable { + static const int default_size = 8; + constexpr static const double rehash_size = 0.75; + + public: + HashTable(); + ~HashTable(); + bool Add(const str& value); + bool Remove(const str& value); + bool Find(const str& value); + + private: + struct Node { + std::string value; + bool state; + Node(const std::string& val) : value{val}, state{true} {} + Node() : state{false} {} + }; + + std::vector list; + int size; // amount of values in table + int buffer_size; // self explanatory + int cells_in_use; // amount of cells that are filled (even deleted values) + + int HashFunction1(const std::string& s, int table_size); + int HashFunction2(const std::string& s, int table_size); + + void Increase_Size(); + void Rehash(); +}; \ No newline at end of file diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617e..29e36ed2 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,27 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "hash_table.hpp" + +TEST(HashTable, Simple) { + HashTable table; + + ASSERT_EQ(table.Find("adasdaw"), false); + ASSERT_EQ(table.Find(""), false); + + ASSERT_EQ(table.Add("abcd"), true); + ASSERT_EQ(table.Add("abcd"), false); + ASSERT_EQ(table.Add("bcda"), true); + ASSERT_EQ(table.Add("cdab"), true); + ASSERT_EQ(table.Add("dabc"), true); + + ASSERT_EQ(table.Find("abcd"), true); + ASSERT_EQ(table.Find("BCDA"), false); + ASSERT_EQ(table.Remove("dabc"), true); + ASSERT_EQ(table.Find("dabc"), false); + ASSERT_EQ(table.Remove("DDDD"), false); + ASSERT_EQ(table.Find("DDDD"), false); + ASSERT_EQ(table.Add("abcd"), false); + ASSERT_EQ(table.Find("abcd"), true); + } From e6328586aed9daf98dc460759341597baba784fc Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Fri, 14 Jun 2024 20:15:39 +0000 Subject: [PATCH 8/9] task_09 --- task_09/src/change_cash.cpp | 24 ++++++++++++++++++++++++ task_09/src/change_cash.hpp | 7 +++++++ task_09/src/test.cpp | 26 +++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 task_09/src/change_cash.cpp create mode 100644 task_09/src/change_cash.hpp diff --git a/task_09/src/change_cash.cpp b/task_09/src/change_cash.cpp new file mode 100644 index 00000000..82d912f2 --- /dev/null +++ b/task_09/src/change_cash.cpp @@ -0,0 +1,24 @@ +#include "change_cash.hpp" + +#include +#include + +unsigned int min_change_count(std::vector coins, + unsigned int amount) { + unsigned int inf = std::numeric_limits::max(); + + std::vector money(amount + 1, inf); + money[0] = 0; + + for (unsigned int summ = 1; summ <= amount; summ++) { + for (unsigned int coin : coins) { + if (coin <= summ and money[summ - coin] != inf) { + money[summ] = std::min(money[summ], money[summ - coin] + 1); + } + } + } + if (money[amount] == inf) { + return -1; + } + return money[amount]; +} \ No newline at end of file diff --git a/task_09/src/change_cash.hpp b/task_09/src/change_cash.hpp new file mode 100644 index 00000000..def41fab --- /dev/null +++ b/task_09/src/change_cash.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include +#include + +unsigned int min_change_count(std::vector coins, + unsigned int amount); \ No newline at end of file diff --git a/task_09/src/test.cpp b/task_09/src/test.cpp index 869094dd..0368f50a 100644 --- a/task_09/src/test.cpp +++ b/task_09/src/test.cpp @@ -1,4 +1,28 @@ #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include + +#include "change_cash.hpp" + +TEST(ChangeCahs, Simple) { + std::vector nominals_1 = {1, 2, 5, 10, 100}; + std::vector nominals_2 = {2, 16, 64, 1024}; + std::vector nominals_3 = {}; + + ASSERT_EQ(min_change_count(nominals_1, 1), 1); + ASSERT_EQ(min_change_count(nominals_2, 1), -1); + ASSERT_EQ(min_change_count(nominals_3, 1), -1); + + ASSERT_EQ(min_change_count(nominals_1, 86), 10); + ASSERT_EQ(min_change_count(nominals_2, 86), 5); + ASSERT_EQ(min_change_count(nominals_3, 86), -1); + + ASSERT_EQ(min_change_count(nominals_1, 13), 3); + ASSERT_EQ(min_change_count(nominals_2, 13), -1); + ASSERT_EQ(min_change_count(nominals_3, 13), -1); + + ASSERT_EQ(min_change_count(nominals_1, 0), 0); + ASSERT_EQ(min_change_count(nominals_2, 0), 0); + ASSERT_EQ(min_change_count(nominals_3, 0), 0); +} From 06560b27530b503a01241a5c38bebfd839b3124e Mon Sep 17 00:00:00 2001 From: XehiDat <63257446+ZetroRetro@users.noreply.github.com> Date: Fri, 14 Jun 2024 20:27:13 +0000 Subject: [PATCH 9/9] format fixing --- task_03/src/test.cpp | 5 ++--- task_04/src/bin_heap.cpp | 3 --- task_08/src/test.cpp | 1 - 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index bd46a048..23e8ca37 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,6 +1,7 @@ #include +#include #include #include "topology_sort.hpp" @@ -17,9 +18,7 @@ TEST(TopologySort, Simple) { std::vector({9, 8, 7, 3, 2, 1, 3, 2, 1, 0, 0, 0})); ASSERT_EQ(find_higher_temp({0, 0, 0, 0, 0, 0, 0}), std::vector({0, 0, 0, 0, 0, 0, 0})); - ASSERT_EQ(find_higher_temp({}), - std::vector({})); + ASSERT_EQ(find_higher_temp({}), std::vector({})); ASSERT_EQ(find_higher_temp({1, 5, 2, 3, 4, 0}), std::vector({1, 0, 1, 1, 0, 0})); - } diff --git a/task_04/src/bin_heap.cpp b/task_04/src/bin_heap.cpp index 8222a8e1..6c559820 100644 --- a/task_04/src/bin_heap.cpp +++ b/task_04/src/bin_heap.cpp @@ -1,8 +1,5 @@ #include "bin_heap.hpp" -#include - - BinHeap::BinHeap() { heap = {}; size = 0; diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 29e36ed2..9a6264ed 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -23,5 +23,4 @@ TEST(HashTable, Simple) { ASSERT_EQ(table.Find("DDDD"), false); ASSERT_EQ(table.Add("abcd"), false); ASSERT_EQ(table.Find("abcd"), true); - }