extern crate num_bigint; // extern crate num_traits; extern crate num_cpus; #[macro_use] extern crate clap; use clap::App; use num_bigint::BigUint; use std::thread; // use std::sync::mpsc; use std::sync::{Arc, Barrier, RwLock}; use std::time::{Duration, Instant}; trait Peristance { fn per_mul(&self) -> u8; } impl Peristance for BigUint { fn per_mul(&self) -> u8 { let mut n = self.to_radix_le(10) .into_iter() .product::(); let mut counter = 1; while n.to_str_radix(10).chars().count() > 1 { n = n.to_radix_le(10) .into_iter() .product::(); counter += 1; } return counter; } } #[derive(Debug)] struct Counter { count: BigUint, step: u8, offset: u8 } impl Counter { fn new(_step: u8, _offset: u8) -> Counter { Counter {count: BigUint::from(0u8), step: _step, offset: _offset} } } impl Iterator for Counter { type Item = BigUint; fn next(&mut self) -> Option { // Increment our count. This is why we started at zero. self.count += self.step; Some(self.count.clone()) } } fn main() { let start = Instant::now(); let args = App::new("Persistance") .version("0.2.0") .author("Daniel Olsen") .about("Finds the sequence of smallest number with a multiplicative persistance of n") .args_from_usage("-j, --jobs=[threads] 'Sets the number of worker threads to spin up, if 0 or empty this equals the number of cores on your system (INCLUDING HYPERTHREADS)' -m, --max=[max] 'Sets the maximum n you want to calculate'") .get_matches(); let mut cpus = value_t!(args, "jobs", u8).unwrap_or(num_cpus::get() as u8); if cpus == 0 { cpus = num_cpus::get() as u8; } let cpus = cpus; let max = value_t!(args, "max", u8).unwrap_or(11u8); println!("threads: {}", cpus); let barrier = Arc::new(Barrier::new(2)); for thread in 0..(cpus) { let c = barrier.clone(); thread::spawn(move || { println!("Started thread {}!", thread); let counter = Counter::new(cpus-thread, cpus); let mut top: u8 = 0; for x in counter { let n = x.per_mul(); if n > top { top = n; println!("{:?} {} - {}: {}", start.elapsed(), thread, n, x); if n > max-1 { c.wait(); return; } } } }); } barrier.wait(); println!("Finding took {:#?}", start.elapsed()); return; }