summaryrefslogtreecommitdiff
path: root/src/01/01b
diff options
context:
space:
mode:
authormo khan <mo.khan@gmail.com>2020-06-29 12:53:12 -0600
committermo khan <mo.khan@gmail.com>2020-06-29 12:53:12 -0600
commite5f55cfd9dec028d537e6b95c0545ec017ee51a5 (patch)
treeacf29e3a8939371cc5864dd5d57a59a8b31c8b8f /src/01/01b
parentc39c57090eb622453234ac059e0604c8c143941f (diff)
Split files to directories for each section of the assignment
Diffstat (limited to 'src/01/01b')
-rw-r--r--src/01/01b/min_stack_test.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/01/01b/min_stack_test.c b/src/01/01b/min_stack_test.c
new file mode 100644
index 0000000..383ae62
--- /dev/null
+++ b/src/01/01b/min_stack_test.c
@@ -0,0 +1,171 @@
+#include <cgreen/cgreen.h>
+
+/*
+ Design and implement a `MinStack` data structure that can store
+ comparable elements and supports the stack operations:
+
+ * `push(x)`
+ * `pop()`
+ * `size()`
+ * `min()`
+ All operations should run in constant time.
+ */
+
+Describe(MinStack);
+BeforeEach(MinStack){ }
+AfterEach(MinStack){ }
+
+struct node {
+ int data;
+ struct node *next;
+};
+
+typedef struct node Node;
+
+typedef struct {
+ Node *head;
+} Stack;
+
+static Stack *initialize() {
+ Stack *self = malloc(sizeof(Stack));
+ self->head = NULL;
+ return self;
+}
+
+static int size(Stack *self) {
+ Node *current = self->head;
+ int i;
+ for (i = 0; current != NULL; i++)
+ current = current->next;
+ return i;
+}
+
+static Node *new(int data) {
+ Node *node = malloc(sizeof(Node));
+ node->next = NULL;
+ node->data = data;
+ return node;
+}
+
+static int compare(int x, int y) {
+ return x == y ? 0 : (x > y) ? 1 : -1;
+}
+
+static void insert(Node **self, int data) {
+ int comparison = compare(data, (*self)->data);
+ Node *node = new(data);
+
+ switch(comparison) {
+ case 1:
+ if ((*self)->next)
+ insert(&((*self)->next), data);
+ else
+ (*self)->next = node;
+ break;
+ default:
+ node->next = *self;
+ *self = node;
+ break;
+ }
+}
+
+static void push(Stack *self, int data) {
+ if (self->head)
+ insert(&self->head, data);
+ else
+ self->head = new(data);
+}
+
+static int min(Stack *self) {
+ if (self && self->head)
+ return self->head->data;
+
+ return (int)NULL;
+}
+
+static int pop(Stack *self) {
+ if (!self->head)
+ return (int)NULL;
+
+ Node *current = self->head;
+ int data = current->data;
+ self->head = current->next;
+ current->next = NULL;
+ free(current);
+ return data;
+}
+
+Ensure(MinStack, when_empty) {
+ Stack *stack = initialize();
+
+ assert_that(size(stack), is_equal_to(0));
+ assert_that(min(stack), is_equal_to(NULL));
+ assert_that(pop(stack), is_equal_to(NULL));
+
+ free(stack);
+}
+
+Ensure(MinStack, when_pushing_a_single_integer) {
+ Stack *stack = initialize();
+
+ push(stack, 1);
+
+ assert_that(size(stack), is_equal_to(1));
+ assert_that(min(stack), is_equal_to(1));
+ assert_that(pop(stack), is_equal_to(1));
+ assert_that(size(stack), is_equal_to(0));
+
+ free(stack);
+}
+
+Ensure(MinStack, when_pushing_multiple_integers_out_of_order) {
+ Stack *stack = initialize();
+
+ push(stack, 2);
+ push(stack, 3);
+ push(stack, 1);
+
+ assert_that(size(stack), is_equal_to(3));
+ assert_that(min(stack), is_equal_to(1));
+
+ assert_that(pop(stack), is_equal_to(1));
+ assert_that(size(stack), is_equal_to(2));
+
+ assert_that(pop(stack), is_equal_to(2));
+ assert_that(size(stack), is_equal_to(1));
+
+ assert_that(pop(stack), is_equal_to(3));
+ assert_that(size(stack), is_equal_to(0));
+
+ assert_that(pop(stack), is_equal_to(NULL));
+ assert_that(size(stack), is_equal_to(0));
+
+ free(stack);
+}
+
+Ensure(MinStack, when_pushing_duplicate_values_on_to_the_stack) {
+ Stack *stack = initialize();
+
+ push(stack, 2);
+ push(stack, 1);
+ push(stack, 2);
+
+ assert_that(size(stack), is_equal_to(3));
+ assert_that(min(stack), is_equal_to(1));
+
+ assert_that(pop(stack), is_equal_to(1));
+ assert_that(pop(stack), is_equal_to(2));
+ assert_that(pop(stack), is_equal_to(2));
+ assert_that(pop(stack), is_equal_to(NULL));
+
+ free(stack);
+}
+
+TestSuite *min_stack_tests() {
+ TestSuite *suite = create_test_suite();
+
+ add_test_with_context(suite, MinStack, when_empty);
+ add_test_with_context(suite, MinStack, when_pushing_a_single_integer);
+ add_test_with_context(suite, MinStack, when_pushing_multiple_integers_out_of_order);
+ return suite;
+}