Skip to content
Empty file added task_02/src/min_stack.cpp
Empty file.
45 changes: 45 additions & 0 deletions task_02/src/min_stack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef MIN_STACK_HPP
#define MIN_STACK_HPP
#include <exception>
#include <optional>
#include <stdexcept>

#include "stack.hpp"

template <class T>
class MinStack {
public:
void push(T value) {
if ((getMin_()) && *getMin_() < value)
min_.push(getMin());
else
min_.push(value);
data_.push(value);
}
T pop() {
T result = data_.pop();
min_.pop();
return result;
}
T getMin() {
T result = min_.pop();
min_.push(result);
return result;
}

private:
std::optional<T> getMin_() {
std::optional<T> result;
try {
result = min_.pop();
min_.push(*result);
} catch (std::exception& e) {
result = std::nullopt;
}
return result;
}
Stack<T> data_;
Stack<T> min_;
};

#endif
21 changes: 0 additions & 21 deletions task_02/src/stack.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +0,0 @@
#include "stack.hpp"

#include <algorithm>

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()); }
29 changes: 14 additions & 15 deletions task_02/src/stack.hpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
#pragma once

#include <stack>
#ifndef STACK_HPP
#define STACK_HPP
#include <exception>
#include <stdexcept>
#include <vector>

template <class T>
class Stack {
public:
void Push(int value);
int Pop();
void push(T value) { data_.push_back(value); }
T pop() {
if (data_.empty()) throw std::runtime_error("stack is empty");
int result = data_.back();
data_.pop_back();
return result;
}

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

class MinStack {
public:
void Push(int value);
int Pop();
int GetMin();

private:
std::vector<int> data_;
};
#endif
74 changes: 43 additions & 31 deletions task_02/src/test.cpp
Original file line number Diff line number Diff line change
@@ -1,42 +1,54 @@

#include <gtest/gtest.h>

#include <stack>
#include <stdexcept>

#include "min_stack.hpp"
#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<int> 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 []
}

TEST(MinStackTest, Simple) {
MinStack stack;
stack.Push(1); // Stack [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.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.GetMin(), 1);
ASSERT_EQ(stack.Pop(), 2); // Stack [1]
stack.Push(3); // Stack [1, 3]
ASSERT_EQ(stack.GetMin(), 1);
ASSERT_EQ(stack.Pop(), 3); // Stack [1]
ASSERT_EQ(stack.Pop(), 1); // Stack []
MinStack<int> stack;
stack.push(1); // Stack [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.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.getMin(), 1);
ASSERT_EQ(stack.pop(), 2); // Stack [1]
stack.push(3); // Stack [1, 3]
ASSERT_EQ(stack.getMin(), 1);
ASSERT_EQ(stack.pop(), 3); // Stack [1]
ASSERT_EQ(stack.pop(), 1); // Stack []
}

TEST(StackTest, empty) {
Stack<int> stack;
ASSERT_THROW(stack.pop(), std::runtime_error);
}

TEST(MinStackTest, empty) {
MinStack<int> stack;
ASSERT_THROW(stack.getMin(), std::runtime_error);
ASSERT_THROW(stack.pop(), std::runtime_error);
}
14 changes: 14 additions & 0 deletions task_03/src/days_till_warming.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "days_till_warming.hpp"

std::vector<size_t> DaysTillWarming(std::vector<double> temps) {
std::vector<Day> days;
std::vector<size_t> result(temps.size(), 0);
for (size_t i = 0; i < temps.size(); i++) {
while (!days.empty() && (days.back().temp_ < temps[i])) {
result[days.back().id_] = i - days.back().id_;
days.pop_back();
}
days.push_back(Day(i, temps[i]));
}
return result;
}
10 changes: 10 additions & 0 deletions task_03/src/days_till_warming.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <cstddef>
#include <vector>

struct Day {
Day(size_t id, double temp) : id_{id}, temp_{temp} {}
size_t id_;
double temp_;
};

std::vector<size_t> DaysTillWarming(std::vector<double> temps);
22 changes: 19 additions & 3 deletions task_03/src/test.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@

#include <gtest/gtest.h>

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

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

