add 21
This commit is contained in:
@@ -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" }
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user