Attempted to separate the snippets of code to small functions and each set of functions have its own file. Also made some improvements by using pools instead of constantly mallocing space.

This commit is contained in:
2026-05-07 02:00:15 +03:00
parent 00396f86fe
commit e3239bf564
15 changed files with 561 additions and 289 deletions
+123
View File
@@ -0,0 +1,123 @@
#include "node.h"
#include "hash.h"
#include "maths.h"
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>
static Node* pool = NULL;
static VisitedEntry* visited_pool = NULL;
static VisitedEntry* hash_table[HASH_SIZE] = {0};
static int pool_ptr = 0;
static int pool_capacity = 0;
static int visited_ptr = 0;
void node_pool_init(int max_nodes) {
pool_capacity = max_nodes;
pool = malloc(pool_capacity * sizeof(Node));
visited_pool = malloc(pool_capacity * sizeof(VisitedEntry));
if (!pool || !visited_pool) {
fprintf(stderr, "Fatal: Could not allocate Node Pool for %d nodes.\n", max_nodes);
exit(1);
}
pool_ptr = 0;
visited_ptr = 0;
for (size_t i = 0; i < HASH_SIZE; ++i) hash_table[i] = NULL;
}
Node* node_pool_alloc() {
if (pool_ptr >= pool_capacity) {
fprintf(stderr, "\nNode Pool Overflow! Need more than %d nodes.\n", pool_capacity);
return NULL;
}
return &pool[pool_ptr++];
}
void node_pool_reset() {
pool_ptr = 0;
}
void node_pool_destroy() {
if (pool) free(pool);
}
int node_pool_usage() {
return pool_ptr;
}
static void make_move(char move, Node* curr) {
int128_t na = curr->a, nb = curr->b, nc = curr->c;
/* Calculate the new triplet based on the move type */
if (move == 'A') {
na = 2 * (curr->b + curr->c) - curr->a;
} else if (move == 'B') {
nb = 2 * (curr->a + curr->c) - curr->b;
} else if (move == 'C') {
nc = 2 * (curr->a + curr->b) - curr->c;
}
/* Validation and Enqueue */
if (safe_val(na) && safe_val(nb) && safe_val(nc)) {
if (visit_and_mark(na, nb, nc)) {
if (pool_ptr >= pool_capacity) return; /* Pool safety */
Node* n = &pool[pool_ptr++];
n->a = na; n->b = nb; n->c = nc;
n->move = move;
n->parent = curr;
n->next = NULL;
q_push(n);
}
}
}
void try_push_children(Node* curr) {
char last = curr->move;
if (last == '\0') {
make_move('A', curr);
make_move('B', curr);
make_move('C', curr);
return;
}
if (last == 'A') {
make_move('C', curr);
make_move('B', curr);
}
else if (last == 'B') {
make_move('C', curr);
make_move('A', curr);
}
else if (last == 'C') {
make_move('B', curr);
make_move('A', curr);
}
}
int visit_and_mark(int128_t a, int128_t b, int128_t c) {
sort_triplet(&a, &b, &c);
unsigned int h = hash_three128(a,b,c);
VisitedEntry* cur = hash_table[h];
while (cur) {
if (cur->a == a && cur->b == b && cur->c == c) return 0;
cur = cur->next;
}
if (visited_ptr >= pool_capacity) {
fprintf(stderr, "VisPool Overflow! Increase MAX_NODES.\n");
exit(1);
}
VisitedEntry* e = &visited_pool[visited_ptr++];
e->a = a; e->b = b; e->c = c;
e->next = hash_table[h];
hash_table[h] = e;
return 1;
}
void clear_hash_table() {
visited_ptr = 0;
for (size_t i = 0; i < HASH_SIZE; ++i) hash_table[i] = NULL;
}