From 8ba0ccaa4b9c44a7a504c01d5cc7bc3d27884a3d Mon Sep 17 00:00:00 2001 From: EFanZh Date: Tue, 3 Dec 2024 22:00:21 +0800 Subject: [PATCH] Add problem 2349: Design a Number Container System --- src/lib.rs | 1 + .../hash_map_and_btree_set.rs | 64 +++++++++++++++++++ .../mod.rs | 51 +++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 src/problem_2349_design_a_number_container_system/hash_map_and_btree_set.rs create mode 100644 src/problem_2349_design_a_number_container_system/mod.rs diff --git a/src/lib.rs b/src/lib.rs index 0f0ba601..172fcc7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1741,6 +1741,7 @@ pub mod problem_2341_maximum_number_of_pairs_in_array; pub mod problem_2342_max_sum_of_a_pair_with_equal_sum_of_digits; pub mod problem_2347_best_poker_hand; pub mod problem_2348_number_of_zero_filled_subarrays; +pub mod problem_2349_design_a_number_container_system; #[cfg(test)] mod test_utilities; diff --git a/src/problem_2349_design_a_number_container_system/hash_map_and_btree_set.rs b/src/problem_2349_design_a_number_container_system/hash_map_and_btree_set.rs new file mode 100644 index 00000000..d0645d5c --- /dev/null +++ b/src/problem_2349_design_a_number_container_system/hash_map_and_btree_set.rs @@ -0,0 +1,64 @@ +// ------------------------------------------------------ snip ------------------------------------------------------ // + +use std::collections::hash_map::Entry; +use std::collections::{BTreeSet, HashMap}; + +pub struct NumberContainers { + index_to_number: HashMap, + number_to_indices: HashMap>, +} + +impl NumberContainers { + fn new() -> Self { + Self { + index_to_number: HashMap::new(), + number_to_indices: HashMap::new(), + } + } + + fn change(&mut self, index: i32, number: i32) { + if let Some(old_number) = self.index_to_number.insert(index, number) { + self.number_to_indices.get_mut(&old_number).unwrap().remove(&index); + } + + match self.number_to_indices.entry(number) { + Entry::Occupied(occupied_entry) => { + occupied_entry.into_mut().insert(index); + } + Entry::Vacant(vacant_entry) => { + vacant_entry.insert(BTreeSet::from([index])); + } + } + } + + fn find(&self, number: i32) -> i32 { + self.number_to_indices + .get(&number) + .and_then(|indices| indices.first().copied()) + .unwrap_or(-1) + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::NumberContainers for NumberContainers { + fn new() -> Self { + Self::new() + } + + fn change(&mut self, index: i32, number: i32) { + self.change(index, number); + } + + fn find(&self, number: i32) -> i32 { + self.find(number) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +} diff --git a/src/problem_2349_design_a_number_container_system/mod.rs b/src/problem_2349_design_a_number_container_system/mod.rs new file mode 100644 index 00000000..717e603d --- /dev/null +++ b/src/problem_2349_design_a_number_container_system/mod.rs @@ -0,0 +1,51 @@ +pub mod hash_map_and_btree_set; + +pub trait NumberContainers { + fn new() -> Self; + fn change(&mut self, index: i32, number: i32); + fn find(&self, number: i32) -> i32; +} + +#[cfg(test)] +mod tests { + use super::NumberContainers; + + enum Operation { + Change(i32, i32), + Find(i32, i32), + } + + pub fn run() { + let test_cases = [ + &[ + Operation::Find(10, -1), + Operation::Change(2, 10), + Operation::Change(1, 10), + Operation::Change(3, 10), + Operation::Change(5, 10), + Operation::Find(10, 1), + Operation::Change(1, 20), + Operation::Find(10, 2), + ] as &[_], + &[ + Operation::Change(1, 10), + Operation::Find(10, 1), + Operation::Change(1, 20), + Operation::Find(10, -1), + Operation::Find(20, 1), + Operation::Find(30, -1), + ], + ]; + + for operations in test_cases { + let mut number_containers = N::new(); + + for operation in operations { + match *operation { + Operation::Change(index, number) => number_containers.change(index, number), + Operation::Find(number, expected) => assert_eq!(number_containers.find(number), expected), + } + } + } + } +}