From 26091914227053b142a0e349973c3dfb48f324bb Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Wed, 6 Dec 2023 20:58:05 +1100 Subject: [PATCH] HashTable works (tm) --- day3/puzzle1.c | 117 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 100 insertions(+), 17 deletions(-) diff --git a/day3/puzzle1.c b/day3/puzzle1.c index e6e1aef..7e26fbf 100644 --- a/day3/puzzle1.c +++ b/day3/puzzle1.c @@ -5,9 +5,10 @@ #include #include #include +#include // https://www.digitalocean.com/community/tutorials/hash-table-in-c-plus-plus -#define CAPACITY 5000 // Size of the hashtable +#define CAPACITY 8000000 // Size of the hashtable struct Ht_entry { @@ -16,30 +17,102 @@ struct Ht_entry struct HashTable { - struct Ht_entry **entry; + struct Ht_entry **entries; int size; int count; }; unsigned long -hash_function(int x, int y, char *c, int r) +hash_function(int x, int y, int num) { unsigned long i = 0; - int str_total = 0; - for (int j = 0; j < r; j++) - { - str_total += (int)c[j]; - } - i = x * y - (int)str_total; + + i = (((x + 1) * num) - y); return i % CAPACITY; } -struct Ht_entry create_item(int x, int y, int num) +struct Ht_entry *create_item(int x, int y, int num) { // Creates a pointer to the a new HashTable item struct Ht_entry *entry = (struct Ht_entry *)malloc(sizeof(struct Ht_entry)); - entry->num = malloc(sizeof(num)); - int nDigits = floor(log10(abs(num))) + 1; + entry->num = (int)malloc(sizeof(num)); + // int nDigits = floor(log10(abs(num))) + 1; + entry->num = num; + return entry; +} + +void free_entry(struct Ht_entry *entry) +{ + free(entry->num); + free(entry); +} + +void free_table(struct HashTable *table) +{ + for (int i = 0; i < table->size; i++) + { + struct Ht_entry *entry = table->entries[i]; + + if (table != NULL) + { + free_entry(entry); + } + } + free(table->entries); + free(table); +} + +void ht_insert(struct HashTable *table, int x, int y, int num) +{ + struct Ht_entry *entry = create_item(x, y, num); + int index = hash_function(x, y, num); + struct Ht_entry *current_item = table->entries[index]; + + if (current_item == NULL) + { + if (table->count == table->size) + { + printf("Hash table full ;|\n"); + free_entry(entry); + return; + } + + table->entries[index] = entry; + table->count++; + } + else + { + printf("Collision at %i, %i, %i, %i\n", index, x, y, num); + // printf("HASH COLISION, MAYDAY MAYDAY!\n"); + // exit(2); + } +} + +struct HashTable *create_table(int size) +{ + struct HashTable *table = (struct HashTable *)malloc(sizeof(struct HashTable)); + table->size = size; + table->count = 0; + table->entries = (struct Ht_entry **)calloc(table->size, sizeof(struct Ht_entry *)); + + for (int i = 0; i < table->size; i++) + { + table->entries[i] = NULL; + } + return table; +} + +int ht_search(struct HashTable *table, int x, int y, int num) +{ + int index = hash_function(x, y, num); + struct Ht_entry *entry = table->entries[index]; + + if (entry != NULL) + { + return entry->num; + } + + return NULL; } int simple_int_conv(char str) @@ -52,7 +125,7 @@ int simple_int_conv(char str) return -69420; } -char *check_numbers_around(int x, int y, char chars[140][141]) +char *check_numbers_around(int x, int y, char chars[140][141], struct HashTable *table) { char *found_str; // printf("%c", chars[x][y]); @@ -64,7 +137,7 @@ char *check_numbers_around(int x, int y, char chars[140][141]) } if (isdigit(num) == 0) { - printf("Is a number: %i\n", num); + ht_insert(table, x, y, num); } if (1) { @@ -72,7 +145,7 @@ char *check_numbers_around(int x, int y, char chars[140][141]) return found_str; } -void check_symbols(int x, int y, char chars[140][141]) +void check_symbols(int x, int y, char chars[140][141], struct HashTable *table) { char *symbols = "*$%&/@-=+#"; for (int i = 0; i < 10; i++) @@ -81,7 +154,7 @@ void check_symbols(int x, int y, char chars[140][141]) if (chars[x][y] == symbols[i] || chars[x][y] == '1') { - check_numbers_around(x, y, chars); + check_numbers_around(x, y, chars, table); // printf("\n\nGot a symbol: %c\n\n", chars[x][y]); exit(0); } @@ -90,9 +163,19 @@ void check_symbols(int x, int y, char chars[140][141]) int main() { + struct HashTable *table = create_table(CAPACITY); + srand(time(NULL)); char *filename = "input"; struct OpenFile *o_file = load_file_to_mem(filename); + for (int i = 0; i < 50; i++) + { + for (int j = 0; j < 50; j++) + { + // printf("Adding %i, %i, %i\n", i, j, 243); + ht_insert(table, i, j, rand()); + } + } // Load the dataset into memory so we have the full data mapped // in an easy to work with way const int line_length = 141; @@ -124,7 +207,7 @@ int main() for (int j = 0; j < line_length; j++) { // printf("%c", chars[i][j]); - check_symbols(i, j, chars); + check_symbols(i, j, chars, table); // if (j % line_length == 0) // {