diff --git a/README.md b/README.md index 0a99331b17358f8485d7dbab08bdd03a83e31804..a6b6ad8a7342aac1d75b68502ae027448db5add4 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,26 @@ Use this command to compile the project. +### Run the program + +Execute the file _stack_ to start the program. + +The program must have the following arguments : + +>./stack [array_length] [elements] + +Example : + +>./stack 5 0 -1 2 7 4 + ### Clean the project > `make clean` Use this command to clean the project. ### Run the tests -> `make run_tests` +> `make test` +> +> `./test` -Use this command to start the tests. \ No newline at end of file +Use this command to compile and start the tests. diff --git a/main.c b/main.c index 736e7ff838d7be9a6dae00e2ed0eec868011d1e9..f6ca00e5498830299b99531d9e94480f296b58e7 100644 --- a/main.c +++ b/main.c @@ -1,13 +1,43 @@ /* Author : Dario GENGA - * Date : 16.11.2021 - * Description : Library to manipulate the pile + * Date : 23.11.2021 + * Description : Library to manipulate the stack */ #include <stdio.h> #include <stdlib.h> #include "stack.h" +#define ARGS_MIN 2 +#define ARG_INDEX_array_size 1 -int main() { - return EXIT_SUCCESS; +void print_array(int *array, int array_size) { + for (int i = 0; i < array_size; i++) { + printf("%d ", array[i]); + } + printf("\n"); } + +int main(int argc, char **argv) { + if (argc < ARGS_MIN) { + printf("Missing arguments.\n"); + return EXIT_FAILURE; + } + + int array_size = atoi(argv[ARG_INDEX_array_size]); + + if (array_size != argc - ARGS_MIN || array_size == 0) { + printf("The number of element must correspond to the size of the array.\n"); + return EXIT_FAILURE; + } + int *array = malloc(array_size * sizeof(int)); + + for (int i = 0; i < argc - ARGS_MIN; i++) { + array[i] = atoi(argv[i + ARGS_MIN]); + } + int* sorted_array = sort(array, array_size); + print_array(sorted_array, array_size); + + free(sorted_array); + free(array); + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/stack.c b/stack.c index 4f024e2154cfac448128432229864a4ded465c8e..5ae98bf16ee7162d1bb3df3e99dbb1159d40bfd6 100644 --- a/stack.c +++ b/stack.c @@ -1,8 +1,117 @@ /* Author : Dario GENGA - * Date : 16.11.2021 + * Date : 23.11.2021 * Description : Library to manipulate the stack */ #include "stack.h" #include <stdio.h> +void stack_init(stack *s, int size) { + s->data = malloc(size * sizeof(int)); + s->size = size; + s->top = -1; +} + +bool stack_is_empty(stack s) { + bool is_empty = true; + + if (s.top >= 0 && s.size >= 0 && s.data[0] >= 0) { + is_empty = false; + } + + return is_empty; +} + +void stack_push(stack *s, int val) { + int next_top = s->top + 1; + + // Push the value if the stack is not full + if (next_top < s->size && s->data[next_top] < 0) { + s->data[next_top] = val; + s->top = next_top; + } +} + +void stack_pop(stack *s, int *val) { + if (s->top >= 0) { + *val = s->data[s->top]; + s->data[s->top] = -1; + s->top -= 1; + } +} + +void stack_peek(stack s, int *val) { + if (s.size > 0) { + *val = s.data[s.top]; + } +} + +void stack_destroy(stack *s) { + free(s->data); + s->data = NULL; + s->top = -1; + s->size = -1; +} + +int *sort(int unsorted_array[], int array_size) { + int *sorted_array = malloc(array_size * sizeof(int)); + int *left_peak = malloc(sizeof(int)); + int *right_peak = malloc(sizeof(int)); + stack left_stack, right_stack; + + stack_init(&left_stack, array_size); + stack_init(&right_stack, array_size); + + for (int i = 0; i < array_size; i++) { + int value = unsorted_array[i]; + + // First stack push + if (stack_is_empty(left_stack)) { + stack_push(&left_stack, value); + } + // Add to left stack if the value is lower than the left peek and higher than the right peak + else { + stack_peek(left_stack, left_peak); + if (*left_peak > value && (right_stack.top < 0 || *right_peak < value)) { + stack_push(&left_stack, value); + } + // Else arrange the stacks + else { + while (left_stack.top >= 0 && *left_peak < value) { + stack_pop(&left_stack, left_peak); + stack_push(&right_stack, *left_peak); + stack_peek(left_stack, left_peak); + stack_peek(right_stack, right_peak); + } + while (right_stack.top >= 0 && *right_peak > value) { + stack_pop(&right_stack, right_peak); + stack_push(&left_stack, *right_peak); + stack_peek(right_stack, right_peak); + } + // Then push the value to the left stack + stack_push(&left_stack, value); + } + } + } + + // Push to right stack to the left stack + while (right_stack.top >= 0) { + stack_peek(right_stack, right_peak); + stack_pop(&right_stack, right_peak); + stack_push(&left_stack, *right_peak); + } + + // Add the stack to the array + for (int i = 0; i < array_size; i++) { + stack_pop(&left_stack, left_peak); + sorted_array[i] = *left_peak; + } + + // Free the memory + free(left_peak); + free(right_peak); + stack_destroy(&left_stack); + stack_destroy(&right_stack); + + return sorted_array; +} \ No newline at end of file diff --git a/stack.h b/stack.h index 207ee6e6d117bef6fceac79054f3df878abd150e..16a072d2eeb42de5840a0a6b5dc9dc4a08383045 100644 --- a/stack.h +++ b/stack.h @@ -1,12 +1,25 @@ /* Author : Dario GENGA - * Date : 16.11.2021 + * Date : 23.11.2021 * Description : Library to manipulate the stack */ -#ifndef _PILE_H -#define _PILE_H +#ifndef _STACK_H +#define _STACK_H #include <stdio.h> #include <stdlib.h> #include <stdbool.h> +typedef struct _stack { + int size; + int top; + int *data; +} stack; + +void stack_init(stack *s, int size); +bool stack_is_empty(stack s); +void stack_push(stack *s, int val); +void stack_pop(stack *s, int *val); +void stack_peek(stack s, int *val); +void stack_destroy(stack *s); +int *sort(int unsorted_array[], int array_size); #endif \ No newline at end of file diff --git a/test.c b/test.c index 1648701add9fde2ef97e30afdeeb940e5d490b4f..3ac1960cbce150f9bae3160a35ff6dc9a328a100 100644 --- a/test.c +++ b/test.c @@ -1,13 +1,132 @@ /* Author : Dario GENGA - * Date : 16.11.2021 - * Description : Manipulate matrix + * Date : 23.11.2021 + * Description : Library to manipulate the stack */ #include "stack.h" #include <assert.h> #include <stdbool.h> #include <stdio.h> +#define ARRAY_SIZE 5 + +void test_stack_init(stack *s, int size) { + printf("Testing stack_init()...\n"); + stack_init(s, size); + assert(s != NULL); + assert(s->size == size); + printf("OK.\n"); +} + +void test_stack_destroy(stack *s) { + printf("Testing stack_destroy()...\n"); + stack_destroy(s); + assert(s->data == NULL); + assert(s->top == -1); + printf("OK.\n"); +} + +void test_stack_is_empty(stack *s) { + printf("Testing stack_is_empty()...\n"); + assert(stack_is_empty(*s) == true); + printf("OK.\n"); +} + +void test_stack_is_not_empty(stack *s) { + printf("Testing stack_is_not_empty()...\n"); + assert(stack_is_empty(*s) == false); + printf("OK.\n"); +} + +void test_stack_peek(stack s, int *val) { + printf("Testing stack_peek()...\n"); + stack_peek(s, val); + // TODO: Verify test + assert(*val == s.data[s.top]); + printf("OK.\n"); +} + +void test_stack_push(stack *s, int val) { + printf("Testing stack_push()...\n"); + stack_push(s, val); + // Testing push with remaining spaces + assert(s->data[s->top] == val); + // Testing push on full stack + stack stack_full; + int value_top_full_stack_value = 100; + stack_init(&stack_full, 1); + stack_push(&stack_full, value_top_full_stack_value); + stack_push(&stack_full, val); + assert(stack_full.data[stack_full.top] == value_top_full_stack_value); + printf("OK.\n"); + stack_destroy(&stack_full); +} + +void test_stack_pop(stack *s, int *val) { + printf("Testing stack_pop()...\n"); + int top_before_pop; + // Test with non-empty stack + if (s-> size == 0) { + // Add a value if the stack is empty + stack_push(s, 5); + } + top_before_pop = s->data[s->top]; + stack_pop(s, val); + assert(*val == top_before_pop); + + // Clear the stack + while(s->top >= 0) { + stack_pop(s, val); + } + // Test pop when stack is empty + val = NULL; + stack_pop(s, val); + assert(val == NULL); + + printf("OK.\n"); +} + +void test_sort(int unsorted_array[], int expected_array[], int array_size) { + printf("Testing sort()...\n"); + int* sorted_array = sort(unsorted_array, array_size); + + for (int i = 0; i < array_size; i++) { + assert(sorted_array[i] == expected_array[i]); + } + + printf("OK.\n"); + free(sorted_array); +} int main() { + stack s, non_empty_stack; + int size = 10, value_to_add = 7; + int val; + int unsorted_array[ARRAY_SIZE] = { 0, -1, 2, 7, 4 }; + int expected_array[ARRAY_SIZE] = { -1, 0, 2, 4, 7 }; + + printf("Starting the tests...\n"); + // Test init and destroy + test_stack_init(&s, size); + test_stack_destroy(&s); + + // Reinitialization + stack_init(&s, size); + stack_init(&non_empty_stack, 3); + non_empty_stack.data[0] = 1; + non_empty_stack.top = 0; + + // Test the other functions + test_stack_is_empty(&s); + test_stack_is_not_empty(&non_empty_stack); + test_stack_peek(s, &val); + test_stack_push(&s, value_to_add); + test_stack_pop(&s, &val); + test_sort(unsorted_array, expected_array, ARRAY_SIZE); + + // Free the memory + stack_destroy(&s); + stack_destroy(&non_empty_stack); + + // End the tests printf("The tests are completed and were successful !\n"); return EXIT_SUCCESS; }