diff --git a/.gitignore b/.gitignore index b48d248..b1e499b 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,7 @@ Module.symvers Mkfile.old dkms.conf +# CMake +build + # End of https://www.toptal.com/developers/gitignore/api/c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d9c782e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.25) + +# Advanced bracket balance +project(advanced_bracket_balance C) + +add_library(stack src/stack_and_queue/stack/stack.c) + +add_executable(advanced_bracket_balance src/stack_and_queue/stack/advanced_bracket_balance.c) +target_link_libraries(advanced_bracket_balance PRIVATE stack) +target_compile_options(advanced_bracket_balance PRIVATE -Wall -Wextra -pedantic) + +# Purely functional queue test +project(purely_functional_queue_test C) + +add_library(purely_functional_queue src/control_work_2/purely_functional_queue/purely_functional_queue.c) + +add_executable(purely_functional_queue_test src/control_work_2/purely_functional_queue/test.c) +target_link_libraries(purely_functional_queue_test PRIVATE purely_functional_queue) +target_compile_options(purely_functional_queue PRIVATE -Wall -Wextra -pedantic) + +# Comparsion +project(comparsion C) + +add_executable(comparsion src/control_work_2/comparsion_in_binary/comparsion_in_binary.c) +target_compile_options(comparsion PRIVATE -Wall -Wextra -pedantic) diff --git a/src/control_work_2/comparsion_in_binary/comparsion_in_binary.c b/src/control_work_2/comparsion_in_binary/comparsion_in_binary.c new file mode 100644 index 0000000..26b66fe --- /dev/null +++ b/src/control_work_2/comparsion_in_binary/comparsion_in_binary.c @@ -0,0 +1,44 @@ +#include +#include +#include + +/* +Compares two numbers in binary form без ведущих нулей, исключая число 0. +If first is bigger, returns 1, if second - -1. +If they equvalent, returns 0. +*/ +int compare(bool* a, bool* b, int aLen, int bLen) +{ + if (aLen > bLen) { + return 1; + } + if (bLen > aLen) { + return -1; + } + for (int i = aLen - 1; i >= 0; --i) { + if (a[i] > b[i]) { + return 1; + } + if (b[i] > a[i]) { + return -1; + } + } + return 0; +} + +int main() +{ + bool a[] = { 1, 1, 0 }; + bool b[] = { 1, 0, 1 }; + assert(compare(a, b, 3, 3) == 1 && "Compare 1 incorrect"); + bool a2[] = { 0 }; + bool b2[] = { 1 }; + assert(compare(a2, b2, 1, 1) == -1 && "Compare 2 incorrect"); + bool a3[] = { 1 }; + bool b3[] = { 1 }; + assert(compare(a3, b3, 1, 1) == 0 && "Compare 3 incorrect"); + + printf("All test are correct.\n"); + + return 0; +} diff --git a/src/control_work_2/purely_functional_queue/purely_functional_queue.c b/src/control_work_2/purely_functional_queue/purely_functional_queue.c new file mode 100644 index 0000000..c81bb16 --- /dev/null +++ b/src/control_work_2/purely_functional_queue/purely_functional_queue.c @@ -0,0 +1,77 @@ +#include "purely_functional_queue.h" + +#include +#include + +typedef struct ListElement { + int value; + struct ListElement* next; + struct ListElement* prev; +} ListElement; + +typedef struct Queue { + ListElement* fHead; + ListElement* rHead; +} Queue; + +void swapLists(Queue* queue) +{ + ListElement* currentElement = queue->rHead; + ListElement* previousElement = currentElement; + while (currentElement != NULL) { + ListElement* temp = currentElement->next; + currentElement->next = currentElement->prev; + currentElement->prev = temp; + + previousElement = currentElement; + currentElement = currentElement->next; + } + + queue->fHead = previousElement; + queue->rHead = NULL; +} + +Queue* createQueue() +{ + Queue* queue = malloc(sizeof(*queue)); + assert(queue != NULL && "Error! Memory is not allocated."); + queue->fHead = NULL; + queue->rHead = NULL; + return queue; +} + +void enqueue(Queue* queue, int value) +{ + ListElement* newElement = malloc(sizeof(*newElement)); + assert(newElement != NULL && "Error! Memory is not allocated."); + newElement->value = value; + newElement->next = NULL; + newElement->prev = queue->rHead; + queue->rHead = newElement; +} + +int dequeue(Queue* queue) +{ + if (queue->fHead == NULL) { + swapLists(queue); + } + if (queue->fHead == NULL) { + return -1; + } + + int value = queue->fHead->value; + ListElement* newHead = queue->fHead->prev; + free(queue->fHead); + queue->fHead = newHead; + queue->fHead->next = NULL; + + return value; +} + +void deleteQueue(Queue* queue) +{ + while (queue->fHead != NULL || queue->rHead != NULL) { + dequeue(queue); + } + free(queue); +} diff --git a/src/control_work_2/purely_functional_queue/purely_functional_queue.h b/src/control_work_2/purely_functional_queue/purely_functional_queue.h new file mode 100644 index 0000000..57f1fee --- /dev/null +++ b/src/control_work_2/purely_functional_queue/purely_functional_queue.h @@ -0,0 +1,24 @@ +#pragma once + +typedef struct Queue Queue; + +/* +Creates purely functional queue and returns pointer on it. +*/ +Queue* createQueue(); + +/* +Pushes value in the queue. +*/ +void enqueue(Queue* queue, int value); + +/* +Pops value from the queue. +If queue is empty, returns -1. +*/ +int dequeue(Queue* queue); + +/* +Creates deletes queue and frees memory. +*/ +void deleteQueue(Queue* queue); diff --git a/src/control_work_2/purely_functional_queue/test.c b/src/control_work_2/purely_functional_queue/test.c new file mode 100644 index 0000000..ab32d40 --- /dev/null +++ b/src/control_work_2/purely_functional_queue/test.c @@ -0,0 +1,19 @@ +#include "purely_functional_queue.c" + +#include +#include + +int main() +{ + Queue* queue = createQueue(); + assert(queue != NULL && queue->fHead == NULL && queue->rHead == NULL && "Queue created incorrect."); + assert(dequeue(queue) == -1 && "Dequeue from empty queue works incorrect."); + enqueue(queue, 1); + assert(queue->rHead->value == 1 && "Enqueue works incorrect."); + assert(dequeue(queue) == 1 && "Dequeue works incorrect."); + enqueue(queue, 1); + enqueue(queue, 2); + assert(dequeue(queue) == 1 && "Dequeue with many elements works incorrect."); + assert(queue->fHead->value == 2 && "ListSwap works incorrect."); + deleteQueue(queue); +} diff --git a/src/stack_and_queue/stack/README.md b/src/stack_and_queue/stack/README.md new file mode 100644 index 0000000..b35bd8e --- /dev/null +++ b/src/stack_and_queue/stack/README.md @@ -0,0 +1,3 @@ +## Compile inctruction for advanced brackets balance +cmake . -B build\ +cmake --build build diff --git a/src/stack_and_queue/stack/advanced_bracket_balance.c b/src/stack_and_queue/stack/advanced_bracket_balance.c new file mode 100644 index 0000000..4ea2006 --- /dev/null +++ b/src/stack_and_queue/stack/advanced_bracket_balance.c @@ -0,0 +1,79 @@ +#include "stack.h" +#include +#include +#include + +bool isBracket(char c) +{ + return (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}'); +} + +// Checks brackets balance. +// Returns true if brackets balanced and false if not. +// Takes string. +bool isBracketsBalanced(char* string) +{ + int size = strlen(string); + Stack* brackets = newStack(); + + for (int i = 0; i < size; i++) { + // If char is opening bracket, pushes individual for all bracket types number in the stack. + // If char is closing bracket, pops number from the stack. If number is not right, returns false. + if (isBracket(string[i])) { + if (string[i] == '(') { + push(brackets, 1); + } + if (string[i] == '[') { + push(brackets, 2); + } + if (string[i] == '{') { + push(brackets, 3); + } + if (string[i] == ')') { + if (pop(brackets) != 1) { + deleteStack(brackets); + return false; + } + } + if (string[i] == ']') { + if (pop(brackets) != 2) { + deleteStack(brackets); + return false; + } + } + if (string[i] == '}') { + if (pop(brackets) != 3) { + deleteStack(brackets); + return false; + } + } + } + } + // Check for all brackets closed. + if (!isEmpty(brackets)) { + deleteStack(brackets); + return false; + } + + deleteStack(brackets); + return true; +} + +int main() +{ + char a[] = "T(e){s}[t]"; + char b[] = "123"; + char c[] = ""; + char d[] = "("; + char e[] = "({a)}"; + char f[] = "((({{{[[[]]]}}})))"; + + printf("%s - %d\n", a, isBracketsBalanced(a)); + printf("%s - %d\n", b, isBracketsBalanced(b)); + printf("%s - %d\n", c, isBracketsBalanced(c)); + printf("%s - %d\n", d, isBracketsBalanced(d)); + printf("%s - %d\n", e, isBracketsBalanced(e)); + printf("%s - %d\n", f, isBracketsBalanced(f)); + + return 0; +} diff --git a/src/stack_and_queue/stack/stack.c b/src/stack_and_queue/stack/stack.c new file mode 100644 index 0000000..7dfb49a --- /dev/null +++ b/src/stack_and_queue/stack/stack.c @@ -0,0 +1,64 @@ +#include "stack.h" + +#include +#include +#include + +typedef struct StackNode { + int value; + struct StackNode* next; +} StackNode; + +struct Stack { + StackNode* head; +}; + +Stack* newStack() +{ + Stack* stack = malloc(sizeof(*stack)); + stack->head = NULL; + return stack; +} + +void deleteStack(Stack* stack) +{ + while (stack->head != NULL) { + pop(stack); + } + free(stack); +} + +void push(Stack* stack, int value) +{ + StackNode* newNode = malloc(sizeof(*newNode)); + newNode->value = value; + newNode->next = stack->head; + stack->head = newNode; +} + +int pop(Stack* stack) +{ + if (isEmpty(stack)) { + return -1; + } + + StackNode* poppedNode = stack->head; + int value = poppedNode->value; + stack->head = poppedNode->next; + free(poppedNode); + return value; +} + +int peek(Stack* stack) +{ + if (isEmpty(stack)) { + return -1; + } + + return stack->head->value; +} + +bool isEmpty(Stack* stack) +{ + return stack->head == NULL; +} diff --git a/src/stack_and_queue/stack/stack.h b/src/stack_and_queue/stack/stack.h new file mode 100644 index 0000000..536c186 --- /dev/null +++ b/src/stack_and_queue/stack/stack.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +typedef struct Stack Stack; + +// Creates new stack. +// Returns pointer on the created stack. +Stack* newStack(); + +// Deletes stack. Frees all memory used in it. +// Takes pointer on the stack. +void deleteStack(Stack* stack); + +// Pushes new value on the top of the stack. +// Takes pointer on the stack and value for push. +void push(Stack* stack, int value); + +// Deletes the top value of the stack and returns it. Frees memory used for top node. +// Takes pointer on the stack. +// If the stack is empty returns -1. +int pop(Stack* stack); + +// Returns the top value of the stack. +// Takes pointer on the stack. +// If the stack is empty returns -1. +int peek(Stack* stack); + +// Returns true if the stack is empty and false if not. +// Takes pointer on the stack. +bool isEmpty(Stack* stack);