diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..772f8ad39b3d13f51dc292721cc3b3dd8e4201d8 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +CC=gcc +FLAGS= -Wall -Werror +CFLAGS= -g -std=c99 +LDFLAGS= -fsanitize=address -fsanitize=leak + +exe: test + ./$^ + +test: stack_test.o stack.o + $(CC) $^ -o $@ $(CFLAGS) $(LDFLAGS) + +main.o: main.c + $(CC) $(FLAGS) $(CFLAGS) $(LDFLAGS) -c $^ + +stack.o: stack.c stack.h + $(CC) $(FLAGS) $(CFLAGS) $(LDFLAGS) -c $< + +stack_test.o: stack_test.c stack.o + $(CC) $(FLAGS) $(CFLAGS) $(LDFLAGS) -c $< + +clean: + rm -f *.o test + +rebuild: clean test \ No newline at end of file diff --git a/stack.c b/stack.c new file mode 100644 index 0000000000000000000000000000000000000000..de5fbbba8ae409dc9ff4acd7e411c2fdfe8cc8e4 --- /dev/null +++ b/stack.c @@ -0,0 +1,110 @@ +#include "stack.h" +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +void stack_init(stack *s, int size) +{ + s->size = size; + s->data = malloc(size*sizeof(int)); + s->top = -1; +} + +bool stack_is_empty(stack s) +{ + return s.top < 0; +} + +void stack_push(stack *s, int val) +{ + if (s->top+1>s->size) + { + return; + } + s->top+=1; + s->data[s->top] = val; +} + +void stack_pop(stack *s, int *val) +{ + if (s->top<0) + { + return; + } + + *val = s->data[s->top]; + s->top-=1; +} + +void stack_peek(stack s, int *val) +{ + stack_pop(&s, val); + stack_push(&s, *val); +} + + +void stack_destroy(stack *s) +{ + s->size = -1; + s->top = -2; + free(s->data); + s->data = NULL; +} +void print_stack(stack s) +{ + if (stack_is_empty(s)) + { + return; + } + int var; + stack_pop(&s, &var); + printf("%d\n", var); + return print_stack(s); +} + +void sort(int *list, int size) +{ + int left = 0; + int right = 0; + stack stack_l; + stack_init(&stack_l, size); + + stack stack_r; + stack_init(&stack_r, size); + + for (int i = 0; i < size; i++) + { + stack_peek(stack_l, &left); + while(list[i] > left && !stack_is_empty(stack_l)) + { + stack_pop(&stack_l, &left); + stack_push(&stack_r, left); + stack_peek(stack_l, &left); + } + stack_peek(stack_r, &right); + while (list[i] < right && !stack_is_empty(stack_r)) + { + stack_pop(&stack_r, &right); + stack_push(&stack_l, right); + stack_peek(stack_r, &right); + } + + stack_push(&stack_l, list[i]); + } + + int tmp; + for (int i = stack_r.top; i > -1; i--) + { + stack_pop(&stack_r, &tmp); + stack_push(&stack_l, tmp); + } + + for (int i = 0; i < size; i++) + { + stack_pop(&stack_l, &tmp); + list[i] = tmp; + } + + stack_destroy(&stack_l); + stack_destroy(&stack_r); +} \ No newline at end of file diff --git a/stack.h b/stack.h new file mode 100644 index 0000000000000000000000000000000000000000..9feebf146d17209c36d9e8d1115f511fb04fb438 --- /dev/null +++ b/stack.h @@ -0,0 +1,22 @@ +#ifndef _STACK_H_ +#define _STACK_H_ + +#include <stdbool.h> +#include <stdint.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); +void sort(int *list, int size); +void print_stack(stack s); + +#endif \ No newline at end of file diff --git a/stack_test.c b/stack_test.c new file mode 100644 index 0000000000000000000000000000000000000000..ad7b3d83e59ea981f973c9bd4929d2f462e8fc63 --- /dev/null +++ b/stack_test.c @@ -0,0 +1,182 @@ +/* +* Author : Alec Schmidt +*/ +#include "stack.h" +#include <math.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <stdint.h> + +typedef struct _test_result +{ + bool passed; + const char *name; +} test_result; + +typedef test_result (*unit_test_t)(void); + +void print_in_color(char *color, char *text) +{ + printf("\033%s", color); + printf("%s", text); + printf("\033[0m"); +} +void print_in_red(char *text) +{ + print_in_color("[0;31m", text); +} +void print_in_green(char *text) +{ + print_in_color("[0;32m", text); +} + +bool dbl_eq(double a, double b) +{ + return fabs(a - b) < 1e-6; +} + +/* + * + * Write your tests here + * + */ +/* TODO +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); +void sort(int *list); +*/ + +test_result t_stack_is_empty() +{ + bool passed = true; + stack s; + stack_init(&s, 4); + + if (!stack_is_empty(s)) + { + passed = false; + } + + free(s.data); + + return (test_result){.passed = passed, .name = "Test stack_is_empty"}; +} + +test_result t_stack_push() +{ + bool passed = true; + stack s; + stack_init(&s, 4); + + stack_push(&s, 3); + + if (s.data[s.top] != 3) + { + passed = false; + } + + free(s.data); + + return (test_result){.passed = passed, .name = "Test stack_push"}; +} + +test_result t_stack_pop() +{ + bool passed = true; + stack s; + int val = 0; + stack_init(&s, 4); + + s.data[0] = 3; + s.top = 0; + stack_pop(&s, &val); + + if (val != 3 || s.top != -1) + { + passed = false; + } + free(s.data); + + return (test_result){.passed = passed, .name = "Test stack_pop"}; +} + +test_result t_stack_peek() +{ + bool passed = true; + stack s; + int val = 0; + stack_init(&s, 4); + + s.data[0] = 3; + s.top = 0; + + stack_peek(s, &val); + + if (val != 3 || s.top != 0) + { + passed = false; + } + + free(s.data); + + return (test_result){.passed = passed, .name = "Test stack_peek"}; +} + +test_result t_sort() +{ + bool passed = true; + int list[] = {17, 34, 20, 40, 25}; + int list_sorted[] = {17, 20, 25, 34, 40}; + + sort(list, 5); + + for (int i = 0; i < 5; i++) + { + if (list[i] != list_sorted[i]) + { + passed = false; + break; + } + } + + return (test_result){.passed = passed, .name = "Test sort"}; +} + + +// Add or remove your test function name here +const unit_test_t tests[] = {t_stack_is_empty, t_stack_push, t_stack_pop, t_stack_peek, t_sort}; + +int main() +{ + uint32_t nb_tests = sizeof(tests) / sizeof(unit_test_t); + char message[256]; + bool all_passed = true; + + for (uint32_t i = 0; i < nb_tests; i++) + { + printf("Running test n°%d: ...\n", i); + test_result r = tests[i](); + if (r.passed) + { + sprintf(message, "\t- %s : OK", r.name); + print_in_green(message); + } + else + { + all_passed = false; + sprintf(message, "\t- %s : FAILED", r.name); + print_in_red(message); + } + printf("\n"); + } + if (all_passed) + print_in_green("\nTests suite result : OK\n"); + else + print_in_red("\nTests suite result : FAILED\n"); +} \ No newline at end of file