Skip to content

HOMEWORK 2 #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
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
Loading