rustgym 0.2.0

rustgym solutions
Documentation
use std::collections::BTreeMap;
use std::collections::HashMap;

#[derive(Default, Debug)]
struct Leaderboard {
    players: HashMap<i32, i32>,
    scores: BTreeMap<i32, usize>,
}

impl Leaderboard {
    fn new() -> Self {
        Leaderboard::default()
    }

    fn add_score(&mut self, player_id: i32, score: i32) {
        let player_score = self.players.entry(player_id).or_default();
        if *player_score != 0 {
            let count = self.scores.entry(*player_score).or_default();
            *count -= 1;
            if *count == 0 {
                self.scores.remove(player_score);
            }
        }
        *player_score += score;
        *self.scores.entry(*player_score).or_default() += 1;
    }

    fn top(&mut self, mut k: i32) -> i32 {
        let mut sum = 0;
        for (s, &v) in self.scores.iter().rev() {
            for _ in 0..v {
                sum += s;
                k -= 1;
                if k == 0 {
                    return sum;
                }
            }
        }
        0
    }

    fn reset(&mut self, player_id: i32) {
        let player_score = self.players.entry(player_id).or_default();
        let count = self.scores.entry(*player_score).or_default();
        *count -= 1;
        if *count == 0 {
            self.scores.remove(player_score);
        }
        *player_score = 0;
    }
}

#[test]
fn test() {
    let mut obj = Leaderboard::new();
    obj.add_score(1, 73);
    obj.add_score(2, 56);
    obj.add_score(3, 39);
    obj.add_score(4, 51);
    obj.add_score(5, 4);
    assert_eq!(obj.top(1), 73);
    obj.reset(1);
    obj.reset(2);
    obj.add_score(2, 51);
    assert_eq!(obj.top(3), 141);
}