The Supermarket Queue - Javascript Best Practice Solution

Viewed 2789

On my travel on learning basic javascript, I have come across the Code Wars Website, which confronts one with different problems. I'm very new to JavaScript development and Code Wars has been of major help in understanding the basic js logic, by studying the best practice solutions for those problems and trying to reconstruct and understand them. With the help of google, youtube etc. I have managed to understand most of the best practice solutions and it has helped me to further my understanding of javascript, although I have now come across a Problem - and a best practice solution - but I just can't wrap my head around its logic and how it works. I'd be very thankful to anyone that could explain the best practice solution in words for dummies.

Problem: There is a queue for the self-checkout tills at the supermarket. Your task is to write a function to calculate the total time required for all the customers to check out! All instructions can be found on the CodeWars Page: https://www.codewars.com/kata/57b06f90e298a7b53d000a86/train/javascript

The best practice solution looks like this:

function queueTime(customers, n) {
  var w = new Array(n).fill(0);
  for (let t of customers) {
    let idx = w.indexOf(Math.min(...w));
    w[idx] += t;
    
  }
  return Math.max(...w);
}

Sample Test:

Test.describe("example tests", function() {
Test.assertEquals(queueTime([], 1), 0);
Test.assertEquals(queueTime([1,2,3,4], 1), 10);
Test.assertEquals(queueTime([2,2,3,3,4,4], 2), 9);
Test.assertEquals(queueTime([1,2,3,4,5], 100), 5);

//add some more example tests here, if you like

})

The main struggle I am having is that I dont understand how the 'w' variable interacts with the 'for of' function. In my understanding, 'w' is an Array filled with zeros, so how does the w.indexOf Method find a min. value to add to idx variable? In general I would be very thankful for anyone that could breakdown the best practice solution.

Thanks, Jerome

2 Answers

Initially w is an array filled with 0s

The code then sets idx to the index of the lowest value.

First time that index would be 0

let idx = [0,0,0,0,0].indexOf(Math.min([0,0,0,0,0])); // 0

So w[0] += t becomes [1,0,0,0,0] for t === 1

next time:

let idx = [1,0,0,0,0].indexOf(Math.min([1,0,0,0,0])); // 1

So w[1] += t becomes [1,2,0,0,0] for t === 2

and so on

Here's the same solution re-written for better readability, with comments to explain each step.

function queueTime(customers, n) {
  // creates an array of length n representing the tills
  // Each till is given a value of 0 to represent initial waitTime before the queue begins.
  const tills = new Array(n).fill(0);
  // goes through the queue of customer waitTimes
  for (let waitTime of customers) {
    // finds the till with the least wait time on it, adds the next customer's time to it
    const lowestWaitTill = tills.indexOf(Math.min(...tills));
    tills[lowestWaitTill] += waitTime;
  }
  // end result is that the waitTimes (load) on the tills are distributed optimally. 
  // The waitTime of the till with the heaviest load represents the total time taken
  return Math.max(...tills);
}

To address your question about "w" and "for of" loop:

In this code the "w" is renamed as tills. Each index in the tills array represents a checkout till. idx is renamed as "lowestWaitTime" and represents the index of the till that has the least load.

Within the for..of loop, the till (index) with the least load (0 initially, as they're all initially 0) is found on this line const lowestWaitTill = tills.indexOf(Math.min(...tills));

Math.min(...tills)); uses spread operator syntax to iterate through the array of tills and returns the lowest value it finds, which in this case is the lowest wait time of any till. tills.indexOf() returns the first index containing the value passed to it, which in this case will be the index of the till with the least load (customer wait time assigned to it).

So, now what we know which till has the least load, we add the current customer's wait time to that till. Then we move to the next customer and repeat, until there are no customers left.

Related