TEST(DaysTillWarming, Simple) {
ASSERT_EQ((DaysTillWarming(std::vector<double>{
+24, +22, +27, +21, +20, +20, +20, +20, +23, +24, +24, +25, +19,
+19, +22, +28, +21, +21, +22})),
(std::vector<size_t>{2, 1, 13, 5, 4, 3, 2, 1, 1, 2, 1, 4, 2, 1, 1,
0, 2, 1, 0}));
ASSERT_EQ((DaysTillWarming(std::vector<double>{-12, -5, -9, 0, +2, +1})),
(std::vector<size_t>{1, 2, 1, 1, 0, 0}));
ASSERT_EQ((DaysTillWarming(std::vector<double>{0, +1})),
(std::vector<size_t>{1, 0}));
ASSERT_EQ((DaysTillWarming(std::vector<double>{0})),
(std::vector<size_t>{0}));
}

TEST(DaysTillWarming, Empty) {
ASSERT_EQ((DaysTillWarming(std::vector<double>{})), (std::vector<size_t>{}));
}
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.

2 changes: 2 additions & 0 deletions task_04/src/heap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// класс шаблонный, но CMake тербует cpp файл
// переписывать CMake не стал, для совместимости
65 changes: 65 additions & 0 deletions task_04/src/heap.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#ifndef HEAP_HPP
#define HEAP_HPP
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <stdexcept>
#include <vector>

template <class T>
class Heap {
public:
Heap() : data_{} {}

Heap(Heap<T> const& other) : data_{other.data_} {}

Heap(std::initializer_list<T> data) : data_{data} {
for (size_t i = data_.size() / 2; i; i--) siftDown(i);
siftDown(0);
}

Heap(std::vector<T> data) : data_{data} {
for (size_t i = data_.size() / 2; i; i--) siftDown(i);
siftDown(0);
}

Heap const& operator=(Heap const& other) {
data_ = other.data_;
return *(this);
}

T popMin() {
if (data_.empty()) throw std::runtime_error("can't pop min: heap is empty");
T result = data_[0];
data_[0] = data_.back();
data_.pop_back();
siftDown(0);
return result;
}
void push(T value) {
data_.push_back(value);
siftUp(data_.size() - 1);
}

private:
void siftUp(size_t i) {
while (i && data_[i] < data_[(i - 1) / 2]) {
std::swap(data_[i], data_[(i - 1) / 2]);
i = (i - 1) / 2;
}
}
void siftDown(size_t i) {
while ((2 * i + 1) < data_.size()) {
size_t left = 2 * i + 1;
size_t right = 2 * i + 2;
size_t j = left;
if ((right < data_.size()) && (data_[right] < data_[left])) j = right;
if (data_[i] <= data_[j]) break;
std::swap(data_[i], data_[j]);
i = j;
}
}
std::vector<T> data_;
};

#endif
41 changes: 39 additions & 2 deletions task_04/src/test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@

#include <gtest/gtest.h>

TEST(TopologySort, Simple) {
ASSERT_EQ(1, 1); // Stack []
#include <stdexcept>

#include "heap.hpp"

TEST(Heap, Simple) {
Heap<int> heap;
heap.push(1);
heap.push(2);
heap.push(-1);
ASSERT_EQ(heap.popMin(), -1);
ASSERT_EQ(heap.popMin(), 1);
ASSERT_EQ(heap.popMin(), 2);
heap.push(1);
ASSERT_EQ(heap.popMin(), 1);
heap.push(2);
heap.push(-1);
heap.push(1);
ASSERT_EQ(heap.popMin(), -1);
heap.push(3);
ASSERT_EQ(heap.popMin(), 1);
ASSERT_EQ(heap.popMin(), 2);
ASSERT_EQ(heap.popMin(), 3);
}

TEST(Heap, empty) {
Heap<int> heap;
ASSERT_THROW(heap.popMin(), std::runtime_error);
}

TEST(Heap, constructor) {
Heap<int> heap = {2, 3, 1, 5, -1};
ASSERT_EQ(heap.popMin(), -1);
ASSERT_EQ(heap.popMin(), 1);
ASSERT_EQ(heap.popMin(), 2);
std::vector<int> vec = {7, 3, -1, 4};
Heap<int> heap2 = vec;
ASSERT_EQ(heap2.popMin(), -1);
ASSERT_EQ(heap2.popMin(), 3);
ASSERT_EQ(heap2.popMin(), 4);
}
Empty file added task_05/src/merge_sort.cpp
Empty file.
Loading