Design A Leaderboard in C++

C++Server Side ProgrammingProgramming

Suppose we have to design a Leaderboard class, there are three different functions −

  • addScore(playerId, score) − This will update the leaderboard by adding score to the given player's score. When there is no such player with given id in the leaderboard, add him to the leaderboard with the given score.
  • top(K) − This will return the score sum of the top K players.
  • reset(playerId) − This will reset the score of the player with the given id to 0. It is guaranteed that the player was added to the leaderboard before calling this function.

Initially, the leaderboard should empty.

If we perform the operations like below −

  • Leaderboard leaderboard = new Leaderboard ();
  • leaderboard.addScore(1,73); // leaderboard is [[1,73]];
  • leaderboard.addScore(2,56); // leaderboard is [[1,73],[2,56]];
  • leaderboard.addScore(3,39); // leaderboard is [[1,73],[2,56],[3,39]];
  • leaderboard.addScore(4,51); // leaderboard is [[1,73],[2,56],[3,39],[4,51]];
  • leaderboard.addScore(5,4); // leaderboard is [[1,73],[2,56],[3,39],[4,51],[5,4]];
  • leaderboard.top(1); // returns 73;
  • leaderboard.reset(1); // leaderboard is [[2,56],[3,39],[4,51],[5,4]];
  • leaderboard.reset(2); // leaderboard is [[3,39],[4,51],[5,4]];
  • leaderboard.addScore(2,51); // leaderboard is [[2,51],[3,39],[4,51],[5,4]];
  • leaderboard.top(3); // returns 141 = 51 + 51 + 39;

To solve this, we will follow these steps −

  • Define a priority queue of integer pairs called pq, make one map of int type keys and int type values m. For the initialization, it will clear the map, and if queue is not empty, delete all elements from the queue.
  • The addScore() method will be like −
    • if playerId is present, then m[playerId] := m[playerId] + score
    • insert a pair (m[playerId], playerId) into pq
    • otherwise m[playerId] = score
  • The top() method will be like
  • make a vector of pairs temp, set sum := 0
  • while k is not 0
    • curr := top of pq, delete from pq
    • if m[second value of curr pair] = first value of curr pair
      • decrease k by 1
      • sum := sum + first value of curr
      • insert curr into temp
  • for i in range 0 to size of temp
    • insert temp[i] into pq
  • The reset() function will be like −
    • m[playerId] = 0

Example(C++)

Let us see the following implementation to get a better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Leaderboard {
public:
   priority_queue< pair <int,int> > pq;
   map < int, int > m;
   Leaderboard() {
      m.clear();
      while(!pq.empty())pq.pop();
   }
   void addScore(int playerId, int score) {
      if(m.find(playerId)!=m.end()){
         m[playerId] += score;
      }
      else m[playerId] = score;;
         pq.push({m[playerId], playerId});
   }
   int top(int k) {
      vector < pair <int,int> > temp;
      int sum = 0;
      while(k){
         pair <int, int> curr = pq.top();
         pq.pop();
         if(m[curr.second] == curr.first){
            k--;
            sum += curr.first;
            temp.push_back(curr);
         }
      }
      for(int i = 0; i < temp.size(); i++)pq.push(temp[i]);
      return sum;
   }
   void reset(int playerId) {
      m[playerId] = 0;
   }
};
main(){
   Leaderboard ob;
   ob.addScore(1,73);
   ob.addScore(2,56);
   ob.addScore(3,39);
   ob.addScore(4,51);
   ob.addScore(5,4);
   cout <<ob.top(1) << endl;
   ob.reset(1);
   ob.reset(2);
   ob.addScore(2,51);
   cout <<ob.top(2) << endl;
}

Input

Initialize leader board then use the functions to see different results. See the main() function

Output

73
102
raja
Published on 17-Mar-2020 15:59:37
Advertisements