How to resolve the algorithm Multi-base primes step by step in the Rust programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Multi-base primes step by step in the Rust programming language

Table of Contents

Problem Statement

Prime numbers are prime no matter what base they are represented in. A prime number in a base other than 10 may not look prime at first glance. For instance: 19 base 10 is 25 in base 7.

Several different prime numbers may be expressed as the "same" string when converted to a different base.

Restricted to bases 2 through 36; find the strings that have the most different bases that evaluate to that string when converting prime numbers to a base. Find the conversion string, the amount of bases that evaluate a prime to that string and the enumeration of bases that evaluate a prime to that string. Display here, on this page, the string, the count and the list for all of the: 1 character, 2 character, 3 character, and 4 character strings that have the maximum base count that evaluate to that string. Should be no surprise, the string '2' has the largest base count for single character strings.

Do the same for the maximum 5 character string.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Multi-base primes step by step in the Rust programming language

Source code in the rust programming language

// [dependencies]
// primal = "0.3"

fn digits(mut n: u32, dig: &mut [u32]) {
    for i in 0..dig.len() {
        dig[i] = n % 10;
        n /= 10;
    }
}

fn evalpoly(x: u64, p: &[u32]) -> u64 {
    let mut result = 0;
    for y in p.iter().rev() {
        result *= x;
        result += *y as u64;
    }
    result
}

fn max_prime_bases(ndig: u32, maxbase: u32) {
    let mut maxlen = 0;
    let mut maxprimebases = Vec::new();
    let limit = 10u32.pow(ndig);
    let mut dig = vec![0; ndig as usize];
    for n in limit / 10..limit {
        digits(n, &mut dig);
        let bases: Vec<u32> = (2..=maxbase)
            .filter(|&x| dig.iter().all(|&y| y < x) && primal::is_prime(evalpoly(x as u64, &dig)))
            .collect();
        if bases.len() > maxlen {
            maxlen = bases.len();
            maxprimebases.clear();
        }
        if bases.len() == maxlen {
            maxprimebases.push((n, bases));
        }
    }
    println!(
        "{} character numeric strings that are prime in maximum bases: {}",
        ndig, maxlen
    );
    for (n, bases) in maxprimebases {
        println!("{} => {:?}", n, bases);
    }
    println!();
}

fn main() {
    for n in 1..=6 {
        max_prime_bases(n, 36);
    }
}


// [dependencies]
// primal = "0.3"

fn to_string(digits: &[usize]) -> String {
    const DIGITS: [char; 62] = [
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
        'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
        'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    ];
    let mut str = String::new();
    for d in digits {
        str.push(DIGITS[*d]);
    }
    str
}

fn increment(digits: &mut [usize], base: usize) -> bool {
    for d in digits.iter_mut().rev() {
        if *d + 1 != base {
            *d += 1;
            return true;
        }
        *d = 0;
    }
    false
}

fn multi_base_primes(max_base: usize, max_length: usize) {
    let sieve = primal::Sieve::new(max_base.pow(max_length as u32));
    for length in 1..=max_length {
        let mut most_bases = 0;
        let mut max_strings = Vec::new();
        let mut digits = vec![0; length];
        digits[0] = 1;
        let mut bases = Vec::new();
        loop {
            let mut min_base = 2;
            if let Some(max) = digits.iter().max() {
                min_base = std::cmp::max(min_base, max + 1);
            }
            if most_bases <= max_base - min_base + 1 {
                bases.clear();
                for b in min_base..=max_base {
                    if max_base - b + 1 + bases.len() < most_bases {
                        break;
                    }
                    let mut n = 0;
                    for d in &digits {
                        n = n * b + d;
                    }
                    if sieve.is_prime(n) {
                        bases.push(b);
                    }
                }
                if bases.len() > most_bases {
                    most_bases = bases.len();
                    max_strings.clear();
                }
                if bases.len() == most_bases {
                    max_strings.push((digits.clone(), bases.clone()));
                }
            }
            if !increment(&mut digits, max_base) {
                break;
            }
        }
        println!(
            "{}-character strings which are prime in most bases: {}",
            length, most_bases
        );
        for (digits, bases) in max_strings {
            println!("{} -> {:?}", to_string(&digits), bases);
        }
        println!();
    }
}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let mut max_base = 36;
    let mut max_length = 4;
    let mut arg = 0;
    while arg + 1 < args.len() {
        if args[arg] == "-max_base" {
            arg += 1;
            match args[arg].parse::<usize>() {
                Ok(n) => max_base = n,
                Err(error) => {
                    eprintln!("{}", error);
                    return;
                }
            }
        } else if args[arg] == "-max_length" {
            arg += 1;
            match args[arg].parse::<usize>() {
                Ok(n) => max_length = n,
                Err(error) => {
                    eprintln!("{}", error);
                    return;
                }
            }
        }
        arg += 1;
    }
    if max_base > 62 {
        eprintln!("Maximum base cannot be greater than 62.");
    } else if max_base < 2 {
        eprintln!("Maximum base cannot be less than 2.");
    } else {
        use std::time::Instant;
        let now = Instant::now();
        multi_base_primes(max_base, max_length);
        let time = now.elapsed();
        println!("elapsed time: {} milliseconds", time.as_millis());
    }
}


  

You may also check:How to resolve the algorithm Least common multiple step by step in the PL/I programming language
You may also check:How to resolve the algorithm Factorions step by step in the Factor programming language
You may also check:How to resolve the algorithm Probabilistic choice step by step in the Perl programming language
You may also check:How to resolve the algorithm 99 bottles of beer step by step in the UnixPipes programming language
You may also check:How to resolve the algorithm Sum multiples of 3 and 5 step by step in the JavaScript programming language