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