Search code examples
javascriptalgorithmperformance

MaxCounters (lesson 4 in codility) - 100% correctness but 60% on efficiency, why?


Link to the problem

In a nutshell:

  • N is an integer that represents a number of counters and the max counter allowed;
  • A is an array that represents the operation done on a specific counter (for example, if A[0] is 1 and N is 3, we need to add 1 to counter[0]);
  • If an element in A is N+1, all elements of the counter should be changed to the largest number in the counter array.

I submitted the code I wrote and got only 60% in performance. Why is that? Any way I should approach a problem next time to make it more efficient? How can I improve?

function solution(N,A){

    let counters = Array(N).fill(0);
    let maxCounter = 0;
    for(i=0;i<A.length;i++){
        if(A[i]<=N){
            counters[A[i]-1]++
            if(counters[A[i]-1]>maxCounter){maxCounter = counters[A[i]-1]};
        }
        else if(A[i]===N+1){
            counters = Array(N).fill(maxCounter)
        }
    }
    return counters
}

Edit: I didn't know that this website wasn't meant for questions regarding code improvement, thanks, I will ask somewhere else.


Solution

  • The 60% score for efficiency is because of the two last test cases where over 10,000 "max counter" operations get performed. https://app.codility.com/demo/results/trainingA86B4F-NDB/

    Each of those operations has to iterate through the counter array, which may have as many as 100,000 elements. That works out to a total of 1 billion writes, so the reason for the performance problem comes quickly in sight.

    To improve this and bring this number down, we can eliminate the needless consecutive "max counter" operations by, for example, introducing a flag denoting whether the counter array is already maxed and there is no need to iterate through it all over again.

    Sample code:

    const solution = (n, arr) => {
      const counter = new Array(n).fill(0);
      let max = 0, counterMaxed = false;
    
      for (let curr of arr) {
        if (curr > n) {
          if (!counterMaxed) { counter.fill(max); counterMaxed = true; }
          continue;
        }
    
        curr--; counter[curr]++; counterMaxed = false;
        if (counter[curr] > max) { max = counter[curr]; }
      }
    
      return counter;
    };
    

    This gets a straight 100% score:
    https://app.codility.com/demo/results/training3H48RM-6EG/