diff --git a/ex01/Makefile b/ex01/Makefile new file mode 100644 index 0000000..1a9658a --- /dev/null +++ b/ex01/Makefile @@ -0,0 +1,4 @@ +override NAME = ex01.out +override SRC_FILES = main.cpp Span.cpp + +include ../Makefile diff --git a/ex01/src/Span.cpp b/ex01/src/Span.cpp new file mode 100644 index 0000000..feb52bb --- /dev/null +++ b/ex01/src/Span.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +Span::Span() : size(0) {} + +Span::Span(const Span& other) : numbers(other.numbers), size(other.size) {} + +Span::Span(unsigned int size) : size(size) {} + +void Span::addNumber(int number) { + if (numbers.size() == size) + throw std::length_error("Can't add number, it would exceed span size"); + + numbers.push_back(number); +} + +int Span::shortestSpan() { + if (numbers.empty()) + throw std::logic_error("Can't find shortest span, no numbers stored"); + + if (numbers.size() == 1) + throw std::logic_error("Can't find shortest span, only one number stored"); + + std::vector sortedNumbers(numbers); + std::sort(sortedNumbers.begin(), sortedNumbers.end()); + + std::vector differences(sortedNumbers.size()); + std::adjacent_difference(sortedNumbers.begin(), sortedNumbers.end(), differences.begin()); + + return *std::min_element(differences.begin() + 1, differences.end()); +} + +int Span::longestSpan() { + if (numbers.empty()) + throw std::logic_error("Can't find longest span, no numbers stored"); + + if (numbers.size() == 1) + throw std::logic_error("Can't find longest span, only one number stored"); + + return *std::max_element(numbers.begin(), numbers.end()) - *std::min_element(numbers.begin(), numbers.end()); +} + +Span& Span::operator=(const Span& other) { + if (this == &other) + return *this; + + size = other.size; + numbers = other.numbers; + + return *this; +} + +Span::~Span() {} diff --git a/ex01/src/Span.hpp b/ex01/src/Span.hpp new file mode 100644 index 0000000..1ac063c --- /dev/null +++ b/ex01/src/Span.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +class Span { + public: + Span(); + Span(const Span& other); + Span(unsigned int size); + + void addNumber(int number); + template void addNumbers(I begin, I end) { + if (numbers.size() + static_cast(std::distance(begin, end)) > size) + throw std::length_error("Can't add numbers, it would exceed span size"); + + numbers.insert(numbers.end(), begin, end); + } + + int shortestSpan(); + int longestSpan(); + + Span& operator=(const Span& other); + + ~Span(); + + private: + std::vector numbers; + unsigned int size; +}; diff --git a/ex01/src/main.cpp b/ex01/src/main.cpp new file mode 100644 index 0000000..ccfbf9c --- /dev/null +++ b/ex01/src/main.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include + +#define ASSERT_THROWS(expression) \ + try { \ + (expression); \ + assert(false && "Expected exception did not throw: " #expression); \ + } catch (...) { \ + } + +int main() { + std::cout << "================ Subject's Test ================" << std::endl; + { + Span sp = Span(5); + + sp.addNumber(6); + sp.addNumber(3); + sp.addNumber(17); + sp.addNumber(9); + sp.addNumber(11); + + std::cout << sp.shortestSpan() << std::endl; + std::cout << sp.longestSpan() << std::endl; + } + + { + Span span = Span(); + + const int array[] = {1, 2, 4, 8, 16, 32, 64, 128}; + const int size = sizeof(array) / sizeof(array[0]); + + std::vector vector = std::vector(array, array + size); + std::deque deque = std::deque(array, array + size); + std::list list = std::list(array, array + size); + + ASSERT_THROWS(span.addNumber(1)); + ASSERT_THROWS(span.addNumbers(vector.begin(), vector.end())); + ASSERT_THROWS(span.addNumbers(deque.begin(), deque.end())); + ASSERT_THROWS(span.addNumbers(list.begin(), list.end())); + ASSERT_THROWS(span.shortestSpan()); + ASSERT_THROWS(span.longestSpan()); + } + + { + Span span = Span(8192); + + std::vector vector(8192); + for (size_t i = 0; i < 8192; ++i) + vector[i] = i; + + span.addNumbers(vector.begin(), vector.end()); + + assert(span.shortestSpan() == 1); + assert(span.longestSpan() == 8191); + } +}