Skip to content

Commit

Permalink
Add problem 1648: Sell Diminishing-Valued Colored Balls
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Oct 22, 2023
1 parent 1d5eb65 commit ae3d4b6
Show file tree
Hide file tree
Showing 3 changed files with 136 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 @@ -1354,6 +1354,7 @@ pub mod problem_1642_furthest_building_you_can_reach;
pub mod problem_1643_kth_smallest_instructions;
pub mod problem_1646_get_maximum_in_generated_array;
pub mod problem_1647_minimum_deletions_to_make_character_frequencies_unique;
pub mod problem_1648_sell_diminishing_valued_colored_balls;
pub mod problem_1652_defuse_the_bomb;
pub mod problem_1653_minimum_deletions_to_make_string_balanced;
pub mod problem_1656_design_an_ordered_stream;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
pub struct Solution;

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

use std::cmp::Ordering;
use std::collections::{BinaryHeap, HashMap};

struct Item {
count: u32,
count_count: u32,
}

impl PartialEq for Item {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}

impl Eq for Item {}

impl PartialOrd for Item {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Item {
fn cmp(&self, other: &Self) -> Ordering {
self.count.cmp(&other.count)
}
}

impl Solution {
fn sum(min_value: u32, max_value: u32) -> u64 {
u64::from(min_value + max_value) * u64::from(max_value + 1 - min_value) / 2
}

pub fn max_profit(inventory: Vec<i32>, orders: i32) -> i32 {
const MODULUS: u64 = 1_000_000_007;

let mut orders = orders as u32;
let mut count_counts = HashMap::<u32, u32>::new();

for count in inventory {
*count_counts.entry(count as _).or_default() += 1;
}

let mut queue = count_counts
.into_iter()
.map(|(count, count_count)| Item { count, count_count })
.collect::<BinaryHeap<_>>();

let mut result = 0_u64;
let mut max_item_1 = queue.pop().unwrap();

while let Some(mut max_item_2) = queue.pop() {
let available = u64::from(max_item_1.count - max_item_2.count) * u64::from(max_item_1.count_count);

if available < u64::from(orders) {
result += Self::sum(max_item_2.count + 1, max_item_1.count) * u64::from(max_item_1.count_count);
result %= MODULUS;

orders -= available as u32;
max_item_2.count_count += max_item_1.count_count;

max_item_1 = max_item_2;
} else {
break;
}
}

let full_cycles = orders / max_item_1.count_count;
let remainder = orders % max_item_1.count_count;
let min_value = max_item_1.count - full_cycles;

result += Self::sum(min_value + 1, max_item_1.count) * u64::from(max_item_1.count_count);
result += u64::from(min_value) * u64::from(remainder);
result %= MODULUS;

result as _
}
}

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

impl super::Solution for Solution {
fn max_profit(inventory: Vec<i32>, orders: i32) -> i32 {
Self::max_profit(inventory, orders)
}
}

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

#[test]
fn test_item_partial_eq() {
assert!(
Item {
count: 2,
count_count: 3
} == Item {
count: 2,
count_count: 5
}
);
}

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

pub trait Solution {
fn max_profit(inventory: Vec<i32>, orders: i32) -> i32;
}

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

pub fn run<S: Solution>() {
let test_cases = [
((&[2, 5] as &[_], 4), 14),
((&[3, 5], 6), 19),
((&[2, 8, 4, 10, 6], 20), 110),
];

for ((inventory, orders), expected) in test_cases {
assert_eq!(S::max_profit(inventory.to_vec(), orders), expected);
}
}
}

0 comments on commit ae3d4b6

Please sign in to comment.