From f78d5ea3bba7ac12854f99e0cffdfb0eb83937e5 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Wed, 30 Oct 2024 21:01:42 +0300 Subject: [PATCH 1/8] Added cyclic list (hw6 task 2) --- homework_6/CMakeLists.txt | 2 + homework_6/task_2/CMakeLists.txt | 9 +++++ homework_6/task_2/cyclicList.c | 52 ++++++++++++++++++++++++++ homework_6/task_2/cyclicList.h | 30 +++++++++++++++ homework_6/task_2/test.c | 63 ++++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+) create mode 100644 homework_6/task_2/CMakeLists.txt create mode 100644 homework_6/task_2/cyclicList.c create mode 100644 homework_6/task_2/cyclicList.h create mode 100644 homework_6/task_2/test.c diff --git a/homework_6/CMakeLists.txt b/homework_6/CMakeLists.txt index 1431304..2b83e01 100644 --- a/homework_6/CMakeLists.txt +++ b/homework_6/CMakeLists.txt @@ -1,3 +1,5 @@ project(homework_6) set(homeworkName "${PROJECT_NAME}") + +add_subdirectory(task_2) diff --git a/homework_6/task_2/CMakeLists.txt b/homework_6/task_2/CMakeLists.txt new file mode 100644 index 0000000..42a5034 --- /dev/null +++ b/homework_6/task_2/CMakeLists.txt @@ -0,0 +1,9 @@ +project("${homeworkName}_task_2") + +add_library(cyclicList cyclicList.c) + +# add_executable(${PROJECT_NAME} main.c) +# target_link_libraries(${PROJECT_NAME} cyclicList) + +add_executable(${PROJECT_NAME}_test test.c) +target_link_libraries(${PROJECT_NAME}_test cyclicList) diff --git a/homework_6/task_2/cyclicList.c b/homework_6/task_2/cyclicList.c new file mode 100644 index 0000000..c0ce636 --- /dev/null +++ b/homework_6/task_2/cyclicList.c @@ -0,0 +1,52 @@ +#include "cyclicList.h" + +#include + +typedef struct ListElement { + struct ListElement *left; + struct ListElement *right; + int value; +} ListElement; + +bool addElementAfter(ListElement *element, ListElement **newElement, int value) { + *newElement = malloc(sizeof(ListElement)); + if (*newElement == NULL) { + return false; + } + + if (element == NULL) { + (*newElement)->left = *newElement; + (*newElement)->right = *newElement; + } else { + (*newElement)->left = element; + (*newElement)->right = element->right; + element->right = *newElement; + } + + (*newElement)->value = value; + + return true; +} + +ListElement *getNext(ListElement *element) { + return element->right; +} + +int getValue(ListElement *element) { + return element->value; +} + +void removeElement(ListElement *element) { + element->left->right = element->right; + element->right->left = element->left; + free(element); +} + +void removeAllElements(ListElement *element) { + ListElement *right = element->right; + do { + ListElement *next = right->right; + removeElement(right); + right = next; + } while (right != element); +} diff --git a/homework_6/task_2/cyclicList.h b/homework_6/task_2/cyclicList.h new file mode 100644 index 0000000..d0db94c --- /dev/null +++ b/homework_6/task_2/cyclicList.h @@ -0,0 +1,30 @@ +#pragma once + +/// @brief Cyclic list element +typedef struct ListElement ListElement; + +/// @brief Adds new element after specified element +/// @param element Element that will be on the left relative to new element, +/// must be `NULL` when creating new list +/// @param newElement Pointer to store created `ListElement` to +/// @param value Value to store in new element +/// @return `true` if added successfully, `false` otherwise (allocaton failed) +bool addElementAfter(ListElement *element, ListElement **newElement, int value); + +/// @brief Gets element on the right of the specified element +/// @param element Element of cyclic list +/// @return Element on the right of the specified element +ListElement *getNext(ListElement *element); + +/// @brief Gets value of the specified element +/// @param element Element of cyclic list +/// @return Value of specified element +int getValue(ListElement *element); + +/// @brief Removes an element (and calls `free()` on it) +/// @param element Element to remove +void removeElement(ListElement *element); + +/// @brief Removes all elements of cyclic list +/// @param element Any element of the list +void removeAllElements(ListElement *element); diff --git a/homework_6/task_2/test.c b/homework_6/task_2/test.c new file mode 100644 index 0000000..7753c20 --- /dev/null +++ b/homework_6/task_2/test.c @@ -0,0 +1,63 @@ +#define CTEST_MAIN +#define CTEST_SEGFAULT +#include "../../ctest/ctest.h" + +#include "cyclicList.h" + +int main(int argc, const char *argv[]) { + return ctest_main(argc, argv); +} + +ListElement *add(ListElement *after, int value) { + ListElement *element; + ASSERT_TRUE(addElementAfter(after, &element, value)); + ASSERT_NOT_NULL(element); + + return element; +} + +CTEST(cyclicListTests, createTest) { + ListElement *element = add(NULL, 0); + + ASSERT_TRUE(getNext(element) == element); + ASSERT_TRUE(getNext(getNext(element)) == element); + + removeAllElements(element); +} + +CTEST(cyclicListTests, addElementTest) { + ListElement *elementA = add(NULL, 0); + ListElement *elementB = add(elementA, 1); + ListElement *elementC = add(elementB, 2); + ListElement *elementD = add(elementC, 3); + + ASSERT_TRUE(getNext(elementA) == elementB); + ASSERT_TRUE(getNext(elementB) == elementC); + ASSERT_TRUE(getNext(elementC) == elementD); + ASSERT_TRUE(getNext(elementD) == elementA); + + ASSERT_EQUAL(getValue(elementA), 0); + ASSERT_EQUAL(getValue(elementB), 1); + ASSERT_EQUAL(getValue(elementC), 2); + ASSERT_EQUAL(getValue(elementD), 3); + + removeAllElements(elementA); +} + +CTEST(cyclicListTests, removeElementTest) { + ListElement *elementA = add(NULL, 0); + ListElement *elementB = add(elementA, 0); + ListElement *elementC = add(elementB, 0); + ListElement *elementD = add(elementC, 0); + + removeElement(elementB); + ASSERT_TRUE(getNext(elementA) == elementC); + + removeElement(elementC); + ASSERT_TRUE(getNext(elementA) == elementD); + + removeElement(elementD); + ASSERT_TRUE(getNext(elementA) == elementA); + + removeAllElements(elementA); +} From bb8d7a302683098b2e10c6df3963ae2048d43c48 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Thu, 31 Oct 2024 19:03:11 +0300 Subject: [PATCH 2/8] Refactored list (hw6 task 2) --- homework_6/task_2/cyclicList.c | 30 ++++++++++++++++++------------ homework_6/task_2/cyclicList.h | 4 ++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/homework_6/task_2/cyclicList.c b/homework_6/task_2/cyclicList.c index c0ce636..ab05b4e 100644 --- a/homework_6/task_2/cyclicList.c +++ b/homework_6/task_2/cyclicList.c @@ -8,22 +8,26 @@ typedef struct ListElement { int value; } ListElement; -bool addElementAfter(ListElement *element, ListElement **newElement, int value) { - *newElement = malloc(sizeof(ListElement)); - if (*newElement == NULL) { +bool addElementAfter(ListElement *previous, ListElement **newElement, int value) { + ListElement *element = malloc(sizeof(ListElement)); + if (element == NULL) { return false; } - if (element == NULL) { - (*newElement)->left = *newElement; - (*newElement)->right = *newElement; + if (previous == NULL) { + element->left = element; + element->right = element; } else { - (*newElement)->left = element; - (*newElement)->right = element->right; - element->right = *newElement; + ListElement *next = previous->right; + element->left = previous; + element->right = next; + + next->left = element; + previous->right = element; } - (*newElement)->value = value; + element->value = value; + *newElement = element; return true; } @@ -37,8 +41,10 @@ int getValue(ListElement *element) { } void removeElement(ListElement *element) { - element->left->right = element->right; - element->right->left = element->left; + ListElement *left = element->left; + ListElement *right = element->right; + left->right = right; + right->left = left; free(element); } diff --git a/homework_6/task_2/cyclicList.h b/homework_6/task_2/cyclicList.h index d0db94c..2202736 100644 --- a/homework_6/task_2/cyclicList.h +++ b/homework_6/task_2/cyclicList.h @@ -4,12 +4,12 @@ typedef struct ListElement ListElement; /// @brief Adds new element after specified element -/// @param element Element that will be on the left relative to new element, +/// @param previous Element that will be on the left relative to new element, /// must be `NULL` when creating new list /// @param newElement Pointer to store created `ListElement` to /// @param value Value to store in new element /// @return `true` if added successfully, `false` otherwise (allocaton failed) -bool addElementAfter(ListElement *element, ListElement **newElement, int value); +bool addElementAfter(ListElement *previous, ListElement **newElement, int value); /// @brief Gets element on the right of the specified element /// @param element Element of cyclic list From ee1b602e6bc87a76a2f0a8fb6f30e4f5627424ce Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Thu, 31 Oct 2024 19:04:15 +0300 Subject: [PATCH 3/8] Homework 6 task 2 --- homework_6/task_2/CMakeLists.txt | 4 +-- homework_6/task_2/main.c | 54 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 homework_6/task_2/main.c diff --git a/homework_6/task_2/CMakeLists.txt b/homework_6/task_2/CMakeLists.txt index 42a5034..39ae0b1 100644 --- a/homework_6/task_2/CMakeLists.txt +++ b/homework_6/task_2/CMakeLists.txt @@ -2,8 +2,8 @@ project("${homeworkName}_task_2") add_library(cyclicList cyclicList.c) -# add_executable(${PROJECT_NAME} main.c) -# target_link_libraries(${PROJECT_NAME} cyclicList) +add_executable(${PROJECT_NAME} main.c) +target_link_libraries(${PROJECT_NAME} cyclicList) add_executable(${PROJECT_NAME}_test test.c) target_link_libraries(${PROJECT_NAME}_test cyclicList) diff --git a/homework_6/task_2/main.c b/homework_6/task_2/main.c new file mode 100644 index 0000000..44463de --- /dev/null +++ b/homework_6/task_2/main.c @@ -0,0 +1,54 @@ +#include + +#include "cyclicList.h" + +bool getLastWarrior(int warriorsCount, int killersPerWarrior, int *result) { + ListElement *lastElement = NULL; + for (int i = 0; i < warriorsCount; ++i) { + ListElement *newElement = NULL; + if (!addElementAfter(lastElement, &newElement, i + 1)) { + return false; + } + + lastElement = newElement; + } + + // set lastElement to point to element + lastElement = getNext(lastElement); + + while (getNext(lastElement) != lastElement) { + for (int i = 0; i < killersPerWarrior; ++i) { + lastElement = getNext(lastElement); + } + ListElement *next = getNext(lastElement); + removeElement(lastElement); + lastElement = next; + } + + *result = getValue(lastElement); + removeAllElements(lastElement); + + return true; +} + +int readValue(const char *prompt, const char *incorrectValueMessage) { + int value; + printf("%s", prompt); + while ((scanf("%d", &value) != 1) || value <= 0) { + while (getchar() != '\n') {} + printf("%s", incorrectValueMessage); + } +} + +int main(void) { + int warriorsCount = readValue("warriors count: ", "incorrect value; warriors count should be greater than zero; try again: "); + int nthWarrior = readValue("n-th warrior to be killed: ", "incorrect value; n should be greater than zero; try again: "); + + int result = 0; + if (!getLastWarrior(warriorsCount, nthWarrior - 1, &result)) { + printf("allocation error\n"); + return 1; + } + + printf("last warrior: %d\n", result); +} From 6470ad20359997b592a165896f1c1a33fb9754e7 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:35:29 +0300 Subject: [PATCH 4/8] Added missing return statement --- homework_6/task_2/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/homework_6/task_2/main.c b/homework_6/task_2/main.c index 44463de..1bd6edf 100644 --- a/homework_6/task_2/main.c +++ b/homework_6/task_2/main.c @@ -38,6 +38,7 @@ int readValue(const char *prompt, const char *incorrectValueMessage) { while (getchar() != '\n') {} printf("%s", incorrectValueMessage); } + return value; } int main(void) { From 7e5f2d6e28a2dfad5f6bb09a132b7ea4352b091f Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:21:48 +0300 Subject: [PATCH 5/8] Added stdbool.h includes (hw6 task 2) --- homework_6/task_2/cyclicList.c | 1 + homework_6/task_2/cyclicList.h | 2 ++ homework_6/task_2/main.c | 1 + 3 files changed, 4 insertions(+) diff --git a/homework_6/task_2/cyclicList.c b/homework_6/task_2/cyclicList.c index ab05b4e..d5d7a96 100644 --- a/homework_6/task_2/cyclicList.c +++ b/homework_6/task_2/cyclicList.c @@ -1,5 +1,6 @@ #include "cyclicList.h" +#include #include typedef struct ListElement { diff --git a/homework_6/task_2/cyclicList.h b/homework_6/task_2/cyclicList.h index 2202736..bed6111 100644 --- a/homework_6/task_2/cyclicList.h +++ b/homework_6/task_2/cyclicList.h @@ -1,5 +1,7 @@ #pragma once +#include + /// @brief Cyclic list element typedef struct ListElement ListElement; diff --git a/homework_6/task_2/main.c b/homework_6/task_2/main.c index 1bd6edf..b2aa61b 100644 --- a/homework_6/task_2/main.c +++ b/homework_6/task_2/main.c @@ -1,3 +1,4 @@ +#include #include #include "cyclicList.h" From d226c392369cd382d70cba69b1192e8b4f5e0cf4 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:52:15 +0300 Subject: [PATCH 6/8] Added stdlib.h include (hw6 task 2) --- homework_6/task_2/test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homework_6/task_2/test.c b/homework_6/task_2/test.c index 7753c20..6a22df2 100644 --- a/homework_6/task_2/test.c +++ b/homework_6/task_2/test.c @@ -2,6 +2,8 @@ #define CTEST_SEGFAULT #include "../../ctest/ctest.h" +#include + #include "cyclicList.h" int main(int argc, const char *argv[]) { From 45e8ccf9ce87bf16147ea4428a565e3d616ee346 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Wed, 25 Dec 2024 19:30:23 +0300 Subject: [PATCH 7/8] Added task name to README (hw6 task 2) --- homework_6/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homework_6/README.md b/homework_6/README.md index 4a2824e..3a5fddc 100644 --- a/homework_6/README.md +++ b/homework_6/README.md @@ -1 +1,3 @@ # Homework 6 + +[Task 1. Counting rhyme](/homework_6/task_2) From 42a41660a8d2f4d1b136af96eaa47be3543542ce Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Wed, 25 Dec 2024 19:32:08 +0300 Subject: [PATCH 8/8] Fixed task name (hw6 task 2) --- homework_6/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_6/README.md b/homework_6/README.md index 3a5fddc..88e7b4d 100644 --- a/homework_6/README.md +++ b/homework_6/README.md @@ -1,3 +1,3 @@ # Homework 6 -[Task 1. Counting rhyme](/homework_6/task_2) +[Task 2. Counting rhyme](/homework_6/task_2)