Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion task_01/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#include <iostream>

int main() { return 0; }
#include "solution.hpp"

int main() {
std::cout << (BinarySearchGEQ({1, 2, 3, 4, 5}, 1, 0, 4) == 0) << std::endl;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]

Suggested change
std::cout << (BinarySearchGEQ({1, 2, 3, 4, 5}, 1, 0, 4) == 0) << std::endl;
std::cout << (BinarySearchGEQ({1, 2, 3, 4, 5}, 1, 0, 4) == 0) << '\n';

std::cout << (BinarySearchGEQ({1, 2, 3, 4, 5}, 5, 0, 4) == 4)
<< std::endl; // Stack []
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]

Suggested change
<< std::endl; // Stack []
<< '\n'; // Stack []

}
40 changes: 40 additions & 0 deletions task_01/src/solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "solution.hpp"

#include <stdexcept>

// Binary search for greater-or-equal element
// Explicitly requires <left> and <right> bounds to support searching in
// subarray
int BinarySearchGEQ(const std::vector<int>& arr, int target, int left,
int right) {
while (left < right) {
int mid = left + (right - left) / 2;
if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}

// Custom error code
struct PairNotFound {};

/*
* Algorithm description:
* run <left> index over array
* search for <right> that is greater or equal to <target - arr[left]>
* ! seach range is (<left>, <right>]
*/
std::pair<int, int> FindPairMatchSum(const std::vector<int>& arr, int target) {
unsigned int left = 0;
unsigned int right =
BinarySearchGEQ(arr, target - arr[left], 0, arr.size() - 1);
while (left < arr.size() - 1 && arr[left] + arr[left + 1] <= target) {
if (arr[left] + arr[right] == target) return {arr[left], arr[right]};
left += 1;
right = BinarySearchGEQ(arr, target - arr[left], left, right);
}
throw std::runtime_error("Failed to find suiable pair");
}
11 changes: 11 additions & 0 deletions task_01/src/solution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef SOLUTION_HPP
#define SOLUTION_HPP

#include <utility>
#include <vector>

std::pair<int, int> FindPairMatchSum(const std::vector<int>& arr, int target);
int BinarySearchGEQ(const std::vector<int>& arr, int target, int left,
int right);

#endif
94 changes: 91 additions & 3 deletions task_01/src/test.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,93 @@
#include <gtest/gtest.h>

TEST(Test, Simple) {
ASSERT_EQ(1, 1); // Stack []
}
#include <algorithm>
#include <random>
#include <vector>

#include "solution.hpp"

TEST(BinarySearchSubtest, EdgeCases) {
ASSERT_EQ(BinarySearchGEQ({1, 2, 3, 4, 5}, 1, 0, 4), 0); // Stack []
ASSERT_EQ(BinarySearchGEQ({1, 2, 3, 4, 5}, 5, 0, 4), 4); // Stack []
}
TEST(BinarySearchSubtest, MiddleCases) {
ASSERT_EQ(BinarySearchGEQ({0, 1, 2, 3, 4, 5}, 3, 0, 5), 3); // Stack []
ASSERT_EQ(BinarySearchGEQ({0, 1, 2, 3, 4, 5}, 4, 0, 5), 4); // Stack []
}
TEST(BinarySearchSubtest, Inequality) {
ASSERT_EQ(BinarySearchGEQ({0, 2, 4, 6, 8, 9}, 31, 0, 5), 5); // Stack []
ASSERT_EQ(BinarySearchGEQ({0, 2, 3, 6, 7, 9}, 5, 0, 5), 3); // Stack []
ASSERT_EQ(BinarySearchGEQ({1, 2, 3, 6, 7, 9}, 0, 0, 5), 0); // Stack []
}
TEST(BinarySearchSubtest, Randomx100) {
std::vector<int> arr(100);
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<int> dist_gen(0, 1000);
std::uniform_int_distribution<int> dist_sample(0, arr.size() - 1);

for (int repetion = 0; repetion < 10000; ++repetion) {
for (int j = 0; j < arr.size(); ++j) arr[j] = dist_gen(rng);
std::sort(arr.begin(), arr.end());

int sample = dist_gen(rng);
int res_pos = BinarySearchGEQ(arr, sample, 0, arr.size() - 1);

if (res_pos != arr.size() - 1) ASSERT_GE(arr[res_pos], sample);
if (res_pos > 0) ASSERT_LT(arr[res_pos - 1], sample);
}
}

TEST(SolutionTest, Simple) {
{
auto [L, R] = FindPairMatchSum({1, 2, 3, 4, 8, 8, 8, 8, 9}, 13);
ASSERT_EQ(L, 4);
ASSERT_EQ(R, 9);
}

{
auto [L, R] = FindPairMatchSum({1, 1, 1, 4, 8, 8, 8, 8, 9, 10, 11}, 13);
ASSERT_EQ(L, 4);
ASSERT_EQ(R, 9);
}
}
TEST(SolutionTest, Random100of1000x1000) {
std::vector<int> arr(100);

std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<int> dist_gen(0, 1000);
std::uniform_int_distribution<int> dist_sample(0, arr.size() - 1);

for (int i = 0; i < 1000; ++i) {
// gen
for (int j = 0; j < 100; ++j) arr[j] = dist_gen(rng);
// sort array according to task
std::sort(arr.begin(), arr.end());

// sample
int first_sample = dist_sample(rng);
int second_sample = first_sample;
while (second_sample == first_sample) second_sample = dist_sample(rng);

// target sum
int sum = arr[first_sample] + arr[second_sample];

// get answer
auto [res_first, res_second] = FindPairMatchSum(arr, sum);

// compare
// ! we might get other indexes then A & B we sampled.
// Let's test the sum and the existance of elements
ASSERT_EQ(res_first + res_second, sum);

auto search_iterator = arr.begin();
while (search_iterator != arr.end() && *search_iterator != res_first)
++search_iterator;
ASSERT_NE(search_iterator, arr.end());
search_iterator = arr.begin();
while (search_iterator != arr.end() && *search_iterator != res_second)
++search_iterator;
ASSERT_NE(search_iterator, arr.end());
}
}
41 changes: 33 additions & 8 deletions task_02/src/stack.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
#include "stack.hpp"

#include <algorithm>
#include <stdexcept>

void Stack::Push(int value) { data_.push(value); }
// ----------------------------------- STACK -----------------------------------

Stack::Stack(unsigned int reserve) : data_() { data_.reserve(reserve); }

void Stack::Push(int value) { data_.push_back(value); }

int Stack::Pop() {
auto result = data_.top();
data_.pop();
if (data_.size() == 0)
throw std::runtime_error("trying to pop from empty stack");
auto result = data_[data_.size() - 1];
data_.pop_back();
return result;
}

void MinStack::Push(int value) { data_.push_back(value); }
int Stack::GetTop() {
if (data_.size() == 0)
throw std::runtime_error("trying get something from empty stack");
return data_[data_.size() - 1];
}

bool Stack::IsEmpy() { return data_.size() == 0; }

// --------------------------------- MIN STACK ---------------------------------

MinStack::MinStack(unsigned int reserve) : data_(reserve), min_(reserve) {}

void MinStack::Push(int value) {
data_.Push(value);

if (min_.IsEmpy())
min_.Push(value);
else
min_.Push(std::min(min_.GetTop(), value));
}

int MinStack::Pop() {
auto result = data_.back();
data_.pop_back();
return result;
min_.Pop();
return data_.Pop();
}

int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); }
int MinStack::GetMin() { return min_.GetTop(); }
10 changes: 8 additions & 2 deletions task_02/src/stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@

