diff --git a/HW5/rhyme/circularList/circularList.c b/HW5/rhyme/circularList/circularList.c new file mode 100644 index 0000000..f0e059b --- /dev/null +++ b/HW5/rhyme/circularList/circularList.c @@ -0,0 +1,77 @@ +#include "circularList.h" +#include +#include + +int addToList(int data, CircularList **head) { + CircularList *newNode = (CircularList *)malloc(sizeof(CircularList)); + if (newNode == NULL) + return -1; + + newNode->data = data; + + if (*head == NULL) { + newNode->next = newNode; + *head = newNode; + return 0; + } + + CircularList *current = *head; + while (current->next != *head) + current = current->next; + newNode->next = *head; + current->next = newNode; + return 0; +} + +int removeFromList(int data, CircularList **head) { + if (*head == NULL) + return -1; + + CircularList *current = *head; + CircularList *prev = NULL; + + do { + if (current->data == data) + break; + prev = current; + current = current->next; + } while (current != *head); + + if (current->data != data) + return -1; + + if (current->next == current) { + free(current); + *head = NULL; + return 0; + } + + if (current == *head) { + prev = *head; + while (prev->next != *head) + prev = prev->next; + *head = current->next; + } + + prev->next = current->next; + free(current); + return 0; +} + +void freeList(CircularList *head) { + if (head == NULL) + return; + + CircularList *last = head; + while (last->next != head) + last = last->next; + last->next = NULL; + + CircularList *current = head; + while (current != NULL) { + CircularList *next = current->next; + free(current); + current = next; + } +} + diff --git a/HW5/rhyme/circularList/circularList.h b/HW5/rhyme/circularList/circularList.h new file mode 100644 index 0000000..e837ea7 --- /dev/null +++ b/HW5/rhyme/circularList/circularList.h @@ -0,0 +1,29 @@ +#pragma once + +typedef struct CircularList { + int data; + struct CircularList *next; +} CircularList; + +/** + * @brief Add element to list + * @param data Integer to add + * @param head Pointer to pointer of list head + * @return -1 if couldn't allocate memory, 0 otherwise + */ +int addToList(int data, CircularList **head); + +/** + * @brief Remove element from list + * @param data Integer to remove + * @param head Pointer to pointer of list head + * @return -1 if couldn't find element, 0 otherwise + */ +int removeFromList(int data, CircularList **head); + +/** + * @brief Free list data + * @param head Pointer to list head + */ +void freeList(CircularList *head); + diff --git a/HW5/rhyme/src/main.c b/HW5/rhyme/src/main.c new file mode 100644 index 0000000..523ed4d --- /dev/null +++ b/HW5/rhyme/src/main.c @@ -0,0 +1,74 @@ +#include "../circularList/circularList.h" +#include +#include + +int rhyme(int numWarrior, int numMurder); + +int main() { + int n = 41; + int m = 3; + int result = rhyme(n, m); + if (result != -1) + printf("Initial position should be: %d\n", result); + + n = 1; + m = 1; + result = rhyme(n, m); + if (result != -1) + printf("Initial position should be: %d\n", result); + + n = 2; + m = 2; + result = rhyme(n, m); + if (result != -1) + printf("Initial position should be: %d\n", result); + + n = 7; + m = 3; + result = rhyme(n, m); + if (result != -1) + printf("Initial position should be: %d\n", result); + + return 0; +} + +int rhyme(int numWarrior, int numMurder) { + if (numWarrior <= 0 || numMurder <= 0) { + printf("Incorrect initial data"); + return -1; + } + + CircularList *head = NULL; + for (int i = 1; i <= numWarrior; ++i) { + if (addToList(i, &head) == -1) { + printf("Couldn't allocate memory"); + freeList(head); + return -1; + } + } + + CircularList *prev = head; + while (prev->next != head) + prev = prev->next; + + CircularList *current = head; + + while (current->next != current) { + for (int i = 0; i < numMurder - 1; ++i) { + prev = current; + current = current->next; + } + + prev->next = current->next; + if (current == head) + head = current->next; + + CircularList *toDelete = current; + current = current->next; + free(toDelete); + } + int lastPos = current->data; + free(current); + return lastPos; +} +