From 381896c84f21e2a526c9482edf225bbf671f70a5 Mon Sep 17 00:00:00 2001 From: Georgios Chatzopoulos Date: Wed, 6 May 2026 22:21:57 +0300 Subject: [PATCH] Uploading my current work to my personal gitea --- Makefile | 147 +++++++++++++++++++++ include/core.h | 16 +++ include/maths.h | 28 ++++ src/core.c | 38 ++++++ src/maths.c | 93 ++++++++++++++ src/stergios.c | 283 +++++++++++++++++++++++++++++++++++++++++ temp/calc_i | Bin 0 -> 16480 bytes temp/calc_i.c | 162 +++++++++++++++++++++++ temp/stergios-int128.c | 259 +++++++++++++++++++++++++++++++++++++ 9 files changed, 1026 insertions(+) create mode 100644 Makefile create mode 100755 include/core.h create mode 100755 include/maths.h create mode 100755 src/core.c create mode 100755 src/maths.c create mode 100755 src/stergios.c create mode 100755 temp/calc_i create mode 100755 temp/calc_i.c create mode 100755 temp/stergios-int128.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7dcef45 --- /dev/null +++ b/Makefile @@ -0,0 +1,147 @@ +# ============================================================ +# C Cross-Platform Build System +# ============================================================ + +# Default Compiler (will be set based on platform) +CC = none + +# Default Compiler Flags +CFLAGS = none + +# Default Platform (will be detected) +PLATFORM = none +ifeq ($(OS),Windows_NT) + PLATFORM = windows +else + PLATFORM = linux +endif + +# Debug flag +DEBUG = -g -DDEBUG=1 + +# ------------------------------------------------------------ +# Include auto-generated dependency files +-include $(OBJ_FILES:.o=.d) + +# ------------------------------------------------------------ +# General information +INCLUDE_FLAGS = -Iinclude + +# Linux-specific information +LINUX_CC = gcc +LINUX_CFLAGS = -O3 $(INCLUDE_FLAGS) -MMD -MP -Wall -Wextra -Werror -pedantic +LINUX_LDFLAGS = -O3 $(INCLUDE_FLAGS) + +# Windows-specific information +WINDOWS_CC = x86_64-w64-mingw32-gcc +WINDOWS_CFLAGS = -O3 $(INCLUDE_FLAGS) -MMD -MP -Wall -Wextra -Werror -pedantic +WINDOWS_LDFLAGS = -O3 $(INCLUDE_FLAGS) + +# ------------------------------------------------------------ +# Project folders +SRC = src +BIN_DIR = ./bin +OBJ_DIR = ./obj + +# ------------------------------------------------------------ +# Detect platform based on make command arguments +ifneq (,$(findstring linux,$(MAKECMDGOALS))) +PLATFORM := linux +endif + +ifneq (,$(findstring windows,$(MAKECMDGOALS))) +PLATFORM := windows +endif + +# ------------------------------------------------------------ +# Project source files +SRC_FILES := $(shell find $(SRC) -name '*.c') +OBJ_FILES := $(patsubst %.c,$(OBJ_DIR)/%.o,$(SRC_FILES)) +TARGET = $(BIN_DIR)/stergios + +# ------------------------------------------------------------ +# Output binary name +ifeq ($(PLATFORM), windows) + CC = $(WINDOWS_CC) + CFLAGS = $(WINDOWS_CFLAGS) + LDFLAGS = $(WINDOWS_LDFLAGS) + OUT = $(TARGET).exe +else ifeq ($(PLATFORM), linux) + CC = $(LINUX_CC) + CFLAGS = $(LINUX_CFLAGS) + LDFLAGS = $(LINUX_LDFLAGS) + OUT = $(TARGET) +endif + +# ------------------------------------------------------------ +# Default Platform (will be detected) +default: $(OUT) + +# ------------------------------------------------------------ +# Help target: Display usage help +help: + @echo "Usage:" + @echo " make - Default Build for your operating system" + @echo " make build linux|windows - Build for your specified platform" + @echo " make debug linux|windows - Build with debug symbols for the engine" + @echo " make run linux|windows - Run the built program" + @echo " make build --debug linux|windows - Build with debug symbols for make" + @echo " make debug --debug linux|windows - Build with debug symbols for make and the engine" + @echo " make run --debug linux|windows - Run with debug symbols" + @echo " make clean - Clean the build directory" + +# ------------------------------------------------------------ +# Ensure build directories exist +check_dirs: + @mkdir -p $(BIN_DIR) + @mkdir -p $(OBJ_DIR) + +# ------------------------------------------------------------ +$(OBJ_DIR)/%.o: %.c | check_dirs + @mkdir -p $(dir $@) + @echo "Compiling $< -> $@" + $(CC) $(CFLAGS) -c $< -o $@ + +# ------------------------------------------------------------ +$(OUT): $(OBJ_FILES) | check_dirs + @echo "Linking final executable: $(OUT)" + $(CC) $(CFLAGS) $(OBJ_FILES) -o $(OUT) $(LDFLAGS) + +# ------------------------------------------------------------ +# Build target +build: $(OUT) + +# ------------------------------------------------------------ +# Run target +run: build +ifeq ($(PLATFORM), windows) + @echo "Running application..." + @start "" "$(OUT)" +else ifeq ($(PLATFORM), linux) + @echo "Running application..." + $(OUT) +else + @echo "Specify a platform: make run linux or make run windows" +endif + +# ------------------------------------------------------------ +# Clean target +clean: + @echo "Cleaning object and bin directories..." + rm -rf $(OBJ_DIR) + rm -rf $(BIN_DIR) + @mkdir -p $(OBJ_DIR) + @mkdir -p $(BIN_DIR) + +# ------------------------------------------------------------ +# Declare linux/windows as fake targets so make doesn’t fail +.PHONY: linux windows +linux: + @true +windows: + @true + +# Debug flag +.PHONY: debug +debug: CFLAGS += DEBUG +debug: $(OUT) \ No newline at end of file diff --git a/include/core.h b/include/core.h new file mode 100755 index 0000000..a7901be --- /dev/null +++ b/include/core.h @@ -0,0 +1,16 @@ +#ifndef CORE_H +#define CORE_H + +__extension__ typedef __int128 int128_t; +__extension__ typedef unsigned __int128 uint128_t; + +// Read 128 bit integers as string +int read_int128_triplet(const char* prompt, int128_t* a, int128_t* b, int128_t* c); + +// Convert the read string into 128 bit integers +int128_t str_to_int128(const char* s); + +// Print 128 but integers +void print_int128(int128_t n); + +#endif \ No newline at end of file diff --git a/include/maths.h b/include/maths.h new file mode 100755 index 0000000..11109ca --- /dev/null +++ b/include/maths.h @@ -0,0 +1,28 @@ +#ifndef MATHS_H +#define MATHS_H + +#include "core.h" + +// Check if a 128 bit integer is a prime number or not +int is_prime(int128_t n); + +// Calculate the GCD for 3 128 bit integers +int128_t gcd3(int128_t a, int128_t b, int128_t c); + +// Calculate the GCD for 2 128 bit integers +int128_t gcd2(int128_t a, int128_t b); + +// Return the absolute value of a 128 bit integer +int128_t abs128(int128_t x); + +// Raise a number a certain exponent +int128_t power(int128_t b, int128_t ex); + +// Generate the factor pairs +void generate_factor_pairs(int128_t* sum, int prime_index, int* exponents, + int128_t* values, int128_t n1, int print_mode); + +// Calculate the square root of an unsigned 128 bit integer +uint128_t mysqrt_uint128(uint128_t number); + +#endif \ No newline at end of file diff --git a/src/core.c b/src/core.c new file mode 100755 index 0000000..3f2ac1b --- /dev/null +++ b/src/core.c @@ -0,0 +1,38 @@ +#include "core.h" + +#include +#include + +int read_int128_triplet(const char* prompt, int128_t* a, int128_t* b, int128_t* c) { + char sa[256], sb[256], sc[256]; + + if (printf("%s ", prompt) < 0) return -1; + + if (scanf("%255s %255s %255s", sa, sb, sc) != 3) return -2; + + *a = str_to_int128(sa); + *b = str_to_int128(sb); + *c = str_to_int128(sc); + return 0; +} + +int128_t str_to_int128(const char* s) { + int sign = (*s == '-') ? (s++, -1) : 1; + int128_t v = 0; + while (*s >= '0' && *s <= '9') v = v * 10 + (*s++ - '0'); + return sign * v; +} + +void print_int128(int128_t n) { + if (n == 0) { printf("0"); return; } + char buf[40]; + int i = 0; + int neg = n < 0; + if (neg) n = -n; + while (n > 0) { + buf[i++] = '0' + n % 10; + n /= 10; + } + if (neg) putchar('-'); + while (i--) putchar(buf[i]); +} \ No newline at end of file diff --git a/src/maths.c b/src/maths.c new file mode 100755 index 0000000..ade5918 --- /dev/null +++ b/src/maths.c @@ -0,0 +1,93 @@ +#include "maths.h" + +#include +#include + +extern int128_t LIMIT; +extern int run_bfs(int128_t* sum, int128_t a0, int128_t b0, int128_t c0, int print_mode); + +const int NUM_PRIMES = 3; +const int primes[] = {2, 3, 5}; + +int is_prime(int128_t n) { + if (n < 2) return 0; + if (n == 2) return 1; + if (n % 2 == 0) return 0; + for (int128_t i = 3; i <= n / i; i += 2) + if (n % i == 0) return 0; + return 1; +} + +int128_t gcd3(int128_t a, int128_t b, int128_t c) { + return gcd2(gcd2(a, b), c); +} + +int128_t gcd2(int128_t a, int128_t b) { + a = a < 0 ? -a : a; + b = b < 0 ? -b : b; + while (b != 0) { + int128_t temp = b; + b = a % b; + a = temp; + } + return a; +} + +int128_t abs128(int128_t x) { + return (x < 0) ? -x : x; +} + +int128_t power(int128_t b, int128_t ex) { + int128_t res = 1; + while (ex > 0) { + if (ex % 2 == 1) res = res * b; + + b = b * b; + ex /= 2; + } + return res; +} + +void generate_factor_pairs(int128_t* sum, int prime_index, int* exponents, + int128_t* values, int128_t n1, int print_mode) { + if (prime_index == NUM_PRIMES) { + int128_t n2 = values[0] / n1; + if (n1 > n2) return; + + 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; + LIMIT = values[1] >= greater ? values[1] * greater / 2 : values[2] * val1 / 2; + run_bfs(sum, values[1], values[2], val1, print_mode); + if (val2 >= 0) { + greater = values[2] >= val2 ? values[2] : val2; + LIMIT = values[1] >= greater ? values[1] * greater / 2 : values[2] * val2 / 2; + run_bfs(sum, values[1], values[2], val2, print_mode); + } + } + return; + } + + int prime = primes[prime_index]; + int exponent = exponents[prime_index]; + int128_t power_of_prime = 1; + + for (int j = 0; j <= exponent; j++) { + int128_t next_n1 = n1 * power_of_prime; + generate_factor_pairs(sum, prime_index+1, exponents, values, next_n1, print_mode); + if (j < exponent) power_of_prime *= prime; + } +} + +uint128_t mysqrt_uint128(uint128_t number) { + if (number == 0) return 0; + uint128_t x = number; + uint128_t y = (x + 1) >> 1; + + while (y < x) { + x = y; + y = (x + number / x) >> 1; + } + return x; +} \ No newline at end of file diff --git a/src/stergios.c b/src/stergios.c new file mode 100755 index 0000000..a07fd99 --- /dev/null +++ b/src/stergios.c @@ -0,0 +1,283 @@ +#include "core.h" +#include "maths.h" + +#include +#include + +#define HASH_SIZE 200003 +//#define LIMIT 100000000LL + +//#define HASH_SIZE 200000003 +//const int128_t LIMIT = (int128_t)1000000000ULL * 1000000000ULL * 1000000000ULL; + +int128_t LIMIT = 0; + +typedef struct Node { + int128_t a, b, c; + char move; + struct Node* parent; + struct Node* next; +} Node; + +typedef struct VisEntry { + int128_t a, b, c; + struct VisEntry* next; +} VisEntry; + +static VisEntry* hash_table[HASH_SIZE] = {0}; + +void clear_hash_table() { + for (size_t i = 0; i < HASH_SIZE; ++i) { + VisEntry* cur = hash_table[i]; + while (cur) { + VisEntry* nx = cur->next; + free(cur); + cur = nx; + } + + hash_table[i] = NULL; + } +} + +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); + VisEntry* cur = hash_table[h]; + while (cur) { + if (cur->a == a && cur->b == b && cur->c == c) return 0; + cur = cur->next; + } + VisEntry* e = (VisEntry*)malloc(sizeof(VisEntry)); + if (!e) { fprintf(stderr, "Out of memory\n"); exit(1); } + e->a = a; e->b = b; e->c = c; + e->next = hash_table[h]; + hash_table[h] = e; + return 1; +} + +static Node* q_front = NULL; +static Node* q_back = NULL; + +static void enqueue(Node* n) { + n->next = NULL; + if (!q_back) q_front = q_back = n; + else { + q_back->next = n; + q_back = n; + } +} + +static Node* dequeue() { + if (!q_front) return NULL; + Node* r = q_front; + q_front = q_front->next; + if (!q_front) q_back = NULL; + r->next = NULL; + return r; +} + +void drain_queue() { + Node* n; + while ((n = dequeue()) != NULL) free(n); +} + +static int safe_val(int128_t x) { + if (x > LIMIT || x < -LIMIT) return 0; + return 1; +} + +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)) { + Node* n = (Node*)malloc(sizeof(Node)); + if (!n) { fprintf(stderr, "Out of memory\n"); exit(1); } + n->a = na; n->b = nb; n->c = nc; + n->move = move; + n->parent = curr; + n->next = NULL; + enqueue(n); + } + } +} + +static void try_push_children(Node* curr) { + char last = curr->move; + + // Root node doesn't have a 'last' move, so try all three. + if (last == '\0') { + make_move('A', curr); + make_move('B', curr); + make_move('C', curr); + return; + } + + // To avoid AAAA, BBBB, or CCCC, we only pick from the other two moves. + // We also prioritize B and C to favor the alternating CBCB pattern. + if (last == 'A') { + // Just did A: try C then B (the two non-A moves) + make_move('C', curr); + make_move('B', curr); + } + else if (last == 'B') { + // Just did B: try C (alternating) then A (neutral) + // We skip B because it would just take us back to the parent. + make_move('C', curr); + make_move('A', curr); + } + else if (last == 'C') { + // Just did C: try B (alternating) then A (neutral) + // We skip C because it's redundant. + make_move('B', curr); + make_move('A', curr); + } +} + +int main() { + int mode = 0, print_mode = 0; + int128_t a0 = 10, b0 = 6, c0 = 0, sum = 0; + while (mode == 0) { + if (printf("1: manual\n") < 0) return 1; + if (printf("2: auto\n") < 0) return 1; + if (printf("Choose what mode you want to enter: ") < 0) return 1; + if (scanf(" %i", &mode) != 1) { + fprintf(stderr, "Input error.\n"); + return 1; + } + if (mode != 1 && mode != 2) mode = 0; + } + + while (print_mode == 0) { + if (printf("1: Print full?\n") < 0) return 1; + if (printf("2: Print minimal?\n") < 0) return 1; + if (printf("Choose what mode you want to enter: ") < 0) return 1; + if (scanf(" %i", &print_mode) != 1) { + fprintf(stderr, "Input error.\n"); + return 1; + } + if (print_mode != 1 && print_mode != 2) print_mode = 0; + } + + if (mode == 1) { + if (read_int128_triplet("Enter initial a b c:", &a0, &b0, &c0) != 0) { + fprintf(stderr, "Input error.\n"); + return 1; + } + + if (a0 == 0 || b0 == 0 || c0 == 0) { + printf("Already zero present: ("); + print_int128(a0); printf(", "); + print_int128(b0); printf(", "); + print_int128(c0); printf(")\n"); + return 0; + } + + int128_t greater = b0 >= c0 ? b0 : c0; + LIMIT = a0 >= greater ? a0 * greater / 2 : b0 * c0 / 2; + + if (!safe_val(a0) || !safe_val(b0) || !safe_val(c0)) { + fprintf(stderr, "Initial values exceed safe limit.\n"); + return 1; + } + + run_bfs(&sum, a0, b0, c0, print_mode); + } else if (mode == 2) { + 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)}; + generate_factor_pairs(&sum, 0, exponents, values, 1, print_mode); + + printf("Total sum is: "); + print_int128(sum); printf("\n"); + } + return 0; +} + +int run_bfs(int128_t* sum, int128_t a0, int128_t b0, int128_t c0, int print_mode) { + drain_queue(); + clear_hash_table(); + + Node* root = malloc(sizeof(Node)); + if (!root) { fprintf(stderr, "Out of memory\n"); return 0; } + root->a = a0; root->b = b0; root->c = c0; + root->move = '\0'; root->parent = NULL; root->next = NULL; + enqueue(root); + visit_and_mark(a0, b0, c0); + + Node* found = NULL; + while ((root = dequeue()) != NULL) { + if (root->a == 0 || root->b == 0 || root->c == 0) { found = root; break; } + try_push_children(root); + } + + if (!found) { + printf("No solution found within bounds/search limits.\n"); + drain_queue(); + clear_hash_table(); + return 0; + } + + int max_moves = 0; + for (Node* p = found; p && p->move != '\0'; p = p->parent) max_moves++; + + char* moves; + if (print_mode == 1) { + moves = malloc(max_moves + 1); + if (!moves) { fprintf(stderr, "Out of memory\n"); return 0; } + moves[max_moves] = '\0'; + + Node* p = found; + int idx = max_moves - 1; + while (p && p->move != '\0') { + moves[idx--] = p->move; + p = p->parent; + } + + printf("\nSolution found!\n"); + printf("Initial: ("); + print_int128(a0); printf(", "); + print_int128(b0); printf(", "); + print_int128(c0); printf(")\n"); + + printf("Final: ("); + print_int128(found->a); printf(", "); + print_int128(found->b); printf(", "); + print_int128(found->c); printf(")\n"); + + printf("Moves (%d): %s\n", max_moves, moves); + } else if (print_mode == 2) { + print_int128(c0); + printf(" the required amount of moves is: %d\n", max_moves); + } + *sum+=max_moves; + + if (print_mode == 1) free(moves); + drain_queue(); + clear_hash_table(); + + return 1; +} \ No newline at end of file diff --git a/temp/calc_i b/temp/calc_i new file mode 100755 index 0000000000000000000000000000000000000000..7fa61638ed4a7a2e22e07b57c297e0024c2a8b1a GIT binary patch literal 16480 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 literal 0 HcmV?d00001 diff --git a/temp/calc_i.c b/temp/calc_i.c new file mode 100755 index 0000000..3d9ee19 --- /dev/null +++ b/temp/calc_i.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include + +// briskei ola ta i + +typedef __int128 int128_t; + +int128_t power(int128_t b, int128_t ex) +{ + int128_t res = (int128_t)1; + while (ex > 0) { + // If the exponent is odd, multiply the result by the current base value + if (ex % 2 == 1) { // Same as (exponent & 1) + res = (int128_t)res * b; + } + + // Square the base for the next iteration + b = (int128_t)b * b; + // Halve the exponent (integer division) + ex /= (int128_t)2; // Same as (exponent >>= 1) + } + return res; +} + +void print_int128(__int128 n) +{ + if (n == 0) { + putchar('0'); + return; + } + if (n < 0) { + putchar('-'); + n = -n; + } + + // A buffer to hold the digits (max digits ~40) + char buf[40]; + int i = 0; + + // Extract digits in reverse order + while (n > 0) { + buf[i++] = (char)((n % 10) + '0'); + n /= 10; + } + + // Print the digits in the correct order + while (i > 0) { + putchar(buf[--i]); + } +} + +const int primes[] = {2, 3, 5}; +int exponents[] = {0, 0, 0}; +const int NUM_PRIMES = 3; + +// Global variable to store the number N (calculated in main) +int128_t N_value = 1; +int128_t a = 1; +int128_t b = 1; +// --- Function to Recursively Generate Factor Pairs --- + +/** + * @brief Recursively generates the first factor (n1) and prints the pair (n1, n2) + * such that n1 * n2 = N. The generation stops when n1 exceeds sqrt(N). + * + * @param prime_index The index of the current prime factor being considered. + * @param n1 The factor built so far. + */ +void generate_factor_pairs(int prime_index, int128_t n1, int f) +{ + // Base Case: If we have considered all unique prime factors, + // n1 is a complete factor of N. + if (prime_index == NUM_PRIMES) { + // Optimization: Stop if n1 exceeds the square root of N. + // This prevents printing the pair (n2, n1) after (n1, n2) has been printed. + // Note: For large N, we should compare n1 * n1 > N_value to avoid + // issues with long long or the sqrt() function if it's less precise. + int128_t n2 = (int128_t)N_value / (int128_t)n1; + if ((int128_t)n1 > (int128_t)n2) { + return; + } + if (((int128_t)n1 + (int128_t)n2) % 2 == 0) { + int128_t i = (int128_t)a + (int128_t)b + (((int128_t)n1 + (int128_t)n2) >> 1); + int128_t k = (((int128_t)n2 - (int128_t)n1) >> 1); + if (f) { + printf("i: "); + print_int128(i); + printf(" k: "); + print_int128(k); + printf(" ("); + print_int128(n1); + printf(" , "); + print_int128(n2); + printf(")"); + printf("\n"); + } + else { + print_int128(i); + printf("\n"); + } + + if ((int128_t)a + (int128_t)b - (((int128_t)n1 + (int128_t)n2) >> 1) >= 0) { + int128_t i = (int128_t)a + (int128_t)b - (((int128_t)n1 + (int128_t)n2) >> 1); + if (f) { + printf("i: "); + print_int128(i); + printf(" k: "); + print_int128(k); + printf(" ("); + print_int128(n1); + printf(" , "); + print_int128(n2); + printf(")"); + printf("\n"); + } + else { + print_int128(i); + printf("\n"); + } + } + } + return; + } + + // Get the current prime and its exponent + int prime = primes[prime_index]; + int exponent = exponents[prime_index]; + int128_t power_of_prime = 1; + + // Recursive Step: Iterate through all possible powers of the current prime + for (int i = 0; i <= exponent; i++) { + // The new factor n1 is the old n1 multiplied by (prime^i) + int128_t next_n1 = (int128_t)n1 * (int128_t)power_of_prime; + + // Recursive call for the next prime factor + generate_factor_pairs(prime_index + 1, next_n1, f); + + // Calculate the next power of the current prime: prime^(i+1) + if (i < exponent) { + power_of_prime *= (int128_t)prime; + } + } +} + +int main(int argc, char **argv) +{ + // long long triple[] = {} + int p; + sscanf(argv[1], "%d", &p); + int f; + sscanf(argv[2], "%d", &f); + a = (int128_t)power(10, p); + b = (int128_t)power(6, p); + N_value = (int128_t)4 * a * b; + exponents[0] = 2 * p + 2; + exponents[1] = p; + exponents[2] = p; + generate_factor_pairs(0, 1, 0); +} + diff --git a/temp/stergios-int128.c b/temp/stergios-int128.c new file mode 100755 index 0000000..b997926 --- /dev/null +++ b/temp/stergios-int128.c @@ -0,0 +1,259 @@ +#include +#include +#include + +typedef __int128 int128_t; +typedef unsigned __int128 uint128_t; + +#define HASH_SIZE 200003 +//static const int128_t LIMIT = (int128_t)1000000000ULL * (int128_t)1000000000ULL * (int128_t)100ULL; +#define LIMIT 1000000000LL + +static int is_prime(int128_t n) { + if (n < 2) return 0; + if (n % 2 == 0) return n == 2; + for (int128_t i = 3; i * i <= n; i += 2) if (n % i == 0) return 0; + return 1; +} + +typedef struct Node { + int128_t a, b, c; + char move; + struct Node *parent; + struct Node *next; +} Node; + +typedef struct VisEntry { + int128_t a, b, c; + struct VisEntry *next; +} VisEntry; + +static VisEntry *hash_table[HASH_SIZE] = {0}; + +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 unsigned int hash_three(int128_t a, int128_t b, int128_t c) { + uint128_t x = (uint128_t)(a + 0x9e3779b97f4a7c15ULL); + x ^= (uint128_t)(b + 0xbf58476d1ce4e5b9ULL) + (x<<6) + (x>>2); + x ^= (uint128_t)(c + 0x94d049bb133111ebULL) + (x<<6) + (x>>2); + return (unsigned int)(x % HASH_SIZE); +} + +static int visit_and_mark(int128_t a, int128_t b, int128_t c) { + //unsigned int h = hash_three(a,b,c); + unsigned int h = hash_three128(a,b,c); + VisEntry *cur = hash_table[h]; + while (cur) { + if (cur->a == a && cur->b == b && cur->c == c) return 0; + cur = cur->next; + } + VisEntry *e = (VisEntry*)malloc(sizeof(VisEntry)); + if (!e) { fprintf(stderr, "Out of memory\n"); exit(1); } + e->a = a; e->b = b; e->c = c; + e->next = hash_table[h]; + hash_table[h] = e; + return 1; +} + +static Node *q_front = NULL; +static Node *q_back = NULL; + +static void enqueue(Node *n) { + n->next = NULL; + if (!q_back) q_front = q_back = n; + else { + q_back->next = n; + q_back = n; + } +} + +static Node *dequeue(void) { + if (!q_front) return NULL; + Node *r = q_front; + q_front = q_front->next; + if (!q_front) q_back = NULL; + r->next = NULL; + return r; +} + +static int safe_val(int128_t x) { + if (x > LIMIT || x < -LIMIT) return 0; + return 1; +} + +static int128_t gcd(int128_t x, int128_t y) { + while (y != 0) { + int128_t t = y; + y = x % y; + x = t; + } + return x < 0 ? -x : x; +} + + +static void try_push_children(Node *curr) { + int128_t a = curr->a, b = curr->b, c = curr->c; + + int128_t g = gcd(a, gcd(b, c)); + if (g > 1) { + int128_t ga = a / g; + int128_t gb = b / g; + int128_t gc = c / g; + + int prime_count = is_prime(ga) + is_prime(gb) + is_prime(gc); + + if (prime_count >= 1) return; + } + + int128_t na = 2*(b + c) - a; + if (safe_val(na) && safe_val(b) && safe_val(c)) { + if (visit_and_mark(na, b, c)) { + Node *n = (Node*)malloc(sizeof(Node)); + n->a = na; n->b = b; n->c = c; n->move = 'A'; n->parent = curr; n->next = NULL; + enqueue(n); + } + } + + int128_t nb = 2*(a + c) - b; + if (safe_val(a) && safe_val(nb) && safe_val(c)) { + if (visit_and_mark(a, nb, c)) { + Node *n = (Node*)malloc(sizeof(Node)); + n->a = a; n->b = nb; n->c = c; n->move = 'B'; n->parent = curr; n->next = NULL; + enqueue(n); + } + } + + int128_t nc = 2*(a + b) - c; + if (safe_val(a) && safe_val(b) && safe_val(nc)) { + if (visit_and_mark(a, b, nc)) { + Node *n = (Node*)malloc(sizeof(Node)); + n->a = a; n->b = b; n->c = nc; n->move = 'C'; n->parent = curr; n->next = NULL; + enqueue(n); + } + } +} + +// Convert string -> int128 +int128_t str_to_int128(const char *s) { + int128_t value = 0; + int sign = 1; + + if (*s == '-') { + sign = -1; + s++; + } + + while (*s >= '0' && *s <= '9') { + value = value * 10 + (*s - '0'); + s++; + } + + return sign * value; +} + +// Print __int128 (for debugging) +void print_int128(int128_t x) { + if (x == 0) { + printf("0"); + return; + } + + if (x < 0) { + putchar('-'); + x = -x; + } + + char buf[64]; + int i = 0; + + while (x > 0) { + buf[i++] = '0' + (int)(x % 10); + x /= 10; + } + + while (i--) putchar(buf[i]); +} + +int main(void) { + char sa[256], sb[256], sc[256]; + int128_t a0, b0, c0; + if (printf("Enter initial a b c: ") < 0) return 1; + if (scanf("%255s %255s %255s", sa, sb, sc) != 3) { + fprintf(stderr, "Invalid input\n"); + return 1; + } + + a0 = str_to_int128(sa); + b0 = str_to_int128(sb); + c0 = str_to_int128(sc); + + if (a0 == 0 || b0 == 0 || c0 == 0) { + printf("Already zero present: ("); + print_int128(a0); printf(", "); + print_int128(b0); printf(", "); + print_int128(c0); printf(")\n"); + return 0; + } + + if (!safe_val(a0) || !safe_val(b0) || !safe_val(c0)) { + fprintf(stderr, "Initial values exceed safe limit.\n"); + return 1; + } + + Node *root = (Node*)malloc(sizeof(Node)); + if (!root) { fprintf(stderr, "Out of memory\n"); return 1; } + root->a = a0; root->b = b0; root->c = c0; root->move = '\0'; root->parent = NULL; root->next = NULL; + enqueue(root); + visit_and_mark(a0,b0,c0); + + Node *found = NULL; + while ((root = dequeue()) != NULL) { + if (root->a == 0 || root->b == 0 || root->c == 0) { + found = root; + break; + } + try_push_children(root); + } + + if (!found) { + printf("No solution found within bounds/search limits.\n"); + return 0; + } + + int max_moves = 0; + Node *p = found; + while (p && p->move != '\0') { max_moves++; p = p->parent; } + + char *moves = (char*)malloc(max_moves + 1); + if (!moves) { fprintf(stderr, "Out of memory\n"); return 1; } + moves[max_moves] = '\0'; + p = found; + int idx = max_moves - 1; + while (p && p->move != '\0') { + moves[idx--] = p->move; + p = p->parent; + } + + printf("\nSolution found!\n"); + printf("Initial: ("); + print_int128(a0); printf(", "); + print_int128(b0); printf(", "); + print_int128(c0); printf(")\n"); + + printf("Final: ("); + print_int128(found->a); printf(", "); + print_int128(found->b); printf(", "); + print_int128(found->c); printf(")\n"); + printf("Moves (%d): %s\n", max_moves, moves); + return 0; +}