Uploading my current work to my personal gitea
This commit is contained in:
@@ -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)
|
||||||
Executable
+16
@@ -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
|
||||||
Executable
+28
@@ -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
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
Executable
+93
@@ -0,0 +1,93 @@
|
|||||||
|
#include "maths.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
Executable
+283
@@ -0,0 +1,283 @@
|
|||||||
|
#include "core.h"
|
||||||
|
#include "maths.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
Executable
BIN
Binary file not shown.
Executable
+162
@@ -0,0 +1,162 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
Executable
+259
@@ -0,0 +1,259 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user