Skip to content

Commit

Permalink
Add problem 2043: Simple Bank System
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Dec 31, 2023
1 parent 135754a commit 87cfab3
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,7 @@ pub mod problem_2028_find_missing_observations;
pub mod problem_2032_two_out_of_three;
pub mod problem_2038_remove_colored_pieces_if_both_neighbors_are_the_same_color;
pub mod problem_2042_check_if_numbers_are_ascending_in_a_sentence;
pub mod problem_2043_simple_bank_system;

#[cfg(test)]
mod test_utilities;
95 changes: 95 additions & 0 deletions src/problem_2043_simple_bank_system/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
pub mod naive;

pub trait Bank {
fn new(balance: Vec<i64>) -> Self;
fn transfer(&mut self, account1: i32, account2: i32, money: i64) -> bool;
fn deposit(&mut self, account: i32, money: i64) -> bool;
fn withdraw(&mut self, account: i32, money: i64) -> bool;
}

#[cfg(test)]
mod tests {
use super::Bank;

enum Operation {
Transfer((i32, i32, i64), bool),
Deposit((i32, i64), bool),
Withdraw((i32, i64), bool),
}

pub fn run<B: Bank>() {
let test_cases = [
(
&[10_i64, 100, 20, 50, 30] as &[_],
&[
Operation::Withdraw((3, 10), true),
Operation::Transfer((5, 1, 20), true),
Operation::Deposit((5, 20), true),
Operation::Transfer((3, 4, 15), false),
Operation::Withdraw((10, 50), false),
] as &[_],
),
(
&[22, 34, 12, 59, 0, 58, 61, 83],
&[
Operation::Withdraw((24, 16), false),
Operation::Deposit((7, 40), true),
Operation::Deposit((1, 10), true),
Operation::Deposit((6, 90), true),
Operation::Transfer((8, 7, 65), true),
Operation::Transfer((4, 55, 80), false),
Operation::Withdraw((70, 19), false),
],
),
(
&[92, 62, 12, 81, 77, 38, 71, 8, 42, 38],
&[
Operation::Transfer((3, 2, 18), false),
Operation::Transfer((29, 3, 99), false),
Operation::Deposit((8, 97), true),
],
),
(
&[
767, 653, 252, 849, 480, 187, 761, 243, 408, 385, 334, 732, 289, 886, 149, 320, 827, 111, 315, 155,
695, 110, 473, 585, 83, 936, 188, 818, 33, 984, 66, 549, 954, 761, 662, 212, 208, 215, 251, 792,
956, 261, 863, 374, 411, 639, 599, 418, 909, 208, 984, 602, 741, 302, 911, 616, 537, 422, 61, 746,
206, 396, 446, 661, 48, 156, 725, 662, 422, 624, 704, 143, 94, 702, 126, 76, 539, 83, 270, 717,
736, 393, 607, 895, 661,
],
&[
Operation::Deposit((68, 668), true),
Operation::Deposit((25, 978), true),
Operation::Transfer((8, 31, 924), false),
Operation::Transfer((2, 6, 857), false),
Operation::Transfer((20, 43, 59), true),
Operation::Deposit((71, 307), true),
Operation::Transfer((11, 46, 577), false),
Operation::Withdraw((37, 377), false),
Operation::Deposit((72, 835), true),
Operation::Withdraw((82, 574), false),
Operation::Transfer((67, 9, 939), false),
Operation::Transfer((24, 49, 251), true),
],
),
];

for (balance, operations) in test_cases {
let mut bank = B::new(balance.to_vec());

for operation in operations {
match *operation {
Operation::Transfer((account1, account2, money), expected) => {
assert_eq!(bank.transfer(account1, account2, money), expected);
}
Operation::Deposit((account, money), expected) => {
assert_eq!(bank.deposit(account, money), expected);
}
Operation::Withdraw((account, money), expected) => {
assert_eq!(bank.withdraw(account, money), expected);
}
}
}
}
}
}
84 changes: 84 additions & 0 deletions src/problem_2043_simple_bank_system/naive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::cell::Cell;

pub struct Bank {
balance: Box<[i64]>,
}

impl Bank {
fn new(balance: Vec<i64>) -> Self {
Self {
balance: balance.into_boxed_slice(),
}
}

fn transfer(&mut self, account1: i32, account2: i32, money: i64) -> bool {
let balance = Cell::from_mut(self.balance.as_mut()).as_slice_of_cells();

if let Some(from) = balance.get((account1 as u32 as usize).wrapping_sub(1)) {
if let Some(to) = balance.get((account2 as u32 as usize).wrapping_sub(1)) {
let from_money = from.get();

if money <= from_money {
from.set(from_money - money);
to.set(to.get() + money);

return true;
}
}
}

false
}

fn deposit(&mut self, account: i32, money: i64) -> bool {
self.balance
.get_mut((account as u32 as usize).wrapping_sub(1))
.map_or(false, |value| {
*value += money;

true
})
}

fn withdraw(&mut self, account: i32, money: i64) -> bool {
if let Some(value) = self.balance.get_mut((account as u32 as usize).wrapping_sub(1)) {
if money <= *value {
*value -= money;

return true;
}
}

false
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Bank for Bank {
fn new(balance: Vec<i64>) -> Self {
Self::new(balance)
}

fn transfer(&mut self, account1: i32, account2: i32, money: i64) -> bool {
self.transfer(account1, account2, money)
}

fn deposit(&mut self, account: i32, money: i64) -> bool {
self.deposit(account, money)
}

fn withdraw(&mut self, account: i32, money: i64) -> bool {
self.withdraw(account, money)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Bank>();
}
}

0 comments on commit 87cfab3

Please sign in to comment.