Compare commits

...

33 Commits

Author SHA1 Message Date
488ea7960b adds ts for tree searches 2023-09-04 23:49:08 -07:00
f3b0be9500 rewrite functions to work with updated strucutres 2023-08-28 00:03:47 -07:00
e819633ba0 start to implement separate chaining for resolving hash collisions 2023-08-26 23:48:43 -07:00
13932df1a8 Merge branch 'main' of git.emanuelrgz.com:ergz/tlacyl 2023-08-26 01:03:38 -07:00
2cc09b147c going through an example of hash table 2023-08-26 01:02:53 -07:00
2a38f98d37 fixed a dumb error 2023-08-20 16:34:37 -07:00
1e8301139a cant figure out qs in python 2023-08-20 16:23:05 -07:00
fb08343f8c implement quicksort in c again to practice and in oding to see what its like 2023-08-17 23:20:31 -07:00
bd0fc7054d gonna try doing the c stuff in odin 2023-08-16 23:22:36 -07:00
08a4142b4a fib with memoization 2023-08-12 00:47:26 -07:00
835dfb6314 get_at_hash() 2023-08-10 23:39:44 -07:00
cd6bb7c39f implementing a hash table in python before attempting to do it in C next 2023-08-09 23:31:56 -07:00
6538a5f98f add python version 2023-08-08 23:15:52 -07:00
b12a36f536 make intersection faster 🚀 2023-08-08 23:03:34 -07:00
7bdaa33236 a simple intersection 2023-08-08 22:59:26 -07:00
dc8d382910 fix py decrement missing and in C move j-- to correct spot 2023-08-07 23:29:47 -07:00
82d3973ade implements insertion sort in c and pytyhon 2023-08-07 23:25:17 -07:00
09e18f9ac9 implements selection sort 2023-08-03 22:38:27 -07:00
5564d94684 Merge branch 'main' of git.emanuelrgz.com:ergz/tlacyl 2023-07-30 20:27:53 -07:00
68ced98e24 more work 2023-07-30 20:27:50 -07:00
84653df183 implement binary search 2023-07-29 23:28:19 -07:00
1986404da5 got the double pointer working 2023-07-26 23:10:22 -07:00
c1614ed7d7 add python stuff 2023-07-24 22:12:34 -07:00
52dd7164c5 wrapping my head around this double pointer thing: 2023-07-22 02:03:06 -07:00
b63d729b87 more work on the array list implementation 2023-07-22 01:25:25 -07:00
3644c63f43 trying to flesh out the array implementation before I proceed to heap 2023-07-19 23:15:15 -07:00
9b53857a64 removes debug prints 2023-07-18 23:10:03 -07:00
213242a4eb tree comparison done 2023-07-18 23:09:01 -07:00
440586dea0 start implementing tree comparisons 2023-07-18 22:54:18 -07:00
bed65ad722 first try, looks bad, but working the second pass will be better 2023-07-16 01:19:08 -07:00
755f16877d forgot to add a subtraction in length of the node 2023-07-15 11:34:31 -07:00
351db3f366 implements the q operations 2023-07-15 11:33:23 -07:00
fe6ba5fa8b set up the ds needed to get the bfs implemented 2023-07-15 11:14:33 -07:00
24 changed files with 1380 additions and 75 deletions

View File

