From ccfb2aa01ac090a8fc208563d0804b20a50b98be Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Fri, 8 Aug 2025 14:47:39 +0200 Subject: [PATCH 01/10] add black scholes algo first iteration --- src/financial/black_scholes.rs | 76 ++++++++++++++++++++++++++++++++++ src/financial/mod.rs | 3 ++ 2 files changed, 79 insertions(+) create mode 100644 src/financial/black_scholes.rs diff --git a/src/financial/black_scholes.rs b/src/financial/black_scholes.rs new file mode 100644 index 00000000000..30d32ad73f4 --- /dev/null +++ b/src/financial/black_scholes.rs @@ -0,0 +1,76 @@ + +/// implementation of the Black-Scholes model for option pricing +/// The model essentially calculates the probability-weighted present value of the option's potential payoffs. +/// The N(d₁) and N(d₂) terms represent probabilities related to the option finishing in-the-money (intrinsic value of the option). + +#[derives(PartialEq, Eq, Debug)] +pub enum BlackScholesError { + InvalidParameters, +} + +pub fn black_scholes( + spot_price: f64, // current price of the stock + strike_price: f64, // price you can buy the stock at + time_to_maturity: f64, // time until the option expires (in years) + risk_free_rate: f64, // risk free interest rate (annualized) + volatility: f64, + +) -> Result { + if spot_price <= 0.0 || strike_price <= 0.0 || time_to_maturity < 0.0 || risk_free_rate < 0.0 || volatility < 0.0 { + return Err(BlackScholesError::InvalidParameters); + } + + let d1 = (spot_price.ln() - strike_price.ln() + (risk_free_rate + 0.5 * volatility.powi(2)) * time_to_maturity) + / (volatility * time_to_maturity.sqrt()); + let d2 = d1 - volatility * time_to_maturity.sqrt(); + + let n_d1 = normal_cdf(d1); + let n_d2 = normal_cdf(d2); + + let call_option_price = spot_price * n_d1 - strike_price * (-risk_free_rate * time_to_maturity).exp() * n_d2; + + Ok(round(call_option_price)) +} + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! test_black_scholes { + ($($name:ident: $inputs:expr,)*) => { + $( + #[test] + fn $name() { + let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; + let expected = black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap(); + assert!(expected >= 0.0); + } + )* + } + } + + macro_rules! test_black_scholes_Err { + ($($name:ident: $inputs:expr,)*) => { + $( + #[test] + fn $name() { + let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; + assert_eq!(black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap_err(), BlackScholesError::InvalidParameters); + } + )* + } + } + + test_black_scholes! { + valid_parameters: (100.0, 100.0, 1.0, 0.05, 0.2), + another_valid_case: (150.0, 100.0, 2.0, 0.03, 0.25), + } + + test_black_scholes_Err! { + negative_spot_price: (-100.0, 100.0, 1.0, 0.05, 0.2), + zero_strike_price: (100.0, 0.0, 1.0, 0.05, 0.2), + negative_time_to_maturity: (100.0, 100.0, -1.0, 0.05, 0.2), + negative_risk_free_rate: (100.0, 100.0, 1.0, -0.05, 0.2), + negative_volatility: (100.0, 100.0, 1.0, 0.05, -0.2), + } +} \ No newline at end of file diff --git a/src/financial/mod.rs b/src/financial/mod.rs index 89b36bfa5e0..16956020402 100644 --- a/src/financial/mod.rs +++ b/src/financial/mod.rs @@ -1,2 +1,5 @@ mod present_value; +mod black_scholes; + pub use present_value::present_value; +pub use black_scholes::black_scholes; From a4aa6bcb010ea8a5a39f8ebe921324d3158a65eb Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Fri, 8 Aug 2025 14:56:11 +0200 Subject: [PATCH 02/10] fix unstable clippy and nalgebra cargo --- Cargo.toml | 2 +- clippy.toml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f48dabb6902..71d16d2eafb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Anshul Malik "] num-bigint = { version = "0.4", optional = true } num-traits = { version = "0.2", optional = true } rand = "0.9" -nalgebra = "0.34.0" +nalgebra = "0.33.0" [dev-dependencies] quickcheck = "1.0" diff --git a/clippy.toml b/clippy.toml index 42484457fb0..1b3dd21fbf7 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,3 +1,4 @@ allowed-duplicate-crates = [ - "glam", + "zerocopy", + "zerocopy-derive", ] From 0a2392e77c81520f3513ae1ab6527d74e2de93d5 Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Mon, 11 Aug 2025 13:35:43 +0200 Subject: [PATCH 03/10] add black_scholes algo --- Cargo.toml | 2 +- clippy.toml | 3 +- src/financial/black_scholes.rs | 105 +++++++++++++++++++-------------- src/financial/mod.rs | 6 +- 4 files changed, 67 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 71d16d2eafb..f48dabb6902 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Anshul Malik "] num-bigint = { version = "0.4", optional = true } num-traits = { version = "0.2", optional = true } rand = "0.9" -nalgebra = "0.33.0" +nalgebra = "0.34.0" [dev-dependencies] quickcheck = "1.0" diff --git a/clippy.toml b/clippy.toml index 1b3dd21fbf7..42484457fb0 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,4 +1,3 @@ allowed-duplicate-crates = [ - "zerocopy", - "zerocopy-derive", + "glam", ] diff --git a/src/financial/black_scholes.rs b/src/financial/black_scholes.rs index 30d32ad73f4..8e64a3fe9a7 100644 --- a/src/financial/black_scholes.rs +++ b/src/financial/black_scholes.rs @@ -1,76 +1,95 @@ - /// implementation of the Black-Scholes model for option pricing -/// The model essentially calculates the probability-weighted present value of the option's potential payoffs. +/// The model essentially calculates the probability-weighted present value of the option's potential payoffs. /// The N(d₁) and N(d₂) terms represent probabilities related to the option finishing in-the-money (intrinsic value of the option). +use std::f64::consts::PI; -#[derives(PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub enum BlackScholesError { InvalidParameters, } +// accumulate standard normal distribution function +fn normal_cdf(x: f64) -> f64 { + 0.5 * (1.0 + (x / (2.0_f64.sqrt() * PI)).exp().tanh()) +} + +// Round to 4 decimal +fn round_to_precision(value: f64, precision: u32) -> f64 { + let multiplier = 10.0f64.powi(precision as i32); + (value * multiplier).round() / multiplier +} + pub fn black_scholes( - spot_price: f64, // current price of the stock - strike_price: f64, // price you can buy the stock at + spot_price: f64, // current price of the stock + strike_price: f64, // price you can buy the stock at time_to_maturity: f64, // time until the option expires (in years) - risk_free_rate: f64, // risk free interest rate (annualized) + risk_free_rate: f64, // risk free interest rate (annualized) volatility: f64, - ) -> Result { - if spot_price <= 0.0 || strike_price <= 0.0 || time_to_maturity < 0.0 || risk_free_rate < 0.0 || volatility < 0.0 { + if spot_price <= 0.0 + || strike_price <= 0.0 + || time_to_maturity < 0.0 + || risk_free_rate < 0.0 + || volatility < 0.0 + { return Err(BlackScholesError::InvalidParameters); } - let d1 = (spot_price.ln() - strike_price.ln() + (risk_free_rate + 0.5 * volatility.powi(2)) * time_to_maturity) + let d1 = (spot_price.ln() - strike_price.ln() + + (risk_free_rate + 0.5 * volatility.powi(2)) * time_to_maturity) / (volatility * time_to_maturity.sqrt()); let d2 = d1 - volatility * time_to_maturity.sqrt(); let n_d1 = normal_cdf(d1); let n_d2 = normal_cdf(d2); - let call_option_price = spot_price * n_d1 - strike_price * (-risk_free_rate * time_to_maturity).exp() * n_d2; + let call_option_price = + spot_price * n_d1 - strike_price * (-risk_free_rate * time_to_maturity).exp() * n_d2; - Ok(round(call_option_price)) + Ok(round_to_precision(call_option_price, 4)) } #[cfg(test)] mod tests { use super::*; - macro_rules! test_black_scholes { - ($($name:ident: $inputs:expr,)*) => { - $( - #[test] - fn $name() { - let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; - let expected = black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap(); - assert!(expected >= 0.0); - } - )* + #[test] + fn my_test() { + macro_rules! test_black_scholes { + ($($name:ident: $inputs:expr,)*) => { + $( + fn $name() { + let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; + let expected = black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap(); + assert!(expected >= 0.0); + } + )* + } } - } - macro_rules! test_black_scholes_Err { - ($($name:ident: $inputs:expr,)*) => { - $( - #[test] - fn $name() { - let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; - assert_eq!(black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap_err(), BlackScholesError::InvalidParameters); - } - )* + macro_rules! test_black_scholes_Err { + ($($name:ident: $inputs:expr,)*) => { + $( + #[test] + fn $name() { + let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; + assert_eq!(black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap_err(), BlackScholesError::InvalidParameters); + } + )* + } } - } - test_black_scholes! { - valid_parameters: (100.0, 100.0, 1.0, 0.05, 0.2), - another_valid_case: (150.0, 100.0, 2.0, 0.03, 0.25), - } + test_black_scholes! { + valid_parameters: (100.0, 100.0, 1.0, 0.05, 0.2), + another_valid_case: (150.0, 100.0, 2.0, 0.03, 0.25), + } - test_black_scholes_Err! { - negative_spot_price: (-100.0, 100.0, 1.0, 0.05, 0.2), - zero_strike_price: (100.0, 0.0, 1.0, 0.05, 0.2), - negative_time_to_maturity: (100.0, 100.0, -1.0, 0.05, 0.2), - negative_risk_free_rate: (100.0, 100.0, 1.0, -0.05, 0.2), - negative_volatility: (100.0, 100.0, 1.0, 0.05, -0.2), + test_black_scholes_Err! { + negative_spot_price: (-100.0, 100.0, 1.0, 0.05, 0.2), + zero_strike_price: (100.0, 0.0, 1.0, 0.05, 0.2), + negative_time_to_maturity: (100.0, 100.0, -1.0, 0.05, 0.2), + negative_risk_free_rate: (100.0, 100.0, 1.0, -0.05, 0.2), + negative_volatility: (100.0, 100.0, 1.0, 0.05, -0.2), + } } -} \ No newline at end of file +} diff --git a/src/financial/mod.rs b/src/financial/mod.rs index 16956020402..e35289795ce 100644 --- a/src/financial/mod.rs +++ b/src/financial/mod.rs @@ -1,5 +1,5 @@ -mod present_value; mod black_scholes; +mod present_value; -pub use present_value::present_value; -pub use black_scholes::black_scholes; +pub use self::black_scholes::black_scholes; +pub use self::present_value::present_value; From 424481d3d4525a3168fb3fbd4a36f85e46079ed1 Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Tue, 12 Aug 2025 18:13:45 +0200 Subject: [PATCH 04/10] remove unnecessary parametter --- src/machine_learning/loss_function/kl_divergence_loss.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine_learning/loss_function/kl_divergence_loss.rs b/src/machine_learning/loss_function/kl_divergence_loss.rs index f477607b20f..918bdc338e6 100644 --- a/src/machine_learning/loss_function/kl_divergence_loss.rs +++ b/src/machine_learning/loss_function/kl_divergence_loss.rs @@ -16,7 +16,7 @@ pub fn kld_loss(actual: &[f64], predicted: &[f64]) -> f64 { let loss: f64 = actual .iter() .zip(predicted.iter()) - .map(|(&a, &p)| ((a + eps) * ((a + eps) / (p + eps)).ln())) + .map(|(&a, &p)| (a + eps) * ((a + eps) / (p + eps)).ln()) .sum(); loss } From 21c51176c6d38eb1c2b7317b48093906473f0392 Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Tue, 12 Aug 2025 18:34:18 +0200 Subject: [PATCH 05/10] changes made due to clippy change --- src/ciphers/aes.rs | 4 ++-- src/ciphers/blake2b.rs | 2 +- src/ciphers/sha3.rs | 2 +- src/ciphers/transposition.rs | 5 ++--- src/data_structures/avl_tree.rs | 4 ++-- src/data_structures/binary_search_tree.rs | 2 +- src/data_structures/probabilistic/bloom_filter.rs | 2 +- src/data_structures/treap.rs | 4 ++-- src/data_structures/veb_tree.rs | 2 +- src/general/huffman_encoding.rs | 5 +++-- src/general/permutations/heap.rs | 2 +- src/math/aliquot_sum.rs | 2 +- src/math/collatz_sequence.rs | 2 +- src/math/factors.rs | 2 +- src/math/interquartile_range.rs | 4 ++-- src/math/perfect_numbers.rs | 2 +- src/math/pollard_rho.rs | 2 +- src/math/prime_check.rs | 4 ++-- src/math/prime_factors.rs | 2 +- src/math/quadratic_residue.rs | 2 +- src/math/random.rs | 2 +- src/number_theory/euler_totient.rs | 4 ++-- 22 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/ciphers/aes.rs b/src/ciphers/aes.rs index 5d2eb98ece0..4616966d5e4 100644 --- a/src/ciphers/aes.rs +++ b/src/ciphers/aes.rs @@ -318,7 +318,7 @@ fn key_expansion(init_key: &[Byte], num_rounds: usize) -> Vec { } fn add_round_key(data: &mut [Byte], round_key: &[Byte]) { - assert!(data.len() % AES_BLOCK_SIZE == 0 && round_key.len() == AES_BLOCK_SIZE); + assert!(data.len().is_multiple_of(AES_BLOCK_SIZE) && round_key.len() == AES_BLOCK_SIZE); let num_blocks = data.len() / AES_BLOCK_SIZE; data.iter_mut() .zip(round_key.repeat(num_blocks)) @@ -348,7 +348,7 @@ fn mix_column_blocks(data: &mut [Byte], mode: AesMode) { } fn padding(data: &[T], block_size: usize) -> Vec { - if data.len() % block_size == 0 { + if data.len().is_multiple_of(block_size) { Vec::from(data) } else { let num_blocks = data.len() / block_size + 1; diff --git a/src/ciphers/blake2b.rs b/src/ciphers/blake2b.rs index c28486489d6..132b8e0d8d7 100644 --- a/src/ciphers/blake2b.rs +++ b/src/ciphers/blake2b.rs @@ -55,7 +55,7 @@ fn add(a: &mut Word, b: Word) { #[inline] const fn ceil(dividend: usize, divisor: usize) -> usize { - (dividend / divisor) + ((dividend % divisor != 0) as usize) + (dividend / divisor) + ((!dividend.is_multiple_of(divisor)) as usize) } fn g(v: &mut [Word; 16], a: usize, b: usize, c: usize, d: usize, x: Word, y: Word) { diff --git a/src/ciphers/sha3.rs b/src/ciphers/sha3.rs index f3791214f3f..40080d1746a 100644 --- a/src/ciphers/sha3.rs +++ b/src/ciphers/sha3.rs @@ -271,7 +271,7 @@ fn h2b(h: &[u8], n: usize) -> Vec { } fn b2h(s: &[bool]) -> Vec { - let m = if s.len() % U8BITS != 0 { + let m = if !s.len().is_multiple_of(U8BITS) { (s.len() / 8) + 1 } else { s.len() / 8 diff --git a/src/ciphers/transposition.rs b/src/ciphers/transposition.rs index d5b2a75196e..a64d593632d 100644 --- a/src/ciphers/transposition.rs +++ b/src/ciphers/transposition.rs @@ -42,9 +42,8 @@ pub fn transposition(decrypt_mode: bool, msg: &str, key: &str) -> String { key_ascii.sort_by_key(|&(index, _)| index); - key_ascii - .into_iter() - .for_each(|(_, key)| key_order.push(key.into())); + for (_, key) in key_ascii + .into_iter() { key_order.push(key.into()); } // Determines whether to encrypt or decrypt the message, // and returns the result diff --git a/src/data_structures/avl_tree.rs b/src/data_structures/avl_tree.rs index 64800a405ca..20fcef1255e 100644 --- a/src/data_structures/avl_tree.rs +++ b/src/data_structures/avl_tree.rs @@ -85,7 +85,7 @@ impl AVLTree { } /// Returns an iterator that visits the nodes in the tree in order. - fn node_iter(&self) -> NodeIter { + fn node_iter(&self) -> NodeIter<'_,T> { let cap = self.root.as_ref().map_or(0, |n| n.height); let mut node_iter = NodeIter { stack: Vec::with_capacity(cap), @@ -100,7 +100,7 @@ impl AVLTree { } /// Returns an iterator that visits the values in the tree in ascending order. - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_,T> { Iter { node_iter: self.node_iter(), } diff --git a/src/data_structures/binary_search_tree.rs b/src/data_structures/binary_search_tree.rs index 193fb485408..159f88fba2f 100644 --- a/src/data_structures/binary_search_tree.rs +++ b/src/data_structures/binary_search_tree.rs @@ -188,7 +188,7 @@ impl BinarySearchTreeIter<'_, T> where T: Ord, { - pub fn new(tree: &BinarySearchTree) -> BinarySearchTreeIter { + pub fn new(tree: &BinarySearchTree) -> BinarySearchTreeIter<'_,T> { let mut iter = BinarySearchTreeIter { stack: vec![tree] }; iter.stack_push_left(); iter diff --git a/src/data_structures/probabilistic/bloom_filter.rs b/src/data_structures/probabilistic/bloom_filter.rs index b75fe5b1c90..564d131eb9d 100644 --- a/src/data_structures/probabilistic/bloom_filter.rs +++ b/src/data_structures/probabilistic/bloom_filter.rs @@ -108,7 +108,7 @@ pub struct MultiBinaryBloomFilter { impl MultiBinaryBloomFilter { pub fn with_dimensions(filter_size: usize, hash_count: usize) -> Self { - let bytes_count = filter_size / 8 + usize::from(filter_size % 8 > 0); // we need 8 times less entries in the array, since we are using bytes. Careful that we have at least one element though + let bytes_count = filter_size / 8 + usize::from(!filter_size.is_multiple_of(8)); // we need 8 times less entries in the array, since we are using bytes. Careful that we have at least one element though Self { filter_size, bytes: vec![0; bytes_count], diff --git a/src/data_structures/treap.rs b/src/data_structures/treap.rs index e78e782a66d..980c30b0812 100644 --- a/src/data_structures/treap.rs +++ b/src/data_structures/treap.rs @@ -85,7 +85,7 @@ impl Treap { } /// Returns an iterator that visits the nodes in the tree in order. - fn node_iter(&self) -> NodeIter { + fn node_iter(&self) -> NodeIter<'_,T> { let mut node_iter = NodeIter { stack: Vec::new() }; // Initialize stack with path to leftmost child let mut child = &self.root; @@ -97,7 +97,7 @@ impl Treap { } /// Returns an iterator that visits the values in the tree in ascending order. - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_,T> { Iter { node_iter: self.node_iter(), } diff --git a/src/data_structures/veb_tree.rs b/src/data_structures/veb_tree.rs index fe5fd7fc06d..7bda299931e 100644 --- a/src/data_structures/veb_tree.rs +++ b/src/data_structures/veb_tree.rs @@ -58,7 +58,7 @@ impl VebTree { self.max } - pub fn iter(&self) -> VebTreeIter { + pub fn iter(&self) -> VebTreeIter<'_> { VebTreeIter::new(self) } diff --git a/src/general/huffman_encoding.rs b/src/general/huffman_encoding.rs index fc26d3cb5ee..3ffd3415fbc 100644 --- a/src/general/huffman_encoding.rs +++ b/src/general/huffman_encoding.rs @@ -110,8 +110,9 @@ impl HuffmanDictionary { } pub fn encode(&self, data: &[T]) -> HuffmanEncoding { let mut result = HuffmanEncoding::new(); - data.iter() - .for_each(|value| result.add_data(self.alphabet[value])); + for value in data.iter() { + result.add_data(self.alphabet[value]); + } result } } diff --git a/src/general/permutations/heap.rs b/src/general/permutations/heap.rs index b1c3b38d198..30bd4f02acb 100644 --- a/src/general/permutations/heap.rs +++ b/src/general/permutations/heap.rs @@ -23,7 +23,7 @@ fn heap_recurse(arr: &mut [T], k: usize, collector: &mut Vec u64 { panic!("Input has to be positive.") } - (1..=number / 2).filter(|&d| number % d == 0).sum() + (1..=number / 2).filter(|&d| number.is_multiple_of(d)).sum() } #[cfg(test)] diff --git a/src/math/collatz_sequence.rs b/src/math/collatz_sequence.rs index 32400cc5baa..b307d66469a 100644 --- a/src/math/collatz_sequence.rs +++ b/src/math/collatz_sequence.rs @@ -6,7 +6,7 @@ pub fn sequence(mut n: usize) -> Option> { let mut list: Vec = vec![]; while n != 1 { list.push(n); - if n % 2 == 0 { + if n.is_multiple_of(2) { n /= 2; } else { n = 3 * n + 1; diff --git a/src/math/factors.rs b/src/math/factors.rs index 5131642dffa..5d38724fb08 100644 --- a/src/math/factors.rs +++ b/src/math/factors.rs @@ -7,7 +7,7 @@ pub fn factors(number: u64) -> Vec { let mut factors: Vec = Vec::new(); for i in 1..=((number as f64).sqrt() as u64) { - if number % i == 0 { + if number.is_multiple_of(i) { factors.push(i); if i != number / i { factors.push(number / i); diff --git a/src/math/interquartile_range.rs b/src/math/interquartile_range.rs index fed92b77709..a1cdb0b7ff2 100644 --- a/src/math/interquartile_range.rs +++ b/src/math/interquartile_range.rs @@ -12,7 +12,7 @@ pub fn find_median(numbers: &[f64]) -> f64 { let length = numbers.len(); let mid = length / 2; - if length % 2 == 0 { + if length.is_multiple_of(2) { f64::midpoint(numbers[mid - 1], numbers[mid]) } else { numbers[mid] @@ -29,7 +29,7 @@ pub fn interquartile_range(numbers: &[f64]) -> f64 { let length = numbers.len(); let mid = length / 2; - let (q1, q3) = if length % 2 == 0 { + let (q1, q3) = if length.is_multiple_of(2) { let first_half = &numbers[0..mid]; let second_half = &numbers[mid..length]; (find_median(first_half), find_median(second_half)) diff --git a/src/math/perfect_numbers.rs b/src/math/perfect_numbers.rs index 0d819d2b2f1..f9a3ff3ce04 100644 --- a/src/math/perfect_numbers.rs +++ b/src/math/perfect_numbers.rs @@ -2,7 +2,7 @@ pub fn is_perfect_number(num: usize) -> bool { let mut sum = 0; for i in 1..num - 1 { - if num % i == 0 { + if num.is_multiple_of(i) { sum += i; } } diff --git a/src/math/pollard_rho.rs b/src/math/pollard_rho.rs index 1ba7481e989..a3c6c897959 100644 --- a/src/math/pollard_rho.rs +++ b/src/math/pollard_rho.rs @@ -137,7 +137,7 @@ pub fn pollard_rho_get_one_factor(number: u64, seed: &mut u32, check_is_prime: b fn get_small_factors(mut number: u64, primes: &[usize]) -> (u64, Vec) { let mut result: Vec = Vec::new(); for p in primes { - while (number % *p as u64) == 0 { + while !(number.is_multiple_of(*p as u64)) { number /= *p as u64; result.push(*p as u64); } diff --git a/src/math/prime_check.rs b/src/math/prime_check.rs index 4902a65dbf7..2f25554d2d3 100644 --- a/src/math/prime_check.rs +++ b/src/math/prime_check.rs @@ -1,13 +1,13 @@ pub fn prime_check(num: usize) -> bool { if (num > 1) & (num < 4) { return true; - } else if (num < 2) || (num % 2 == 0) { + } else if (num < 2) || (num.is_multiple_of(2)) { return false; } let stop: usize = (num as f64).sqrt() as usize + 1; for i in (3..stop).step_by(2) { - if num % i == 0 { + if !num.is_multiple_of(i) { return false; } } diff --git a/src/math/prime_factors.rs b/src/math/prime_factors.rs index 7b89b09c9b8..fcdeba2d729 100644 --- a/src/math/prime_factors.rs +++ b/src/math/prime_factors.rs @@ -5,7 +5,7 @@ pub fn prime_factors(n: u64) -> Vec { let mut n = n; let mut factors = Vec::new(); while i * i <= n { - if n % i != 0 { + if !n.is_multiple_of(i) { if i != 2 { i += 1; } diff --git a/src/math/quadratic_residue.rs b/src/math/quadratic_residue.rs index e3f2e6b819b..a64d6fff6eb 100644 --- a/src/math/quadratic_residue.rs +++ b/src/math/quadratic_residue.rs @@ -78,7 +78,7 @@ fn is_residue(x: u64, modulus: u64) -> bool { /// /// pub fn legendre_symbol(a: u64, odd_prime: u64) -> i64 { - debug_assert!(odd_prime % 2 != 0, "prime must be odd"); + debug_assert!(!odd_prime.is_multiple_of(2), "prime must be odd"); if a == 0 { 0 } else if is_residue(a, odd_prime) { diff --git a/src/math/random.rs b/src/math/random.rs index de218035484..de4b05e11f3 100644 --- a/src/math/random.rs +++ b/src/math/random.rs @@ -102,7 +102,7 @@ impl PCG32 { pub fn get_state(&self) -> u64 { self.state } - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_> { IterMut { pcg: self } } } diff --git a/src/number_theory/euler_totient.rs b/src/number_theory/euler_totient.rs index 69c0694a335..c5448127465 100644 --- a/src/number_theory/euler_totient.rs +++ b/src/number_theory/euler_totient.rs @@ -6,10 +6,10 @@ pub fn euler_totient(n: u64) -> u64 { // Find all prime factors and apply formula while p * p <= num { // Check if p is a divisor of n - if num % p == 0 { + if num.is_multiple_of(p) { // If yes, then it is a prime factor // Apply the formula: result = result * (1 - 1/p) - while num % p == 0 { + while num.is_multiple_of(p) { num /= p; } result -= result / p; From 44e41d1cbadc5528b2848200a0ea99379f7eac98 Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Mon, 18 Aug 2025 10:09:20 +0200 Subject: [PATCH 06/10] update avl_tree.rs --- src/data_structures/avl_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data_structures/avl_tree.rs b/src/data_structures/avl_tree.rs index 20fcef1255e..6893ad69b28 100644 --- a/src/data_structures/avl_tree.rs +++ b/src/data_structures/avl_tree.rs @@ -85,7 +85,7 @@ impl AVLTree { } /// Returns an iterator that visits the nodes in the tree in order. - fn node_iter(&self) -> NodeIter<'_,T> { + fn node_iter(&self) -> NodeIter<'_, T> { let cap = self.root.as_ref().map_or(0, |n| n.height); let mut node_iter = NodeIter { stack: Vec::with_capacity(cap), From 59922a380266c451b166fe2431f4abf59486999d Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Mon, 18 Aug 2025 10:43:50 +0200 Subject: [PATCH 07/10] add directory --- DIRECTORY.md | 1 + output.txt | Bin 0 -> 255852 bytes src/ciphers/diffie_hellman.rs | 5 +---- src/ciphers/transposition.rs | 5 +++-- src/data_structures/avl_tree.rs | 2 +- src/data_structures/binary_search_tree.rs | 2 +- .../probabilistic/bloom_filter.rs | 1 + src/data_structures/treap.rs | 4 ++-- src/general/genetic.rs | 2 ++ src/math/pollard_rho.rs | 2 +- src/math/prime_check.rs | 2 +- 11 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 output.txt diff --git a/DIRECTORY.md b/DIRECTORY.md index 564a7813807..8f3e4d15f95 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -105,6 +105,7 @@ * [Word Break](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/word_break.rs) * Financial * [Present Value](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/present_value.rs) + * [Present Value](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/black_scholes.rs) * General * [Convex Hull](https://github.com/TheAlgorithms/Rust/blob/master/src/general/convex_hull.rs) * [Fisher Yates Shuffle](https://github.com/TheAlgorithms/Rust/blob/master/src/general/fisher_yates_shuffle.rs) diff --git a/output.txt b/output.txt new file mode 100644 index 0000000000000000000000000000000000000000..2df1454496b4183f28f2194bfa7feaeac2ff154a GIT binary patch literal 255852 zcmds=+pgZYa_7J64eWRD)g%Fujc(iB>AeTJ2#^E_kT;kNR(xFTw%vBT?6%zxKQsL4 z@7hI5`XrJfC9Q#BdmTQhip4rtvG{-g&mS*;xO}*Ly8Igcyb6DBFApx?Uw*p$c=>bq z>f`0b?CcQ*l_7vZTF0~|hcb9o&8J`A}1Y54OXyzlj4 z*u4lVd>?TCdJ=r5)cPS%>-%c#ZU?%*zx*8D!hXI9e?NTVlcil_*WZU-|1j*k_AP$b z=kWWF!&@IFZ@#O>v^Up5$495d4!L@9`S0-W>(k=+I$#G6yco0r5`8o9z>`5M{CX0+ z(McZym*0ec!3>GIxj4W68h-cdptxJsW5ZMln6$)tk$2 z0oym>bNqHpp;{{%Lm9tw$u2D8dmiop&%1$I_(k*d-J5pqYs9;}Hx@`%uI%vHyWm^C z41bWFSAmkh22PFnaDT~v6XfB;H@zP7@p-r}#_+yK3>pSWfwnP!#w)Jrn=bQFxxorpO~BqWtfmYv4b2_-*)# z==9a)%kFzgY>VfJ4}|^2qr?yS625cZt>rLy^=*LgCcG10^wl@seHNn7X9LWs1x_)7 zVsQEK7_e(E0?uRvh%MiRsBurM%sZ4uAeNu=TaU*G&RMbq$6&aG(M{k?yie!KGveqr z|7bkhdUrKC!e!yrkkul-eLv`~qqLS|L=IBfB=U!!!grQOd^&tjGR-LVOn4FDbWN!-qU@2bZ_>tzS6lj$35Oa zQzGQIgJ0*B;$<5o&s5JKu~z?k9^OI}N4}AFZOP@tFlzClQjUFob|`huMiq~CYOQLE zz41KjheLOVY|fX!sr4~T3u=(Py&Yuc)sV9~a%bXvRV^OWZ}G74o|O+IgF5vCoEQC5 zyfgvG9oJHbfYfjkdm@Bk(}ilk=prMDZ;diqC_; zXZ2X}p;!ZD$Ug;}Qr}mQ%Rh58Q|{|?*g1Nk>a+A)a4=ekN?x;`(lMsiF}TL^&hC*D zep9WJw@~da@YI{Z6S01^M?p8&`!;QH`61x)!%67!W5DIdli>1Gz~!eyaB&%@mO&;5 zd9#cXRiK;D14&#*#iicQsOKZgm!5~SuVeIh7g;m->O}PnGCOE_=2{B}4?GR;q5DZ3 z@pi`N@Z27{mwX#NCgio{d#NtQ8{7`_=C{>6-U~0I<-XX(KAUL0*M3bQ$9tq&v{&l) zrHaQh$MesNA%?*7#&>)_@HUw_D$jJHNzTZAecX+w#}Ur)RGPzRPbt3!KjrB(F0A(u zOLb5kc2;>F+q=CqMC!}p$)Yo?^NlWTx>PtJLG8zE#5u4-e_?fw$C9W@=Sa+!9%Tvd z!tPzerNsKZ8hk;tA=V$wr>aC6kA0o-7T};KL2FtRZuaHDE^Ge4VHC8Jw#-l>KUDz{niyjS*vQa zS<70Lrwx>~+(12)&tXT14u~P24Lzzvf$H`D5aj+CnTxS<`S<*iX(#bgy@tAe!mzx9 zV*ZJnkV{$5r?lC>WlA9r^^~IfL%C}-KfX4RfOUkB@g~Y7C&AAwC&5$8H8y|BJ!MYz z@tjxO%s$(1>a-MnEN?;w>-XWz(syBBrg?g=q~SUJmZ7PRq6+r?L!h(vAf@**b*}R~ zzVq`yqu1g8DQ!HT5Pwdw7rRJSN~c)%g+Lp=b*eumzq-Z14v^#sSC!B4ZdoC6?B^ybnBWxGvRK?&~^Ac!ya4Ocf$dmW3f}9cKv1 ze0?0U0aG8wqg~Zom5bngPlCN!t0>OF#*bfu^CY~LoX7WJ^3-yl$=us(R;K#thmaAO zt}f=DyCLIG$J7$v%wd(k=0C5@+nT;zeS*ZSemdEAe2LQ2C-GzD&nkCSy3QKvQ^T{< zz-92J_{Y>KTRAnuEi2F6;fEpLw%o}TuR)TcY}||R+~XO^@jb(L@^zGQ=`xh~y_}CW zK4}X@y}0Q)9sEL@5Jgt*ZTRkKkX31>ek-oQrJgR*dP_V@_G7uHZH{yB>|Tf6dKhRH zzn!n24!LXlEtIqgd$HEz_scW)+QBWA|B}_c4Ac|%dr&79 z$Ucu(DIa3_MA&xN)>DP1oWp^B1Ia>5P9=NEF0M}@DqSIGKXn$)BurNCW1z8O&6evh z>ZLh-`ZC(_p~E23!^0(_(tKs&-El`q56GW`zd*eXUxWU#@@P}tEBZIKRdFmKxn8gA zPk93CM!j9}AyoNw#vg*;ls6yO>q>VF2zXC|M>hhypxW_tb$s$k@T`cj@UwEx15ejT z_n+n{;-`^0!G_bBIJZ{K9ODV{2jCgc51~WkY4~}K7u^pJc7@4itPdJ7g@O5P{G?2x zH0KZdx>N~MTttS23Ety5sbkr4o*7fqq19;YHxc@nup(*?jNXXpTW1P^+R*k zlAeHy_p5BT@CTWm@Fd}nHZeoaI_QWYDk=3pV~;=PW?_zRTeHKtZ^h3M-=YhVoVNIT zhP8AzJr0^uMbRaGI64LomfR>E>!se#GM)IXykbQe?RUcRhg;vDYDMvm);E z_2*=YNQ}KDuYnA28--VVW8dNQX*Y!m2!jg)=fGDyu{^geJh$8XGmNrdV3sN>*T?jk-R zQtJKItl#rf^*P2bgB6-m+q4fmD_@{jN8>sM<9w@iY?bN1bvQmN0Lf8TSZf&d9f~=g zkNJnop7b=jSf`D5K<810?kJmv$(o4`;WBbkI!~o3D(a-dqmOw|pS0Be)rhb!AcbV6>ulQR1rvG|5<-{bvx)ti4<#8XLXL(gG81t`d z(D~={Gu_uHKmXpXc=_{degiTs+h7td?|?|1Q}lRkHZ4i3r7BFM6Vu9`vHCi?ckTJL zeQb%BvJPj$$?dV_ME1mv$n{Iu#kC!E{*SS1w{zuqxNa}0rcjv5Fo^f|AdZ?q>{EG5)h+Cny+P@7>^KUtlO7j@4 z)iSQx$oaRG?%dc$&cC$>)l!L{S}5nPd7Nye>3iaA*?qz~-G}>xx%Y!C&(euKjx?qz z+23}2;&}Iwz?3h0;QeUD6Y|r=iUV`9Tt5ue)%6Mx|FxIA@z8q zl1PV@t*A~a{dv<^xfF2@&BtQPp08y#ukCrQ} zh=e&u^DIc{*GbPytPfII*V$dVWa=cP7A}>7_1yJ*MxhoaYvoqqeOJnqJKbcwKinsQ z7xsnfrwW$fJ`bJ>-iqZcKMl5?8;h_*SS|WS<;#eAQ$LQbVa{Qzzj&FKTELSZ4c6$@ z<@(M#JY~=_efg|>3s~|ndUFWWwc2cN zSlsYo=i9cyD&vghPQdlODucFs-&<>FaQ$*@+Zy7Jo8>HyF?3FonjsQ>UEa+i)9Xvm zDxBme1nK!l8|=wd%l=SnsxSLI>(E5CuR&jOngpxBJ)v|<(*wDD=NXneNLhqV>ek6u5 zb+_T6^GiB;Lm&B^#g@Mk%P`#r(`U9~f@WyVNL+oGJ3g z#4z-6%uQp7n^uNnUsg83PTRZQCDPcom!){7nIXqy8y44gk51xzF5i!<%J6Ed4N7+` z<|DUs?d(e_KIkC)6!n{a2v$a34*m)qOs@h@dsoT&OqF%rP>Nwp8~IRhmSKiv+!|d{ zwR#fzaF;YfENS-nZBk}$S%T^l6zT6_GMId&V<5x3{UMuYstz3Xr9Vtjbzg{3vmL}T z`-a~{2A7(~HtLcu`#pG(icD_N{xEcS~^bRo=**U19$VB;lIDR|d?SUmR z%>K0WD8YCbed+tK)g#$TIk=1&dy0V1v%4|fz-r9DN6^i2vb#%4_Hue&C8tZk&cZOk zZS6Gnx^1uF7GE_}y#xdAqh#&JVur4Rhn6cNIXLnbd@Rnnyb15b_nP_#&xW{{%#E^2 zWKGEBXvUyDx4$kb)9d2#tytz!j3^roB#J4EM<$L;lTPmXZ#A)0-r3d~5POlcqviOi zYP2k5j2Ya*zmYkIT|Nn54UDoWxWqGOe$JRPTcaxh`Tm&LYaQ z0<$mQzDC2Ig+|8B`_m}hE7J^q&p5drCXJ@_^Bd&(Jv9(DHSlf4Q_29y_Z&9TG2ekiD37&h2=P!20o4}41<<7U|VitJ$5}N z=8ygCH5^-b*-R*S7rY26C-eMWiCemOiz zrQBqgXPIHgE$>7@{#hyy%m_#7m1AP+?>2sIy)wz2CfP#|r_EOF^xuIZFNVL#W=E6sEU5g)_$+bZ-o7s2O5`xHy{RLFYz=dhjDDZXtlYw;pyLI3C0 zIHeXou{*p?6n_i_&>?moT)cHb`lnZ;6JcDdYzd$EMG2)v@W@axsAtXTYQ;XS~jB z*J#4+NYrrDE%IuZa5B~TN9|ZSc6;t(DR#Yf7LQw1IPOh=0_4ixC!sv$Z$Vcc(QKg&o@XQ=sQLX^1cWBJl4v z>}1#HdqmoHsx3i+Z_&rw&r>WxQ8u$5y|5c?&QL6^qTT6~ozLnkX?S38XNo#LiBi#p*zqOk^H1D_Tfe@n+^V|nW7ukz;K#flPlm{u zXWAYEWh=aY51zJFSl^0wLd)LREcUHdv31S@?Tw94Zyo=upAtR8&xs9*+KKl)pRvSw zN7Eaut@gK-+P14pylFj5WD>ZSOmb$Nxd#T+tFQ`od!lxX?Ax||f)k9_Ev{UmgeL6% zIy@zB68d3*_r=3ykBq!-b!?IQDy7HV=eJRUKG18KhInUU9k~Q?nme&PEA~Z|x%|5r z-5zqkVeUPQ>-r*p)tvDAF5s;jDVJ8>5-Pb?^)KdStXjfm#e1(;eIq(=uosOj{@dPB zlFv=tS@3S7?#hSeT(mFuqM?bCtg@XOWqb{Ko;yv|cP76?XGh)+Kg9x|lkgg_iTDrH zbNKnPuWL`JyTbDGoMENXuC6U0Tjgn)2m9e^UCZP1LTfg^A4YMM;8Z+{KAsCww;j>z zQMkaFcp}e-{sDPv)HR8XI2p!NO)63D2U`ciQ5dT#!<{GSKD%dxU40wAL!yvatDGK% zrRE&lY3DiIj=~I&l@pE7=~?*mD(o#BsOqDpd>n(skm{vO+5)NDau!#4fC-DQCIRD{>SkGlr+wCKbQVTv(QIL6LgZa zOf@5sNUB4R#gfbs#Q5+a^T8s~J3>{wv{67p5bF2j?-oZn&yr}H7 z=Y(V2kD_H9*?}MR-Sf#v9ND{eiS0`2BOOJ}SWm~h>k-3QEDbpa-76DI)A@GZW~!cJ ze;u3al+s>fvr{X66i?>i+y`4KTGA-Q(O&t8^U%}DDp+hf`1Leak)Gbq!~Zs`td+g4 z!*CqeIHp)m^u142YqRflcupyKHvHnLUQRQ4LZYNrejF7QIrt9i`xw`waXSYt##zRx z(|Glqc%ErL$27F>opQ(V8hLf)M^nwL&dyll9jTiYImH;#mq0Y*G&~!AOx~q7uNf(1 zP|kv_`wpi6j^sbG?di_yC+&B3nipR3SS-_S{xqkM$lWNKn!c+I4X5v2!jTE1OaLO1 zqT_){I?9YpvtpWKYM(*om6sqhp_Ag$OGm6@y6Pjan4{)7FtdJTWwVL$e4p9Lv>zX7 zqSk>9XTQ;u%>F%srs7Y!%g8&~9eb7!)9GpJbJtJl(WWjpr93ehr=^~TwXAhV=jPF- zP?qG4IOR6blnfA9S`B>qmLq7b?k{kYtr=Irj=@P?znVEluJ#A9&3~IbMdeUkGmprvpSZ+ zF+Wl#^pxl6;lFL$u^&&u!Pqgpv@J7Za(9(F4_QlkGRHj-*EJ5_BYq`*2LIBDfW=c( z*hU}KVrG4+_yAyrZ=wD&)!OjTudVo4%;O%dl3w-Rd!6Dn$0^6sjUCmQGy2TgcX$$C zVxF&$#TFk?osRS^3d3VDvdZstpNSNh0H7=d{v)(L7F+xwtFF@XX*yr~el%{1|B0zw z>)^lHnMi3LqonMi=Aqm-%;6eztD=haGbO#X)VNwa=8gM=>G^0or}fD(zyVm~OUM!>Rk-WKut|`Y5wczz}vJsw&PhXXt ztL?$-)K$5&D&}gN3;H%-zQ0ybb%q=4n5aNCQ?pio3$@?+H>wx|D$*b^vWXkgpc*oG6GclYvx}G1KT4g<@lRm__nhrJ1!L^}Z8=R-u zjc0W)-Eo)8d2Miw^DmZjJrgaNV5}^wcNp}@UACd7y#))FKMQ2v9k=c;-}y7`H`z9# zeRPF%wyFSYw*;D$yU@&o@mu;yL9bOnnftv8bw}CU zGM%7GS4G@I^yBMnbzWso!?xb3*bBtVCiBy(_Ol26>0a<1=leO~Lhg6GGy47gk)!$5 zx&K9VgS-)wFh4b_*zK`v4#PW5$=1em?ko!5BmQeGRlYv?M)TU=R@kyjZ44Ptx8Lg4 zcklkLEobNMBX7nt@pQ*HT{ZB?ee#o-#ld+-JJ}KE)R~>b&e8nsFL~q&s(?B<%MfHMf`FgN)sF@+?aDVHzoUbtm>=>ELWu?5F1*~l3tWnr;wZmV;ZePI(kQqMhSO;>OVlEBkTdlN z>qVas7L1byYj?-z_N4UK>9opi)k)1t_RK;XYPZ1OI`Z4v^sVwUrdLaUqdjhMEzx$o zk9=+2@wu85di{2==Erko>~FZnJsz*vvpg$aV~!)Q*|sXTh5KR(YC@k*W*)z{p5yJ6 zW!OTu7`wS0=G=na`f?`wl6s42_NJHjv4zgd_>S$-@m!nY8%x)iOU{hz+39NDQ7ak} zClN(6(NiaER4e3+D8BI2TlTEXaX6^w(K8pwnfk82G|Ic7eg? z-UjT>f>Y{m9EX)oIoT~ki9rn_o<}lRJ^A38IH|j~yE5C=AEGs%|c9S+m?uHFf&8te2GI9nSp|Bs^Fv?KKloJ9r$Yo&8~=fH@0 zf!uf&^V%6OGcT<-Z&}}s%}klsOY_~@OWx+kK+#qw;_gCrf=Tah68|=aZe2sIGAlU{ z-3x0Y7nq+WUfU?2)M^ zfd6QgLizajf#1i|n8=0Pmo+NZ8uOcLq5HB9P2hMPc0;#DXbSiJTSpqzUFW*{vM+WI zHN6`09j#AlPL|rNirbJse6vJ&XHRDDio{kan)jNPWvJ~9WT;&WkOL#jL?yL-7S>>5 zi^{NeOCViDwfAUB#yFADC+em?a5P@hcXxq9s5-kY_g(HW0jhp)Q+=RQKky;cJkM@l z!xCy+v~&!%mR(49Rd?a=vy>0^;WV5gyUj2+U4AQG^DyB7_X-C)k2k?KNgmp=$6NP>p zsza=oh=v@=yWy^+r-5JIgui@}`XIl38h*lkAM`Jh*?%+8XD-(D&c*bTc-_o9L#vo} zL1KgjI`L(|?@jmwoZ6?GHIF~YKRgS6#0i=t3f(w4Whc?&Xd>p1qbw%3TD~84OZ`CZ z8MW&6$)nwMJl6O#_w?3QJeGA0ysaCHZKk$yziuvv53uD}ACnx@6q2L2LruVbwxl8E zVIhaSSrc~R-py&=A@4{aTj7dg`IsbkCpW zQ+RgbZgFLOAog0N`A66QBu;n0^x4lBC&Bu0d1OsID?Rf8IkZpibu4pD%-pw7(306itvPBc`Cs z5^XZqTN&RL2M%9`6o^GiN85M#xu=TN!6BVW!SHys20#j5!2qoeMX&CAqUQ%62TDF8gtj zJY6Id4^8(@{1PRr(z4qcpmI8 zG{P5o7Nkv?d`>a&GsQNFLCVh>#JO#_XZ`e2nXH)KKGqt*lFp*e!kQGPr8--6tbYix z;N6guCFepEN8OFN0?!t60%q&clkk4enh5KmgPneHVqUAC^s9>OyAQ;WwfnFyreqTD z2d2bi@I5}t(KxTm;<}!tdPuzwDZsiA8!&Z2`5a{2I*n3opzo|AxmLS|n_59C&5T&j zlp^TZg2rF3d0^YHHymPW_JxQCh!>8&RrPT{*fw`>KZxmRMd#SQH1_($mX*pUzyl=L zLp=vO8S|!OjhUO|?X;tceL$YrhP;^jlb$WOpCUk_$E7)fSp17w%NvOL?ju(iwJpy8i1}wbCrP6l*E@`7pOh zel48qRNro8kgYetqrVORW3ggcn|c-&@6#)IQorSrcq9o>Ka@Jt!=gZ-O3e4b8l1)nUj6BG*LLQ<^Np zX2;$KZ4Y(Tp~o&xX|0?KpIo;Fx$m?d2Ka@2(>c>N_@?hR`J#Iw|NZo;z|GcYs54B@ z8&anZ!kP_?>0bxIZ-<=rrc*^=!e$RTrn^?o5&5f4A=UB+{d>p@UaVpdc;#d8A@QH) zdr{Fwcn8u;>K2jqS8q=&X`Fm{AKpehgEv+}^WM0<4n8dX483uRdv{yWCReV>>1k5p zng^W9Tn+87t#dy*Q-x5(at)Wg`H{-r8csFzVOQx}#sgM|0G<(66fXgZMuMkS&?XM7 zJ;@v;D}6KV@tA9lR*AI@kep`}dcJ0|k_! zhtJq^ujD8bpm$>_;JI&MuL& zpK#(-)r;^9r(t5tvwT(~=EZGTr4}0MLdATV>?;WmhuuX#sw+x-Z1+Y9cYekWLFLB- zrSaIyEX$sni#4U1i^$v7qId%hC4B~F+jN(BmiN%P0zX^s1inQNk~O8PTT(XVWH_F_ zc_cyoW#W0b+Ria8o%)HncRM!fj+9&<0iP8RTgfwJ=hUSaQ=`5&t1Yc$>Cm+3FD!uV zHajXla2mG3dMVyDSki*b_4Wx3`8tRlU}Arnm*J=M@EtTC0q$MPpp1893uNgtWN2^5 zteFZ4U7Pz+`cYR(BXQ~$MyJs=jP^`B`O#*Y`@zIY)ezN_@@~ivwxvZbM#Q9e;Amdr zaprvG)YeLQF&7^)6Uyd6Noh8GbufJ0m|xo9RFbX9(HFT`#k@r2ksL=E4?$h_otoI! z@E2PW+g!emb+!1z&wK0v&HdoG>hAa+g#&(IO1V8SNquJb%{-r1p1p%7>o{TD5w!;e z#xP^9Kx33!mD;s4IVX;6_gVcIs_NP9JtL#-F;V`)y|(_EU>@TB+8`f~Jv72RHb-iO zd5p$Vx)(=|;qIdyuF;^itiHPZ5_}*TuI!dw**!bl)ryPd#lLai<)iMZm z^&0g#$q%Pa^CiR?*u&2=w3^R=w_FjtSYBIT4R>KTtXE1IYdj6O>{^Bo8>akr&hz=J zq>l-&(E2PrKNS0k>G>jAB%4$MW^uN>H*Bq6c_Paw$y&K|^v1zGa50h_;Ik-cRomK&=`5*gPp>(bL zS)dfI^B((4Z=y1~WgT60bjL%bl8#N(6mYcAyiGLQ+M5ICaVm$dNaE|DSGi4v4hByC z&QB$c*IW{bl|e~&-sC%Nnc~k7ja%;KfaK?qxZzR=^VTM zJ5cZ2)Y9Jjtk4})@2O*xE1`N=QYWm(px(OH!&J{PTF}pwl=ZxCgH7Gq^4#i-^K+;D z`7GV*?RdD15W8r8CH9EA^R-Nyvai|)-ve@vWZ?SK0DopKyH(ElHLGXcWc0}XlJ77t zpnUyQ^q++1>51elmbws`1W8Sr9=i3u#?=2Q_vu~-IA{`f{Fk6bmOPO0XW2KTpl=I7X9t(mEsqdln zii5oiJER^u@;@bAG4_U**wF2aMphP#`ibM0&nZ1Hb397yh2~D;=gG^z8?x)v{mm9x zy=h60wDs8A;6$DRJ3@wcY){xV_P~B`F>VRvTJB-$fxNiT0Za}6KErb19k3tnLFDsV z8)_n#^ORI39s7;Vt)V27P~pHShq*1xU+?v|xiu~8p3i$@iDt@sC zXb}Zsx$lCsF-y?y?8H`1SIckdZ!k<8UjEs+avB>nWgA}y9LV+I(Q(QUZBBJO=YAk! zHk%1y^KDBhK>ZNTn4`kn4HfEzVzxT;M6RJSz8SS*sK0ck-q*hTBwpCutW}^(kK!HW zsjsN9AlEhPA$(pX#<(J;9meOu6d{mdNbULO$}mM z|F^-#HNu!;{dd4&rxda3i${OkDG|@9()<9TBO*=o@3?Ln+bZQ%@k`;c`DeG%Y72HT zAM+kG`#w0!s{x)Y81yWmYR>b@J7JIDh9|3f$}O^L$;u^IFRe|Mw7v>($JdJYTV1$u zEP$WllLss^*uLjFAE-Jy)-P1g}~2cNdP zkXvAnPuqL<@yA4Q-58a_2RWM2DAt$yP&~e)0!zh?angDD&fDBI?6C)E$Q+M27iVhklh!DjPdSz2h({iT5{96FUd0q@5OsBPfYw9%RUDQ@`Q z7hPlc-WR=M`1aNzHl0vW<~1M7OE+-%6 z9_f8p!;-IcAMjT+%2XfKLY0Xn>SXuWU%W;l7u86)t8Y0T+HOPJaMyHY_`%Y``>*MB zkP|4#d@Sfne5G7wo&@oH?tGW+J3!Qq|ekdV6`J|cv4oIGfcjs z?YW8`Sf|+PoVq6dI_6ugOMkqXT}h6V_)9&5>_&_1N`Ktn4Bq1zsSOuHSw%Zcy5yuI z-V`-!Dj;tI)z8QsbeF~WI(5&4uhTb`!gEsBu|?luS=>WcUm+)Y(5ggt>Ykg%cRt@Q zXU$7pNI5=YJLzq``Z0&j@A({kjVe=dNsor-ZqCZC4e z;i~HykAc%*>)j`=?+rFSCD98tFJib4Lyacpo%m~NH`ImU9iCuX61BeaHJ8HGiPq;s zEJ9Su36K4tLoG$WR1*5H*8Dr@onPsScb8la+@X_#c=tN%#!kmOD$QUghuGDnCreho z^qwgO;7M(eNRA#%eB|S>fs*X`nK06cu$Vsao?5I9#zcuZ^jpuKIY){6u@mV@Pj=G$ zg1j?VY2>lYZ&NcPzQr~L#^IzH>#Dsx1LsB+e$T5K4;q5-SP9&eX&((elPP8$Is-_v3|WeXJ9uT zrt+H)o!Jvp?3Y%ovq<#Yp&!h;EJ0+A+-!sm(O200+rf6c4qu_Axt|f4*QB#0_}gTn zW{-6O-cFj}F`yroRvhakdro)g;UVK&W1*B2SFW6&Ojix%bOv<~Xq+n59!UF^u95SD z=o8EGQ)%I>F*k~8wbK>Gk_1=iX36gY9_w+YSrk#Y9rSqaC3YazEX#BE;(ezE#@hW1 za4Mrqv{-xA^bYqvpn1x;qaCGE9h4tAx85UKLqIcdBxVy(_J_V9{G7Z zPGeIWoJzzr`%Zj`K0(r!?^cXuu^vKv1~}FOu`K6GUkMiILUg015N?Mst(LT=hEMQ&fC_Bgz^g9kDGc>5 z=)PG^y~00RzezHdj(Q)|CMFSMTSqQ=0>zAG+w(o}c~2|NIHup(>0#+q_oawoWff9? zHQz?G#pU5(q3UtDrXh3u?|84ixU{Hi zJ_}NAXTs&n^8NcEs?Rywlknoq&cI8mZon{S8TaMtT%_zJk>&|;_$!uMD_Vp%@(HN1!ana!kVUNfP9 z@NReqdQc}Hz)jQ3AB4|7i12?9KB38!FD`$){2@GR*u_%VhH9Fx|1!Y;)9{BC-45%) z(|LZmMkm8uIb6C@z?e)AYsF{pjk{w!os?8hC;UGmJZ^O-&ZNVPJe9H~7T@Q>-cQ={ zYs_R3;ljJHyY%Nx_4N1?$`Fyy&RusIZyJBgzd*W)u+?9zo~AZ-eLGfQR(&{WVR)8*ZT9hRHCOH-;ZciIoK&=k4LF@k3ZiMlJCNCa1^u4Yk(K1h1IMv zjW^BTkj*9{Kq^!z^{RL-98FLno`8dN{&va}WV-07VQ0xX%=LQu-sZxNcV=#l%}Wl1#oValA(`-Cuehcv6!)M*cU(b z>fm>#b(lG9OKB#)FmIQf8GI9GcIV_``Sb7@xop)`^D%-;nO!i|+E}sjej(~^*WO5` z08Unx1dc1qGB3Sb-iN)B{!Q#}3p&ila>%)@v;`ECKQO0Lq;5>Zhx7s;oV`H@)RUlD~y7 zN<3A~bgkdKb@NK0bY<#CJS{tzw24o@PJT>FsUmJ0&(%2l&f_V567S z=eOs|{q6@Ske?MR-*F^2&Nk)uua(0}IVt8a#Ka7V_5mMzj9dE8k?ky zCjr0oqvCi6!52?F&Bg8q-%ou>YxR^AC~c>Vp!C;3Y3|s~j}yyxm;5!o#>fYhrfY$$ zu(F_djs0j1Ykr_?rC~udo~k%YZ4b#Jbh*2@RHb0MA5z z2QiYJ^wQed zzMOV2^KEZCn2)lxbInUKbITpoVYPkZ8mPR9PH zRQZ08@>;5}BGda=UY+lq@`S8EC!xmm*Lc!kK5yj0^{n5kpmo?qYFqFxnl8VVlV(_# zRvLH8!=>u|f&W~iT5r*E{RsKunY=zQINCaM@E7Rg%7a7K7x`9joz_^{%km2A`a9iY z(`Ut(P!=0N9*~`)Zdf9vYb%*TC8q&j$g`ktp&i|((5z>9pS4XhoaGcHW5X`2Wtfpj zb@G**U&Dfwzdt|ju6=)g2BQuFJ@NT`R!5`!j?>yT^j*Qjf>UjEE9gz35+AN+j~{pD zq5SDDb@b2g(yV)b{tTeH_vg>xQ4RzPOCFum6REG9eut0yJp92|Dw(lY3#Du(VJVb2 zs*In_)gJLPIkZzxA~^_r3Hf?tLPY(3P}5U5G1mLREa^CjG0dZDxaL2@1p`s$)38n|yRYV_XizAKe<+T0Pc zD1B|o6kgx;c~2|(44qW&yTUn$rE64wB+;gF**XI{&6jxp?VR?>?YmVUpPvF4*VwLg z%X{3K_XaY@&%aeB6wOhm=_Nn0oYvTNs1LvVI^?d%J2;J}JK-m5&6{wGk-tLqK9HAT z=lku$IO5O8FrPDZlJ8l;{_eGUX#&q6<*&XqhGav^J7?Lw&%smG3^p=S??c9#j>R?; zlBm3z-PfrAb(3o9<&^hL59HDjpZn)Xo~CbnJNVhDA%dm(%3&N$}wOw07lKdXPynOpeh_KXrv4SBatY1Kn@rg}e$ zZo@t8Aj0cV57?NG@?~io|Hi!sqPjW{Jbs1BI>VKZ6VEVDCGW&$jqkB-)p53ep7&~2 zy%i^Vi?7Q7cq+TYX)I2E%UTdGm2?Db)hP4ya#@9obSC{sEEU_5JEqby)fd^Z+6mv0?H%>QWzgTBL#)|_wljQsk^`ni=X^S645(>rivrLbq*k36Lp zbC;0|=>|K8uyRbfi}xZ4n8bGmVEZk~IH$gO{} z?EQ)-rv9hpuiLzB+_9usm=$o!J3q3}O0VIpoQ8J>ZGl2=Lp?c`OBA;9q*Y;=QjLrf z^}L(l)02;3ZJJRA=1`%8o^?2A@&Z%4HG2T~c2})V>yk0Sv+a+I^C(px>y~2AH9dGw z4A_gZIt+VOw+FuNG3W2OVj_6*PA1FjzRk~}4sFvd&V!Rx^O!xa`s8`=JR?r=elF9F z99vpZ-*eYd$8p>WKHrWta|nNiWu-P&{XQ|;J%0s2#* z#8|@8y!L*0O#Psk-}b{pwOKkT;Q*?QW{L7M*PJ-=bQP&UmurStSX^L&`kRbPXKMt5PY6|vHlioLfu zZOYSb=b3MqK7SnKIWM=x?TEVXMztVYdFmJ7#o>YHN7d4bL^;0)J>b3@vIq>#0<^A| z=?-{Jykr(jTc|f-y_&=&zJU|5h`AiF6`QyZ5xt6+k)LDP3O(L|d@Z#V>dV2OQhZGJ z65bWQf61L#;GlD%)6TRdPAl10_<|^axQRYi<;+s4Nx!ShlxZ#7U};hl)FgV~KEJ%F zT3cXCU+f2I?=_ZYJZoubaQ0r`KKmyqwQIwwBYV0*B)+3pK7-9_pUS*hIb;$q7yp)A z17F)y-ib*bh8r}|LZ61bcgYOTBeBf)=8nWNzoL31micwqBeBe{-V!m|DNwjyH4OYR z_l%K&_1o)^i`*Vb&W3S^jh%k7n3A*5SSRIDu1lh@JT1wFJf_aU) zwj1bq;0``VYaMDMjPcP8|OzBaY8FZ4%;a@}&LO}mxr>f6X!8mj{f>^#5^X;lF}cO zN2lQv$K+@}VLlE~$Trz|9p0gPgLSVJd9CY_@LCRPnG;H3ZP5v(u$E;lo+;zm0!^VL zgFp{c{Fx~Qy{@vHM_7vROV_l_p)tO7Yf`P9o?tQ#^pw~f9NphSzwXj%dtk5^(Dw&IR|q&yVwina{jg#)MM7V9AWiY z>k%+}M?&-5dj!k}94 zKAbo&d)G8_Y(s}Wp6xc=-0wb$r>}93V|Gqm;P{pCcf8)5D57S6$5HVawdyq-d&KQE zG-Pi$8=>3JmB&1f1Ye`x{o%#)($XdSOqyrBmbL}^E}^P>rSDkK2A9f+{?oBJI=v93x8gP*f56Bmcz=SwbY&gj)9Yo%5=uJ)x>L@au(GF&P;y@+(?dsmDrs@ycPfbOGOT}9Y(B*6P&LCZuIcd z8^XyYPPDe*)Lxi+jRxsvO2*nPU-3?X)$Pz*+zvmBnZ@bH?`)hE*@n|EfrFWp+Eb6_ z!f3&hxv;kD%v?w@Z;qq&P{P*|NYDfg&wP1f@gf1uC^V8mtgNf>nR_#TCrwVYVtx)?N$OO z=0o?Iyqmwa0$75B(brE?Z0SNMfxNc**s7ItcnKy`8nm!IB^a#H;%xYA$w9ZEi)X|4 zkdbS<<5=v+tLwO&g;$(9$8bv;3%XW4mOj_8vY4W;rc1f!8ZJk1^EG_+a<4%!a2rV6_qYG2JcPv4rF z=Ju7=R4}(fJz}Ltth1&nyOp*z71*sXYpShVVb)YunX|4NT5iHjL(LYnjBeV?Z{Kmc zdH$Jl4Z-Ym^3AWmWkks_F^6@Urzn{W*+=iz)Qh+7XiaVSF8FeG_MFMvPF;MwXCd1* zrLOO7n)$-3r+z^d@MHMH%?`R7jk|)%_q#uCoUOhMYdi~f(2RUPoP8de8CK_^7XH!J zxe0B#tA*c>Tv4$^@>)%knb&S*kfs^AEm_H}u=l5QOv9F$;WA3BVX-a3Ym3YI_GnAA z*@iYA`PODhTjOyCj&Z7-hi4q8qqt_A?XnX}^|`JsymJkkt@Yu;r4v&j^qA(9M8GO zQyD$uUe95996djWsD4delsP#@YVz^hkA`y@{+g;ynLe3=T2ntMgPKNmAH!tqd48GW z>U}t7o-Y0OV+&=D<<+%&5#p73wXckC=69v0Hq-)cO?_xP++$XI%vx)zMB6D`Q-j+M zwWd0?9coSOZ#&eQTG4i>HPxaesLIDHFaIQ*u9?=2IE6!0K&(Lj@|W=cZ{hzpp{}=l zzihd-+=|WGME(94sm5^@`i!yZPoKOqvPbe%3k=Um$MJ5L*KSKRMGYOt81|rJ&dkDI zCk>bB*A6r4S)4#r9B~sO5AKfSe|}0OpPQ!9*{yk?W)18*SuiYz@TO-1PoJ|gWXZvt zJ2v?}G<Y-L}271onWt6=i91&;o&PHA0b>l^(iTlIomJ)ZutMIcdJU2j` zfg`Tb^L}x~nDTxyklq?;jAd%m<;J88>u%FM!Q5qk7j~83P5oQT&r5RjYE`KLz|Fc$_!@6k>xE;N)`(7(zD;jFT6#+<4MaI|VApBwcyMp}`(am~g*EBteIXLD zV7=&^Q=g6~{9;vx=Xc^Za8%w}Mf3FYeb*XG4jh9H`?{j3wysk5WZwoVPwPzd8191w zn%iy*=l*WyGWgA0buyRk+*E@&SHoX+YdEk?66$!24!&Q5-r%+&d(#xUx(v2xuXllB z%e-vRS;v;W{1klCr{6fl-q~YCc#%1@YoYt|*0diam;F*5^J(ZK)-;o)-D#&s^B~gU zjCOfetikf$-2IeO z=T*=h=t82#*Wta);+9rPXZJ^YyE0!9DfRxof(_mOdXi@5w+* z=D(r?G*t>87;D2D-vw$v34h@zMHc86ev5tL>B{z2)zPb)y`K0IHG)!$=v>gw_ zaGOtm8`h4lj5YL>=IvtdJb1O1Kkx0eR-Ozvoa6aK+k+{^wsEOV+gjp7r_uTyfnzBs zeg9fF*7*H-`_Rv?&V{c$aq8ceY0y$iu653gDVg*Bsb${owdcTfIjYYol)l~ln)dvMuj=<1m%V=}!#ve`?d(JuT-Sv?SJzKpm95t0uJ3BMYsa#6waz>M z9nN3Qje7QX?(=07#*flO;bqGmpVX(0LQFaTWG!c3d!MaVzH~Y>AQuzX<{IT_3e`$O zdkVG4v$V%*dz{)HCnUX1oh1)9o25Y1_Bm*UqvWjykN(n@k5yk;%g19sNz2D+FFDJ{ zsGXFV=Od|I?p3I@SS2uO`LG1W_Wdk@)`Fwo519%2F{rI9dmwccxqJxiB7uCE`_izM z2U!nUM>4wH;&ALf8IQKFZI-Na4_db24klN<2wudmArHts(98R0-gasJtb}&k^;A0H zO&O1AY+tL_OW(f5-^qhj%WZjY-)lcw@N?dZ+W8U0n`^yFZR#s?E4#To3flH_(7#{5 zRgz6UEgG(~irZkd=J&N#_T_$ZM%2XK3_Y6Y5~|a1(Ds~k4V}xSgfnu?i$DX$yg1c} zRL;~jKo{@NVTEg5nqJ4nKjMva+I$$g5a^GwYNYs)s^qI7PM*Rx&XxB-6kOJ)Q-%ro zo)-ZZtlpDQL8XiSm$3Su!%wJz5fLcU#so@M)E;B2wSk3hvtoCi2dwDJw%<u0eW{YiJyO?N@oq8|I4xA%(^ z^HvA_T6U%8LZ#QkdVSJ9fznRCJcvuR?j^3_Obq@4=alFWL-z5tu_|wepPJQV&JA7} zo(ohZTQt>{@=KUFi+2JQELVY@rxOz&z;!BpQ&#!PJzFPEj`bQ= zPR`rwr8ej7TeObtt+We0w(c>M_e0=y(2;A}bINh*t9m}@I$$|v>bpzIq0ZUNJ>f6O ze@{HH0n9!J1{#lZvo@ujUE`FD_d2pa$SpkB6DzbCu?1b={12AsF`_NaFR-p_Fru54 zQ)=>Z^QWAQ_0T%k7#9Q8^+QaFF*d}*OZwa1=-RLh3wqw6%-%ToG^|)&OS!2vW!A77 z^YcFNmn5nb1GxN}m6XOd{S8O7I`Jjjp9?qU2-h7wSBke|{#su+t@;bzbNf z|DmgMFhJwAi~w`t@;NLkHmxkj8h6Pla-n8uo`KaG=Ati`yeGlanR{kg+R-ZRNnCr! zlEhzohWZI-8}Pq4N%QiuHb-xa3sI`YrBe*h-~M~$;$K~U542yK)H3Gm+<05hsXmcw zrOMZYH)pFZ+q;+^Q+jb8g0ZL*N=sGkFl6Eu*A7d^}yO*Q>B@Y7s5znffe>gf!PCj!2gwjyZ9z zZZ+M>ID=A_X)2>3dciX^c!x2E#qxbO=v#OR4-&majQ*h;y<=`@yQ}$YRv!!%EIVnb zH6Mk~U65SP|02h2ad;c{lguW&|0aAzEQ^h07pU>cm;TroD)r&d0n*n1`9sJ&l0zgj z1l(n*D&umK*_6BcLm1~M$Y9(J8C0D*ZHWP0LR6k@7KP-M><8AF+UPF>eeoaEZT++< zjfn`z0a+(o+Z{|}9n(FWlVS$p%f>5-eLRQ7ZFTTw%UwgF#hpktRs~D;rYj89P(KDJ z*f(UN<%*W93Es!&02L2KG2~v5HL*=ziNS8mp-by_FBz%ihR@a-t{l2-J-OW$w88sl zvJ0ojnFPlK3?d{vGD(wqLhwYV-j4Zz;57fH5>!KPKBLMrE3HtGohRlQTt~WA1-T(^GacWL5_Ij4p^;6qQ!D)-#}Rm3+3dad_^eFK zgtxIIIyo}MKpmv?gmJ#2A03nlo8y1)6G*v5lHG1xB3P=467SEOG3ZhW& zPFHSU^(RFX)0~}U|A}K&eE@!WX1NVyB*^+vOSq~Wdh8jYz266KrL;Cz4mDoi&E@;x z7sar>7UR3omkMk6aG#I30y)6a^~Oh8mDF1$HdB>_drFLB%VMjVy}E{r`SFHHUz#A7 zw}Cs=&k%FW`kd0#j+fJ53HDm&Vo%s>-HcmdTb**uhkbWCj?k2ku+A`LK2;l{9z&+l ztZ#2QxQ^Aeh#%bdk&QaswrMr;UVaj6YEjYXaV;_ZJetfVFUaNbfL(4k0dg4RIiyUQXCbk_;*K|OMrfi8#ZFko? z4zbj`k1TsUt}>TJ3#G7Q-!;~NN70;!zq}u#bk#4vMJU+4wku6{mfjvaqsu;*cMO!S z%<_jlSLOM!o>1Ng%Savh)8Mhvq0?6qBzNRJ72meD6e(wr5wWl(uEiNVW{}?t*rQ3q? z^{l^rO6zA8y0;FF_gL(;GJ5T5Gk#M_&2#1Sb4-^=;d=BG^X}77K||9KFX#kM54u?W zU>?tUOSR4eK&JP44syv#e+lxY8TClvuc0TNEEn~BGy?t-`VD_&8XrMlKEX7u+_#kA z_Buc&&q!yaC_+V>c$ql~>J6M?#l31T17`I3WAUU*`83?%{ZOSHv31zE#@W)-vmJJ= z=UWRIEzZ8dP1XsvKlPD7^3--l0S;HTi~Q^{95KdeZ;n)U%%R4eO4nm}_ovD{ojU$8 z?M5dN+WvXS{`c1$Q>bN`(^hN!Zils6R^IubKYj7-Oc#)o-^ z2eP-`6}zvlUW=dhw_9UAL2F|>$V6*GQ~$kMr^>#&l={5=*Pp_hc9S!C2;WTpHG5+f zH}ky9>;!%Srv&LA{W-i>^ImhjP&&9Yr&iuZ>09!j>Q8l@lca8Ix&iuneeM_xQh6-F zp?+821;1Tqb8Y@Y{yxPqLH<)^>v|RNE2(SYTgc{F=k3$LS_M}3)Y$Dzw z`j*%ZuVqSc>H$~_>#Pi%#v!uYKvGBEevDOQSJ$bq(hcO2o@>gv2zn1z%_ zHl}9#m04%owW{4-c+iphYxsknAg3@#t@f*rD`+Y5xmZNAd~GW!D$2}p6mdVSk!HBbNM0Mz}_Ajn(#}2#5oA(K-S7nu#)5>shSZ# z+BErnc*1TS;ItFBEuiJdmF@!_9f>8ytCBad58UM)@tVz^bkNL}{UBbaw<6Oq$F`RX z^C0K;+@dh`NbL>V>v!|g*&ZL82RKKI_RywK%B5kmTbb;ZWb7ZBOl#^ZX`;xm_=X?s!k5FQ@RlC$Vkad64a9urZaT zbv*xo&e6GJsYy+cUvUAG3~nQhn=h;aCL&+ z^Ju+xNu3rc1$D|E+gxKMa(Q+h^7>70;DlWT4tt&AzP$VMFwq?~-F*3w(@#=gcsIm> zTjb;t13??NX(mADrd=BCzoT6NIbF~zua(v;Oh)0HgkZu-faVX`sz@X!a^MEz-ZMXb+DD8P7yKa-2~?1?&mkzq0>HFMqa zAjTdPbTRu`HpQYG79K|F9I1LJo`dVX#&{}o3Ts-CZO=b3bfYkFC{+M??I}*}F_^29 zz*VY0lUlpKeabQFUscS9 zW4VeY-OU-=jV=W;S+m~ni23}QPVAIpq2V>^?rCBTo4iK{mT42O$@E%rn#mz1M_=-9nZC?j^HTMr55)0lxwucd zKYh_A7H`kzWqYk!JOq!qRr2g~AE@JQL$gs1x0H{0qw;0Qh|ZAc+#|Ikt#K;Ru^jW6 z@}8{uyCT;idp3AqxU$EwM^ZZPtain~oS)QE#$$CmJzlZ%`X10NpZhfEY*n7HUU4>J zJmaDSE4pNKve+scSiy0>(3Jc640OS^(3ds$)E;SFY>68G>I!rdiz>Zv!rT zmEQ21eiz?iQlH7WwyHXeTF6~X3MqE-?iNi+s`Yi-(#j-9y_JeDO<$Y?L*~vS)kpvy z3TM;ZduxLu`A25k=S!YFQ6hK02fXpQuFqDtWZt4U^^e4CURFym z%H5ebUaYn0xv-dnuc}K7NgA=dR*?%eUSXO`>p{;Hg3cWf#dCfJ{(W2Ir{%73OHMi$ z#(KSF4|=w&b>yymyr)oG8Czv&`tEIP&+JTr>@D37v6t0@{!{2`THUk5sRwfGYuV5i_|TcHYOLjw*1D2fKy?j8BtaH>&oxiwwG0QZTf+rq z^YiDU6tZx{Tz01twP`%w?ff|PZMUwz#r}hX^`w_@AJs?tK|MYt%dgukcn`n9dqN-l zI^)+1CQl%JoV(zE@`8$fknClu*ZfAe+u7!AGk>8)Ug!O=+7_zbJ(GDH~ATs<-xGuM5(-6pXI0cp}avm;Xh|Of!!v@ g=O28tio8#g3v`lAze8Fc1dRR^w9Y?) -> Self { - let mut _group: u8 = 14; - if let Some(x) = group { - _group = x; - } + let _group = group.unwrap_or(14); if !PRIMES.contains_key(&_group) { panic!("group not in primes") diff --git a/src/ciphers/transposition.rs b/src/ciphers/transposition.rs index a64d593632d..fda24126922 100644 --- a/src/ciphers/transposition.rs +++ b/src/ciphers/transposition.rs @@ -42,8 +42,9 @@ pub fn transposition(decrypt_mode: bool, msg: &str, key: &str) -> String { key_ascii.sort_by_key(|&(index, _)| index); - for (_, key) in key_ascii - .into_iter() { key_order.push(key.into()); } + for (_, key) in key_ascii { + key_order.push(key.into()); + } // Determines whether to encrypt or decrypt the message, // and returns the result diff --git a/src/data_structures/avl_tree.rs b/src/data_structures/avl_tree.rs index 6893ad69b28..37d5c29131d 100644 --- a/src/data_structures/avl_tree.rs +++ b/src/data_structures/avl_tree.rs @@ -100,7 +100,7 @@ impl AVLTree { } /// Returns an iterator that visits the values in the tree in ascending order. - pub fn iter(&self) -> Iter<'_,T> { + pub fn iter(&self) -> Iter<'_, T> { Iter { node_iter: self.node_iter(), } diff --git a/src/data_structures/binary_search_tree.rs b/src/data_structures/binary_search_tree.rs index 159f88fba2f..05e8614ea1a 100644 --- a/src/data_structures/binary_search_tree.rs +++ b/src/data_structures/binary_search_tree.rs @@ -188,7 +188,7 @@ impl BinarySearchTreeIter<'_, T> where T: Ord, { - pub fn new(tree: &BinarySearchTree) -> BinarySearchTreeIter<'_,T> { + pub fn new(tree: &BinarySearchTree) -> BinarySearchTreeIter<'_, T> { let mut iter = BinarySearchTreeIter { stack: vec![tree] }; iter.stack_push_left(); iter diff --git a/src/data_structures/probabilistic/bloom_filter.rs b/src/data_structures/probabilistic/bloom_filter.rs index 564d131eb9d..7e664ade62c 100644 --- a/src/data_structures/probabilistic/bloom_filter.rs +++ b/src/data_structures/probabilistic/bloom_filter.rs @@ -22,6 +22,7 @@ pub trait BloomFilter { /// If it's `false` it's absolutely sure the item isn't present /// If it's `true` the item may be present, or maybe another one produces the same hash #[derive(Debug)] +#[allow(dead_code)] struct BasicBloomFilter { vec: [bool; CAPACITY], } diff --git a/src/data_structures/treap.rs b/src/data_structures/treap.rs index 980c30b0812..98531f03bfb 100644 --- a/src/data_structures/treap.rs +++ b/src/data_structures/treap.rs @@ -85,7 +85,7 @@ impl Treap { } /// Returns an iterator that visits the nodes in the tree in order. - fn node_iter(&self) -> NodeIter<'_,T> { + fn node_iter(&self) -> NodeIter<'_, T> { let mut node_iter = NodeIter { stack: Vec::new() }; // Initialize stack with path to leftmost child let mut child = &self.root; @@ -97,7 +97,7 @@ impl Treap { } /// Returns an iterator that visits the values in the tree in ascending order. - pub fn iter(&self) -> Iter<'_,T> { + pub fn iter(&self) -> Iter<'_, T> { Iter { node_iter: self.node_iter(), } diff --git a/src/general/genetic.rs b/src/general/genetic.rs index 43221989a23..51b5a0bfe46 100644 --- a/src/general/genetic.rs +++ b/src/general/genetic.rs @@ -36,6 +36,7 @@ pub trait SelectionStrategy { /// A roulette wheel selection strategy /// https://en.wikipedia.org/wiki/Fitness_proportionate_selection +#[allow(dead_code)] pub struct RouletteWheel { rng: Rng, } @@ -84,6 +85,7 @@ impl SelectionStrategy for RouletteWheel { } } +#[allow(dead_code)] pub struct Tournament { rng: Rng, } diff --git a/src/math/pollard_rho.rs b/src/math/pollard_rho.rs index a3c6c897959..31e271e8e15 100644 --- a/src/math/pollard_rho.rs +++ b/src/math/pollard_rho.rs @@ -137,7 +137,7 @@ pub fn pollard_rho_get_one_factor(number: u64, seed: &mut u32, check_is_prime: b fn get_small_factors(mut number: u64, primes: &[usize]) -> (u64, Vec) { let mut result: Vec = Vec::new(); for p in primes { - while !(number.is_multiple_of(*p as u64)) { + while number.is_multiple_of(*p as u64) { number /= *p as u64; result.push(*p as u64); } diff --git a/src/math/prime_check.rs b/src/math/prime_check.rs index 2f25554d2d3..f38366c35fc 100644 --- a/src/math/prime_check.rs +++ b/src/math/prime_check.rs @@ -7,7 +7,7 @@ pub fn prime_check(num: usize) -> bool { let stop: usize = (num as f64).sqrt() as usize + 1; for i in (3..stop).step_by(2) { - if !num.is_multiple_of(i) { + if num.is_multiple_of(i) { return false; } } From 8d4cc7e5faca4158ca0be1500a866c2e04f22f4b Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Mon, 18 Aug 2025 10:45:37 +0200 Subject: [PATCH 08/10] change label in directory --- DIRECTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 8f3e4d15f95..be2a903d0cb 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -105,7 +105,7 @@ * [Word Break](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/word_break.rs) * Financial * [Present Value](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/present_value.rs) - * [Present Value](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/black_scholes.rs) + * [Black Scholes](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/black_scholes.rs) * General * [Convex Hull](https://github.com/TheAlgorithms/Rust/blob/master/src/general/convex_hull.rs) * [Fisher Yates Shuffle](https://github.com/TheAlgorithms/Rust/blob/master/src/general/fisher_yates_shuffle.rs) From cfe620588fb1b2205ee3476d56b277efe5ff6188 Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Mon, 18 Aug 2025 15:47:06 +0200 Subject: [PATCH 09/10] fix errors clippy --- src/financial/black_scholes.rs | 65 +++++++++++++-------------- src/general/huffman_encoding.rs | 4 +- src/geometry/ramer_douglas_peucker.rs | 2 +- src/graph/graph_enumeration.rs | 8 +++- src/math/fast_fourier_transform.rs | 8 +++- src/math/pollard_rho.rs | 2 +- 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/financial/black_scholes.rs b/src/financial/black_scholes.rs index 8e64a3fe9a7..a9bc7f348d6 100644 --- a/src/financial/black_scholes.rs +++ b/src/financial/black_scholes.rs @@ -52,44 +52,41 @@ pub fn black_scholes( #[cfg(test)] mod tests { use super::*; - - #[test] - fn my_test() { - macro_rules! test_black_scholes { - ($($name:ident: $inputs:expr,)*) => { - $( - fn $name() { - let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; - let expected = black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap(); - assert!(expected >= 0.0); - } - )* - } + macro_rules! test_black_scholes { + ($($name:ident: $inputs:expr,)*) => { + $( + #[test] + fn $name() { + let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; + let expected = black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap(); + assert!(expected >= 0.0); + } + )* } + } - macro_rules! test_black_scholes_Err { - ($($name:ident: $inputs:expr,)*) => { - $( - #[test] - fn $name() { - let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; - assert_eq!(black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap_err(), BlackScholesError::InvalidParameters); - } - )* - } + macro_rules! test_black_scholes_Err { + ($($name:ident: $inputs:expr,)*) => { + $( + #[test] + fn $name() { + let (spot_price, strike_price, time_to_maturity, risk_free_rate, volatility) = $inputs; + assert_eq!(black_scholes(spot_price, strike_price, time_to_maturity, risk_free_rate, volatility).unwrap_err(), BlackScholesError::InvalidParameters); + } + )* } + } - test_black_scholes! { - valid_parameters: (100.0, 100.0, 1.0, 0.05, 0.2), - another_valid_case: (150.0, 100.0, 2.0, 0.03, 0.25), - } + test_black_scholes! { + valid_parameters: (100.0, 100.0, 1.0, 0.05, 0.2), + another_valid_case: (150.0, 100.0, 2.0, 0.03, 0.25), + } - test_black_scholes_Err! { - negative_spot_price: (-100.0, 100.0, 1.0, 0.05, 0.2), - zero_strike_price: (100.0, 0.0, 1.0, 0.05, 0.2), - negative_time_to_maturity: (100.0, 100.0, -1.0, 0.05, 0.2), - negative_risk_free_rate: (100.0, 100.0, 1.0, -0.05, 0.2), - negative_volatility: (100.0, 100.0, 1.0, 0.05, -0.2), - } + test_black_scholes_Err! { + negative_spot_price: (-100.0, 100.0, 1.0, 0.05, 0.2), + zero_strike_price: (100.0, 0.0, 1.0, 0.05, 0.2), + negative_time_to_maturity: (100.0, 100.0, -1.0, 0.05, 0.2), + negative_risk_free_rate: (100.0, 100.0, 1.0, -0.05, 0.2), + negative_volatility: (100.0, 100.0, 1.0, 0.05, -0.2), } } diff --git a/src/general/huffman_encoding.rs b/src/general/huffman_encoding.rs index 3ffd3415fbc..4a792af59de 100644 --- a/src/general/huffman_encoding.rs +++ b/src/general/huffman_encoding.rs @@ -174,7 +174,9 @@ mod tests { use super::*; fn get_frequency(bytes: &[u8]) -> Vec<(u8, u64)> { let mut cnts: Vec = vec![0; 256]; - bytes.iter().for_each(|&b| cnts[b as usize] += 1); + for &b in bytes.iter() { + cnts[b as usize] += 1; + } let mut result = vec![]; cnts.iter() .enumerate() diff --git a/src/geometry/ramer_douglas_peucker.rs b/src/geometry/ramer_douglas_peucker.rs index ca9d53084b7..014b3b409bf 100644 --- a/src/geometry/ramer_douglas_peucker.rs +++ b/src/geometry/ramer_douglas_peucker.rs @@ -104,7 +104,7 @@ mod tests { assert_eq!(ramer_douglas_peucker(&[], epsilon), vec![]); assert_eq!( - ramer_douglas_peucker(&[a.clone()], epsilon), + ramer_douglas_peucker(std::slice::from_ref(&a), epsilon), vec![a.clone()] ); assert_eq!( diff --git a/src/graph/graph_enumeration.rs b/src/graph/graph_enumeration.rs index 24326c84aa7..e593ea7cbc5 100644 --- a/src/graph/graph_enumeration.rs +++ b/src/graph/graph_enumeration.rs @@ -41,7 +41,9 @@ mod tests { let mut result = enumerate_graph(&graph); let expected = vec![vec![], vec![2, 3], vec![1, 3, 4], vec![1, 2], vec![2]]; - result.iter_mut().for_each(|v| v.sort_unstable()); + for v in result.iter_mut() { + v.sort_unstable(); + } assert_eq!(result, expected); } @@ -55,7 +57,9 @@ mod tests { let mut result = enumerate_graph(&graph); let expected = vec![vec![], vec![2, 3], vec![1, 3, 4], vec![1, 2], vec![2]]; - result.iter_mut().for_each(|v| v.sort_unstable()); + for v in result.iter_mut() { + v.sort_unstable(); + } assert_eq!(result, expected); } } diff --git a/src/math/fast_fourier_transform.rs b/src/math/fast_fourier_transform.rs index 6ed81e7db6a..d5579db64ac 100644 --- a/src/math/fast_fourier_transform.rs +++ b/src/math/fast_fourier_transform.rs @@ -192,7 +192,9 @@ mod tests { polynomial.append(&mut vec![0.0; 4]); let permutation = fast_fourier_transform_input_permutation(polynomial.len()); let mut fft = fast_fourier_transform(&polynomial, &permutation); - fft.iter_mut().for_each(|num| *num *= *num); + for num in fft.iter_mut() { + *num *= *num; + } let ifft = inverse_fast_fourier_transform(&fft, &permutation); let expected = [1.0, 2.0, 1.0, 4.0, 4.0, 0.0, 4.0, 0.0, 0.0]; for (x, y) in ifft.iter().zip(expected.iter()) { @@ -210,7 +212,9 @@ mod tests { polynomial.append(&mut vec![0.0f64; n]); let permutation = fast_fourier_transform_input_permutation(polynomial.len()); let mut fft = fast_fourier_transform(&polynomial, &permutation); - fft.iter_mut().for_each(|num| *num *= *num); + for num in fft.iter_mut() { + *num *= *num; + } let ifft = inverse_fast_fourier_transform(&fft, &permutation); let expected = (0..((n << 1) - 1)).map(|i| std::cmp::min(i + 1, (n << 1) - 1 - i) as f64); for (&x, y) in ifft.iter().zip(expected) { diff --git a/src/math/pollard_rho.rs b/src/math/pollard_rho.rs index 31e271e8e15..75a1cbc009f 100644 --- a/src/math/pollard_rho.rs +++ b/src/math/pollard_rho.rs @@ -201,7 +201,7 @@ mod test { use super::*; fn check_is_proper_factor(number: u64, factor: u64) -> bool { - factor > 1 && factor < number && ((number % factor) == 0) + factor > 1 && factor < number && number.is_multiple_of(factor) } fn check_factorization(number: u64, factors: &[u64]) -> bool { From 9692311f4428cba17ec4a2aabfd0e2c023d316ae Mon Sep 17 00:00:00 2001 From: TRIUYEN_TANG Date: Mon, 8 Sep 2025 10:37:44 +0200 Subject: [PATCH 10/10] duplicated line --- src/data_structures/probabilistic/bloom_filter.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/data_structures/probabilistic/bloom_filter.rs b/src/data_structures/probabilistic/bloom_filter.rs index 26ec918a896..f460031f1d9 100644 --- a/src/data_structures/probabilistic/bloom_filter.rs +++ b/src/data_structures/probabilistic/bloom_filter.rs @@ -23,7 +23,6 @@ pub trait BloomFilter { /// If it's `true` the item may be present, or maybe another one produces the same hash #[allow(dead_code)] #[derive(Debug)] -#[allow(dead_code)] struct BasicBloomFilter { vec: [bool; CAPACITY], }