From 9019283341ab77e9a50d2a6f2d04680224efab4a Mon Sep 17 00:00:00 2001 From: omi Date: Sun, 26 Oct 2025 23:46:40 +0530 Subject: [PATCH 1/6] added npv, compound interest and payback period --- src/financial/compound_interest.rs | 24 ++++++++++++++++ src/financial/mod.rs | 6 ++++ src/financial/npv.rs | 44 ++++++++++++++++++++++++++++++ src/financial/payback.rs | 30 ++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 src/financial/compound_interest.rs create mode 100644 src/financial/npv.rs create mode 100644 src/financial/payback.rs diff --git a/src/financial/compound_interest.rs b/src/financial/compound_interest.rs new file mode 100644 index 00000000000..d348078ddcc --- /dev/null +++ b/src/financial/compound_interest.rs @@ -0,0 +1,24 @@ +// compound interest is given by A = P(1+r/n)^nt +// where: A = Final Amount, P = Principal Amount, r = rate of interest, +// n = number of times interest is compounded per year and t = time (in years) + +pub fn compound_interest(princpal: f64, rate: f64, comp_per_year: u32, years: f64) -> f64 { + let amount = princpal * (1.00 + rate / comp_per_year as f64).powf(comp_per_year as f64 * years); + return amount; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_compound_interest() { + let principal = 1000.0; + let rate = 0.05; // 5% annual interest + let times_per_year = 4; // interest compounded quarterly + let years = 2.0; // 2 years tenure + let result = compound_interest(principal, rate, times_per_year, years); + assert!((result - 1104.486).abs() < 0.001); // expected value rounded up to 3 decimal + // places + } +} diff --git a/src/financial/mod.rs b/src/financial/mod.rs index 89b36bfa5e0..b257aec4d7a 100644 --- a/src/financial/mod.rs +++ b/src/financial/mod.rs @@ -1,2 +1,8 @@ +mod compound_interest; +mod npv; +mod payback; mod present_value; +pub use compound_interest::compound_interest; +pub use npv::npv; +pub use payback; pub use present_value::present_value; diff --git a/src/financial/npv.rs b/src/financial/npv.rs new file mode 100644 index 00000000000..d194fa302ff --- /dev/null +++ b/src/financial/npv.rs @@ -0,0 +1,44 @@ +/// Calculates Net Present Value given a vector of cash flows and a discount rate. +/// cash_flows: Vector of f64 representing cash flows for each period. +/// rate: Discount rate as an f64 (e.g., 0.05 for 5%) + +pub fn npv(cash_flows: &[f64], rate: f64) -> f64 { + cash_flows + .iter() + .enumerate() + .map(|(t, &cf)| cf / (1.00 + rate).powi(t as i32)) + .sum() +} + +// tests + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_npv_basic() { + let cash_flows = vec![-1000.0, 300.0, 400.0, -50.0]; + let rate = 0.10; + let result = npv(&cash_flows, rate); + // Calculated value ≈ -434.25 + assert!((result - (-434.25)).abs() < 0.05); // Allow small margin of error + } + + #[test] + fn test_npv_zero_rate() { + let cash_flows = vec![100.0, 200.0, -50.0]; + let rate = 0.0; + let result = npv(&cash_flows, rate); + assert!((result - 250.0).abs() < 0.05); + } + + #[test] + fn test_npv_empty() { + // For empty cash flows: NPV should be 0 + let cash_flows: Vec = vec![]; + let rate = 0.05; + let result = npv(&cash_flows, rate); + assert_eq!(result, 0.0); + } +} diff --git a/src/financial/payback.rs b/src/financial/payback.rs new file mode 100644 index 00000000000..012e50c503a --- /dev/null +++ b/src/financial/payback.rs @@ -0,0 +1,30 @@ +/// Returns the payback period in years +/// If investment is not paid back, returns None. + +pub fn payback(cash_flow: &[f64]) -> Option { + let mut total = 0.00; + for (year, &cf) in cash_flow.iter().enumerate() { + total += cf; + if total >= 0.00 { + return Some(year); + } + } + None +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_payback() { + let cash_flows = vec![-1000.0, 300.0, 400.0, 500.0]; + assert_eq!(payback(&cash_flows), Some(3)); // paid back in year 3 + } + + #[test] + fn test_no_payback() { + let cash_flows = vec![-1000.0, 100.0, 100.0, 100.0]; + assert_eq!(payback(&cash_flows), None); // never paid back + } +} From c202eeeb6975504b08d1f09091daa86bc33ac61b Mon Sep 17 00:00:00 2001 From: omi Date: Sun, 26 Oct 2025 23:53:52 +0530 Subject: [PATCH 2/6] fixed mod.rs errors --- src/financial/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/financial/mod.rs b/src/financial/mod.rs index b257aec4d7a..f1e11883fea 100644 --- a/src/financial/mod.rs +++ b/src/financial/mod.rs @@ -4,5 +4,5 @@ mod payback; mod present_value; pub use compound_interest::compound_interest; pub use npv::npv; -pub use payback; +pub use payback::payback; pub use present_value::present_value; From 8f93f282553689e76b51cac146db93a06bcf5e4b Mon Sep 17 00:00:00 2001 From: omi Date: Mon, 27 Oct 2025 00:00:03 +0530 Subject: [PATCH 3/6] added algos to DIRECTORY.md --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 7a800e41379..5edeaf0decc 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -105,6 +105,9 @@ * [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) + * [Net Present Value](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/npv.rs) + * [Compound Interest](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/compound_interest.rs) + * [Payback Period](https://github.com/TheAlgorithms/Rust/blob/master/src/financial/payback.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 d29ce8c3af0fba8f65f2a174137500d3508da8fb Mon Sep 17 00:00:00 2001 From: omi Date: Mon, 27 Oct 2025 07:26:55 +0530 Subject: [PATCH 4/6] fixed typos + removed 'return' keyword --- src/financial/compound_interest.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/financial/compound_interest.rs b/src/financial/compound_interest.rs index d348078ddcc..664ea47805c 100644 --- a/src/financial/compound_interest.rs +++ b/src/financial/compound_interest.rs @@ -2,9 +2,10 @@ // where: A = Final Amount, P = Principal Amount, r = rate of interest, // n = number of times interest is compounded per year and t = time (in years) -pub fn compound_interest(princpal: f64, rate: f64, comp_per_year: u32, years: f64) -> f64 { - let amount = princpal * (1.00 + rate / comp_per_year as f64).powf(comp_per_year as f64 * years); - return amount; +pub fn compound_interest(principal: f64, rate: f64, comp_per_year: u32, years: f64) -> f64 { + let amount = + principal * (1.00 + rate / comp_per_year as f64).powf(comp_per_year as f64 * years); + amount } #[cfg(test)] From ec6f731a35979523b5bc8121e48d8bb6b021987f Mon Sep 17 00:00:00 2001 From: omi Date: Mon, 27 Oct 2025 07:33:17 +0530 Subject: [PATCH 5/6] made the function more idiomatic to resolve clippy warnings --- src/financial/compound_interest.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/financial/compound_interest.rs b/src/financial/compound_interest.rs index 664ea47805c..e8fb7fffc33 100644 --- a/src/financial/compound_interest.rs +++ b/src/financial/compound_interest.rs @@ -3,9 +3,7 @@ // n = number of times interest is compounded per year and t = time (in years) pub fn compound_interest(principal: f64, rate: f64, comp_per_year: u32, years: f64) -> f64 { - let amount = - principal * (1.00 + rate / comp_per_year as f64).powf(comp_per_year as f64 * years); - amount + principal * (1.00 + rate / comp_per_year as f64).powf(comp_per_year as f64 * years) } #[cfg(test)] From 21541d8b16337b86cda2c1fa9f8e9444edf04ae6 Mon Sep 17 00:00:00 2001 From: Andrii Siriak Date: Mon, 27 Oct 2025 09:28:23 +0200 Subject: [PATCH 6/6] Update src/financial/compound_interest.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/financial/compound_interest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/financial/compound_interest.rs b/src/financial/compound_interest.rs index e8fb7fffc33..bc3bfbc23e0 100644 --- a/src/financial/compound_interest.rs +++ b/src/financial/compound_interest.rs @@ -17,7 +17,7 @@ mod tests { let times_per_year = 4; // interest compounded quarterly let years = 2.0; // 2 years tenure let result = compound_interest(principal, rate, times_per_year, years); - assert!((result - 1104.486).abs() < 0.001); // expected value rounded up to 3 decimal + assert!((result - 1104.486).abs() < 0.001); // expected value rounded to 3 decimal // places } }