-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add problem 2172: Maximum AND Sum of Array
- Loading branch information
Showing
4 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/problem_2172_maximum_and_sum_of_array/dynamic_programming.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
pub struct Solution; | ||
|
||
// ------------------------------------------------------ snip ------------------------------------------------------ // | ||
|
||
impl Solution { | ||
fn count_numbers(mut x: u16) -> u8 { | ||
let mut result = 0; | ||
|
||
while x != 0 { | ||
let digit = x % 3; | ||
|
||
x /= 3; | ||
|
||
result += digit as u8; | ||
} | ||
|
||
result | ||
} | ||
|
||
pub fn maximum_and_sum(nums: Vec<i32>, num_slots: i32) -> i32 { | ||
let n = nums.len() as u8; | ||
let num_slots = num_slots as u32 as usize; | ||
let configurations = u16::pow(3, num_slots as _); | ||
let mut cache = vec![0_u8; usize::from(configurations)].into_boxed_slice(); | ||
let mut result = 0; | ||
|
||
for configuration in 1..configurations { | ||
let count = Self::count_numbers(configuration); | ||
|
||
if count > n { | ||
continue; | ||
} | ||
|
||
let num = nums[usize::from(count - 1)] as u8; | ||
let mut iter = configuration; | ||
let mut slot = 1; | ||
let mut probe = 1; | ||
let mut max = 0; | ||
|
||
loop { | ||
let digit = iter % 3; | ||
|
||
iter /= 3; | ||
|
||
if digit != 0 { | ||
max = max.max(cache[usize::from(configuration - probe)] + (slot & num)); | ||
} | ||
|
||
if iter == 0 { | ||
break; | ||
} | ||
|
||
slot += 1; | ||
probe *= 3; | ||
} | ||
|
||
cache[usize::from(configuration)] = max; | ||
|
||
if count == n { | ||
result = result.max(max); | ||
} | ||
} | ||
|
||
i32::from(result) | ||
} | ||
} | ||
|
||
// ------------------------------------------------------ snip ------------------------------------------------------ // | ||
|
||
impl super::Solution for Solution { | ||
fn maximum_and_sum(nums: Vec<i32>, num_slots: i32) -> i32 { | ||
Self::maximum_and_sum(nums, num_slots) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#[test] | ||
fn test_solution() { | ||
super::super::tests::run::<super::Solution>(); | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
src/problem_2172_maximum_and_sum_of_array/dynamic_programming_2.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
pub struct Solution; | ||
|
||
// ------------------------------------------------------ snip ------------------------------------------------------ // | ||
|
||
impl Solution { | ||
fn combinations(n: u8, mut k: u8, base: u16, f: &mut impl FnMut(u16)) { | ||
match k { | ||
0 => f(base), | ||
1 => { | ||
let mut probe = 1; | ||
|
||
for _ in 0..n { | ||
f(base + probe); | ||
|
||
probe *= 3; | ||
} | ||
} | ||
_ => { | ||
let mut start = k / 2; | ||
let mut probe = u16::pow(3, u32::from(start)); | ||
|
||
k -= 1; | ||
|
||
for i in start..n { | ||
Self::combinations(i, k, base + probe, f); | ||
|
||
probe *= 3; | ||
} | ||
|
||
start = k / 2; | ||
probe = u16::pow(3, u32::from(start)) * 2; | ||
k -= 1; | ||
|
||
for i in start..n { | ||
Self::combinations(i, k, base + probe, f); | ||
|
||
probe *= 3; | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn maximum_and_sum(nums: Vec<i32>, num_slots: i32) -> i32 { | ||
let n = nums.len() as u8; | ||
let num_slots = num_slots as u32 as usize; | ||
let configurations = u16::pow(3, num_slots as _); | ||
let mut cache = vec![0_u8; usize::from(configurations)].into_boxed_slice(); | ||
|
||
(1..).zip(&nums).for_each(|(count, num)| { | ||
let num = *num as u8; | ||
|
||
Self::combinations(num_slots as _, count, 0, &mut |configuration| { | ||
let mut iter = configuration; | ||
let mut slot = 1; | ||
let mut probe = 1; | ||
let mut max = 0; | ||
|
||
loop { | ||
let digit = iter % 3; | ||
|
||
iter /= 3; | ||
|
||
if digit != 0 { | ||
max = max.max(cache[usize::from(configuration - probe)] + (slot & num)); | ||
} | ||
|
||
if iter == 0 { | ||
break; | ||
} | ||
|
||
slot += 1; | ||
probe *= 3; | ||
} | ||
|
||
cache[usize::from(configuration)] = max; | ||
}); | ||
}); | ||
|
||
let mut result = 0; | ||
|
||
Self::combinations(num_slots as _, n, 0, &mut |configuration| { | ||
result = result.max(cache[usize::from(configuration)]); | ||
}); | ||
|
||
i32::from(result) | ||
} | ||
} | ||
|
||
// ------------------------------------------------------ snip ------------------------------------------------------ // | ||
|
||
impl super::Solution for Solution { | ||
fn maximum_and_sum(nums: Vec<i32>, num_slots: i32) -> i32 { | ||
Self::maximum_and_sum(nums, num_slots) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#[test] | ||
fn test_solution() { | ||
super::super::tests::run::<super::Solution>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
pub mod dynamic_programming; | ||
pub mod dynamic_programming_2; | ||
|
||
pub trait Solution { | ||
fn maximum_and_sum(nums: Vec<i32>, num_slots: i32) -> i32; | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::Solution; | ||
|
||
pub fn run<S: Solution>() { | ||
let test_cases = [ | ||
((&[1, 2, 3, 4, 5, 6] as &[_], 3), 9), | ||
((&[1, 3, 10, 4, 7, 1], 9), 24), | ||
((&[10, 5, 3, 6, 11, 8, 8], 4), 16), | ||
((&[8, 13, 3, 15, 3, 15, 2, 15, 5, 7, 6], 8), 60), | ||
]; | ||
|
||
for ((nums, num_slots), expected) in test_cases { | ||
assert_eq!(S::maximum_and_sum(nums.to_vec(), num_slots), expected); | ||
} | ||
} | ||
} |