use std::process::Command;
const N: usize = 128;
fn is_prime(num: usize) -> bool {
if num < 2 { return false; }
for i in 2..=(num as f64).sqrt() as usize {
if num.is_multiple_of(i) { return false; }
}
true
}
fn check_distinct_differences(exponents: &[usize; 9]) -> bool {
let mut seen = [false; N + 1];
for i in 0..9 {
for j in (i + 1)..9 {
let diff = exponents[j].abs_diff(exponents[i]);
if seen[diff] {
return false;
}
seen[diff] = true;
}
}
true
}
fn find_candidates(
buckets: &Vec<Vec<usize>>,
current_idx: usize,
current_exponents: &mut [usize; 9]
) -> bool {
if current_idx == 8 {
if check_distinct_differences(current_exponents) {
let candidate_str = format!("x^{} + x^{} + x^{} + x^{} + x^{} + x^{} + x^{} + x^{} + 1",
current_exponents[8], current_exponents[7], current_exponents[6],
current_exponents[5], current_exponents[4], current_exponents[3],
current_exponents[2], current_exponents[1]
);
println!("Testing candidate: {}", candidate_str);
let sage_script = format!(
"R.<x> = GF(2)[]\nP = {}\nif P.is_primitive():\n print('SUCCESS')\nelse:\n print('FAILED')",
candidate_str
);
let output = Command::new("sage")
.arg("-c")
.arg(&sage_script)
.output();
match output {
Ok(out) => {
let out_str = String::from_utf8_lossy(&out.stdout);
if out_str.contains("SUCCESS") {
println!("\n=======================================================");
println!("SUCCESS! FOUND PRIMITIVE ELK POLYNOMIAL:");
println!("{}", candidate_str);
println!("=======================================================\n");
return true; }
},
Err(e) => {
eprintln!("\n[ERROR] Failed to execute SageMath. Is it installed and in your PATH?");
eprintln!("System Error: {}", e);
std::process::exit(1);
}
}
}
return false;
}
for &prime in &buckets[current_idx - 1] {
current_exponents[current_idx] = prime;
if find_candidates(buckets, current_idx + 1, current_exponents) {
return true;
}
}
false
}
fn main() {
println!("Searching for ELK polynomial candidates for N = {}", N);
let interval_size = N / 8;
let mut buckets: Vec<Vec<usize>> = vec![Vec::new(); 7];
for i in 1..=7 {
let start = interval_size * i;
let end = interval_size * (i + 1) - 1;
for num in start..=end {
if is_prime(num) {
buckets[i - 1].push(num);
}
}
println!("Bucket {} ({} to {}): {} primes", i, start, end, buckets[i-1].len());
}
let mut exponents = [0; 9];
exponents[0] = 0;
exponents[8] = N;
println!("\nStarting search and primitivity testing...\n");
let mut reversed_buckets = buckets.clone();
reversed_buckets.reverse();
let found = find_candidates(&reversed_buckets, 1, &mut exponents);
if !found {
println!("\nNo candidates found matching the specific prime distribution constraints.");
}
}