@@ -1,61 +1,184 @@
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
typedef struct ArrayList { typedef struct i32_ArrayList {
int capacity; int capacity; // capacity of the array
int index; int index; // the current location the list that is to be written to
int data[]; int32_t data[]; // the data
} ArrayList; } i32_ArrayList;
i32_ArrayList *new_arraylist(int cap) {
i32_ArrayList *arr = malloc(sizeof(i32_ArrayList) + cap * sizeof(int));
if (arr == NULL) {
printf(
"ERROR: there was an error attemping to allocate memory for "
"i32_ArrayList\n");
exit(1);
}
ArrayList* new_arraylist(int cap) {
ArrayList* arr = malloc(sizeof(ArrayList) + cap * sizeof(int));
arr->capacity = cap; arr->capacity = cap;
arr->index = 0; arr->index = 0;
for (int i = 0; i < cap; i++) {
arr->data[i] = 0;
}
return arr; return arr;
} }
void push_to_array(ArrayList* s, int v) { // add to end of the array
if (s->index == s->capacity) { void do_append(i32_ArrayList *s, int v) {
printf("you attempted to insert %d, but array is at capacity cannot add mode values\n", v); s->data[s->index] = v;
s->index++;
}
// takes the address of a pointer
i32_ArrayList *resize_arraylist(i32_ArrayList *arr) {
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) {
fprintf(stderr, "ERROR: unable to resize array\n");
exit(1);
}
new_arr->capacity = new_cap;
return (new_arr);
}
void array_append(i32_ArrayList **arr_ptr, int v) {
i32_ArrayList *arr = *arr_ptr;
if (arr->index == arr->capacity) {
i32_ArrayList *new_arr = resize_arraylist(arr);
*arr_ptr = new_arr;
do_append(*arr_ptr, v);
} else { } else {
s->data[s->index] = v; do_append(arr, v);
s->index++;
} }
} }
void pop_from_array(ArrayList* s) { // create an array list and fill in with values from array
i32_ArrayList *new_arraylist_from_array(int cap, int *arr) {
i32_ArrayList *out = new_arraylist(cap);
for (int i = 0; i < cap; i++) {
do_append(out, arr[i]);
}
return (out);
}
// insert value at index
// the strategy here is to start from the last element in the array and shift it
// to the right gotta be careful and check that the index + 1 <= capacity
// otherwise we are in trouble
void array_insert_at(i32_ArrayList *arr, int at_index, int32_t value) {
if (at_index == arr->index) {
do_append(arr, value);
}
// TODO: eh this should be much better
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("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--) {
arr->data[i + 1] = arr->data[i];
}
arr->data[at_index] = value;
}
int32_t array_get_at(i32_ArrayList *arr, int index) {
return (arr->data[index]);
}
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);
} else { } else {
int32_t val = s->data[s->index - 1];
s->index--; s->index--;
return (val);
} }
} }
void grow_array_list(ArrayList* s, int amount) { void print_array_list(i32_ArrayList *arr) {
}
void print_array_list(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]);
} }
printf("]\n"); printf("]\t<capacity: %d; index: %d>\n", arr->capacity, arr->index);
} }
int main() { int main() {
ArrayList* a = new_arraylist(5); i32_ArrayList *a = new_arraylist(5);
push_to_array(a, 10); int arr_values[5] = {1, 2, 3, 4, 5};
push_to_array(a, 11); i32_ArrayList *b = new_arraylist_from_array(5, arr_values);
push_to_array(a, 12); print_array_list(b);
push_to_array(a, 12);
push_to_array(a, 12); // these should all work just fine
push_to_array(a, 12); array_append(&a, 10);
push_to_array(a, 12);
pop_from_array(a);
push_to_array(a, 155);
print_array_list(a); print_array_list(a);
} array_append(&a, 11);
print_array_list(a);
array_append(&a, 12);
print_array_list(a);
array_append(&a, 13);
print_array_list(a);
array_append(&a, 14);
print_array_list(a);
// this one will error
array_append(&a, 100);
// so we remove one and then add
pop_from_array(a);
print_array_list(a);
array_append(&a, 100);
print_array_list(a);
// now we test inserting different index
array_insert_at(a, 3, 55);
print_array_list(a);
array_insert_at(a, 4, 555);
print_array_list(a);
// what happens if try to insert at the last element
// this first implementation of the araylist will just overwrite this value
array_insert_at(a, 4, 100);
print_array_list(a);
// what if insert at 3 in this first version?
// this will shift the current 3 to 4, but this causes the 100 to be removed
array_insert_at(a, 3, 123);
print_array_list(a);
array_append(&a, 5000);
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);
// print_array_list(a);
// pop_from_array(a);
// print_array_list(a);
// array_insert_at(a, 5, 90000);
// print_array_list(a);
// array_insert_at(a, 3, 1000);
// array_insert_at(a, 4, 1000);
// array_insert_at(a, 5, 10001);
// print_array_list(a);
}

38
c/binary-search.c Normal file
View 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");
}

View File

