extern crate ramp; use ramp::Int; extern crate num_cpus; #[macro_use] extern crate clap; use clap::App; use std::thread; // use std::sync::mpsc; use std::sync::{Arc, Barrier, RwLock}; use std::time::{Duration, Instant}; trait Peristance { fn per_mul(&self) -> i32; } impl Peristance for Int { fn per_mul(&self) -> i32 { let mut n = self.to_str_radix(10, false) .chars() .map(|x| x as i32 - 48) .fold(Int::one(), |acc, x| acc * x); let mut counter = 1; while n.to_str_radix(10, false).chars().count() > 1 { n = n.to_str_radix(10, false) .chars() .map(|x| x as i32 - 48) .fold(Int::one(), |acc, x| acc * x); counter += 1; } return counter; } } #[derive(Debug)] struct Counter { count: Int, step: i32, offset: i32 } impl Counter { fn new(_step: i32, _offset: i32) -> Counter { Counter {count: Int::zero(), step: _step, offset: _offset} } } impl Iterator for Counter { type Item = Int; 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", i32).unwrap_or(num_cpus::get() as i32); if cpus == 0 { cpus = num_cpus::get() as i32; } let cpus = cpus; let max: i32 = value_t!(args, "max", i32).unwrap_or(11i32); 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: i32 = 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; }