From bb1151ae5cf30dd1ac0d5ae447bed1a4967fdb74 Mon Sep 17 00:00:00 2001 From: Marcel Gaupp Date: Mon, 9 Sep 2024 17:49:42 +0200 Subject: [PATCH] Replace exercise with simpler one --- .../templates/aeolus/c_plus_plus/default.sh | 8 +- .../templates/aeolus/c_plus_plus/default.yaml | 8 +- .../c_plus_plus/exercise/.clang-format | 6 +- .../c_plus_plus/exercise/CMakeLists.txt | 4 +- .../exercise/include/ast-polymorphic.hpp | 3 - .../exercise/include/ast-template.hpp | 3 - .../exercise/include/linked-list-iterator.hpp | 3 - .../c_plus_plus/exercise/include/sort.hpp | 19 ++ .../c_plus_plus/exercise/src/main.cpp | 2 + .../c_plus_plus/exercise/src/sort.cpp | 35 ++ .../resources/templates/c_plus_plus/readme | 28 +- .../c_plus_plus/solution/.clang-format | 6 +- .../c_plus_plus/solution/CMakeLists.txt | 4 +- .../solution/include/ast-polymorphic.hpp | 255 --------------- .../solution/include/ast-template.hpp | 236 -------------- .../solution/include/linked-list-iterator.hpp | 303 ------------------ .../c_plus_plus/solution/include/sort.hpp | 19 ++ .../c_plus_plus/solution/src/main.cpp | 2 + .../c_plus_plus/solution/src/sort.cpp | 73 +++++ .../templates/c_plus_plus/test/.clang-format | 6 +- .../templates/c_plus_plus/test/.gitignore | 1 + .../templates/c_plus_plus/test/CMakeLists.txt | 22 +- .../templates/c_plus_plus/test/Tests.py | 16 +- .../test/src/ast-polymorphic-test.cpp | 27 -- .../test/src/ast-template-simplify-test.cpp | 13 - .../test/src/ast-template-test.cpp | 15 - .../test/src/linked-list-iterator-test.cpp | 155 --------- .../c_plus_plus/test/src/sort-test.cpp | 121 +++++++ .../c_plus_plus/test/tests/TestCatch2.py | 4 +- 29 files changed, 316 insertions(+), 1081 deletions(-) delete mode 100644 src/main/resources/templates/c_plus_plus/exercise/include/ast-polymorphic.hpp delete mode 100644 src/main/resources/templates/c_plus_plus/exercise/include/ast-template.hpp delete mode 100644 src/main/resources/templates/c_plus_plus/exercise/include/linked-list-iterator.hpp create mode 100644 src/main/resources/templates/c_plus_plus/exercise/include/sort.hpp create mode 100644 src/main/resources/templates/c_plus_plus/exercise/src/sort.cpp delete mode 100644 src/main/resources/templates/c_plus_plus/solution/include/ast-polymorphic.hpp delete mode 100644 src/main/resources/templates/c_plus_plus/solution/include/ast-template.hpp delete mode 100644 src/main/resources/templates/c_plus_plus/solution/include/linked-list-iterator.hpp create mode 100644 src/main/resources/templates/c_plus_plus/solution/include/sort.hpp create mode 100644 src/main/resources/templates/c_plus_plus/solution/src/sort.cpp delete mode 100644 src/main/resources/templates/c_plus_plus/test/src/ast-polymorphic-test.cpp delete mode 100644 src/main/resources/templates/c_plus_plus/test/src/ast-template-simplify-test.cpp delete mode 100644 src/main/resources/templates/c_plus_plus/test/src/ast-template-test.cpp delete mode 100644 src/main/resources/templates/c_plus_plus/test/src/linked-list-iterator-test.cpp create mode 100644 src/main/resources/templates/c_plus_plus/test/src/sort-test.cpp diff --git a/src/main/resources/templates/aeolus/c_plus_plus/default.sh b/src/main/resources/templates/aeolus/c_plus_plus/default.sh index 5cf92b6e8c44..3e38f702df59 100644 --- a/src/main/resources/templates/aeolus/c_plus_plus/default.sh +++ b/src/main/resources/templates/aeolus/c_plus_plus/default.sh @@ -10,12 +10,11 @@ setup_the_build_environment () { # Setup the build environment # ------------------------------ - # Updating assignment and test-reports ownership... - sudo chown artemis_user:artemis_user assignment/ -R + # Updating ownership... + sudo chown -R artemis_user:artemis_user . + mkdir test-reports - chown artemis_user:artemis_user test-reports/ -R - # assignment REQ_FILE=requirements.txt if [ -f "$REQ_FILE" ]; then pip3 install --user -r requirements.txt || true @@ -32,7 +31,6 @@ build_and_run_all_tests () { # Task Description: # Build and run all tests # ------------------------------ - sudo chown artemis_user:artemis_user . python3 Tests.py || true } diff --git a/src/main/resources/templates/aeolus/c_plus_plus/default.yaml b/src/main/resources/templates/aeolus/c_plus_plus/default.yaml index 78a1898978c8..09f1b8ad6209 100644 --- a/src/main/resources/templates/aeolus/c_plus_plus/default.yaml +++ b/src/main/resources/templates/aeolus/c_plus_plus/default.yaml @@ -13,12 +13,11 @@ actions: # Setup the build environment # ------------------------------ - # Updating assignment and test-reports ownership... - sudo chown artemis_user:artemis_user assignment/ -R + # Updating ownership... + sudo chown -R artemis_user:artemis_user . + mkdir test-reports - chown artemis_user:artemis_user test-reports/ -R - # assignment REQ_FILE=requirements.txt if [ -f "$REQ_FILE" ]; then pip3 install --user -r requirements.txt || true @@ -34,7 +33,6 @@ actions: # Task Description: # Build and run all tests # ------------------------------ - sudo chown artemis_user:artemis_user . python3 Tests.py || true runAlways: false results: diff --git a/src/main/resources/templates/c_plus_plus/exercise/.clang-format b/src/main/resources/templates/c_plus_plus/exercise/.clang-format index 3891fbdbc3b0..6c9e19c8bc73 100644 --- a/src/main/resources/templates/c_plus_plus/exercise/.clang-format +++ b/src/main/resources/templates/c_plus_plus/exercise/.clang-format @@ -1,6 +1,8 @@ --- -Language: Cpp +Language: Cpp BasedOnStyle: Google IndentWidth: 4 +ColumnLimit: 120 PointerAlignment: Left -DerivePointerAlignment: false \ No newline at end of file +DerivePointerAlignment: false +IncludeBlocks: Preserve diff --git a/src/main/resources/templates/c_plus_plus/exercise/CMakeLists.txt b/src/main/resources/templates/c_plus_plus/exercise/CMakeLists.txt index 6affe797caf6..d58e0d43ff0f 100644 --- a/src/main/resources/templates/c_plus_plus/exercise/CMakeLists.txt +++ b/src/main/resources/templates/c_plus_plus/exercise/CMakeLists.txt @@ -4,8 +4,8 @@ project(ArtemisExercise) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -add_library(assignment INTERFACE) -target_include_directories(assignment INTERFACE include) +add_library(assignment src/sort.cpp) +target_include_directories(assignment PUBLIC include) add_executable(assignment_main src/main.cpp) target_link_libraries(assignment_main assignment) \ No newline at end of file diff --git a/src/main/resources/templates/c_plus_plus/exercise/include/ast-polymorphic.hpp b/src/main/resources/templates/c_plus_plus/exercise/include/ast-polymorphic.hpp deleted file mode 100644 index 559c14c28e4c..000000000000 --- a/src/main/resources/templates/c_plus_plus/exercise/include/ast-polymorphic.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -// your code here diff --git a/src/main/resources/templates/c_plus_plus/exercise/include/ast-template.hpp b/src/main/resources/templates/c_plus_plus/exercise/include/ast-template.hpp deleted file mode 100644 index 559c14c28e4c..000000000000 --- a/src/main/resources/templates/c_plus_plus/exercise/include/ast-template.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -// your code here diff --git a/src/main/resources/templates/c_plus_plus/exercise/include/linked-list-iterator.hpp b/src/main/resources/templates/c_plus_plus/exercise/include/linked-list-iterator.hpp deleted file mode 100644 index 559c14c28e4c..000000000000 --- a/src/main/resources/templates/c_plus_plus/exercise/include/linked-list-iterator.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -// your code here diff --git a/src/main/resources/templates/c_plus_plus/exercise/include/sort.hpp b/src/main/resources/templates/c_plus_plus/exercise/include/sort.hpp new file mode 100644 index 000000000000..270eb5106fc6 --- /dev/null +++ b/src/main/resources/templates/c_plus_plus/exercise/include/sort.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +void selection_sort(std::vector::iterator begin, std::vector::iterator end); + +void insertion_sort(std::vector::iterator begin, std::vector::iterator end); + +void quicksort(std::vector::iterator begin, std::vector::iterator end); + +void mergesort(std::vector::iterator begin, std::vector::iterator end); + +void mergesort_inplace(std::vector::iterator begin, std::vector::iterator end); + +void heapsort(std::vector::iterator begin, std::vector::iterator end); + +void heapsort_explicit(std::vector::iterator begin, std::vector::iterator end); + +void bogosort(std::vector::iterator begin, std::vector::iterator end); diff --git a/src/main/resources/templates/c_plus_plus/exercise/src/main.cpp b/src/main/resources/templates/c_plus_plus/exercise/src/main.cpp index 406b1a9ada5e..b7cc0e71af2c 100644 --- a/src/main/resources/templates/c_plus_plus/exercise/src/main.cpp +++ b/src/main/resources/templates/c_plus_plus/exercise/src/main.cpp @@ -1,3 +1,5 @@ +#include "sort.hpp" + int main() { // Test your implementation here } diff --git a/src/main/resources/templates/c_plus_plus/exercise/src/sort.cpp b/src/main/resources/templates/c_plus_plus/exercise/src/sort.cpp new file mode 100644 index 000000000000..b0f5a82719d4 --- /dev/null +++ b/src/main/resources/templates/c_plus_plus/exercise/src/sort.cpp @@ -0,0 +1,35 @@ +#include "sort.hpp" + +#include + +void selection_sort(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} + +void insertion_sort(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} + +void quicksort(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} + +void mergesort(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} + +void mergesort_inplace(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} + +void heapsort(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} + +void heapsort_explicit(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} + +void bogosort(std::vector::iterator begin, std::vector::iterator end) { + throw std::logic_error("not implemented"); +} diff --git a/src/main/resources/templates/c_plus_plus/readme b/src/main/resources/templates/c_plus_plus/readme index fd1d81f7455d..cba9206b12f6 100644 --- a/src/main/resources/templates/c_plus_plus/readme +++ b/src/main/resources/templates/c_plus_plus/readme @@ -1,17 +1,15 @@ -[task][CMake runs correctly](TestConfigure) +1. [task][CMake runs correctly](TestConfigure) +2. [task][Your code compiles](CompileSort) +3. [task][Code is formatted with clang-format](clang-format(sort.cpp)) -# Templated doubly linked list -1. [task][Your code compiles](CompileLinkedList) -2. [task][Tests are passing](TestCatch2(linked-list-iterator-test)) -3. [task][Code is formatted with clang-format](clang-format(linked-list-iterator.hpp)) -# AST with polymorphism -1. [task][Your code compiles](CompileASTPolymorphic) -2. [task][Tests are passing](TestCatch2(ast-polymorphic-test)) -3. [task][Code is formatted with clang-format](clang-format(ast-polymorphic.hpp)) - -# AST with templates -1. [task][Your code compiles](CompileASTTemplate) -2. [task][Tests are passing](TestCatch2(ast-template-test)) -3. [task][Code is formatted with clang-format](clang-format(ast-template.hpp)) -4. Optional: [task][Tests for simplify are passing](TestCatch2(ast-template-simplify-test)) \ No newline at end of file +# Sorting Algorithms +[task][All algorithms sort correctly](TestCatch2(sort-test)) +1. [task][Selection Sort](sorting_algorithms/selection_sort,sorting_algorithms/all_elements_equal/selection_sort,sorting_algorithms/reverse-sorted_values/selection_sort,sorting_algorithms/single_values/selection_sort,sorting_algorithms/empty_input/selection_sort,sorting_algorithms/large_input/selection_sort) +2. [task][Insertion Sort](sorting_algorithms/insertion_sort,sorting_algorithms/all_elements_equal/insertion_sort,sorting_algorithms/reverse-sorted_values/insertion_sort,sorting_algorithms/single_values/insertion_sort,sorting_algorithms/empty_input/insertion_sort,sorting_algorithms/large_input/insertion_sort) +3. [task][Quicksort](sorting_algorithms/quicksort,sorting_algorithms/all_elements_equal/quicksort,sorting_algorithms/reverse-sorted_values/quicksort,sorting_algorithms/single_values/quicksort,sorting_algorithms/empty_input/quicksort,sorting_algorithms/large_input/quicksort) +4. [task][Mergesort](sorting_algorithms/mergesort,sorting_algorithms/all_elements_equal/mergesort,sorting_algorithms/reverse-sorted_values/mergesort,sorting_algorithms/single_values/mergesort,sorting_algorithms/empty_input/mergesort,sorting_algorithms/large_input/mergesort) +5. [task][Mergesort Inplace](sorting_algorithms/mergesort_inplace,sorting_algorithms/all_elements_equal/mergesort_inplace,sorting_algorithms/reverse-sorted_values/mergesort_inplace,sorting_algorithms/single_values/mergesort_inplace,sorting_algorithms/empty_input/mergesort_inplace,sorting_algorithms/large_input/mergesort_inplace) +6. [task][Heapsort](sorting_algorithms/heapsort,sorting_algorithms/all_elements_equal/heapsort,sorting_algorithms/reverse-sorted_values/heapsort,sorting_algorithms/single_values/heapsort,sorting_algorithms/empty_input/heapsort,sorting_algorithms/large_input/heapsort) +7. [task][Explicit Heapsort](sorting_algorithms/heapsort_explicit,sorting_algorithms/all_elements_equal/heapsort_explicit,sorting_algorithms/reverse-sorted_values/heapsort_explicit,sorting_algorithms/single_values/heapsort_explicit,sorting_algorithms/empty_input/heapsort_explicit,sorting_algorithms/large_input/heapsort_explicit) +8. [task][Bogosort](bogosort,bogosort/empty_input,bogosort/single_value) diff --git a/src/main/resources/templates/c_plus_plus/solution/.clang-format b/src/main/resources/templates/c_plus_plus/solution/.clang-format index 3891fbdbc3b0..6c9e19c8bc73 100644 --- a/src/main/resources/templates/c_plus_plus/solution/.clang-format +++ b/src/main/resources/templates/c_plus_plus/solution/.clang-format @@ -1,6 +1,8 @@ --- -Language: Cpp +Language: Cpp BasedOnStyle: Google IndentWidth: 4 +ColumnLimit: 120 PointerAlignment: Left -DerivePointerAlignment: false \ No newline at end of file +DerivePointerAlignment: false +IncludeBlocks: Preserve diff --git a/src/main/resources/templates/c_plus_plus/solution/CMakeLists.txt b/src/main/resources/templates/c_plus_plus/solution/CMakeLists.txt index 6affe797caf6..d58e0d43ff0f 100644 --- a/src/main/resources/templates/c_plus_plus/solution/CMakeLists.txt +++ b/src/main/resources/templates/c_plus_plus/solution/CMakeLists.txt @@ -4,8 +4,8 @@ project(ArtemisExercise) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -add_library(assignment INTERFACE) -target_include_directories(assignment INTERFACE include) +add_library(assignment src/sort.cpp) +target_include_directories(assignment PUBLIC include) add_executable(assignment_main src/main.cpp) target_link_libraries(assignment_main assignment) \ No newline at end of file diff --git a/src/main/resources/templates/c_plus_plus/solution/include/ast-polymorphic.hpp b/src/main/resources/templates/c_plus_plus/solution/include/ast-polymorphic.hpp deleted file mode 100644 index 38e58d00aaa7..000000000000 --- a/src/main/resources/templates/c_plus_plus/solution/include/ast-polymorphic.hpp +++ /dev/null @@ -1,255 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -enum class operation_type { plus, minus, multiply, divide, modulo }; - -struct variables { - std::map values; -}; - -class node { - public: - virtual ~node() = default; - - virtual int evaluate(const variables& vars = {}) const = 0; - virtual std::string reverse_polish() const = 0; -}; - -class number : public node { - public: - number(int value) : value{value} {} - - int evaluate(const variables&) const override { return value; } - - std::string reverse_polish() const override { - return std::to_string(value); - } - - int value; -}; - -class variable : public node { - public: - variable(std::string name) : name{name} {} - - int evaluate(const variables& vars) const override { - return vars.values.at(name); - } - - std::string reverse_polish() const override { return name; } - - std::string name; -}; - -class binary_operation : public node { - public: - binary_operation(operation_type type, std::unique_ptr left_child, - std::unique_ptr right_child) - : type{type}, - left_child{std::move(left_child)}, - right_child{std::move(right_child)} {} - - int evaluate(const variables& vars) const override { - const auto left_value = left_child->evaluate(vars); - const auto right_value = right_child->evaluate(vars); - switch (type) { - case operation_type::plus: - return left_value + right_value; - case operation_type::minus: - return left_value - right_value; - case operation_type::multiply: - return left_value * right_value; - case operation_type::divide: - return left_value / right_value; - case operation_type::modulo: - return left_value % right_value; - default: - assert(false); // this should never be reached - return -1; - } - } - - std::string reverse_polish() const override { - auto expr = left_child->reverse_polish() + " " + - right_child->reverse_polish() + " "; - switch (type) { - case operation_type::plus: - expr += '+'; - break; - case operation_type::minus: - expr += '-'; - break; - case operation_type::multiply: - expr += '*'; - break; - case operation_type::divide: - expr += '/'; - break; - case operation_type::modulo: - expr += '%'; - break; - } - return expr; - } - - operation_type type; - std::unique_ptr left_child; - std::unique_ptr right_child; -}; - -std::unique_ptr operator""_num(unsigned long long i) { - return std::make_unique(int(i)); -} - -std::unique_ptr operator""_var(const char* name, std::size_t len) { - return std::make_unique(std::string{name, len}); -} - -std::unique_ptr operator+(std::unique_ptr lhs, - std::unique_ptr rhs) { - return std::make_unique(operation_type::plus, - std::move(lhs), std::move(rhs)); -} - -std::unique_ptr operator-(std::unique_ptr lhs, - std::unique_ptr rhs) { - return std::make_unique(operation_type::minus, - std::move(lhs), std::move(rhs)); -} - -std::unique_ptr operator*(std::unique_ptr lhs, - std::unique_ptr rhs) { - return std::make_unique(operation_type::multiply, - std::move(lhs), std::move(rhs)); -} - -std::unique_ptr operator/(std::unique_ptr lhs, - std::unique_ptr rhs) { - return std::make_unique(operation_type::divide, - std::move(lhs), std::move(rhs)); -} - -std::unique_ptr operator%(std::unique_ptr lhs, - std::unique_ptr rhs) { - return std::make_unique(operation_type::modulo, - std::move(lhs), std::move(rhs)); -} - -enum class token_type { - number, - plus, - minus, - multiply, - divide, - modulo, - variable -}; - -struct token { - token_type type{}; - int value{}; - std::string variable_name{}; -}; - -std::ostream& operator<<(std::ostream& stream, const token& t) { - switch (t.type) { - case token_type::number: - stream << t.value; - break; - case token_type::plus: - stream << "+"; - break; - case token_type::minus: - stream << "-"; - break; - case token_type::multiply: - stream << "*"; - break; - case token_type::divide: - stream << "/"; - break; - case token_type::modulo: - stream << "%"; - break; - case token_type::variable: - stream << t.variable_name; - break; - } - return stream; -} - -std::istream& operator>>(std::istream& stream, token& t) { - std::string candidate; - stream >> candidate; - if (candidate.find_first_of("0123456789") == std::string::npos) { - if (candidate == "+") { - t = token{.type = token_type::plus}; - } else if (candidate == "-") { - t = token{.type = token_type::minus}; - } else if (candidate == "*") { - t = token{.type = token_type::multiply}; - } else if (candidate == "/") { - t = token{.type = token_type::divide}; - } else if (candidate == "%") { - t = token{.type = token_type::modulo}; - } else { - t = token{.type = token_type::variable, .variable_name = candidate}; - } - } else { - t = token{.type = token_type::number, .value = std::stoi(candidate)}; - } - return stream; -} - -operation_type token_type_to_operation_type(token_type type) { - switch (type) { - case token_type::plus: - return operation_type::plus; - case token_type::minus: - return operation_type::minus; - case token_type::multiply: - return operation_type::multiply; - case token_type::divide: - return operation_type::divide; - case token_type::modulo: - return operation_type::modulo; - case token_type::number: - case token_type::variable: - default: - throw std::runtime_error{ - "Expected operation type, got number or variable instead"}; - } -} - -std::unique_ptr parse_from_reverse_polish(const std::string& input) { - std::stringstream stream{input}; - std::vector> nodes; - std::vector node_stack; - token t; - std::size_t i = 0; - while (stream >> t) { - if (t.type == token_type::number) { - nodes.push_back(std::make_unique(t.value)); - } else if (t.type == token_type::variable) { - nodes.push_back(std::make_unique(t.variable_name)); - } else { - auto rhs = std::move(nodes[node_stack.back()]); - node_stack.pop_back(); - auto lhs = std::move(nodes[node_stack.back()]); - node_stack.pop_back(); - nodes.push_back(std::make_unique( - token_type_to_operation_type(t.type), std::move(lhs), - std::move(rhs))); - } - node_stack.push_back(i); - i++; - } - return std::move(nodes.back()); -} diff --git a/src/main/resources/templates/c_plus_plus/solution/include/ast-template.hpp b/src/main/resources/templates/c_plus_plus/solution/include/ast-template.hpp deleted file mode 100644 index a4d61634413d..000000000000 --- a/src/main/resources/templates/c_plus_plus/solution/include/ast-template.hpp +++ /dev/null @@ -1,236 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -enum class operation_type { plus, minus, multiply, divide, modulo }; - -struct variables { - std::map values; -}; - -template -struct number { - constexpr static int value = i; -}; - -struct variable { - std::string name; -}; - -template -struct is_number_helper : std::false_type {}; - -template -struct is_binary_operation_helper : std::false_type {}; - -template -concept Node = is_number_helper::value || std::is_same_v || - is_binary_operation_helper::value; - -template -struct binary_operation { - public: - constexpr binary_operation(Left left_child = {}, Right right_child = {}) - : left_child{left_child}, right_child{right_child} {} - - using left_type = Left; - using right_type = Right; - - Left left_child; - Right right_child; -}; - -template -struct is_number_helper> : std::true_type {}; - -template -struct is_binary_operation_helper> - : std::true_type {}; - -constexpr int pow10(int i) { return i == 0 ? 1 : 10 * pow10(i - 1); } - -template -constexpr int get_value() { - static_assert(c >= '0' && c <= '9'); - if constexpr (sizeof...(cs) > 0) { - return pow10(sizeof...(cs)) * (c - '0') + get_value(); - } else { - return (c - '0'); - } -} - -template -constexpr number()> operator""_num() { - return number()>{}; -} - -inline variable operator""_var(const char* name, std::size_t len) { - return variable{std::string{name, len}}; -} - -template -constexpr binary_operation operator+( - Left lhs, Right rhs) { - return binary_operation(lhs, rhs); -} - -template -constexpr binary_operation operator-( - Left lhs, Right rhs) { - return binary_operation(lhs, rhs); -} - -template -constexpr binary_operation operator*( - Left lhs, Right rhs) { - return binary_operation(lhs, rhs); -} - -template -constexpr binary_operation operator/( - Left lhs, Right rhs) { - return binary_operation(lhs, rhs); -} - -template -constexpr binary_operation operator%( - Left lhs, Right rhs) { - return binary_operation(lhs, rhs); -} - -template -constexpr int evaluate(number, const variables& = {}) { - return i; -} - -template -constexpr int const_evaluate(number) { - return i; -} - -inline int evaluate(variable v, const variables& vars = {}) { - return vars.values.at(v.name); -} - -template -constexpr int evaluate(binary_operation node, - const variables& vars = {}) { - auto left_value = evaluate(node.left_child, vars); - auto right_value = evaluate(node.right_child, vars); - switch (type) { - case operation_type::plus: - return left_value + right_value; - case operation_type::minus: - return left_value - right_value; - case operation_type::multiply: - return left_value * right_value; - case operation_type::divide: - return left_value / right_value; - case operation_type::modulo: - return left_value % right_value; - } -} - -template -constexpr int const_evaluate(binary_operation node) { - auto left_value = const_evaluate(node.left_child); - auto right_value = const_evaluate(node.right_child); - switch (type) { - case operation_type::plus: - return left_value + right_value; - case operation_type::minus: - return left_value - right_value; - case operation_type::multiply: - return left_value * right_value; - case operation_type::divide: - return left_value / right_value; - case operation_type::modulo: - return left_value % right_value; - } -} - -template -std::string reverse_polish(number) { - return std::to_string(i); -} - -inline std::string reverse_polish(variable v) { return v.name; } - -template -std::string reverse_polish(binary_operation node) { - auto left_value = reverse_polish(node.left_child); - auto right_value = reverse_polish(node.right_child); - switch (type) { - case operation_type::plus: - return left_value + " " + right_value + " +"; - case operation_type::minus: - return left_value + " " + right_value + " -"; - case operation_type::multiply: - return left_value + " " + right_value + " *"; - case operation_type::divide: - return left_value + " " + right_value + " /"; - case operation_type::modulo: - return left_value + " " + right_value + " %"; - default: - assert(false); // this should never be reached - return ""; - } -} - -template -struct is_const_binary_operation_helper : std::false_type {}; - -template -concept ConstNode = Node && (is_number_helper::value || - is_const_binary_operation_helper::value); - -template -struct is_const_binary_operation_helper> - : std::true_type {}; - -template -struct simplify_helper { - using type = T; - - static T simplify(T node) { return node; } -}; - -template -constexpr auto simplify(T node) { - return simplify_helper::simplify(node); -} - -template -struct simplify_helper> { - using type = number; - - constexpr static number simplify(number) { return {}; } -}; - -template -struct simplify_helper> { - constexpr static int result = - const_evaluate(binary_operation{}); - using type = number; - - constexpr static number simplify( - binary_operation) { - return {}; - } -}; - -template -struct simplify_helper> { - using left_type = typename simplify_helper::type; - using right_type = typename simplify_helper::type; - using type = binary_operation; - - constexpr static type simplify(binary_operation op) { - return {::simplify(op.left_child), ::simplify(op.right_child)}; - } -}; diff --git a/src/main/resources/templates/c_plus_plus/solution/include/linked-list-iterator.hpp b/src/main/resources/templates/c_plus_plus/solution/include/linked-list-iterator.hpp deleted file mode 100644 index f6544b812a08..000000000000 --- a/src/main/resources/templates/c_plus_plus/solution/include/linked-list-iterator.hpp +++ /dev/null @@ -1,303 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -template -class linked_list; - -template -struct node { - T data; - node* prev; - node* next; - - node() : data{}, prev{this}, next{this} {} - - node(T data, node* prev, node* next) - : data{std::move(data)}, prev{prev}, next{next} { - // insert node between prev and next - prev->next = this; - next->prev = this; - } - - ~node() { - // make sure we don't stay attached for safety if somebody keeps - // iterators to removed elements. - next = nullptr; - prev = nullptr; - } -}; - -template -class linked_list_iterator { - friend class linked_list; - - public: - using difference_type = std::ptrdiff_t; - using value_type = T; - using reference = T&; - using pointer = T*; - using iterator_category = std::bidirectional_iterator_tag; - - linked_list_iterator(node* ptr) : ptr{ptr} {} - - linked_list_iterator& operator++() { - ptr = ptr->next; - return *this; - } - - linked_list_iterator& operator--() { - ptr = ptr->prev; - return *this; - } - - reference operator*() const { return ptr->data; } - - friend bool operator==(linked_list_iterator lhs, linked_list_iterator rhs) { - return lhs.ptr == rhs.ptr; - } - - friend bool operator!=(linked_list_iterator lhs, linked_list_iterator rhs) { - return !(lhs == rhs); - } - - private: - node* ptr; -}; - -template -class const_linked_list_iterator { - friend class linked_list; - - public: - using difference_type = std::ptrdiff_t; - using value_type = T; - using reference = const T&; - using pointer = const T*; - using iterator_category = std::bidirectional_iterator_tag; - - const_linked_list_iterator(const node* ptr) : ptr{ptr} {} - - const_linked_list_iterator& operator++() { - ptr = ptr->next; - return *this; - } - - const_linked_list_iterator& operator--() { - ptr = ptr->prev; - return *this; - } - - reference operator*() const { return ptr->data; } - - friend bool operator==(const_linked_list_iterator lhs, - const_linked_list_iterator rhs) { - return lhs.ptr == rhs.ptr; - } - - friend bool operator!=(const_linked_list_iterator lhs, - const_linked_list_iterator rhs) { - return !(lhs == rhs); - } - - private: - const node* ptr; -}; - -template -class linked_list { - public: - linked_list(); - ~linked_list(); - linked_list(const linked_list& list); - linked_list(linked_list&& list); - linked_list& operator=(const linked_list& list); - linked_list& operator=(linked_list&& list); - - linked_list_iterator begin(); - linked_list_iterator end(); - - const_linked_list_iterator begin() const; - const_linked_list_iterator end() const; - const_linked_list_iterator cbegin() const; - const_linked_list_iterator cend() const; - - std::vector to_vector() const; - - T& front(); - const T& front() const; - void push_front(T data); - void pop_front(); - - T& back(); - const T& back() const; - void push_back(T data); - void pop_back(); - - linked_list_iterator erase(linked_list_iterator it); - linked_list_iterator insert(linked_list_iterator it, T data); - - bool empty(); - void clear(); - - private: - void delete_node(node* to_delete); - - std::unique_ptr> sentinel; -}; - -template -linked_list::linked_list() : sentinel{std::make_unique>()} {} - -template -linked_list::~linked_list() { - clear(); -} - -template -linked_list::linked_list(const linked_list& list) : linked_list{} { - for (auto cur = list.sentinel->next; cur != list.sentinel.get(); - cur = cur->next) { - push_back(cur->data); - } -} - -template -linked_list::linked_list(linked_list&& list) - : sentinel{std::exchange(list.sentinel, std::make_unique>())} {} - -template -linked_list& linked_list::operator=(const linked_list& list) { - if (this != &list) { - // call copy-constructor and move-assignment operator - *this = linked_list{list}; - } - return *this; -} - -template -linked_list& linked_list::operator=(linked_list&& list) { - if (this != &list) { - clear(); - // this list is now empty, so we can swap it with list - std::swap(list.sentinel, sentinel); - } - return *this; -} - -template -linked_list_iterator linked_list::begin() { - return linked_list_iterator{sentinel->next}; -} - -template -linked_list_iterator linked_list::end() { - return linked_list_iterator{sentinel.get()}; -} - -template -const_linked_list_iterator linked_list::begin() const { - return const_linked_list_iterator{sentinel->next}; -} - -template -const_linked_list_iterator linked_list::end() const { - return const_linked_list_iterator{sentinel.get()}; -} - -template -const_linked_list_iterator linked_list::cbegin() const { - return const_linked_list_iterator{sentinel->next}; -} - -template -const_linked_list_iterator linked_list::cend() const { - return const_linked_list_iterator{sentinel.get()}; -} - -template -std::vector linked_list::to_vector() const { - std::vector result; - for (const auto& element : *this) { - result.push_back(element); - } - return result; -} - -template -T& linked_list::front() { - return sentinel->next->data; -} - -template -const T& linked_list::front() const { - return sentinel->next->data; -} - -template -void linked_list::push_front(T data) { - new node(std::move(data), sentinel.get(), sentinel->next); -} - -template -void linked_list::delete_node(node* to_delete) { - to_delete->next->prev = to_delete->prev; - to_delete->prev->next = to_delete->next; - delete to_delete; -} - -template -void linked_list::pop_front() { - delete_node(sentinel->next); -} - -template -T& linked_list::back() { - return sentinel->prev->data; -} - -template -const T& linked_list::back() const { - return sentinel->prev->data; -} - -template -void linked_list::push_back(T data) { - new node(std::move(data), sentinel->prev, sentinel.get()); -} - -template -void linked_list::pop_back() { - delete_node(sentinel->prev); -} - -template -bool linked_list::empty() { - return sentinel->next == sentinel.get(); -} - -template -void linked_list::clear() { - while (!empty()) { - pop_back(); - } -} - -template -linked_list_iterator linked_list::erase(linked_list_iterator it) { - auto next_element = it.ptr->next; - delete_node(it.ptr); - return linked_list_iterator{next_element}; -} - -template -linked_list_iterator linked_list::insert(linked_list_iterator it, - T data) { - return linked_list_iterator{ - new node(std::move(data), it.ptr->prev, it.ptr)}; -} diff --git a/src/main/resources/templates/c_plus_plus/solution/include/sort.hpp b/src/main/resources/templates/c_plus_plus/solution/include/sort.hpp new file mode 100644 index 000000000000..270eb5106fc6 --- /dev/null +++ b/src/main/resources/templates/c_plus_plus/solution/include/sort.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +void selection_sort(std::vector::iterator begin, std::vector::iterator end); + +void insertion_sort(std::vector::iterator begin, std::vector::iterator end); + +void quicksort(std::vector::iterator begin, std::vector::iterator end); + +void mergesort(std::vector::iterator begin, std::vector::iterator end); + +void mergesort_inplace(std::vector::iterator begin, std::vector::iterator end); + +void heapsort(std::vector::iterator begin, std::vector::iterator end); + +void heapsort_explicit(std::vector::iterator begin, std::vector::iterator end); + +void bogosort(std::vector::iterator begin, std::vector::iterator end); diff --git a/src/main/resources/templates/c_plus_plus/solution/src/main.cpp b/src/main/resources/templates/c_plus_plus/solution/src/main.cpp index 406b1a9ada5e..b7cc0e71af2c 100644 --- a/src/main/resources/templates/c_plus_plus/solution/src/main.cpp +++ b/src/main/resources/templates/c_plus_plus/solution/src/main.cpp @@ -1,3 +1,5 @@ +#include "sort.hpp" + int main() { // Test your implementation here } diff --git a/src/main/resources/templates/c_plus_plus/solution/src/sort.cpp b/src/main/resources/templates/c_plus_plus/solution/src/sort.cpp new file mode 100644 index 000000000000..d1f671f1bc74 --- /dev/null +++ b/src/main/resources/templates/c_plus_plus/solution/src/sort.cpp @@ -0,0 +1,73 @@ +#include "sort.hpp" + +#include +#include +#include + +void selection_sort(std::vector::iterator begin, std::vector::iterator end) { + for (auto it = begin; it != end; ++it) { + auto min = std::min_element(it, end); + // std::iter_swap(min, it); // unstable + std::rotate(it, min, min + 1); + } +} + +void insertion_sort(std::vector::iterator begin, std::vector::iterator end) { + for (auto it = begin; it != end; ++it) { + auto insertion_pos = std::upper_bound(begin, it, *it); + std::rotate(insertion_pos, it, it + 1); + } +} + +void quicksort(std::vector::iterator begin, std::vector::iterator end) { + if (end - begin <= 1) { + return; + } + auto pivot = *begin; + auto middle = std::partition(begin + 1, end, [pivot](int i) { return i < pivot; }); + auto new_middle = std::rotate(begin, begin + 1, middle); + quicksort(begin, new_middle); + quicksort(new_middle + 1, end); +} + +void mergesort(std::vector::iterator begin, std::vector::iterator end) { + auto length = end - begin; + if (length <= 1) { + return; + } + std::vector tmp(begin, end); + auto middle = tmp.begin() + length / 2; + mergesort(tmp.begin(), middle); + mergesort(middle, tmp.end()); + std::merge(tmp.begin(), middle, middle, tmp.end(), begin); +} + +void mergesort_inplace(std::vector::iterator begin, std::vector::iterator end) { + auto length = end - begin; + if (length <= 1) { + return; + } + auto middle = begin + length / 2; + mergesort_inplace(begin, middle); + mergesort_inplace(middle, end); + std::inplace_merge(begin, middle, end); +} + +void heapsort(std::vector::iterator begin, std::vector::iterator end) { + std::make_heap(begin, end); + std::sort_heap(begin, end); +} + +void heapsort_explicit(std::vector::iterator begin, std::vector::iterator end) { + std::make_heap(begin, end); + while (end != begin) { + std::pop_heap(begin, end); + --end; + } +} + +void bogosort(std::vector::iterator begin, std::vector::iterator end) { + while (!std::is_sorted(begin, end)) { + std::next_permutation(begin, end); + } +} diff --git a/src/main/resources/templates/c_plus_plus/test/.clang-format b/src/main/resources/templates/c_plus_plus/test/.clang-format index 3891fbdbc3b0..6c9e19c8bc73 100644 --- a/src/main/resources/templates/c_plus_plus/test/.clang-format +++ b/src/main/resources/templates/c_plus_plus/test/.clang-format @@ -1,6 +1,8 @@ --- -Language: Cpp +Language: Cpp BasedOnStyle: Google IndentWidth: 4 +ColumnLimit: 120 PointerAlignment: Left -DerivePointerAlignment: false \ No newline at end of file +DerivePointerAlignment: false +IncludeBlocks: Preserve diff --git a/src/main/resources/templates/c_plus_plus/test/.gitignore b/src/main/resources/templates/c_plus_plus/test/.gitignore index 55856e95ac6a..94435c6345d7 100644 --- a/src/main/resources/templates/c_plus_plus/test/.gitignore +++ b/src/main/resources/templates/c_plus_plus/test/.gitignore @@ -1,4 +1,5 @@ /assignment/ +/test-reports/ /build/ cmake-build-*/ diff --git a/src/main/resources/templates/c_plus_plus/test/CMakeLists.txt b/src/main/resources/templates/c_plus_plus/test/CMakeLists.txt index 7d4af64c6a18..250620938ac6 100644 --- a/src/main/resources/templates/c_plus_plus/test/CMakeLists.txt +++ b/src/main/resources/templates/c_plus_plus/test/CMakeLists.txt @@ -5,26 +5,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) include(CTest) -# Fetch Catch2 find_package(Catch2 REQUIRED) add_subdirectory(assignment) -# Add test for task 1 -add_executable(ast-polymorphic-test src/ast-polymorphic-test.cpp) -target_link_libraries(ast-polymorphic-test assignment Catch2::Catch2WithMain) -add_test(NAME ast-polymorphic COMMAND ast-polymorphic-test) - -# Add test for task 2 -add_executable(ast-template-test src/ast-template-test.cpp) -target_link_libraries(ast-template-test assignment Catch2::Catch2WithMain) -add_test(NAME ast-template COMMAND ast-template-test) - -add_executable(ast-template-simplify-test src/ast-template-simplify-test.cpp) -target_link_libraries(ast-template-simplify-test assignment Catch2::Catch2WithMain) -add_test(NAME ast-template-simplify COMMAND ast-template-simplify-test) - -# Add test for task 3 -add_executable(linked-list-iterator-test src/linked-list-iterator-test.cpp) -target_link_libraries(linked-list-iterator-test assignment Catch2::Catch2WithMain) -add_test(NAME linked-list-iterator COMMAND linked-list-iterator-test) +add_executable(sort-test src/sort-test.cpp) +target_link_libraries(sort-test assignment Catch2::Catch2WithMain) +add_test(NAME sort-test COMMAND sort-test) diff --git a/src/main/resources/templates/c_plus_plus/test/Tests.py b/src/main/resources/templates/c_plus_plus/test/Tests.py index f1d9125997c9..58a186854eb8 100755 --- a/src/main/resources/templates/c_plus_plus/test/Tests.py +++ b/src/main/resources/templates/c_plus_plus/test/Tests.py @@ -17,20 +17,12 @@ def main(): # Configure: testConfigure: TestConfigure = TestConfigure(".", buildDir, ["-DCMAKE_BUILD_TYPE=Debug", - "-DCMAKE_CXX_FLAGS=-fsanitize=address -Wall -Wextra -Wpedantic -Werror", + "-DCMAKE_CXX_FLAGS=-fsanitize=address", "-DCMAKE_EXE_LINKER_FLAGS=-fsanitize=address"]) tester.addTest(testConfigure) - tester.addTest(TestCompile(buildDir, "linked-list-iterator-test", requirements=[testConfigure.name], name="CompileLinkedList")) - tester.addTest(TestCatch2(buildDir, "linked-list-iterator-test", ["CompileLinkedList"])) - tester.addTest(TestCompile(buildDir, "ast-polymorphic-test", requirements=[testConfigure.name], name="CompileASTPolymorphic")) - tester.addTest(TestCatch2(buildDir, "ast-polymorphic-test", ["CompileASTPolymorphic"])) - tester.addTest(TestCompile(buildDir, "ast-template-test", requirements=[testConfigure.name], name="CompileASTTemplate")) - tester.addTest(TestCatch2(buildDir, "ast-template-test", ["CompileASTTemplate"])) - tester.addTest(TestCompile(buildDir, "ast-template-simplify-test", requirements=[testConfigure.name], name="CompileASTTemplateSimplify")) - tester.addTest(TestCatch2(buildDir, "ast-template-simplify-test", ["CompileASTTemplateSimplify"])) - tester.addTest(TestClangFormat("./assignment", "include/ast-polymorphic.hpp", name="clang-format(ast-polymorphic.hpp)")) - tester.addTest(TestClangFormat("./assignment", "include/ast-template.hpp", name="clang-format(ast-template.hpp)")) - tester.addTest(TestClangFormat("./assignment", "include/linked-list-iterator.hpp", name="clang-format(linked-list-iterator.hpp)")) + tester.addTest(TestCompile(buildDir, "sort-test", requirements=[testConfigure.name], name="CompileSort")) + tester.addTest(TestCatch2(buildDir, "sort-test", ["CompileSort"])) + tester.addTest(TestClangFormat("./assignment", "src/sort.cpp", name="clang-format(sort.cpp)")) # Run the actual tests: tester.run() diff --git a/src/main/resources/templates/c_plus_plus/test/src/ast-polymorphic-test.cpp b/src/main/resources/templates/c_plus_plus/test/src/ast-polymorphic-test.cpp deleted file mode 100644 index b7101287b536..000000000000 --- a/src/main/resources/templates/c_plus_plus/test/src/ast-polymorphic-test.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "ast-polymorphic.hpp" - -#include - -TEST_CASE("AST Polymorphic") { - auto expr = ("x"_var + 1_num) - "y"_var * "z"_var + "x"_var; - auto expr2 = 1_num + 2_num * (3_num - 4_num * 5_num); - - CHECK(expr->evaluate({.values = {{"x", 1}, {"y", 4}, {"z", 2}}}) == -5); - CHECK(expr->evaluate({.values = {{"x", 3}, {"y", -5}, {"z", 0}}}) == 7); - CHECK(expr2->evaluate() == -33); - - CHECK(expr->reverse_polish() == "x 1 + y z * - x +"); - CHECK(expr2->reverse_polish() == "1 2 3 4 5 * - * +"); -} - -TEST_CASE("Parse Polymorphic") { - auto expr = parse_from_reverse_polish("x 1 + y z * - x +"); - auto expr2 = parse_from_reverse_polish("1 2 3 4 5 * - * +"); - - CHECK(expr->evaluate({.values = {{"x", 1}, {"y", 4}, {"z", 2}}}) == -5); - CHECK(expr->evaluate({.values = {{"x", 3}, {"y", -5}, {"z", 0}}}) == 7); - CHECK(expr2->evaluate() == -33); - - CHECK(expr->reverse_polish() == "x 1 + y z * - x +"); - CHECK(expr2->reverse_polish() == "1 2 3 4 5 * - * +"); -} diff --git a/src/main/resources/templates/c_plus_plus/test/src/ast-template-simplify-test.cpp b/src/main/resources/templates/c_plus_plus/test/src/ast-template-simplify-test.cpp deleted file mode 100644 index 69c503245e36..000000000000 --- a/src/main/resources/templates/c_plus_plus/test/src/ast-template-simplify-test.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include - -#include "ast-template.hpp" - -TEST_CASE("Simplify Templated") { - auto expr = - simplify((123_num + 24_num * (3_num - 4_num * 5_num)) * "x"_var); - CHECK( - std::string(typeid(expr).name()) == - typeid( - binary_operation, variable>) - .name()); -} diff --git a/src/main/resources/templates/c_plus_plus/test/src/ast-template-test.cpp b/src/main/resources/templates/c_plus_plus/test/src/ast-template-test.cpp deleted file mode 100644 index 4a094c62b067..000000000000 --- a/src/main/resources/templates/c_plus_plus/test/src/ast-template-test.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "ast-template.hpp" - -#include - -TEST_CASE("AST Templated") { - auto expr = ("x"_var + 1_num) - "y"_var * "z"_var + "x"_var; - auto expr2 = 123_num + 24_num * (3_num - 4_num * 5_num); - - CHECK(evaluate(expr, {.values = {{"x", 1}, {"y", 4}, {"z", 2}}}) == -5); - CHECK(evaluate(expr, {.values = {{"x", 3}, {"y", -5}, {"z", 0}}}) == 7); - CHECK(evaluate(expr2) == -285); - - CHECK(reverse_polish(expr) == "x 1 + y z * - x +"); - CHECK(reverse_polish(expr2) == "123 24 3 4 5 * - * +"); -} diff --git a/src/main/resources/templates/c_plus_plus/test/src/linked-list-iterator-test.cpp b/src/main/resources/templates/c_plus_plus/test/src/linked-list-iterator-test.cpp deleted file mode 100644 index 9176b484c06b..000000000000 --- a/src/main/resources/templates/c_plus_plus/test/src/linked-list-iterator-test.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include "../assignment/include/linked-list-iterator.hpp" - -#include -#include -#include -#include - -template -std::vector create_values(); - -template <> -std::vector create_values() { - return std::vector{1, 10, 2, 5, 3, 6, 7, 7, 8, 4}; -} - -template <> -std::vector create_values() { - auto vec = create_values(); - return std::vector{vec.begin(), vec.end()}; -} - -template <> -std::vector create_values() { - return std::vector{"zero", "ten", "two", "five", "three", - "six", "seven", "seven2", "eight", "four"}; -} - -template <> -std::vector> -create_values>() { - return std::vector>{ - {}, - {"zehn", "ziegen", "zogen", "zehn", "zentner", "zucker", "zum", "zoo"}, - {"two", "II"}, - {"Jackson Five", "Peter Davison", "Aaron Doral", "Multipass"}, - {"D'Artagnan", "Athos", "Porthos", "Aramis"}, - {"Catherine of Aragon", "Anne Boleyn", "Jane Seymour", "Anne of Cleves", - "Catherine Howard", "Catherine Parr"}, - {"Seven of Nine", "Seven Deadly Sins"}, - {"7/11"}, - {"8 Mile"}, - {"IV"}}; -} - -TEMPLATE_TEST_CASE("linked_list", "", int, double, std::string, - std::vector) { - // generically contains the values we want to put into the list - auto v = create_values(); - - // Here the actual test starts - linked_list list; - // insertion and deletion - CHECK(list.empty() == true); - list.push_front(v[0]); - CHECK(list.empty() == false); - CHECK(list.front() == v[0]); - CHECK(list.back() == v[0]); - auto ptr1 = &list.front(); - { - // scope to avoid reusing ptr2 - list.push_front(v[1]); - CHECK(list.front() == v[1]); - auto ptr2 = &list.front(); - auto ptr3 = &list.back(); - CHECK(ptr1 == ptr3); - CHECK(*ptr1 == v[0]); - CHECK(*ptr2 == v[1]); - list.pop_front(); - } - CHECK(list.front() == v[0]); - CHECK(&list.front() == ptr1); - CHECK(&list.back() == ptr1); - list.push_front(v[2]); - list.push_back(v[3]); - list.push_front(v[4]); - list.push_back(v[5]); - list.push_back(v[6]); - list.pop_back(); - list.push_back(v[7]); - list.push_back(v[8]); - list.push_front(v[9]); - auto vector = list.to_vector(); - CHECK(vector == std::vector{v[9], v[4], v[2], v[0], v[3], v[5], - v[7], v[8]}); - int i = 0; - for (auto el : list) { - CHECK(vector[i] == el); - i++; - } - // copy construction and assignment - auto list2 = list; - CHECK(&list.front() != &list2.front()); - CHECK(list.to_vector() == list2.to_vector()); - list2.clear(); - CHECK(list2.empty() == true); - linked_list list3; - list3 = list; - CHECK(list3.to_vector() == list.to_vector()); - // self-assignment - { - auto ptr2 = &list.front(); - list = list; - CHECK(list.to_vector() == vector); - CHECK(&list.front() == ptr2); - } - // move construction and assignment - { - auto ptr2 = &list3.front(); - auto list4 = std::move(list3); - CHECK(list3.empty()); - CHECK(list4.to_vector() == list.to_vector()); - CHECK(&list4.front() == ptr2); - linked_list list5; - list5 = std::move(list4); - CHECK(list4.empty()); - CHECK(list5.to_vector() == list.to_vector()); - CHECK(&list5.front() == ptr2); - } -} - -TEMPLATE_TEST_CASE("linked_list insert/erase", "", int, double, std::string, - std::vector) { - // generically contains the values we want to put into the list - auto v = create_values(); - - linked_list list; - list.push_back(v[0]); - list.push_back(v[1]); - list.push_back(v[2]); - list.push_front(v[3]); - auto it = list.begin(); - ++it; - it = list.erase(it); - ++it; - it = list.insert(it, v[4]); - it = list.insert(it, v[5]); - CHECK(list.to_vector() == - std::vector{v[3], v[1], v[5], v[4], v[2]}); -} - -TEMPLATE_TEST_CASE("linked_list iterator algorithms", "", int, double, - std::string, std::vector) { - // generically contains the values we want to put into the list - auto v = create_values(); - - linked_list list; - for (const auto& element : v) { - list.push_back(element); - } - - std::reverse(list.begin(), list.end()); - std::reverse(v.begin(), v.end()); - - CHECK(list.to_vector() == v); -} \ No newline at end of file diff --git a/src/main/resources/templates/c_plus_plus/test/src/sort-test.cpp b/src/main/resources/templates/c_plus_plus/test/src/sort-test.cpp new file mode 100644 index 000000000000..16cddf856c8a --- /dev/null +++ b/src/main/resources/templates/c_plus_plus/test/src/sort-test.cpp @@ -0,0 +1,121 @@ +#include "sort.hpp" + +#include +#include +#include +#include + +#include + +void run_all_algorithms(std::vector& values, const std::vector& expected) { + SECTION("selection_sort") { + selection_sort(values.begin(), values.end()); + REQUIRE(values == expected); + } + SECTION("insertion_sort") { + insertion_sort(values.begin(), values.end()); + REQUIRE(values == expected); + } + SECTION("quicksort") { + quicksort(values.begin(), values.end()); + REQUIRE(values == expected); + } + SECTION("mergesort") { + mergesort(values.begin(), values.end()); + REQUIRE(values == expected); + } + SECTION("mergesort_inplace") { + mergesort_inplace(values.begin(), values.end()); + REQUIRE(values == expected); + } + SECTION("heapsort") { + heapsort(values.begin(), values.end()); + REQUIRE(values == expected); + } + SECTION("heapsort_explicit") { + heapsort_explicit(values.begin(), values.end()); + REQUIRE(values == expected); + } +} + +TEST_CASE("sorting_algorithms") { + std::vector values{6, 2, 4, 2, 1, 7, 0, 2, 3, 4, 8}; + std::vector expected{0, 1, 2, 2, 2, 3, 4, 4, 6, 7, 8}; + + run_all_algorithms(values, expected); +} + +TEST_CASE("sorting_algorithms/all_elements_equal") { + std::vector values(20, 1); + auto expected = values; + + // just to make sure your code doesn't crash on repeated values + run_all_algorithms(values, expected); +} + +TEST_CASE("sorting_algorithms/reverse-sorted_values") { + std::vector values(20, 1); + std::iota(values.begin(), values.end(), 0); + auto expected = values; + std::reverse(values.begin(), values.end()); + + run_all_algorithms(values, expected); +} + +TEST_CASE("sorting_algorithms/single_values") { + std::vector values{4}; + std::vector expected{4}; + + // just to make sure your code doesn't crash on single values + run_all_algorithms(values, expected); +} + +TEST_CASE("sorting_algorithms/empty_input") { + std::vector values; + std::vector expected; + + // just to make sure your code doesn't crash on empty inputs + run_all_algorithms(values, expected); +} + +TEST_CASE("sorting_algorithms/large_input") { + std::vector values; + std::uniform_int_distribution dist{0, 50}; + std::default_random_engine rng; // default seed + for (int i = 0; i < 100; ++i) { + values.push_back(dist(rng)); + } + auto expected = values; + std::sort(expected.begin(), expected.end()); + + run_all_algorithms(values, expected); +} + +TEST_CASE("bogosort") { + // bogosort only works for very small inputs, + // large inputs take forever + std::vector values{6, 2, 4, 2}; + std::vector expected{2, 2, 4, 6}; + + bogosort(values.begin(), values.end()); + + REQUIRE(values == expected); +} + +TEST_CASE("bogosort/empty_input") { + std::vector values{}; + std::vector expected{}; + + bogosort(values.begin(), values.end()); + + REQUIRE(values == expected); +} + +TEST_CASE("bogosort/single_value") { + std::vector values{3}; + std::vector expected{3}; + + bogosort(values.begin(), values.end()); + + REQUIRE(values == expected); +} diff --git a/src/main/resources/templates/c_plus_plus/test/tests/TestCatch2.py b/src/main/resources/templates/c_plus_plus/test/tests/TestCatch2.py index 41b595b4b054..4142813b5c80 100644 --- a/src/main/resources/templates/c_plus_plus/test/tests/TestCatch2.py +++ b/src/main/resources/templates/c_plus_plus/test/tests/TestCatch2.py @@ -13,7 +13,7 @@ def __init__(self, location: str, executable: str, requirements: List[str] = Non def _run(self): # Start the program: outputFilename = f"result-{self.executable}.xml" - self.pWrap = self._createPWrap([join(".", self.executable), "--reporter", f"JUnit::out={outputFilename}", "--reporter", "console::out=-::colour-mode=none"], self.executionDirectory) + self.pWrap = self._createPWrap([join(".", self.executable), "--success", "--reporter", f"JUnit::out={outputFilename}", "--reporter", "console::out=-::colour-mode=none"], self.executionDirectory) self._startPWrap(self.pWrap) self.pWrap.waitUntilTerminationReading() @@ -26,7 +26,7 @@ def _run(self): printTester(f"Appended {catchXmlSuite}") except Exception as E: printTester(f"Exception {str(E)}") - pass + pass if retCode != 0: self._failWith(