Made an improvement for storing a global table for possible duplicate numbers (after dividing by gcd)

This commit is contained in:
2026-05-06 23:47:55 +03:00
parent 51881687f5
commit 7e215dc877
2 changed files with 74 additions and 18 deletions
+14 -7
View File
@@ -5,6 +5,7 @@
extern int128_t LIMIT;
extern int run_bfs(int128_t* sum, int128_t a0, int128_t b0, int128_t c0, int print_mode);
extern int is_new_root(int128_t a, int128_t b, int128_t c);
const int NUM_PRIMES = 3;
const int primes[] = {2, 3, 5};
@@ -57,15 +58,21 @@ void generate_factor_pairs(int128_t* sum, int prime_index, int* exponents,
if ((n1 + n2) % 2 == 0) {
int128_t val1 = values[1] + values[2] + ((n1 + n2) >> 1);
int128_t val2 = values[1] + values[2] - ((n1 + n2) >> 1);
int128_t greater = values[2] >= val1 ? values[2] : val1;
int128_t gcd1 = gcd3(values[1], values[2], val1);
int128_t gcd2 = gcd3(values[1], values[2], val2);
LIMIT = values[1] >= greater ? values[1] * greater / (2 * gcd1 * gcd1) : values[2] * val1 / (2 * gcd1 * gcd1);
run_bfs(sum, values[1] / gcd1, values[2] / gcd1, val1 / gcd1, print_mode);
if (val2 >= 0) {
greater = values[2] >= val2 ? values[2] : val2;
LIMIT =values[1] >= greater ? values[1] * greater / (2 * gcd2 * gcd2) : values[2] * val2 / (2 * gcd2 * gcd2);
run_bfs(sum, values[1] / gcd2, values[2] / gcd2, val2 / gcd2, print_mode);
int128_t r1a = values[1] / gcd1, r1b = values[2] / gcd1, r1c = val1 / gcd1;
int128_t r2a = values[1] / gcd2, r2b = values[2] / gcd2, r2c = val2 / gcd2;
if (is_new_root(r1a, r1b, r1c)) {
int128_t greater = values[2] >= val1 ? values[2] : val1;
LIMIT = values[1] >= greater ? values[1] * greater / (2 * gcd1 * gcd1) : values[2] * val1 / (2 * gcd1 * gcd1);
run_bfs(sum, r1a, r1b, r1c, print_mode);
}
if (val2 >= 0 && is_new_root(r2a, r2b, r2c)) {
int128_t greater = values[2] >= val2 ? values[2] : val2;
LIMIT = values[1] >= greater ? values[1] * greater / (2 * gcd2 * gcd2) : values[2] * val2 / (2 * gcd2 * gcd2);
run_bfs(sum, r2a, r2b, r2c, print_mode);
}
}
return;
+60 -11
View File
@@ -7,6 +7,65 @@
#define HASH_SIZE 200003
int128_t LIMIT = 0;
typedef struct GlobalEntry {
int128_t a, b, c;
struct GlobalEntry* next;
} GlobalEntry;
static GlobalEntry* global_root_table[HASH_SIZE] = {0};
// Helper to sort the triplet so order doesn't matter
static void sort_triplet(int128_t* a, int128_t* b, int128_t* c) {
int128_t tmp;
if (*a > *b) { tmp = *a; *a = *b; *b = tmp; }
if (*b > *c) { tmp = *b; *b = *c; *c = tmp; }
if (*a > *b) { tmp = *a; *a = *b; *b = tmp; }
}
static inline uint128_t mix128(uint128_t a, uint128_t b, uint128_t c) {
uint128_t x = a + (uint128_t)0x9e3779b97f4a7c15ULL + ((uint128_t)0x9e3779b97f4a7c15ULL << 64);
x ^= b + ((uint128_t)0xbf58476d1ce4e5b9ULL + ((uint128_t)0xbf58476d1ce4e5b9ULL << 64)) + (x << 6) + (x >> 2);
x ^= c + ((uint128_t)0x94d049bb133111ebULL + ((uint128_t)0x94d049bb133111ebULL << 64)) + (x << 6) + (x >> 2);
return x;
}
static unsigned int hash_three128(uint128_t a, uint128_t b, uint128_t c) {
uint128_t x = mix128(a, b, c);
return (unsigned int)(x % HASH_SIZE);
}
// Returns 1 if this is a new root, 0 if we've already calculated it
int is_new_root(int128_t a, int128_t b, int128_t c) {
sort_triplet(&a, &b, &c);
unsigned int h = hash_three128((uint128_t)a, (uint128_t)b, (uint128_t)c);
GlobalEntry* cur = global_root_table[h];
while (cur) {
if (cur->a == a && cur->b == b && cur->c == c) return 0;
cur = cur->next;
}
GlobalEntry* e = malloc(sizeof(GlobalEntry));
if (!e) return 1; // Fallback to running BFS if malloc fails
e->a = a; e->b = b; e->c = c;
e->next = global_root_table[h];
global_root_table[h] = e;
return 1;
}
// Call this at the start of 'auto' mode
void clear_global_table() {
for (int i = 0; i < HASH_SIZE; i++) {
GlobalEntry* cur = global_root_table[i];
while (cur) {
GlobalEntry* next = cur->next;
free(cur);
cur = next;
}
global_root_table[i] = NULL;
}
}
typedef struct Node {
int128_t a, b, c;
char move;
@@ -36,17 +95,6 @@ void clear_hash_table() {
int run_bfs(int128_t* sum, int128_t a0, int128_t b0, int128_t c0, int print_mode);
static inline uint128_t mix128(uint128_t a, uint128_t b, uint128_t c) {
uint128_t x = a + (uint128_t)0x9e3779b97f4a7c15ULL + ((uint128_t)0x9e3779b97f4a7c15ULL << 64);
x ^= b + ((uint128_t)0xbf58476d1ce4e5b9ULL + ((uint128_t)0xbf58476d1ce4e5b9ULL << 64)) + (x << 6) + (x >> 2);
x ^= c + ((uint128_t)0x94d049bb133111ebULL + ((uint128_t)0x94d049bb133111ebULL << 64)) + (x << 6) + (x >> 2);
return x;
}
static unsigned int hash_three128(uint128_t a, uint128_t b, uint128_t c) {
uint128_t x = mix128(a, b, c);
return (unsigned int)(x % HASH_SIZE);
}
static int visit_and_mark(int128_t a, int128_t b, int128_t c) {
unsigned int h = hash_three128(a,b,c);
@@ -202,6 +250,7 @@ int main() {
run_bfs(&sum, a0 / gcd, b0 / gcd, c0 / gcd, print_mode);
} else if (mode == 2) {
clear_global_table(); // Reset unique root tracker
int p = 3;
int exponents[3] = {2*p + 2, p, p};
int128_t values[3] = {4 * power(a0, p) * power(b0, p), power(a0, p), power(b0, p)};