Compare commits
23 Commits
52dd7164c5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 488ea7960b | |||
| f3b0be9500 | |||
| e819633ba0 | |||
| 13932df1a8 | |||
| 2cc09b147c | |||
| 2a38f98d37 | |||
| 1e8301139a | |||
| fb08343f8c | |||
| bd0fc7054d | |||
| 08a4142b4a | |||
| 835dfb6314 | |||
| cd6bb7c39f | |||
| 6538a5f98f | |||
| b12a36f536 | |||
| 7bdaa33236 | |||
| dc8d382910 | |||
| 82d3973ade | |||
| 09e18f9ac9 | |||
| 5564d94684 | |||
| 68ced98e24 | |||
| 84653df183 | |||
| 1986404da5 | |||
| c1614ed7d7 |
110
c/arraylist.c
110
c/arraylist.c
@@ -8,11 +8,13 @@ typedef struct i32_ArrayList {
|
|||||||
int32_t data[]; // the data
|
int32_t data[]; // the data
|
||||||
} i32_ArrayList;
|
} i32_ArrayList;
|
||||||
|
|
||||||
i32_ArrayList* new_arraylist(int cap) {
|
i32_ArrayList *new_arraylist(int cap) {
|
||||||
i32_ArrayList* arr = malloc(sizeof(i32_ArrayList) + cap * sizeof(int));
|
i32_ArrayList *arr = malloc(sizeof(i32_ArrayList) + cap * sizeof(int));
|
||||||
|
|
||||||
if (arr == NULL) {
|
if (arr == NULL) {
|
||||||
printf("ERROR: there was an error attemping to allocate memory for i32_ArrayList\n");
|
printf(
|
||||||
|
"ERROR: there was an error attemping to allocate memory for "
|
||||||
|
"i32_ArrayList\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,59 +25,65 @@ i32_ArrayList* new_arraylist(int cap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add to end of the array
|
// add to end of the array
|
||||||
void array_append(i32_ArrayList* s, int v) {
|
void do_append(i32_ArrayList *s, int v) {
|
||||||
if (s->index == s->capacity) {
|
s->data[s->index] = v;
|
||||||
printf("you attempted to insert %d, but array is at capacity cannot add mode values\n", v);
|
s->index++;
|
||||||
} else {
|
|
||||||
s->data[s->index] = v;
|
|
||||||
s->index++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize_arraylist(i32_ArrayList** arr) {
|
// takes the address of a pointer
|
||||||
int new_size = (*arr)->capacity * 2;
|
i32_ArrayList *resize_arraylist(i32_ArrayList *arr) {
|
||||||
i32_ArrayList* new_arr = realloc((*arr), (sizeof(int) * new_size) + sizeof(i32_ArrayList));
|
int new_cap = arr->capacity * 2;
|
||||||
|
|
||||||
|
i32_ArrayList *new_arr = (i32_ArrayList *)realloc(
|
||||||
|
arr, (sizeof(int) * new_cap) + sizeof(i32_ArrayList));
|
||||||
|
|
||||||
if (new_arr == NULL) {
|
if (new_arr == NULL) {
|
||||||
fprintf(stderr, "ERROR: unable to resize array\n");
|
fprintf(stderr, "ERROR: unable to resize array\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*arr) = new_arr;
|
new_arr->capacity = new_cap;
|
||||||
(*arr)->capacity = new_size;
|
return (new_arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_append2(i32_ArrayList* arr, int v) {
|
void array_append(i32_ArrayList **arr_ptr, int v) {
|
||||||
|
i32_ArrayList *arr = *arr_ptr;
|
||||||
if (arr->index == arr->capacity) {
|
if (arr->index == arr->capacity) {
|
||||||
// lets just double the capacity
|
i32_ArrayList *new_arr = resize_arraylist(arr);
|
||||||
resize_arraylist(&arr);
|
*arr_ptr = new_arr;
|
||||||
printf("size of arr: %d\n", arr->capacity);
|
do_append(*arr_ptr, v);
|
||||||
}
|
|
||||||
|
|
||||||
array_append(arr, v);
|
} else {
|
||||||
|
do_append(arr, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an array list and fill in with values from array
|
// create an array list and fill in with values from array
|
||||||
i32_ArrayList* new_arraylist_from_array(int cap, int* arr) {
|
i32_ArrayList *new_arraylist_from_array(int cap, int *arr) {
|
||||||
i32_ArrayList* out = new_arraylist(cap);
|
i32_ArrayList *out = new_arraylist(cap);
|
||||||
for (int i = 0; i < cap; i++) {
|
for (int i = 0; i < cap; i++) {
|
||||||
array_append(out, arr[i]);
|
do_append(out, arr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (out);
|
return (out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert value at index
|
// insert value at index
|
||||||
// the strategy here is to start from the last element in the array and shift it to the right
|
// the strategy here is to start from the last element in the array and shift it
|
||||||
// gotta be careful and check that the index + 1 <= capacity otherwise we are in trouble
|
// to the right gotta be careful and check that the index + 1 <= capacity
|
||||||
void array_insert_at(i32_ArrayList* arr, int at_index, int32_t value) {
|
// otherwise we are in trouble
|
||||||
|
void array_insert_at(i32_ArrayList *arr, int at_index, int32_t value) {
|
||||||
if (at_index == arr->index) {
|
if (at_index == arr->index) {
|
||||||
array_append(arr, value);
|
do_append(arr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: eh this should be much better
|
||||||
if (at_index + 1 > arr->capacity) {
|
if (at_index + 1 > arr->capacity) {
|
||||||
printf("ERROR: this insert is not possible since the shift required would be over the capacity of the array\n");
|
printf(
|
||||||
printf("You requested insert at %d but array capacity is set to %d\n", at_index, arr->capacity);
|
"ERROR: this insert is not possible since the shift required "
|
||||||
|
"would be over the capacity of the array\n");
|
||||||
|
printf("You requested insert at %d but array capacity is set to %d\n",
|
||||||
|
at_index, arr->capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = arr->index; i >= at_index; i--) {
|
for (int i = arr->index; i >= at_index; i--) {
|
||||||
@@ -84,11 +92,11 @@ void array_insert_at(i32_ArrayList* arr, int at_index, int32_t value) {
|
|||||||
arr->data[at_index] = value;
|
arr->data[at_index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t array_get_at(i32_ArrayList* arr, int index) {
|
int32_t array_get_at(i32_ArrayList *arr, int index) {
|
||||||
return (arr->data[index]);
|
return (arr->data[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t pop_from_array(i32_ArrayList* s) {
|
int32_t pop_from_array(i32_ArrayList *s) {
|
||||||
if (s->index == 0) {
|
if (s->index == 0) {
|
||||||
printf("there is nothing to remove!\n");
|
printf("there is nothing to remove!\n");
|
||||||
return (-99);
|
return (-99);
|
||||||
@@ -100,10 +108,7 @@ int32_t pop_from_array(i32_ArrayList* s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void grow_array_list(i32_ArrayList* s, int amount) {
|
void print_array_list(i32_ArrayList *arr) {
|
||||||
}
|
|
||||||
|
|
||||||
void print_array_list(i32_ArrayList* arr) {
|
|
||||||
printf("[");
|
printf("[");
|
||||||
for (int i = 0; i < arr->index; i++) {
|
for (int i = 0; i < arr->index; i++) {
|
||||||
printf(" %d ", arr->data[i]);
|
printf(" %d ", arr->data[i]);
|
||||||
@@ -112,30 +117,30 @@ void print_array_list(i32_ArrayList* arr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
i32_ArrayList* a = new_arraylist(5);
|
i32_ArrayList *a = new_arraylist(5);
|
||||||
int arr_values[5] = {1, 2, 3, 4, 5};
|
int arr_values[5] = {1, 2, 3, 4, 5};
|
||||||
i32_ArrayList* b = new_arraylist_from_array(5, arr_values);
|
i32_ArrayList *b = new_arraylist_from_array(5, arr_values);
|
||||||
print_array_list(b);
|
print_array_list(b);
|
||||||
|
|
||||||
// these should all work just fine
|
// these should all work just fine
|
||||||
array_append(a, 10);
|
array_append(&a, 10);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
array_append(a, 11);
|
array_append(&a, 11);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
array_append(a, 12);
|
array_append(&a, 12);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
array_append(a, 13);
|
array_append(&a, 13);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
array_append(a, 14);
|
array_append(&a, 14);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
|
|
||||||
// this one will error
|
// this one will error
|
||||||
array_append(a, 100);
|
array_append(&a, 100);
|
||||||
|
|
||||||
// so we remove one and then add
|
// so we remove one and then add
|
||||||
pop_from_array(a);
|
pop_from_array(a);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
array_append(a, 100);
|
array_append(&a, 100);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
|
|
||||||
// now we test inserting different index
|
// now we test inserting different index
|
||||||
@@ -153,12 +158,19 @@ int main() {
|
|||||||
// this will shift the current 3 to 4, but this causes the 100 to be removed
|
// this will shift the current 3 to 4, but this causes the 100 to be removed
|
||||||
array_insert_at(a, 3, 123);
|
array_insert_at(a, 3, 123);
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
|
array_append(&a, 5000);
|
||||||
// lets implement v2 versions of these function that will grow
|
|
||||||
// the array when required
|
|
||||||
array_append2(a, 5656);
|
|
||||||
print_array_list(a);
|
print_array_list(a);
|
||||||
|
|
||||||
|
printf("--------------------------------\n");
|
||||||
|
print_array_list(b);
|
||||||
|
array_append(&b, 100);
|
||||||
|
print_array_list(b);
|
||||||
|
|
||||||
|
int vals[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
i32_ArrayList *c = new_arraylist_from_array(10, vals);
|
||||||
|
|
||||||
|
array_append(&c, 10);
|
||||||
|
print_array_list(c);
|
||||||
// array_append(a, 14);
|
// array_append(a, 14);
|
||||||
// print_array_list(a);
|
// print_array_list(a);
|
||||||
// pop_from_array(a);
|
// pop_from_array(a);
|
||||||
|
|||||||
38
c/binary-search.c
Normal file
38
c/binary-search.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
bool binary_search(int *arr, int len, int val) {
|
||||||
|
int lo_bound = 0;
|
||||||
|
int hi_bound = len - 1;
|
||||||
|
|
||||||
|
int mid_index;
|
||||||
|
int mid_val;
|
||||||
|
|
||||||
|
int counter = 1;
|
||||||
|
|
||||||
|
while (lo_bound <= hi_bound) {
|
||||||
|
mid_index = (hi_bound + lo_bound) / 2;
|
||||||
|
|
||||||
|
mid_val = arr[mid_index];
|
||||||
|
|
||||||
|
if (mid_val == val) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val < mid_val) {
|
||||||
|
hi_bound = mid_index - 1;
|
||||||
|
} else {
|
||||||
|
lo_bound = mid_index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
printf("total iterations: %d\n", counter);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int arr[8] = {1, 3, 4, 5, 6, 7, 8, 10};
|
||||||
|
bool result = binary_search(arr, 8, 11);
|
||||||
|
printf("the result is %s\n", result ? "true" : "false");
|
||||||
|
}
|
||||||
@@ -14,34 +14,34 @@ parse it as a tree???
|
|||||||
|
|
||||||
typedef struct Node {
|
typedef struct Node {
|
||||||
int value;
|
int value;
|
||||||
struct Node* prev;
|
struct Node *prev;
|
||||||
} Node;
|
} Node;
|
||||||
|
|
||||||
typedef struct Stack {
|
typedef struct Stack {
|
||||||
int len;
|
int len;
|
||||||
Node* head;
|
Node *head;
|
||||||
} Stack;
|
} Stack;
|
||||||
|
|
||||||
Stack* new_stack() {
|
Stack *new_stack() {
|
||||||
Stack* s = malloc(sizeof(Stack));
|
Stack *s = malloc(sizeof(Stack));
|
||||||
s->head = NULL;
|
s->head = NULL;
|
||||||
s->len = 0;
|
s->len = 0;
|
||||||
return (s);
|
return (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* new_node(int value) {
|
Node *new_node(int value) {
|
||||||
Node* n = malloc(sizeof(Node));
|
Node *n = malloc(sizeof(Node));
|
||||||
n->prev = NULL;
|
n->prev = NULL;
|
||||||
n->value = value;
|
n->value = value;
|
||||||
|
|
||||||
return (n);
|
return (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void json_file_to_tree(char* filepath) {
|
void json_file_to_tree(char *filepath) {
|
||||||
// TODO!!!!
|
// TODO!!!!
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(Stack* stack, Node* node) {
|
void push(Stack *stack, Node *node) {
|
||||||
if (stack->len == 0) {
|
if (stack->len == 0) {
|
||||||
stack->head = node;
|
stack->head = node;
|
||||||
stack->len++;
|
stack->len++;
|
||||||
@@ -52,9 +52,9 @@ void push(Stack* stack, Node* node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pop(Stack* stack) {
|
int pop(Stack *stack) {
|
||||||
if (stack->len > 0) {
|
if (stack->len > 0) {
|
||||||
Node* node = stack->head;
|
Node *node = stack->head;
|
||||||
int node_val = node->value;
|
int node_val = node->value;
|
||||||
stack->head = node->prev;
|
stack->head = node->prev;
|
||||||
stack->len--;
|
stack->len--;
|
||||||
@@ -67,12 +67,12 @@ int pop(Stack* stack) {
|
|||||||
|
|
||||||
typedef struct IntBinaryNode {
|
typedef struct IntBinaryNode {
|
||||||
int value;
|
int value;
|
||||||
struct IntBinaryNode* left;
|
struct IntBinaryNode *left;
|
||||||
struct IntBinaryNode* right;
|
struct IntBinaryNode *right;
|
||||||
} IntBinaryNode;
|
} IntBinaryNode;
|
||||||
|
|
||||||
IntBinaryNode* new_int_binary_node(int value) {
|
IntBinaryNode *new_int_binary_node(int value) {
|
||||||
IntBinaryNode* n = malloc(sizeof(IntBinaryNode));
|
IntBinaryNode *n = malloc(sizeof(IntBinaryNode));
|
||||||
n->left = NULL;
|
n->left = NULL;
|
||||||
n->right = NULL;
|
n->right = NULL;
|
||||||
n->value = value;
|
n->value = value;
|
||||||
@@ -81,17 +81,17 @@ IntBinaryNode* new_int_binary_node(int value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct BinaryTree {
|
typedef struct BinaryTree {
|
||||||
IntBinaryNode* root;
|
IntBinaryNode *root;
|
||||||
} BinaryTree;
|
} BinaryTree;
|
||||||
|
|
||||||
BinaryTree* new_binary_tree(IntBinaryNode* n) {
|
BinaryTree *new_binary_tree(IntBinaryNode *n) {
|
||||||
BinaryTree* b = malloc(sizeof(BinaryTree));
|
BinaryTree *b = malloc(sizeof(BinaryTree));
|
||||||
b->root = n;
|
b->root = n;
|
||||||
|
|
||||||
return (b);
|
return (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_child_node(IntBinaryNode* parent, IntBinaryNode* child, char position) {
|
void add_child_node(IntBinaryNode *parent, IntBinaryNode *child, char position) {
|
||||||
if (position != 'l' && position != 'r') {
|
if (position != 'l' && position != 'r') {
|
||||||
printf("ERROR: position must be either (l)eft or (r)ight\n");
|
printf("ERROR: position must be either (l)eft or (r)ight\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -115,7 +115,7 @@ void add_child_node(IntBinaryNode* parent, IntBinaryNode* child, char position)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prints the bottom row of a tree
|
// prints the bottom row of a tree
|
||||||
void print_binary_tree(IntBinaryNode* node) {
|
void print_binary_tree(IntBinaryNode *node) {
|
||||||
if (node->left == NULL && node->right == NULL) {
|
if (node->left == NULL && node->right == NULL) {
|
||||||
printf("<%d>\n", node->value);
|
printf("<%d>\n", node->value);
|
||||||
} else {
|
} else {
|
||||||
@@ -124,7 +124,7 @@ void print_binary_tree(IntBinaryNode* node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void walk_tree_pre_order(IntBinaryNode* current_node, Stack* stack) {
|
void walk_tree_pre_order(IntBinaryNode *current_node, Stack *stack) {
|
||||||
if (current_node->left == NULL && current_node->right == NULL) {
|
if (current_node->left == NULL && current_node->right == NULL) {
|
||||||
push(stack, new_node(current_node->value));
|
push(stack, new_node(current_node->value));
|
||||||
} else {
|
} else {
|
||||||
@@ -134,7 +134,7 @@ void walk_tree_pre_order(IntBinaryNode* current_node, Stack* stack) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void walk_tree_post_order(IntBinaryNode* current_node, Stack* stack) {
|
void walk_tree_post_order(IntBinaryNode *current_node, Stack *stack) {
|
||||||
if (current_node->left == NULL && current_node->right == NULL) {
|
if (current_node->left == NULL && current_node->right == NULL) {
|
||||||
push(stack, new_node(current_node->value));
|
push(stack, new_node(current_node->value));
|
||||||
} else {
|
} else {
|
||||||
@@ -144,7 +144,7 @@ void walk_tree_post_order(IntBinaryNode* current_node, Stack* stack) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void walk_tree_in_order(IntBinaryNode* current_node, Stack* stack) {
|
void walk_tree_in_order(IntBinaryNode *current_node, Stack *stack) {
|
||||||
if (current_node->left == NULL && current_node->right == NULL) {
|
if (current_node->left == NULL && current_node->right == NULL) {
|
||||||
push(stack, new_node(current_node->value));
|
push(stack, new_node(current_node->value));
|
||||||
} else {
|
} else {
|
||||||
@@ -154,7 +154,7 @@ void walk_tree_in_order(IntBinaryNode* current_node, Stack* stack) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_stack(Stack* stack) {
|
void print_stack(Stack *stack) {
|
||||||
if (stack->len == 0) {
|
if (stack->len == 0) {
|
||||||
printf("empty stack\n");
|
printf("empty stack\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -167,13 +167,13 @@ void print_stack(Stack* stack) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_stack_v2(Stack* stack) {
|
void print_stack_v2(Stack *stack) {
|
||||||
if (stack->len == 0) {
|
if (stack->len == 0) {
|
||||||
printf("ERROR: empty stack\n");
|
printf("ERROR: empty stack\n");
|
||||||
} else {
|
} else {
|
||||||
printf("[ ");
|
printf("[ ");
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
Node* curr = stack->head;
|
Node *curr = stack->head;
|
||||||
while (counter < stack->len) {
|
while (counter < stack->len) {
|
||||||
printf("%d ", curr->value);
|
printf("%d ", curr->value);
|
||||||
curr = curr->prev;
|
curr = curr->prev;
|
||||||
@@ -190,8 +190,8 @@ int main() {
|
|||||||
10 11 44 77
|
10 11 44 77
|
||||||
|
|
||||||
*/
|
*/
|
||||||
IntBinaryNode* root_node = new_int_binary_node(12);
|
IntBinaryNode *root_node = new_int_binary_node(12);
|
||||||
BinaryTree* tree = new_binary_tree(root_node);
|
BinaryTree *tree = new_binary_tree(root_node);
|
||||||
|
|
||||||
add_child_node(root_node, new_int_binary_node(4), 'l');
|
add_child_node(root_node, new_int_binary_node(4), 'l');
|
||||||
add_child_node(root_node, new_int_binary_node(6), 'r');
|
add_child_node(root_node, new_int_binary_node(6), 'r');
|
||||||
@@ -201,9 +201,9 @@ int main() {
|
|||||||
add_child_node(root_node->right, new_int_binary_node(44), 'l');
|
add_child_node(root_node->right, new_int_binary_node(44), 'l');
|
||||||
add_child_node(root_node->right, new_int_binary_node(77), 'r');
|
add_child_node(root_node->right, new_int_binary_node(77), 'r');
|
||||||
|
|
||||||
Stack* stack = new_stack();
|
Stack *stack = new_stack();
|
||||||
Stack* post_stack = new_stack();
|
Stack *post_stack = new_stack();
|
||||||
Stack* in_order_stack = new_stack();
|
Stack *in_order_stack = new_stack();
|
||||||
walk_tree_pre_order(root_node, stack);
|
walk_tree_pre_order(root_node, stack);
|
||||||
walk_tree_post_order(root_node, post_stack);
|
walk_tree_post_order(root_node, post_stack);
|
||||||
walk_tree_in_order(root_node, in_order_stack);
|
walk_tree_in_order(root_node, in_order_stack);
|
||||||
|
|||||||
45
c/bubble-sort-take-2.c
Normal file
45
c/bubble-sort-take-2.c
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
in bubble sort we iterate through the array each time we encounter adjacent elements
|
||||||
|
out of order, we swap them. We continue this iteration until we have reached
|
||||||
|
*/
|
||||||
|
|
||||||
|
void swap(int *a, int *b) {
|
||||||
|
int temp = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bubble_sort(int arr[], int len) {
|
||||||
|
int swap_count = 1;
|
||||||
|
int temp;
|
||||||
|
int end_index = len - 1;
|
||||||
|
|
||||||
|
while (swap_count > 0) {
|
||||||
|
swap_count = 0;
|
||||||
|
for (int i = 0; i < end_index; i++) {
|
||||||
|
if (arr[i] > arr[i + 1]) {
|
||||||
|
temp = arr[i];
|
||||||
|
arr[i] = arr[i + 1];
|
||||||
|
arr[i + 1] = temp;
|
||||||
|
swap_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end_index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_array(int arr[], int len) {
|
||||||
|
printf("[ ");
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
printf(" %d", arr[i]);
|
||||||
|
}
|
||||||
|
printf(" ]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int input[5] = {5, 4, 3, 2, 1};
|
||||||
|
bubble_sort(input, 5);
|
||||||
|
print_array(input, 5);
|
||||||
|
}
|
||||||
@@ -1,25 +1,59 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// asume the array is sorted of course
|
|
||||||
void bubble_sort(int arr[], int len) {
|
void bubble_sort(int arr[], int len) {
|
||||||
|
int total_iterations = 0;
|
||||||
int temp;
|
int temp;
|
||||||
|
int total_swaps = 1;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
|
total_iterations++;
|
||||||
|
if (total_swaps == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
total_swaps = 0;
|
||||||
for (int j = 0; j < len - 1; j++) {
|
for (int j = 0; j < len - 1; j++) {
|
||||||
if (arr[j] > arr[j+1]) {
|
if (arr[j] > arr[j + 1]) {
|
||||||
temp = arr[j+1];
|
total_swaps++;
|
||||||
arr[j+1] = arr[j];
|
temp = arr[j + 1];
|
||||||
|
arr[j + 1] = arr[j];
|
||||||
arr[j] = temp;
|
arr[j] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printf("total iterations: %d\n", total_iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(int* a, int* b) {
|
||||||
|
int temp = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bubble_sort_3(int arr[], int len) {
|
||||||
|
int swaps = 1;
|
||||||
|
while (swaps > 0) {
|
||||||
|
swaps = 0;
|
||||||
|
for (int i = 0; i < len - 1; i++) {
|
||||||
|
if (arr[i] > arr[i + 1]) {
|
||||||
|
swap(&arr[i], &arr[i + 1]);
|
||||||
|
swaps++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
void print_array(int* arr, int len) {
|
||||||
int arr[5] = {1, 3, 2, 4, 5};
|
printf("[ ");
|
||||||
bubble_sort(arr, 5);
|
for (int i = 0; i < len; i++) {
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
printf("%d ", arr[i]);
|
printf("%d ", arr[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int arr[10] = {2, 1, 3, 4, 5, 7, 33, 7, 8, 20};
|
||||||
|
printf("before the sort:\n");
|
||||||
|
print_array(arr, 10);
|
||||||
|
bubble_sort_3(arr, 10);
|
||||||
|
printf("after the sort:\n");
|
||||||
|
print_array(arr, 10);
|
||||||
}
|
}
|
||||||
37
c/hash-table-pro.c
Normal file
37
c/hash-table-pro.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct item {
|
||||||
|
char *key;
|
||||||
|
int value;
|
||||||
|
} item;
|
||||||
|
|
||||||
|
item *linear_search(item *items, size_t size, const char *key) {
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
if (strcmp(items[i].key, key) == 0) {
|
||||||
|
return (&items[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
item items[] = {
|
||||||
|
{"foo", 10},
|
||||||
|
{"bar", 20},
|
||||||
|
{"hello", 30},
|
||||||
|
{"x", 40}};
|
||||||
|
|
||||||
|
size_t total_items = sizeof(items) / sizeof(items);
|
||||||
|
|
||||||
|
item *found = linear_search(items, total_items, "foo");
|
||||||
|
|
||||||
|
if (found == NULL) {
|
||||||
|
printf("linear search: value of 'foo' has no key\n");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("linear search: value of 'foo' is: %d", found->value);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
136
c/hash-table.c
Normal file
136
c/hash-table.c
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MAX_HASH_TABLE_SIZE 16
|
||||||
|
|
||||||
|
typedef struct KV {
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
} KV;
|
||||||
|
|
||||||
|
typedef struct Node {
|
||||||
|
KV kv;
|
||||||
|
struct Node *next;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
typedef struct HashTable {
|
||||||
|
Node *data[MAX_HASH_TABLE_SIZE];
|
||||||
|
} HashTable;
|
||||||
|
|
||||||
|
HashTable *new_hashtable() {
|
||||||
|
HashTable *ht = malloc(sizeof(HashTable));
|
||||||
|
for (int i = 0; i < MAX_HASH_TABLE_SIZE; i++) {
|
||||||
|
ht->data[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ht);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *new_node() {
|
||||||
|
Node *node = malloc(sizeof(Node));
|
||||||
|
node->next = NULL;
|
||||||
|
|
||||||
|
return (node);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_index_for_letter(char letter) {
|
||||||
|
if (letter >= 'a' && letter <= 'z') {
|
||||||
|
return (letter - 'a') + 1;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash(char *word) {
|
||||||
|
int word_len = strlen(word);
|
||||||
|
int accum = 1;
|
||||||
|
int index;
|
||||||
|
for (int i = 0; i < word_len; i++) {
|
||||||
|
index = get_index_for_letter(word[i]);
|
||||||
|
accum *= index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum % 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
KV *find_KV_in_ht(HashTable h, char *key) {
|
||||||
|
for (size_t i = 0; i < MAX_HASH_TABLE_SIZE; i++) {
|
||||||
|
if ((h.data[i] != NULL) && (strcmp(h.data[i]->kv.key, key) == 0)) {
|
||||||
|
return (&h.data[i]->kv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *get_value(HashTable ht, char *key) {
|
||||||
|
int hash_key = hash(key);
|
||||||
|
|
||||||
|
Node *node_at_hash = ht.data[hash_key];
|
||||||
|
|
||||||
|
if (node_at_hash == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: key not found in hashtable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if next is NULL then this is the only at this hash so just return it
|
||||||
|
if (node_at_hash->next == NULL) {
|
||||||
|
return node_at_hash->kv.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kv->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_kv(HashTable *ht, char *key, char *value) {
|
||||||
|
int hashed_key = hash(key);
|
||||||
|
|
||||||
|
Node *current = ht->data[hashed_key];
|
||||||
|
|
||||||
|
while (current) {
|
||||||
|
if (strcmp(current->kv.key, key) == 0) {
|
||||||
|
current->kv.value = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *new = new_node();
|
||||||
|
new->kv.key = key;
|
||||||
|
new->kv.value = value;
|
||||||
|
new->next = current;
|
||||||
|
ht->data[hashed_key] = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
// char *get(HashTable *h, char *key) {
|
||||||
|
// int hash_val = hash(key);
|
||||||
|
// return h->data[hash_val];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void insert(HashTable *h, char *key, char *value) {
|
||||||
|
// int hashed_key = hash(key);
|
||||||
|
|
||||||
|
// if (h->data[hashed_key] != NULL) {
|
||||||
|
// fprintf(stderr, "ERROR: collision!");
|
||||||
|
// exit(1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// h->data[hashed_key] = value;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void delete(HashTable *h, char *key) {
|
||||||
|
// int hashed_key = hash(key);
|
||||||
|
// h->data[hashed_key] = NULL;
|
||||||
|
// }
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
HashTable *h = new_hashtable();
|
||||||
|
|
||||||
|
// test
|
||||||
|
insert_kv(h, "hello", "world");
|
||||||
|
char *result = get_value(*h, "hello");
|
||||||
|
printf("the value corresponding to the key 'hello' is: '%s'", result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
33
c/insertion-sort.c
Normal file
33
c/insertion-sort.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void insertion_sort(int arr[], int len) {
|
||||||
|
int temp;
|
||||||
|
int j;
|
||||||
|
for (int i = 1; i < len; i++) {
|
||||||
|
temp = arr[i];
|
||||||
|
j = i - 1;
|
||||||
|
while (j >= 0) {
|
||||||
|
if (temp < arr[j]) {
|
||||||
|
arr[j + 1] = arr[j];
|
||||||
|
j--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr[j + 1] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_array(int arr[], int len) {
|
||||||
|
printf("[ ");
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
printf("%d ", arr[i]);
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int arr[10] = {10, 9, 8, 7, 6, 5, 4, 3, 1, 2};
|
||||||
|
insertion_sort(arr, 10);
|
||||||
|
print_array(arr, 10);
|
||||||
|
}
|
||||||
69
c/intersection.c
Normal file
69
c/intersection.c
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define MAX_DATA 50
|
||||||
|
|
||||||
|
typedef struct ArrayList {
|
||||||
|
int cap;
|
||||||
|
int index;
|
||||||
|
int data[];
|
||||||
|
} ArrayList;
|
||||||
|
|
||||||
|
ArrayList *new_array_list(int cap) {
|
||||||
|
ArrayList *arr = malloc(sizeof(ArrayList) + cap * sizeof(int));
|
||||||
|
|
||||||
|
if (arr == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: cannot allocate mem for arraylist\n");
|
||||||
|
}
|
||||||
|
arr->cap = cap;
|
||||||
|
arr->index = 0;
|
||||||
|
|
||||||
|
return (arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(ArrayList *arr, int val) {
|
||||||
|
if (arr->index == arr->cap) {
|
||||||
|
fprintf(stderr, "ERROR: cannot append to array at capacity");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
arr->data[arr->index] = val;
|
||||||
|
arr->index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop(ArrayList *arr) {
|
||||||
|
if (arr->index == 0) {
|
||||||
|
fprintf(stderr, "ERROR: canoot pop from empty array");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
arr->index--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for now we only return the indices on the left that that are in the right */
|
||||||
|
ArrayList *intersection(int left[], int right[], int left_len, int right_len) {
|
||||||
|
ArrayList *arr = new_array_list(left_len);
|
||||||
|
|
||||||
|
for (int i = 0; i < left_len; i++) {
|
||||||
|
for (int j = 0; j < right_len; j++) {
|
||||||
|
if (left[i] == right[j]) {
|
||||||
|
push(arr, left[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int a[5] = {1, 2, 3, 4, 8};
|
||||||
|
int b[5] = {4, 5, 6, 7, 8};
|
||||||
|
|
||||||
|
ArrayList *arr = intersection(a, b, 5, 5);
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
printf("%d ", arr->data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
109
c/ordered-arrays.c
Normal file
109
c/ordered-arrays.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
an ordered array is just a regular array except all elements must be in order,
|
||||||
|
so there a few things to note:
|
||||||
|
|
||||||
|
1. inserting must respect order
|
||||||
|
2. removing must respect order
|
||||||
|
3. serching can be made faster with binary search
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct FixedOrderedArray {
|
||||||
|
int capacity;
|
||||||
|
int index; // index next to insert at, arr[index] should be empty
|
||||||
|
int data[];
|
||||||
|
} FixedOrderedArray;
|
||||||
|
|
||||||
|
|
||||||
|
FixedOrderedArray *new_fixed_ordered_array(int capacity) {
|
||||||
|
FixedOrderedArray *arr = malloc(sizeof(FixedOrderedArray) + (sizeof(int) * capacity));
|
||||||
|
arr->capacity = capacity;
|
||||||
|
arr->index = 0;
|
||||||
|
|
||||||
|
return (arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixed_ordered_array_insert(FixedOrderedArray *arr, int val) {
|
||||||
|
if (arr->capacity == arr->index) {
|
||||||
|
fprintf(stderr, "ERROR: array is at capacity, cannot append value\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arr->index == 0) {
|
||||||
|
arr->data[0] = val;
|
||||||
|
arr->index++;
|
||||||
|
} else if (val >= arr->data[arr->index - 1]) {
|
||||||
|
arr->data[arr->index] = val;
|
||||||
|
arr->index++;
|
||||||
|
} else if (val <= arr->data[0]) { // its smallest to add to start
|
||||||
|
for (int i = arr->index; i > 0; i--) { // shift everything to the right
|
||||||
|
arr->data[i] = arr->data[i - 1];
|
||||||
|
}
|
||||||
|
arr->data[0] = val;
|
||||||
|
arr->index++;
|
||||||
|
} else { // look for where it belongs
|
||||||
|
for (int i = 0; i < arr->index; i++) {
|
||||||
|
if (arr->data[i] > val) { // we must shift everything to the right up to this index
|
||||||
|
for (int j = arr->index; j > i; j--) {
|
||||||
|
arr->data[j] = arr->data[j - 1];
|
||||||
|
}
|
||||||
|
arr->data[i] = val;
|
||||||
|
arr->index++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool search_fixed_ordered_array(FixedOrderedArray *arr, int val) {
|
||||||
|
if (arr->index == 0) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val < arr->data[0]) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val > arr->data[arr->index - 1]) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < arr->index; i++) {
|
||||||
|
if (val == arr->data[i]) {
|
||||||
|
return (true);
|
||||||
|
} else if (arr->data[i] > val) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_array_list(FixedOrderedArray *arr) {
|
||||||
|
printf("[");
|
||||||
|
for (int i = 0; i < arr->index; i++) {
|
||||||
|
printf(" %d ", arr->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("]\t<capacity: %d; index: %d>\n", arr->capacity, arr->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
FixedOrderedArray *arr = new_fixed_ordered_array(5);
|
||||||
|
|
||||||
|
fixed_ordered_array_insert(arr, 10);
|
||||||
|
print_array_list(arr);
|
||||||
|
fixed_ordered_array_insert(arr, 9);
|
||||||
|
print_array_list(arr);
|
||||||
|
fixed_ordered_array_insert(arr, 13);
|
||||||
|
print_array_list(arr);
|
||||||
|
fixed_ordered_array_insert(arr, 11);
|
||||||
|
print_array_list(arr);
|
||||||
|
fixed_ordered_array_insert(arr, 9);
|
||||||
|
print_array_list(arr);
|
||||||
|
|
||||||
|
bool result = search_fixed_ordered_array(arr, 11);
|
||||||
|
printf("the result is %d\n", result);
|
||||||
|
}
|
||||||
2
c/qs.c
2
c/qs.c
@@ -38,7 +38,7 @@ void quick_sort(int arr[], int lo, int hi) {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int array_len = 5;
|
int array_len = 5;
|
||||||
int arr[5] = {5, 4, 3, 2, 1};
|
int arr[5] = {0, 2, 5, 1, 6};
|
||||||
quick_sort(arr, 0, array_len - 1);
|
quick_sort(arr, 0, array_len - 1);
|
||||||
|
|
||||||
printf("[ ");
|
printf("[ ");
|
||||||
|
|||||||
51
c/quicksort.c
Normal file
51
c/quicksort.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// the partition will weakly sort the array and return the index of
|
||||||
|
// the pivot
|
||||||
|
int partition(int arr[], int lo, int hi) {
|
||||||
|
int pivot_value = arr[hi];
|
||||||
|
int current_index = lo - 1;
|
||||||
|
int temp;
|
||||||
|
for (int i = lo; i < hi; i++) {
|
||||||
|
if (arr[i] <= pivot_value) {
|
||||||
|
current_index++;
|
||||||
|
|
||||||
|
temp = arr[i];
|
||||||
|
arr[i] = arr[current_index];
|
||||||
|
arr[current_index] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// once done with loop the current_index will hold
|
||||||
|
// the location where we need to place the pivot_value
|
||||||
|
current_index++;
|
||||||
|
arr[hi] = arr[current_index];
|
||||||
|
arr[current_index] = pivot_value;
|
||||||
|
|
||||||
|
return (current_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qs(int arr[], int lo, int hi) {
|
||||||
|
if (lo < hi) {
|
||||||
|
int current_pivot = partition(arr, lo, hi);
|
||||||
|
qs(arr, lo, current_pivot - 1);
|
||||||
|
qs(arr, current_pivot + 1, hi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_array(int arr[], int len) {
|
||||||
|
printf("[ ");
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
printf("%d ", arr[i]);
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int arr[5] = {0, 2, 5, 1, 6};
|
||||||
|
print_array(arr, 5);
|
||||||
|
qs(arr, 0, 4);
|
||||||
|
print_array(arr, 5);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
35
c/selection-sort.c
Normal file
35
c/selection-sort.c
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void swap(int *a, int *b) {
|
||||||
|
int temp = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void selection_sort(int arr[], int len) {
|
||||||
|
int lo_index;
|
||||||
|
for (int i = 0; i < len; i++) { // keep track of pass
|
||||||
|
lo_index = i; // low index always starts as the pass iteration
|
||||||
|
for (int j = i + 1; j < len; j++) { // keep track of array comparisons
|
||||||
|
if (arr[j] < arr[i]) {
|
||||||
|
lo_index = j;
|
||||||
|
}
|
||||||
|
} // after done with this loop we swap the value at lo_index to the current pass index
|
||||||
|
|
||||||
|
swap(&arr[i], &arr[lo_index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_array(int arr[], int len) {
|
||||||
|
printf("[ ");
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
printf("%d ", arr[i]);
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int arr[5] = {5, 4, 3, 2, 1};
|
||||||
|
selection_sort(arr, 5);
|
||||||
|
print_array(arr, 5);
|
||||||
|
}
|
||||||
54
odin/main.odin
Normal file
54
odin/main.odin
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
linear_search :: proc(arr: []int, len: int, needle: int) -> bool {
|
||||||
|
for index, val in arr {
|
||||||
|
if val == needle {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
partition :: proc(arr: ^[]int, lo: int, hi: int) -> int {
|
||||||
|
pivot_value := arr[hi]
|
||||||
|
current_index := lo - 1
|
||||||
|
|
||||||
|
for i := lo; i < hi; i +=1 {
|
||||||
|
if arr[i] <= pivot_value {
|
||||||
|
current_index += 1
|
||||||
|
tmp := arr[i]
|
||||||
|
arr[i] = arr[current_index]
|
||||||
|
arr[current_index] = tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current_index += 1
|
||||||
|
arr[hi] = arr[current_index]
|
||||||
|
arr[current_index] = pivot_value
|
||||||
|
|
||||||
|
return(current_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
quick_sort :: proc(arr: ^[]int, lo: int, hi: int) {
|
||||||
|
if lo < hi {
|
||||||
|
current_pivot := partition(arr, lo, hi);
|
||||||
|
quick_sort(arr, lo, current_pivot - 1);
|
||||||
|
quick_sort(arr, current_pivot + 1, hi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
fmt.println("hello there here is a for loop")
|
||||||
|
|
||||||
|
values: []int = {1, 2, 3, 4, 5}
|
||||||
|
res: bool = linear_search(values, 5, 2)
|
||||||
|
fmt.println(res)
|
||||||
|
|
||||||
|
fmt.println("quicksort ----------------")
|
||||||
|
arr: []int = {0, 2, 5, 1, 6}
|
||||||
|
fmt.println(arr);
|
||||||
|
quick_sort(&arr, 0, 4);
|
||||||
|
fmt.println(arr);
|
||||||
|
}
|
||||||
35
python/bubble-sort.py
Normal file
35
python/bubble-sort.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
def bubble_sort(arr: List[int]):
|
||||||
|
total_iterations = 0
|
||||||
|
for i in range(len(arr)):
|
||||||
|
total_iterations += 1
|
||||||
|
for j in range(len(arr) - 1):
|
||||||
|
if arr[j] > arr[j + 1]:
|
||||||
|
temp = arr[j]
|
||||||
|
arr[j] = arr[j + 1]
|
||||||
|
arr[j + 1] = temp
|
||||||
|
print(f"the total number of iterations: {total_iterations}")
|
||||||
|
|
||||||
|
|
||||||
|
def bubble_sort2(arr: List[int]):
|
||||||
|
total_swaps = 1
|
||||||
|
total_iterations = 0
|
||||||
|
for i in range(len(arr)):
|
||||||
|
if total_swaps == 0:
|
||||||
|
break
|
||||||
|
total_swaps = 0
|
||||||
|
total_iterations += 1
|
||||||
|
for j in range(len(arr) - 1):
|
||||||
|
if arr[j] > arr[j + 1]:
|
||||||
|
total_swaps += 1
|
||||||
|
arr[j], arr[j + 1] = arr[j + 1], arr[j]
|
||||||
|
print(f"total iterations: {total_iterations}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
a = [2, 1, 3, 4, 5]
|
||||||
|
print(a)
|
||||||
|
bubble_sort2(a)
|
||||||
|
print(a)
|
||||||
28
python/fib.py
Normal file
28
python/fib.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
def fib(n, counter):
|
||||||
|
if n == 0 or n == 1:
|
||||||
|
return n
|
||||||
|
|
||||||
|
else:
|
||||||
|
counter.append(1)
|
||||||
|
print("calling fib")
|
||||||
|
return fib(n - 1, counter) + fib(n - 2, counter)
|
||||||
|
|
||||||
|
|
||||||
|
def fib_memo(n, memo={}, counter=[]):
|
||||||
|
if n == 0 or n == 1:
|
||||||
|
return n
|
||||||
|
|
||||||
|
if not memo.get(n):
|
||||||
|
counter.append(1)
|
||||||
|
memo[n] = fib_memo(n - 1, memo, counter) + fib_memo(n - 2, memo, counter)
|
||||||
|
|
||||||
|
return memo[n]
|
||||||
|
|
||||||
|
|
||||||
|
count = []
|
||||||
|
fib(6, counter=count)
|
||||||
|
sum(count)
|
||||||
|
|
||||||
|
fib_counter = []
|
||||||
|
fib_memo(6, memo={}, counter=fib_counter)
|
||||||
|
sum(fib_counter)
|
||||||
52
python/hash-table.py
Normal file
52
python/hash-table.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import string
|
||||||
|
|
||||||
|
alphabet = [i for i in string.ascii_lowercase]
|
||||||
|
|
||||||
|
alphabet.split()
|
||||||
|
|
||||||
|
|
||||||
|
def linear_search(val, arr):
|
||||||
|
for i, letter in enumerate(arr):
|
||||||
|
if val == letter:
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def hash(word):
|
||||||
|
split_word = [i for i in word]
|
||||||
|
split_prods = [linear_search(i, alphabet) for i in split_word]
|
||||||
|
hash_key = 1
|
||||||
|
for i in split_prods:
|
||||||
|
hash_key *= i
|
||||||
|
|
||||||
|
return hash_key % 16
|
||||||
|
|
||||||
|
|
||||||
|
def get_at_hash(key, container):
|
||||||
|
return container[hash(key)]
|
||||||
|
|
||||||
|
|
||||||
|
def insert_at_hash(key, value, container):
|
||||||
|
key_hash = hash(key)
|
||||||
|
|
||||||
|
if container[key_hash] is None:
|
||||||
|
# no collision just insert and return
|
||||||
|
container[key_hash] = value
|
||||||
|
return container
|
||||||
|
else:
|
||||||
|
# resolve collision
|
||||||
|
# but I don't know what was the key, it could any permutation
|
||||||
|
# of the letters BAD in the example I am working through
|
||||||
|
existing_value = container[key_hash]
|
||||||
|
container[key_hash] = [[existing_value], [key, value]]
|
||||||
|
return container
|
||||||
|
|
||||||
|
|
||||||
|
container = [None for i in range(15)]
|
||||||
|
|
||||||
|
insert_at_hash("bad", "evil", container)
|
||||||
|
insert_at_hash("dab", "good", container)
|
||||||
|
|
||||||
|
|
||||||
|
get_at_hash("bad", container)
|
||||||
14
python/insertion-sort.py
Normal file
14
python/insertion-sort.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
def insertion_sort(array):
|
||||||
|
for index in range(1, len(array)):
|
||||||
|
temp_value = array[index]
|
||||||
|
position = index - 1
|
||||||
|
|
||||||
|
while position >= 0:
|
||||||
|
if array[position] > temp_value:
|
||||||
|
array[position + 1] = array[position]
|
||||||
|
position -= 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
array[position + 1] = temp_value
|
||||||
|
|
||||||
|
return array
|
||||||
43
python/intersection.py
Normal file
43
python/intersection.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
def intersection(left: List[int], right: List[int]) -> List[int]:
|
||||||
|
result = []
|
||||||
|
for i in range(0, len(left)):
|
||||||
|
for j in range(0, len(right)):
|
||||||
|
if left[i] == right[j]:
|
||||||
|
result.append(left[i])
|
||||||
|
break
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def intersection2(left: List[int], right: List[int]) -> List[int]:
|
||||||
|
result = []
|
||||||
|
for left_val in left:
|
||||||
|
for right_val in right:
|
||||||
|
if left_val == right_val:
|
||||||
|
result.append(left_val)
|
||||||
|
break
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# silly to make intoa function but here we are
|
||||||
|
def intersection3(left: List[int], right: List[int]) -> List[int]:
|
||||||
|
return [i for i in left if i in right]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
res = intersection([1, 2, 3, 4, 5], [5, 6, 7, 8, 9, 4])
|
||||||
|
res2 = intersection2([1, 2, 3, 4, 5], [5, 6, 7, 8, 9, 4, 5, 5, 5, 1, 2, 3, 4])
|
||||||
|
res3 = intersection3([1, 2, 3, 4, 5], [5, 6, 7, 8, 9, 4, 5, 5, 5, 1, 2, 3, 4])
|
||||||
|
|
||||||
|
# and the list comprehension
|
||||||
|
print(res)
|
||||||
|
print(res2)
|
||||||
|
print(res3)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
20
python/quicksort.py
Normal file
20
python/quicksort.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
def partition(arr, lo, hi):
|
||||||
|
pivot_value = arr[hi]
|
||||||
|
current_index = lo - 1
|
||||||
|
|
||||||
|
for i in range(lo, hi):
|
||||||
|
if arr[i] <= pivot_value:
|
||||||
|
current_index += 1
|
||||||
|
arr[current_index], arr[i] = arr[i], arr[current_index]
|
||||||
|
current_index += 1
|
||||||
|
arr[hi] = arr[current_index]
|
||||||
|
arr[current_index] = pivot_value
|
||||||
|
return current_index
|
||||||
|
|
||||||
|
def quicksort(arr, lo, hi):
|
||||||
|
if lo < hi:
|
||||||
|
part = partition(arr, lo, hi)
|
||||||
|
quicksort(arr, lo, part - 1)
|
||||||
|
quicksort(arr, part + 1, hi)
|
||||||
|
|
||||||
|
|
||||||
38
ts/bfs.test.ts
Normal file
38
ts/bfs.test.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { tree } from "./tree"
|
||||||
|
|
||||||
|
type BinaryNode<T> = {
|
||||||
|
value: T;
|
||||||
|
left: BinaryNode<T> | null;
|
||||||
|
right: BinaryNode<T> | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function bfs(head: BinaryNode<number> | null, needle: number): boolean {
|
||||||
|
const q: (BinaryNode<number> | null)[] = [head];
|
||||||
|
|
||||||
|
while (q.length) {
|
||||||
|
const current = q.shift() as BinaryNode<number>;
|
||||||
|
|
||||||
|
if (current.value === needle) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current.left) {
|
||||||
|
q.push(current.left);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current.right) {
|
||||||
|
q.push(current.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test("bfs search works a number of values", function () {
|
||||||
|
expect(bfs(tree, 20)).toEqual(true);
|
||||||
|
expect(bfs(tree, -20)).toEqual(false);
|
||||||
|
expect(bfs(tree, 10)).toEqual(true);
|
||||||
|
expect(bfs(tree, 7)).toEqual(true);
|
||||||
|
})
|
||||||
47
ts/tree.ts
Normal file
47
ts/tree.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
type BinaryNode<T> = {
|
||||||
|
value: T;
|
||||||
|
left: BinaryNode<T> | null;
|
||||||
|
right: BinaryNode<T> | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const tree: BinaryNode<number> = {
|
||||||
|
value: 20,
|
||||||
|
right: {
|
||||||
|
value: 50,
|
||||||
|
right: {
|
||||||
|
value: 100,
|
||||||
|
right: null,
|
||||||
|
left: null,
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
value: 30,
|
||||||
|
right: {
|
||||||
|
value: 45,
|
||||||
|
right: null,
|
||||||
|
left: null,
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
value: 29,
|
||||||
|
right: null,
|
||||||
|
left: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
value: 10,
|
||||||
|
right: {
|
||||||
|
value: 15,
|
||||||
|
right: null,
|
||||||
|
left: null,
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
value: 5,
|
||||||
|
right: {
|
||||||
|
value: 7,
|
||||||
|
right: null,
|
||||||
|
left: null,
|
||||||
|
},
|
||||||
|
left: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
44
ts/tree_traversal.test.ts
Normal file
44
ts/tree_traversal.test.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { tree } from "./tree"
|
||||||
|
|
||||||
|
type BinaryNode<T> = {
|
||||||
|
value: T;
|
||||||
|
left: BinaryNode<T> | null;
|
||||||
|
right: BinaryNode<T> | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// pre order
|
||||||
|
function walk(current: BinaryNode<number> | null, path: number[]): number[] {
|
||||||
|
if (!current) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
path.push(current.value);
|
||||||
|
walk(current.left, path);
|
||||||
|
walk(current.right, path);
|
||||||
|
|
||||||
|
return path;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function pre_order_search(head: BinaryNode<number>): number[] {
|
||||||
|
const path: number[] = [];
|
||||||
|
walk(head, path);
|
||||||
|
|
||||||
|
return path;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
test("Pre order", function () {
|
||||||
|
expect(pre_order_search(tree)).toEqual([
|
||||||
|
20,
|
||||||
|
10,
|
||||||
|
5,
|
||||||
|
7,
|
||||||
|
15,
|
||||||
|
50,
|
||||||
|
30,
|
||||||
|
29,
|
||||||
|
45,
|
||||||
|
100,
|
||||||
|
]);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user