This commit is contained in:
timeshifter
2025-03-12 16:17:41 +01:00
parent 6aee127071
commit 37f40689dc
2 changed files with 116 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "euler21"
version = "0.1.0"
edition = "2024"
[profile.release]
debug = true
lto = "off"
[dependencies]
proper_divisors = { version = "*", path = "../../lib/proper_divisors" }
+105
View File
@@ -0,0 +1,105 @@
use proper_divisors::ProperDivisors;
use std::collections::HashMap;
const MIN: usize = 2;
const MAX: usize = 10_000;
fn main() {
let pd = ProperDivisors::get_between(MIN, MAX);
let mut map = NumberDivisorSumMap::build(pd);
let mut sum = 0;
for i in MIN..MAX {
if let Some(pair) = map.find_amicable_number(i) {
sum += pair + i;
}
}
println!("{sum}");
}
#[derive(Debug)]
struct NumberDivisorSumMap {
map: HashMap<usize, usize>,
}
impl NumberDivisorSumMap {
fn build(pd: ProperDivisors) -> Self {
let mut number_divisor_sum_map = HashMap::new();
for number in pd.min..pd.max {
let sum: usize = pd.get(number).iter().sum();
number_divisor_sum_map.insert(number, sum);
}
Self {
map: number_divisor_sum_map,
}
}
fn get(&self, key: &usize) -> Option<&usize> {
self.map.get(key)
}
fn remove(&mut self, key: &usize) {
self.map.remove(key);
}
fn remove_all(&mut self, keys: &[usize]) {
for key in keys {
self.remove(key);
}
}
fn find_amicable_number(&mut self, number: usize) -> Option<usize> {
let possible_pair = match self.get(&number) {
None => return None,
Some(possible_pair) => possible_pair.to_owned(),
};
if possible_pair == number {
return None;
}
if self.get(&possible_pair) == Some(&number) {
self.remove_all(&[number, possible_pair]);
return Some(possible_pair);
}
None
}
}
#[cfg(test)]
mod tests {
use proper_divisors::ProperDivisors;
use crate::NumberDivisorSumMap;
#[test]
fn case_pair() {
let pd = ProperDivisors::get_between(2, 10_000);
let mut number_divisor_sum_map = NumberDivisorSumMap::build(pd);
let result = number_divisor_sum_map.find_amicable_number(220);
assert_eq!(result, Some(284));
}
#[test]
fn case_not_pair() {
let pd = ProperDivisors::get_between(2, 10_000);
let mut number_divisor_sum_map = NumberDivisorSumMap::build(pd);
let result = number_divisor_sum_map.find_amicable_number(221);
assert_eq!(result, None);
}
#[test]
fn case_false_pair() {
let pd = ProperDivisors::get_between(2, 10);
let mut number_divisor_sum_map = NumberDivisorSumMap::build(pd);
let result = number_divisor_sum_map.find_amicable_number(6);
assert_eq!(result, None);
}
}