Skip to content

Instantly share code, notes, and snippets.

@Sporif
Last active August 28, 2021 11:32
Show Gist options
  • Save Sporif/48ed08be47b8488c728ae2c9f9718a11 to your computer and use it in GitHub Desktop.
Save Sporif/48ed08be47b8488c728ae2c9f9718a11 to your computer and use it in GitHub Desktop.
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
use flume::bounded;
use std::sync::mpsc::sync_channel;
use std::thread;
const NUM_DIVISORS: i64 = 2000;
fn main() {
// create a channel to dequeue work
let (work_tx, work_rx) = bounded::<_>(0);
// create a channel to send the result
let (result_tx, result_rx) = sync_channel::<_>(0);
// spawn worker threads
let cpus = num_cpus::get();
println!("spawn worker threads: {}", cpus);
let join_handles = (0..cpus)
.map(|_| {
let work_rx = work_rx.clone();
let result_tx = result_tx.clone();
thread::spawn(move || {
for num in work_rx {
let factors = find_factor_count(num);
if factors >= NUM_DIVISORS {
result_tx.send(num).unwrap();
}
}
})
})
.collect::<Vec<_>>();
// send work to workers
let mut num = 0;
for i in 1.. {
// check if result is available
if let Ok(result) = result_rx.try_recv() {
drop(work_tx);
num = result;
break;
}
num += i;
work_tx.send(num).unwrap();
}
// wait for threads to finish
for j in join_handles {
j.join().unwrap();
}
println!("result: {}", num);
}
#[allow(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::float_cmp
)]
fn find_factor_count(num: i64) -> i64 {
let square = (num as f64).sqrt();
let i_square = square as i64;
let count = if square == (i_square as f64) { -1 } else { 0 };
(1..=i_square)
.into_iter()
.filter(|x| num % x == 0)
.map(|_| 2)
.sum::<i64>()
+ count
}
#[allow(dead_code)]
fn find_factor_count_new(num: i64) -> i64 {
(1..num)
.take_while(|i| i * i <= num)
.filter(|i| num % i == 0)
.map(|i| if i * i == num { 1 } else { 2 })
.sum::<i64>()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment