optimizations

This commit is contained in:
William Ball 2020-07-24 17:04:00 -07:00
parent e6d61cbf1b
commit a74ede0ac8

View file

@ -1,64 +1,50 @@
use rug::{Assign, Integer};
use std::thread; use std::thread;
use std::collections::HashSet;
const NUM_THREADS: usize = 12; const NUM_THREADS: usize = 12;
const BASE: u64 = 10; const BASE: u64 = 10;
fn is_fourth_free(x: &Integer) -> bool { fn is_fourth_free(x: &u64) -> bool {
let mut i = Integer::new(); let mut i = 2;
i.assign(2); let mut fourth = i * i * i * i;
let mut fourth = Integer::from(&Integer::from(&i * &i) * &Integer::from(&i * &i));
while fourth < *x { while fourth < *x {
if x % (fourth) == 0 { if x % fourth == 0 {
return false; return false;
} }
i += 1; i += 1;
fourth = Integer::from(&Integer::from(&i * &i) * &Integer::from(&i * &i)); fourth = i * i * i * i;
} }
true true
} }
fn step(x: &Integer) -> Vec<Integer> { fn step(x: &u64) -> Vec<u64> {
let mut new_xs: HashSet<Integer> = HashSet::new(); let mut new_xs: Vec<u64> = Vec::new();
for d in 0..BASE { for d in 0..BASE {
let mut temp = Integer::from(x * BASE); let temp = x * BASE + d;
temp += d;
if is_fourth_free(&temp) { if is_fourth_free(&temp) {
new_xs.insert(temp); new_xs.push(temp);
} }
} }
new_xs.iter().cloned().collect() new_xs
} }
fn next(ls: &Vec<Integer>) -> Vec<Integer> { fn next(ls: Vec<u64>) -> Vec<u64> {
let mut new: Vec<Integer> = Vec::new(); let mut new: Vec<u64> = Vec::new();
let mut slices: Vec<Vec<Integer>> = Vec::new();
let mut children = Vec::with_capacity(NUM_THREADS); let mut children = Vec::with_capacity(NUM_THREADS);
let size = ls.len() / NUM_THREADS; let size = ls.len() / NUM_THREADS;
for i in 0..(NUM_THREADS - 1) { (0..(NUM_THREADS - 1))
let mut new = Vec::with_capacity(size); .map(|i| -> Vec<u64> { (&ls[size * i..size * (i + 1)]).iter().copied().collect() })
for val in ls.iter().skip(size * i).take(size) { .for_each(|slice| {
new.push(val.clone()); children.push(thread::spawn(move || {
} slice.iter().map(|oldval| step(oldval)).flatten().collect()
slices.push(new); }))
} });
{ children.push(thread::spawn(move || -> Vec<u64> {
let mut new = Vec::new(); let mut new = Vec::new();
for val in ls.iter().skip(size * (NUM_THREADS - 1)) { for oldval in &ls[size * (NUM_THREADS - 1)..] {
new.push(val.clone()); new.append(&mut step(oldval));
}
slices.push(new);
}
for slice in slices {
children.push(thread::spawn(move || -> Vec<Integer> {
let mut new = Vec::new();
for oldval in slice {
new.append(&mut step(&oldval));
} }
new new
})); }));
}
for child in children { for child in children {
new.append(&mut child.join().unwrap()); new.append(&mut child.join().unwrap());
} }
@ -67,14 +53,16 @@ fn next(ls: &Vec<Integer>) -> Vec<Integer> {
fn main() { fn main() {
let mut i = 0; let mut i = 0;
let mut ls: Vec<Integer> = (1..BASE) let mut ls: Vec<u64> = (1..BASE)
.into_iter() .into_iter()
.map(|x| Integer::from(x))
.filter(|x| is_fourth_free(x)) .filter(|x| is_fourth_free(x))
.collect(); .collect();
loop { loop {
i += 1; i += 1;
println!("{}\t{}", i, ls.len()); println!("{}\t{}", i, ls.len());
ls = next(&ls); ls = next(ls);
if i == 6 {
break;
}
} }
} }