From a6e62a99cce6d5dd949c74e86cb4437b6adf7ef9 Mon Sep 17 00:00:00 2001 From: William Ball Date: Thu, 23 Jul 2020 14:30:27 -0700 Subject: [PATCH] added investigations of inserting digits anywhere --- .../Cargo.toml | 10 ++ .../src/main.rs | 119 ++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 rust/insert_digit_anywhere_primes_constant/Cargo.toml create mode 100644 rust/insert_digit_anywhere_primes_constant/src/main.rs diff --git a/rust/insert_digit_anywhere_primes_constant/Cargo.toml b/rust/insert_digit_anywhere_primes_constant/Cargo.toml new file mode 100644 index 0000000..5c88300 --- /dev/null +++ b/rust/insert_digit_anywhere_primes_constant/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "insert_digit_anywhere_primes_constant" +version = "0.1.0" +authors = ["William Ball "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +primal = "0.3.0" diff --git a/rust/insert_digit_anywhere_primes_constant/src/main.rs b/rust/insert_digit_anywhere_primes_constant/src/main.rs new file mode 100644 index 0000000..5405e5a --- /dev/null +++ b/rust/insert_digit_anywhere_primes_constant/src/main.rs @@ -0,0 +1,119 @@ +use std::thread; +use std::collections::HashSet; + +const NUM_THREADS: usize = 6; +const THREAD_SKIP: u64 = 1_000; +const BASE: u64 = 16; + +fn remove_duplicates(ls: Vec) -> Vec { + let mut hs: HashSet = HashSet::new(); + for val in &ls { + hs.insert(*val); + } + hs.iter().map(|x| *x).collect() +} + +fn u64_to_v(x: u64) -> Vec { + let mut ll = Vec::new(); + let mut x = x; + while x > 0 { + ll.push(x % BASE); + x /= BASE; + } + ll +} + +fn v_to_u64(ll: Vec) -> u64 { + let mut val = 0; + let mut ll = ll; + loop { + match ll.pop() { + Some(v) => { + val += v; + val *= BASE; + } + None => break, + }; + } + val / BASE +} + +fn step(x: u64) -> Vec { + let mut new_xs = Vec::new(); + let v_x = u64_to_v(x); + for i in 0..v_x.len() + 1 { + for d in 0..BASE { + let mut v_x = u64_to_v(x); + v_x.insert(i, d); + let temp = v_to_u64(v_x); + if !(i == 0 && d == 0) { + if primal::is_prime(temp) { + new_xs.push(temp); + } + } + } + } + new_xs +} + +fn next(ls: Vec) -> (f64, Vec) { + let old = ls.len(); + let mut count = 0; + let mut new: Vec = Vec::new(); + let mut slices: Vec> = Vec::new(); + let mut children = Vec::with_capacity(NUM_THREADS); + let size = ls.len() / NUM_THREADS; + for i in 0..(NUM_THREADS - 1) { + let mut new = Vec::with_capacity(size); + for val in ls.iter().skip(size * i).take(size) { + new.push(*val); + } + slices.push(new); + } + { + let mut new = Vec::new(); + for val in ls.iter().skip(size * (NUM_THREADS - 1)) { + new.push(*val); + } + slices.push(new); + } + for slice in slices { + children.push(thread::spawn(move || -> (u64, Vec) { + let mut new = Vec::new(); + let mut count = 0; + for oldval in slice { + // let mut temp = step(oldval); + let temp = step(oldval); + count += temp.len() as u64; + new.push(oldval + THREAD_SKIP); + // new.append(&mut temp); + } + (count, new) + })); + } + for child in children { + let (temp1, mut temp2) = child.join().unwrap(); + new.append(&mut temp2); + count += temp1; + } + (count as f64 / old as f64, remove_duplicates(new)) +} + +fn main() { + let mut ls: Vec = (1..(NUM_THREADS as u64) * THREAD_SKIP) + .into_iter() + .collect(); + let mut count: f64; + let mut i = 0; + let mut total: f64 = 0.0; + // let mut ls = primal::Primes::all().take_while(|x| *x < BASE as usize).map(|x| x as u64).collect(); + loop { + let res = next(ls); + count = res.0; + ls = res.1; + i += 1; + total += count; + let res = total as f64 / i as f64; + println!("{}\t{}", res, f64::abs(res / (BASE as f64 / f64::ln(BASE as f64)))); + } +}