Skip to content

Commit

Permalink
Add problem 2349: Design a Number Container System
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Dec 3, 2024
1 parent bace9d4 commit 8ba0cca
Show file tree
Hide file tree
Showing 3 changed files with 116 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 @@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::collections::hash_map::Entry;
use std::collections::{BTreeSet, HashMap};

pub struct NumberContainers {
index_to_number: HashMap<i32, i32>,
number_to_indices: HashMap<i32, BTreeSet<i32>>,
}

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::<super::NumberContainers>();
}
}
51 changes: 51 additions & 0 deletions src/problem_2349_design_a_number_container_system/mod.rs
Original file line number Diff line number Diff line change
@@ -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<N: NumberContainers>() {
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),
}
}
}
}
}

0 comments on commit 8ba0cca

Please sign in to comment.