Skip to content

Commit

Permalink
Add problem 2212: Maximum Points in an Archery Competition
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Oct 21, 2024
1 parent 515f877 commit ceb0421
Show file tree
Hide file tree
Showing 3 changed files with 101 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 @@ -1651,6 +1651,7 @@ pub mod problem_2208_minimum_operations_to_halve_array_sum;
pub mod problem_2209_minimum_white_tiles_after_covering_with_carpets;
pub mod problem_2210_count_hills_and_valleys_in_an_array;
pub mod problem_2211_count_collisions_on_a_road;
pub mod problem_2212_maximum_points_in_an_archery_competition;
pub mod problem_2215_find_the_difference_of_two_arrays;
pub mod problem_2216_minimum_deletions_to_make_array_beautiful;
pub mod problem_2218_maximum_value_of_k_coins_from_piles;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
pub struct Solution;

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

impl Solution {
fn helper(num_arrows: u32, alice_arrows: &mut [i32; 12]) {
const CONFIGURATIONS: usize = 1 << 11;

let mut arrow_sums = [0_u32; CONFIGURATIONS];
let mut scores = [0_u8; CONFIGURATIONS];
let mut max_score = 0;
let mut max_score_configuration = 0;
let mut max_score_arrows = 0;

alice_arrows.iter_mut().for_each(|x| *x += 1);

for configuration in 1..CONFIGURATIONS {
let i = configuration.trailing_zeros() as usize;
let prev = configuration & (configuration - 1);
let arrow_sum = arrow_sums[prev] + alice_arrows[i + 1] as u32;

arrow_sums[configuration] = arrow_sum;

let score = scores[prev] + i as u8 + 1;

scores[configuration] = score;

if arrow_sum <= num_arrows && score > max_score {
max_score = score;
max_score_configuration = configuration;
max_score_arrows = arrow_sum;
}
}

alice_arrows[0] = (num_arrows - max_score_arrows) as _;

alice_arrows[1..].iter_mut().enumerate().for_each(|(i, count)| {
if max_score_configuration & (1 << i) == 0 {
*count = 0;
}
});
}

pub fn maximum_bob_points(num_arrows: i32, alice_arrows: Vec<i32>) -> Vec<i32> {
let mut alice_arrows = alice_arrows;

Self::helper(num_arrows as _, alice_arrows.as_mut_slice().try_into().ok().unwrap());

alice_arrows
}
}

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

impl super::Solution for Solution {
fn maximum_bob_points(num_arrows: i32, alice_arrows: Vec<i32>) -> Vec<i32> {
Self::maximum_bob_points(num_arrows, alice_arrows)
}
}

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

pub trait Solution {
fn maximum_bob_points(num_arrows: i32, alice_arrows: Vec<i32>) -> Vec<i32>;
}

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

pub fn run<S: Solution>() {
let test_cases = [
((9, [1, 1, 0, 1, 0, 0, 2, 1, 0, 1, 2, 0]), 47),
((3, [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2]), 27),
];

for ((num_arrows, alice_arrows), expected) in test_cases {
let result = S::maximum_bob_points(num_arrows, alice_arrows.to_vec());
let result: &[_; 12] = result.as_slice().try_into().unwrap();

assert_eq!(result.iter().sum::<i32>(), num_arrows);

assert_eq!(
(0..)
.zip(result.iter().zip(&alice_arrows))
.fold(0, |score, (i, (bob_count, alice_count))| {
score + (if bob_count > alice_count { i } else { 0 })
}),
expected,
);
}
}
}

0 comments on commit ceb0421

Please sign in to comment.