Skip to content

Commit

Permalink
Add problem 2094: Finding 3-Digit Even Numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Jul 9, 2024
1 parent 0ac0af2 commit f7e3c78
Show file tree
Hide file tree
Showing 4 changed files with 157 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 @@ -1523,6 +1523,7 @@ pub mod problem_2087_minimum_cost_homecoming_of_a_robot_in_a_grid;
pub mod problem_2089_find_target_indices_after_sorting_array;
pub mod problem_2090_k_radius_subarray_averages;
pub mod problem_2091_removing_minimum_and_maximum_from_array;
pub mod problem_2094_finding_3_digit_even_numbers;
pub mod problem_2095_delete_the_middle_node_of_a_linked_list;
pub mod problem_2099_find_subsequence_of_length_k_with_the_largest_sum;
pub mod problem_2103_rings_and_rods;
Expand Down
62 changes: 62 additions & 0 deletions src/problem_2094_finding_3_digit_even_numbers/brute_force.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
pub struct Solution;

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

use std::cell::Cell;

impl Solution {
pub fn find_even_numbers(digits: Vec<i32>) -> Vec<i32> {
#[allow(clippy::declare_interior_mutable_const)] // TODO: Use inline
const ZERO_CELL: Cell<u8> = Cell::new(0);

let mut counts = [ZERO_CELL; 10];

for digit in digits {
*counts[digit as u32 as usize].get_mut() += 1;
}

let mut result = Vec::new();

for candidate in (100_u32..1000).step_by(2) {
let first_count = &counts[(candidate / 100) as usize];

if first_count.get() != 0 {
first_count.set(first_count.get() - 1);

let second_count = &counts[((candidate / 10) % 10) as usize];

if second_count.get() != 0 {
second_count.set(second_count.get() - 1);

let third_count = &counts[(candidate % 10) as usize];

if third_count.get() != 0 {
result.push(candidate as _);
}

second_count.set(second_count.get() + 1);
}

first_count.set(first_count.get() + 1);
}
}

result
}
}

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

impl super::Solution for Solution {
fn find_even_numbers(digits: Vec<i32>) -> Vec<i32> {
Self::find_even_numbers(digits)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
68 changes: 68 additions & 0 deletions src/problem_2094_finding_3_digit_even_numbers/brute_force_2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
pub struct Solution;

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

use std::cell::Cell;

impl Solution {
pub fn find_even_numbers(digits: Vec<i32>) -> Vec<i32> {
#[allow(clippy::declare_interior_mutable_const)] // TODO: Use inline
const ZERO_CELL: Cell<u8> = Cell::new(0);

let mut counts = [ZERO_CELL; 10];

for digit in digits {
*counts[digit as u32 as usize].get_mut() += 1;
}

let mut result = Vec::new();

for first in 1..10 {
let first_count = &counts[first];

if first_count.get() != 0 {
let value = first as i32 * 100;

first_count.set(first_count.get() - 1);

for second in 0..10 {
let second_count = &counts[second];

if second_count.get() != 0 {
let value = value + second as i32 * 10;

second_count.set(second_count.get() - 1);

for third in (0..10).step_by(2) {
if counts[third].get() != 0 {
result.push(value + third as i32);
}
}

second_count.set(second_count.get() + 1);
}
}

first_count.set(first_count.get() + 1);
}
}

result
}
}

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

impl super::Solution for Solution {
fn find_even_numbers(digits: Vec<i32>) -> Vec<i32> {
Self::find_even_numbers(digits)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
26 changes: 26 additions & 0 deletions src/problem_2094_finding_3_digit_even_numbers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
pub mod brute_force;
pub mod brute_force_2;

pub trait Solution {
fn find_even_numbers(digits: Vec<i32>) -> Vec<i32>;
}

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

pub fn run<S: Solution>() {
let test_cases = [
(
&[2, 1, 3, 0] as &[_],
&[102, 120, 130, 132, 210, 230, 302, 310, 312, 320] as &[_],
),
(&[2, 2, 8, 8, 2], &[222, 228, 282, 288, 822, 828, 882]),
(&[3, 7, 5], &[]),
];

for (digits, expected) in test_cases {
assert_eq!(S::find_even_numbers(digits.to_vec()), expected);
}
}
}

0 comments on commit f7e3c78

Please sign in to comment.