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:
+123
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user