From 8678cfebbba45c60cf7186b4878628e8bd3b44ef Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Fri, 8 Nov 2024 23:56:31 +0300 Subject: [PATCH 1/6] Homework 6 task 3 (WIP) --- homework_6/CMakeLists.txt | 2 + homework_6/task_3/CMakeLists.txt | 9 ++ homework_6/task_3/main.c | 133 +++++++++++++++++++++++++++++ homework_6/task_3/sortedList.c | 118 ++++++++++++++++++++++++++ homework_6/task_3/sortedList.h | 21 +++++ homework_6/task_3/test.c | 140 +++++++++++++++++++++++++++++++ 6 files changed, 423 insertions(+) create mode 100644 homework_6/task_3/CMakeLists.txt create mode 100644 homework_6/task_3/main.c create mode 100644 homework_6/task_3/sortedList.c create mode 100644 homework_6/task_3/sortedList.h create mode 100644 homework_6/task_3/test.c diff --git a/homework_6/CMakeLists.txt b/homework_6/CMakeLists.txt index 1431304..9299a7a 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_3) diff --git a/homework_6/task_3/CMakeLists.txt b/homework_6/task_3/CMakeLists.txt new file mode 100644 index 0000000..3da8703 --- /dev/null +++ b/homework_6/task_3/CMakeLists.txt @@ -0,0 +1,9 @@ +project("${homeworkName}_task_3") + +add_library(sortedList sortedList.c) + +add_executable(${PROJECT_NAME} main.c) +target_link_libraries(${PROJECT_NAME} sortedList) + +add_executable(${PROJECT_NAME}_test test.c) +target_link_libraries(${PROJECT_NAME}_test sortedList) diff --git a/homework_6/task_3/main.c b/homework_6/task_3/main.c new file mode 100644 index 0000000..6391e5a --- /dev/null +++ b/homework_6/task_3/main.c @@ -0,0 +1,133 @@ +#include + +#include "sortedList.h" + +typedef enum { + Exit, + Menu, + AddElement, + RemoveElement, + PrintList +} State; + +State readCommand(void) { + int command = -1; + if (scanf("%d", &command) != 1) { + command = -1; + } + while (getchar() != '\n') {} + switch (command) { + case 0: + return Exit; + case 1: + return AddElement; + case 2: + return RemoveElement; + case 3: + return PrintList; + default: + printf("Error: unknown command\n"); + return Menu; + } +} + +State addElementCommand(SortedList *list) { + printf("Enter a number to add: "); + int value = 0; + if (scanf("%d", &value) != 1) { + printf("Error: not a number\n"); + return Menu; + } + + if (!addElement(list, value)) { + printf("Error: cannot add number\n"); + return Menu; + } + + return Menu; +} + +State removeElementCommand(SortedList *list) { + printf("Enter a number to remove: "); + int value = 0; + if (scanf("%d", &value) != 1) { + printf("Error: not a number\n"); + return Menu; + } + + if (!removeElement(list, value)) { + printf("Error: cannot remove number; probably, it isn't in the list\n"); + return Menu; + } + + return Menu; +} + +State printListCommand(SortedList *list) { + printf("[ "); + Element *element = getFirst(list); + while (element != NULL) { + printf("%d", getValue(element)); + + element = getNext(element); + if (element != NULL & getNext(element) != NULL) { + printf(", "); + } + } + printf(" ]\n"); + + return Menu; +} + +bool doConversation(SortedList *list) { + printf("Sorted list\n"); + printf("Available commands: \n"); + printf(" 0 - exit;\n"); + printf(" 1 - add a number;\n"); + printf(" 2 - remove a number;\n"); + printf(" 3 - print list.\n"); + + State state = Menu; + while (true) { + switch (state) + { + case Exit: + return true; + + case Menu: + printf("sorted_list> "); + state = readCommand(); + break; + + case AddElement: + state = addElementCommand(list); + break; + + case RemoveElement: + state = removeElementCommand(list); + break; + + case PrintList: + state = printListCommand(list); + break; + + default: + printf("Error: unknown state\n"); + return false; + } + } +} + +int main(void) { + SortedList *list = NULL; + if (!createList(&list)) { + printf("Error: allocation failed\n"); + return 1; + } + + if (!doConversation(list)) { + disposeList(list); + return 1; + } + disposeList(list); +} diff --git a/homework_6/task_3/sortedList.c b/homework_6/task_3/sortedList.c new file mode 100644 index 0000000..811fc90 --- /dev/null +++ b/homework_6/task_3/sortedList.c @@ -0,0 +1,118 @@ +#include "sortedList.h" + +#include +#include + +typedef struct Element { + int value; + struct Element *next; +} Element; + +typedef struct SortedList { + Element *first; +} SortedList; + +bool createList(SortedList **list) { + *list = malloc(sizeof(SortedList)); + if (*list == NULL) { + return false; + } + + (*list)->first = NULL; + // (*list)->last = NULL; + + return true; +} + +bool addElement(SortedList *list, int value) { + Element *element = malloc(sizeof(Element)); + if (element == NULL) { + return false; + } + + element->value = value; + element->next = NULL; + + if (list->first == NULL) { + list->first = element; + return true; + } + + if (value < getValue(list->first)) { + element->next = list->first; + list->first = element; + return true; + } + + Element *last = list->first; + while (last->next != NULL) { + if (getValue(last->next) > value) { + break; + } + + last = last->next; + } + + element->next = last->next; + last->next = element; + + return true; +} + +bool removeElement(SortedList *list, int value) { + if (list->first == NULL) { + return false; + } + + if (value < getValue(list->first)) { + return false; + } + + if (value == getValue(list->first)) { + Element *next = list->first->next; + free(list->first); + list->first = next; + return true; + } + + Element *last = list->first; + while (last->next != NULL) { + if (getValue(last->next) == value) { + break; + } + + last = last->next; + } + + if (last->next == NULL) { + return false; + } + + Element *next = last->next->next; + free(last->next); + last->next = next; + + return true; +} + +Element *getFirst(SortedList *list) { + return list->first; +} + +void disposeList(SortedList *list) { + Element *last = list->first; + while (last != NULL) { + Element *next = last->next; + free(last); + last = next; + } + free(list); +} + +Element *getNext(Element *element) { + return element->next; +} + +int getValue(Element *element) { + return element->value; +} diff --git a/homework_6/task_3/sortedList.h b/homework_6/task_3/sortedList.h new file mode 100644 index 0000000..156631d --- /dev/null +++ b/homework_6/task_3/sortedList.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +typedef struct Element Element; + +typedef struct SortedList SortedList; + +bool createList(SortedList **list); + +bool addElement(SortedList *list, int value); + +bool removeElement(SortedList *list, int value); + +Element *getFirst(SortedList *list); + +void disposeList(SortedList *list); + +Element *getNext(Element *element); + +int getValue(Element *element); diff --git a/homework_6/task_3/test.c b/homework_6/task_3/test.c new file mode 100644 index 0000000..a26ec9c --- /dev/null +++ b/homework_6/task_3/test.c @@ -0,0 +1,140 @@ +#define CTEST_MAIN +#define CTEST_SEGFAULT +#include "../../ctest/ctest.h" + +#include + +#include "sortedList.h" + +int main(int argc, const char *argv[]) { + return ctest_main(argc, argv); +} + +SortedList *createNewList(void) { + SortedList *list = NULL; + ASSERT_TRUE(createList(&list)); + return list; +} + +void addToList(SortedList *list, int value) { + ASSERT_TRUE(addElement(list, value)); +} + +void assertEqual(SortedList *list, const int *array, int size) { + int i = 0; + Element *element = getFirst(list); + while (element != NULL) { + ASSERT_LE(i, size); + ASSERT_EQUAL(getValue(element), array[i]); + ++i; + element = getNext(element); + } + ASSERT_EQUAL(i, size); +} + +CTEST(sortedListTests, emptyListTest) { + SortedList *list = createNewList(); + assertEqual(list, NULL, 0); +} + +CTEST(sortedListTests, singleElementTest) { +#define size 1 + SortedList *list = createNewList(); + addToList(list, 5); + + int array[size] = { 5 }; + assertEqual(list, array, size); +#undef size +} + +CTEST(sortedListTests, constantSizeListTestA) { +#define size 4 + SortedList *list = createNewList(); + addToList(list, 1); + addToList(list, 4); + addToList(list, 9); + addToList(list, 13); + + int array[size] = { 1, 4, 9, 13 }; + assertEqual(list, array, size); +#undef size +} + +CTEST(sortedListTests, constantSizeListTestB) { +#define size 8 + SortedList *list = createNewList(); + addToList(list, 45); + addToList(list, 22); + addToList(list, 52); + addToList(list, 282); + addToList(list, -23); + addToList(list, 0); + addToList(list, 3432); + addToList(list, 734); + + int array[size] = { -23, 0, 22, 45, 52, 282, 734, 3432 }; + assertEqual(list, array, size); +#undef size +} + +CTEST(sortedListTests, addAndRemoveElementsTest) { +#define size 8 + SortedList *list = createNewList(); + addToList(list, 543); + addToList(list, 62); + addToList(list, 224); + addToList(list, -234); + addToList(list, 4352); + addToList(list, 6); + addToList(list, -675); + addToList(list, 879); + + int arrayA[size] = { -675, -234, 6, 62, 224, 543, 879, 4352 }; + assertEqual(list, arrayA, size); + + ASSERT_TRUE(removeElement(list, -675)); +#define size 7 + int arrayB[size] = { -234, 6, 62, 224, 543, 879, 4352 }; + assertEqual(list, arrayB, size); + + ASSERT_TRUE(removeElement(list, 4352)); +#define size 6 + int arrayC[size] = { -234, 6, 62, 224, 543, 879 }; + assertEqual(list, arrayC, size); + + ASSERT_TRUE(removeElement(list, 224)); +#define size 5 + int arrayD[size] = { -234, 6, 62, 543, 879 }; + assertEqual(list, arrayD, size); + + ASSERT_TRUE(removeElement(list, 543)); +#define size 4 + int arrayE[size] = { -234, 6, 62, 879 }; + assertEqual(list, arrayE, size); + + ASSERT_TRUE(removeElement(list, 6)); +#define size 3 + int arrayF[size] = { -234, 62, 879 }; + assertEqual(list, arrayF, size); + + ASSERT_TRUE(removeElement(list, -234)); +#define size 2 + int arrayG[size] = { 62, 879 }; + assertEqual(list, arrayG, size); + + ASSERT_TRUE(removeElement(list, 879)); + ASSERT_EQUAL(getValue(getFirst(list)), 62); + + ASSERT_FALSE(removeElement(list, -1)); + ASSERT_FALSE(removeElement(list, 100)); + + ASSERT_TRUE(removeElement(list, 62)); + + ASSERT_FALSE(removeElement(list, 0)); + ASSERT_FALSE(removeElement(list, 12)); + ASSERT_FALSE(removeElement(list, 100)); + + ASSERT_NULL(getFirst(list)); + +#undef size +} From 954fad365079f9533079172b3a53acd428f5c3ef Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sat, 9 Nov 2024 00:08:10 +0300 Subject: [PATCH 2/6] Fixed list printing --- homework_6/task_3/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_6/task_3/main.c b/homework_6/task_3/main.c index 6391e5a..0766e4f 100644 --- a/homework_6/task_3/main.c +++ b/homework_6/task_3/main.c @@ -70,7 +70,7 @@ State printListCommand(SortedList *list) { printf("%d", getValue(element)); element = getNext(element); - if (element != NULL & getNext(element) != NULL) { + if (element != NULL) { printf(", "); } } From e0cde7ddd34d35b7e60919f9dac154747b896f0f Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sat, 9 Nov 2024 01:51:56 +0300 Subject: [PATCH 3/6] Added comments (hw6 task 3) --- homework_6/task_3/sortedList.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/homework_6/task_3/sortedList.h b/homework_6/task_3/sortedList.h index 156631d..cb8c982 100644 --- a/homework_6/task_3/sortedList.h +++ b/homework_6/task_3/sortedList.h @@ -2,20 +2,44 @@ #include +/// @brief Element of the sorted list typedef struct Element Element; +/// @brief List of numbers that remains always sorted typedef struct SortedList SortedList; +/// @brief Creates new instance of `SortedList` +/// @param list Pointer to store list to +/// @return `true` if created successfully, `false` otherwise (allocation failed) bool createList(SortedList **list); +/// @brief Adds value to list +/// @param list List to add value to +/// @param value Value to add +/// @return `true` if added successfully, `false` otherwise (allocation failed) bool addElement(SortedList *list, int value); +/// @brief Removes value from list +/// @param list List to remove value from +/// @param value Value to remove +/// @return `true` if removed successfully, `false` otherwise (element doesn't exist in list) bool removeElement(SortedList *list, int value); +/// @brief Gets first element in list +/// @param list List to get first element from +/// @return First element in list Element *getFirst(SortedList *list); +/// @brief Disposes list and all of its elements +/// @param list List to dispose void disposeList(SortedList *list); +/// @brief Gets element that follows specified element +/// @param element An element +/// @return Element that follows specified element Element *getNext(Element *element); +/// @brief Gets value of specified element +/// @param element An element +/// @return Value of an element int getValue(Element *element); From a99531caefaa7d4ebb4e3a0302858ab00908d66c Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Fri, 29 Nov 2024 14:55:17 +0300 Subject: [PATCH 4/6] Fixed macro redefinition (hw6 task 3) --- homework_6/task_3/test.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/homework_6/task_3/test.c b/homework_6/task_3/test.c index a26ec9c..35d9393 100644 --- a/homework_6/task_3/test.c +++ b/homework_6/task_3/test.c @@ -93,36 +93,33 @@ CTEST(sortedListTests, addAndRemoveElementsTest) { assertEqual(list, arrayA, size); ASSERT_TRUE(removeElement(list, -675)); -#define size 7 - int arrayB[size] = { -234, 6, 62, 224, 543, 879, 4352 }; - assertEqual(list, arrayB, size); + int arrayB[size - 1] = { -234, 6, 62, 224, 543, 879, 4352 }; + assertEqual(list, arrayB, size - 1); ASSERT_TRUE(removeElement(list, 4352)); -#define size 6 - int arrayC[size] = { -234, 6, 62, 224, 543, 879 }; - assertEqual(list, arrayC, size); + int arrayC[size - 2] = { -234, 6, 62, 224, 543, 879 }; + assertEqual(list, arrayC, size - 2); ASSERT_TRUE(removeElement(list, 224)); -#define size 5 - int arrayD[size] = { -234, 6, 62, 543, 879 }; - assertEqual(list, arrayD, size); + int arrayD[size - 3] = { -234, 6, 62, 543, 879 }; + assertEqual(list, arrayD, size - 3); ASSERT_TRUE(removeElement(list, 543)); -#define size 4 - int arrayE[size] = { -234, 6, 62, 879 }; - assertEqual(list, arrayE, size); + int arrayE[size - 4] = { -234, 6, 62, 879 }; + assertEqual(list, arrayE, size - 4); ASSERT_TRUE(removeElement(list, 6)); -#define size 3 - int arrayF[size] = { -234, 62, 879 }; - assertEqual(list, arrayF, size); + int arrayF[size - 5] = { -234, 62, 879 }; + assertEqual(list, arrayF, size - 5); ASSERT_TRUE(removeElement(list, -234)); -#define size 2 - int arrayG[size] = { 62, 879 }; - assertEqual(list, arrayG, size); + int arrayG[size - 6] = { 62, 879 }; + assertEqual(list, arrayG, size - 6); ASSERT_TRUE(removeElement(list, 879)); + int arrayH[size - 7] = { 62 }; + assertEqual(list, arrayH, size - 7); + ASSERT_EQUAL(getValue(getFirst(list)), 62); ASSERT_FALSE(removeElement(list, -1)); From 14bb0a7905da01a2835f0c4b7865a6daa41bf538 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:24:58 +0300 Subject: [PATCH 5/6] Added stdbool.h include (hw6 task 3) --- homework_6/task_3/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/homework_6/task_3/main.c b/homework_6/task_3/main.c index 0766e4f..7fb35aa 100644 --- a/homework_6/task_3/main.c +++ b/homework_6/task_3/main.c @@ -1,3 +1,4 @@ +#include #include #include "sortedList.h" From d4184c5f3b6393623f43c71044dce508f20e1da4 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Wed, 25 Dec 2024 19:31:21 +0300 Subject: [PATCH 6/6] Added task name to README (hw6 task 3) --- homework_6/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homework_6/README.md b/homework_6/README.md index 4a2824e..48b6cce 100644 --- a/homework_6/README.md +++ b/homework_6/README.md @@ -1 +1,3 @@ # Homework 6 + +[Task 3. Sorted list](/homework_6/task_3)