first attempt at sort

This commit is contained in:
Daniel Bulant 2024-12-02 22:48:46 +01:00
parent f22fea708c
commit 759ecb151e
No known key found for this signature in database

View file

@ -35,6 +35,8 @@ void DS_grow(struct DynSlice* slice, usize newcap) {
usize cap = slice->capacity; usize cap = slice->capacity;
usize size = slice->size; usize size = slice->size;
if(cap >= newcap) return;
void* dataptr = slice->data; void* dataptr = slice->data;
if(cap == 0) cap = 1; if(cap == 0) cap = 1;
@ -58,6 +60,10 @@ void DS_debugprint(const struct DynSlice* slice) {
printf("dynslice, size %li, cap %li, size of %li\n", slice->size, slice->capacity, slice->size_of); printf("dynslice, size %li, cap %li, size of %li\n", slice->size, slice->capacity, slice->size_of);
} }
void* DS_iptr(struct DynSlice* slice, usize index) {
return slice->data + index * slice->size_of;
}
// Pushes a new object. Accepts a pointer to said object. Copies. // Pushes a new object. Accepts a pointer to said object. Copies.
// returns index of pushed data // returns index of pushed data
// assumes size_of from slice. Take care of types lol. // assumes size_of from slice. Take care of types lol.
@ -67,15 +73,15 @@ usize DS_push(struct DynSlice* slice, void* ptr) {
if(cap <= size) { if(cap <= size) {
DS_grow(slice, cap+1); DS_grow(slice, cap+1);
} }
memcpy(slice->data + slice->size * slice->size_of, ptr, slice->size_of); memcpy(DS_iptr(slice, slice->size), ptr, slice->size_of);
slice->size += 1; slice->size += 1;
return size; return size;
} }
// Extends a slice from another array-like object // Extends a slice from another array-like object
void DS_extend(struct DynSlice* slice, void* ptr, usize count) { void DS_extend(struct DynSlice* slice, void* ptr, usize count) {
if(slice->capacity < slice->size + count) DS_grow(slice, slice->size + count); DS_grow(slice, slice->size + count);
memcpy(slice->data + slice->size * slice->size_of, ptr, slice->size_of * count); memcpy(DS_iptr(slice, slice->size), ptr, slice->size_of * count);
slice->size += count; slice->size += count;
} }
@ -103,7 +109,7 @@ void DS_drop(struct DynSlice* slice) {
// Gets pointer to a single element, checking it's size // Gets pointer to a single element, checking it's size
void* DS_get(const struct DynSlice* slice, const usize i) { void* DS_get(const struct DynSlice* slice, const usize i) {
if(slice->size >= i) { if(slice->size <= i) {
panic("DS Get out of bounds"); panic("DS Get out of bounds");
} }
return slice->data + i * slice->size_of; return slice->data + i * slice->size_of;
@ -144,15 +150,102 @@ struct DynSlice DS_line_from_file(FILE* input) {
} }
} }
// Swaps two indexes in place, using last element of vector (may grow the vector and cause alloc)
void DS_swap(struct DynSlice* slice, usize i, usize j) {
DS_grow(slice, slice->size + 1);
memcpy(DS_iptr(slice, slice->size), DS_iptr(slice, i), slice->size_of);
memcpy(DS_iptr(slice, i), DS_iptr(slice, j), slice->size_of);
memcpy(DS_iptr(slice, j), DS_iptr(slice, slice->size), slice->size_of);
}
void DS_intdebugprint(struct DynSlice* slice) {
if(slice->size_of != sizeof(int)) panic("using int debug print on non-int");
DS_debugprint(slice);
printf("values: ");
for(usize i = 0; i < slice->size; i += 1) {
printf("%i ", *(int*)DS_get(slice, i));
}
printf("\n");
}
// Sorts the array between left and right
// Uses a compare function. Returning -1 means the left number is smaller, 0 =, 1 left > right
// quicksort impl based on https://www.youtube.com/watch?v=Hoixgm4-P4M
void DS_sort_sliced(struct DynSlice* slice, int (*compare)(void*, void*), usize left, usize right) {
if(right <= left) return;
usize pivot = left;
usize len = right - left;
DS_swap(slice, pivot, right);
pivot = right;
while(1) {
usize itemFromLeft = left;
while(compare(DS_get(slice, itemFromLeft), DS_get(slice, pivot)) < 0)
itemFromLeft += 1;
usize itemFromRight = right - 1;
while(compare(DS_get(slice, itemFromRight), DS_get(slice, pivot)) > 0)
itemFromRight -= 1;
if(itemFromLeft < itemFromRight) {
DS_swap(slice, itemFromLeft, itemFromRight);
} else {
DS_swap(slice, itemFromLeft, pivot);
pivot = itemFromLeft;
DS_intdebugprint(slice);
break;
}
}
}
// Sort the array using Quicksort
// Uses a compare function. Returning -1 means the left number is smaller, 0 =, 1 left > right
void DS_sort(struct DynSlice* slice, int (*compare)(void*, void*)) {
DS_sort_sliced(slice, compare, 0, slice->size);
}
int intcompare(int* a, int* b) {
if(*a > *b) return 1;
if(*a == *b) return 0;
if(*a < *b) return -1;
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0);
const char* loc = argv[1]; const char* loc = argv[1];
printf("file %s\n", loc); printf("file %s\n", loc);
FILE* input = fopen(loc, "r"); FILE* input = fopen(loc, "r");
struct DynSlice left = DS_create(sizeof(int));
struct DynSlice right = DS_create(sizeof(int));
while(!feof(input)) { while(!feof(input)) {
struct DynSlice line = DS_line_from_file(input); struct DynSlice line = DS_line_from_file(input);
printf("%s\n", (char*)line.data);
// line is in a format of int int
// find space, add 2 to it. Then 0 - space is one int, space+3 - end is the other one.
// we do this by inserting a null byte to effectively split into two strings
char* spaceptr = strchr(line.data, ' ');
*spaceptr = '\0';
spaceptr += 3;
int first = atoi(line.data);
DS_push(&left, &first);
int second = atoi(spaceptr);
DS_push(&left, &first);
DS_drop(&line); DS_drop(&line);
} }
DS_intdebugprint(&left);
DS_sort(&left, intcompare);
fclose(input); fclose(input);
DS_drop(&left);
DS_drop(&right);
} }