class Stack {
public:
Stack(unsigned int reserve = 0);
void Push(int value);
int Pop();
// some handy extensions
int GetTop(); // sometimes called Peek but GetTop is more self-describing
bool IsEmpy();

private:
std::stack<int> data_;
std::vector<int> data_;
};

class MinStack {
public:
MinStack(unsigned int reserve = 0);
void Push(int value);
int Pop();
int GetMin();

private:
std::vector<int> data_;
Stack data_;
Stack min_;
};
35 changes: 33 additions & 2 deletions task_02/src/test.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

#include <gtest/gtest.h>

#include <stack>
#include <algorithm>
#include <random>

#include "stack.hpp"

Expand Down Expand Up @@ -39,4 +40,34 @@ TEST(MinStackTest, Simple) {
ASSERT_EQ(stack.GetMin(), 1);
ASSERT_EQ(stack.Pop(), 3); // Stack [1]
ASSERT_EQ(stack.Pop(), 1); // Stack []
}
}

TEST(MinStackTest, Random) {
MinStack mstack;

std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<int> dist(-1000000, 1000000);

for (unsigned int repeation = 0; repeation < 1000; ++repeation) {
constexpr unsigned int N = 1000;
std::array<int, N> min;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: uninitialized record type: 'min' [cppcoreguidelines-pro-type-member-init]

Suggested change
std::array<int, N> min;
std::array<int, N> min{};


min[0] = dist(rng);
mstack.Push(min[0]);
ASSERT_EQ(min[0], mstack.GetMin()); // forward pass - zero
for (unsigned int i = 1; i < N; ++i) {
int value = dist(rng);

min[i] = std::min(min[i - 1], value);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index]

      min[i] = std::min(min[i - 1], value);
                        ^

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index]

      min[i] = std::min(min[i - 1], value);
      ^

mstack.Push(value);

ASSERT_EQ(min[i], mstack.GetMin()); // forward pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index]

      ASSERT_EQ(min[i], mstack.GetMin());  // forward pass
                ^

}
for (int i = N - 1; i >= 0; --i) {
ASSERT_EQ(mstack.GetMin(), min[i]); // backward pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index]

      ASSERT_EQ(mstack.GetMin(), min[i]);  // backward pass
                                 ^


mstack.Pop();
}
}
}
34 changes: 34 additions & 0 deletions task_03/src/solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "solution.hpp"

