WIP PE 095, getting bullied by the borrow checker
This commit is contained in:
84
projecteuler/095/src/main.rs
Normal file
84
projecteuler/095/src/main.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
time::Instant,
|
||||
u64::MAX,
|
||||
};
|
||||
|
||||
fn sum_of_divisors(n: u64, divisor_map: &HashMap<u64, HashSet<u64>>) -> (u64, HashSet<u64>) {
|
||||
let max_div = n / 2 + 1;
|
||||
let mut result = HashSet::new();
|
||||
|
||||
for i in 1..=max_div {
|
||||
if n % i == 0 {
|
||||
result.insert(i);
|
||||
if let Some(div_set) = divisor_map.get(&(n / i)) {
|
||||
result = result.union(div_set).collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (result.iter().sum(), result);
|
||||
}
|
||||
|
||||
fn find_longest_amicable_chain(limit: u64) -> u64 {
|
||||
let mut chain_numbers = HashSet::new();
|
||||
let mut max_chain_length = 0;
|
||||
let mut smallest_chain_number = MAX;
|
||||
let mut divisor_sums = HashMap::new();
|
||||
|
||||
for n in 0..limit {
|
||||
if chain_numbers.contains(&n) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let l = n;
|
||||
let mut chain = vec![l];
|
||||
loop {
|
||||
let (l, l_divisors) = sum_of_divisors(l, &divisor_sums);
|
||||
divisor_sums.insert(l, l_divisors);
|
||||
|
||||
if l >= limit {
|
||||
chain.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if chain.contains(&l) {
|
||||
break;
|
||||
}
|
||||
|
||||
if chain_numbers.contains(&l) {
|
||||
chain.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
chain.push(l);
|
||||
// We want to push numbers into the found_numbers even if the chain might get too big
|
||||
// in the future, since this is just a list of numbers that we don't want to
|
||||
// investigate further.
|
||||
chain_numbers.insert(l);
|
||||
}
|
||||
|
||||
if chain.len() > max_chain_length {
|
||||
max_chain_length = chain.len();
|
||||
smallest_chain_number = chain.into_iter().min().unwrap();
|
||||
|
||||
println!("{}", smallest_chain_number);
|
||||
}
|
||||
}
|
||||
|
||||
return smallest_chain_number;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, this is Patrick!");
|
||||
let now = Instant::now();
|
||||
|
||||
const LIMIT: u64 = 1000000;
|
||||
|
||||
println!(
|
||||
"Smallest element of amicable chain containing only elements below 1 million: {}",
|
||||
find_longest_amicable_chain(LIMIT)
|
||||
);
|
||||
|
||||
println!("Time passed: {:?}", Instant::now() - now);
|
||||
}
|
||||
Reference in New Issue
Block a user