@@ -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,6 +167,22 @@ void print_stack(Stack* stack) {
} }
} }
void print_stack_v2(Stack *stack) {
if (stack->len == 0) {
printf("ERROR: empty stack\n");
} else {
printf("[ ");
int counter = 0;
Node *curr = stack->head;
while (counter < stack->len) {
printf("%d ", curr->value);
curr = curr->prev;
counter++;
}
printf(" ]\n");
}
}
int main() { int main() {
/* lets create the following tree /* lets create the following tree
12 12
@@ -174,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');
@@ -185,17 +201,19 @@ 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);
printf("the len of the stack is %d\n", stack->len); printf("pre order: ", stack->len);
print_stack(stack); print_stack_v2(stack);
print_stack(post_stack); printf("in order: ", stack->len);
print_stack(in_order_stack); print_stack_v2(post_stack);
printf("post order: ", stack->len);
print_stack_v2(in_order_stack);
free(stack); free(stack);
free(post_stack); free(post_stack);
free(in_order_stack); free(in_order_stack);

202
c/breadth-first-search.c Normal file
View File

@@ -0,0 +1,202 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode {
int value;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
typedef struct Tree {
TreeNode* root;
} Tree;
/* Set up data structures to be able to support the breadth first search of a tree */
typedef struct QNode {
TreeNode* tnode; // this is the value of the QNode
struct QNode* next;
} QNode;
typedef struct Q {
QNode* head;
QNode* tail;
int length;
} Q;
TreeNode* new_tree_node(int value) {
TreeNode* node = malloc(sizeof(TreeNode));
node->left = NULL;
node->right = NULL;
node->value = value;
return (node);
}
QNode* new_qnode(TreeNode* tnode) {
QNode* node = malloc(sizeof(QNode));
node->next = NULL;
node->tnode = tnode;
return (node);
}
Tree* new_tree(TreeNode* root) {
Tree* tree = malloc(sizeof(Tree));
tree->root = root;
return (tree);
}
Q* new_Q() {
Q* q = malloc(sizeof(Q));
q->head = NULL;
q->tail = NULL;
q->length = 0;
return (q);
}
void add_child_left(TreeNode* parent, TreeNode* node) {
if (parent->left != NULL) {
printf("ERROR: left child is non-empty\n");
exit(1);
} else {
parent->left = node;
}
}
void add_child_right(TreeNode* parent, TreeNode* node) {
if (parent->right != NULL) {
printf("ERROR: right child is non-empty\n");
exit(1);
} else {
parent->right = node;
}
}
// always add at tail
void q_add_node(Q* q, QNode* node) {
if (q->length == 0) {
q->head = node;
q->tail = node;
q->length++;
} else {
q->tail->next = node;
q->tail = node;
q->length++;
}
}
// always remove from head
TreeNode* q_remove_node(Q* q) {
QNode* n = q->head;
TreeNode* tnode_at_head = n->tnode;
q->head = n->next;
q->length--;
free(n);
return (tnode_at_head);
}
/*
[10, 5, 7, 12, 8, 88, 14]
10
5 7
12 8 88 14
*/
bool bf_search(Tree tree, int value) {
// start by adding th eroot of tree to the q
Q* search_path = new_Q();
QNode* n = new_qnode(tree.root);
q_add_node(search_path, n);
TreeNode* current_value;
int count_iterations = 1;
while (search_path->length > 0) {
count_iterations++;
current_value = q_remove_node(search_path);
if (current_value->value == value) {
free(search_path);
printf("total itarations: %d\n", count_iterations);
return (true);
}
if (current_value->left != NULL) {
q_add_node(search_path, new_qnode(current_value->left));
}
if (current_value->right != NULL) {
q_add_node(search_path, new_qnode(current_value->right));
}
}
printf("total itarations: %d\n", count_iterations);
free(search_path);
return (false);
}
bool is_leaf(TreeNode* a) {
if (a->left == NULL && a->right == NULL) {
return (true);
} else {
return (false);
}
}
// determine if two trees are equal
bool tree_equal(TreeNode* root_a, TreeNode* root_b) {
if (root_a->value != root_b->value) {
return (false);
}
if (is_leaf(root_a) && is_leaf(root_b)) {
return (true);
}
if (is_leaf(root_a) || is_leaf(root_b)) {
return (false);
}
return (tree_equal(root_a->left, root_b->left) && tree_equal(root_a->right, root_b->right));
}
/*
The reason for choose the Q as the data strucuture to keep track
of the search path is to
*/
int main() {
TreeNode* root = new_tree_node(10);
TreeNode* root2 = new_tree_node(10);
Tree* tree = new_tree(root);
Tree* tree2 = new_tree(root2);
add_child_left(root, new_tree_node(5));
add_child_right(root, new_tree_node(7));
add_child_left(root->left, new_tree_node(12));
add_child_right(root->left, new_tree_node(8));
add_child_left(root->right, new_tree_node(88));
add_child_right(root->right, new_tree_node(14));
// create the second tree
add_child_left(root2, new_tree_node(5));
add_child_right(root2, new_tree_node(7));
add_child_left(root2->left, new_tree_node(12));
add_child_right(root2->left, new_tree_node(8));
add_child_left(root2->right, new_tree_node(88));
add_child_right(root2->right, new_tree_node(14));
bool answer;
answer = bf_search(*tree, 10);
printf("the answer is %s\n", answer ? "true" : "false");
bool trees_are_equal;
trees_are_equal = tree_equal(tree->root, tree2->root);
printf("are the trees equal? %s\n", trees_are_equal ? "yes" : "no");
return (0);
}

45
c/bubble-sort-take-2.c Normal file
View 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);
}

View File

@@ -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
View 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
View 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
View 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
View 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
View 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
View File

@@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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,
]);
});