#include <stack>
#include <vector>

std::vector<int> DaysToWarming(std::vector<float> temps) {
std::stack<float> temp_steps;
std::stack<float> temp_steps_days;

std::vector<int> res(temps.size());

for (int day = temps.size() - 1; day >= 0; --day) {
while (!temp_steps.empty() && temp_steps.top() <= temps[day]) {
temp_steps.pop();
temp_steps_days.pop();
}

if (!temp_steps.empty()) {
//
// 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
// | c | 1 | 2 | 3 | + |
//
// 6 - 2 = 4 = 3 + current
res[day] = temp_steps_days.top() - day;
} else {
res[day] = 0; // there won't be any warmer days
}

temp_steps.push(temps[day]);
temp_steps_days.push(day);
}

return res;
}
4 changes: 4 additions & 0 deletions task_03/src/solution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

#include <vector>
std::vector<int> DaysToWarming(std::vector<float> temps);
30 changes: 27 additions & 3 deletions task_03/src/test.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@

#include <gtest/gtest.h>

#include "topology_sort.hpp"
#include <vector>

TEST(TopologySort, Simple) {
ASSERT_EQ(1, 1); // Stack []
#include "solution.hpp"

TEST(DaysToWarming, Case_One) {
/*
* .-------------------x
* 8 # .-------x
* 7 # #
* 6 # .--8--->###
* 5 #1# ##### .-.---x
* 4 ### .2##### #1#.-.x
* 3 ###321#1##### ####1##
* 2 #############1#######
* 1 #####################
*
* 012345678901234567890
*/

std::vector<float> temps{8, 4, 5, 2, 2, 2, 3, 2, 5, 5, 6,
6, 7, 1, 4, 3, 4, 3, 2, 3, 3};
std::vector<int> exprected_res{0, 1, 8, 3, 2, 1, 2, 1, 2, 1, 2,
1, 0, 1, 0, 1, 0, 0, 1, 0, 0};
auto res = DaysToWarming(temps);

ASSERT_EQ(res.size(), exprected_res.size());
for (int i = 0; i < res.size(); ++i)
ASSERT_EQ(res[i], exprected_res[i]) << "Result wrong at index " << i;
}
1 change: 0 additions & 1 deletion task_03/src/topology_sort.cpp

This file was deleted.

1 change: 0 additions & 1 deletion task_03/src/topology_sort.hpp

This file was deleted.

Loading