#include "node.h" #include "hash.h" #include "maths.h" #include "queue.h" #include #include 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; }