Supermarket Queue

Photo by sq lim on Unsplash

Supermarket Queue

·

3 min read

function queueTime(customers, n) {
  let tills = Array(n).fill(0);
  for (let i = 0; i < customers.length; i++) {
    let idx = tills.indexOf(Math.min(...tills));
    tills[idx] += customers[i];
  }
  return Math.max(...tills);
}
  let tills = Array(n).fill(0);

Here we're creating an array called tills, which is going to represent each checkout till in the supermarket. The array is filled with zeroes, because in the beginning, no till has any customers, so they are all idle (which is represented by zero).

    let idx = tills.indexOf(Math.min(...tills));

In this line, you're trying to figure out which checkout till will be free the soonest. Imagine you're looking at a screen that shows how many minutes until each till is free. You find the till with the smallest number -- the one that will be free the soonest. This is what Math.min(...tills) is doing. The ... operator (spread operator) is used to pass all elements of tills array to the Math.min function, which finds the smallest number in the array.

But knowing that the soonest free till is, for example, "2 minutes until free" isn't enough -- you need to know which till that is. You might have Till #1 with 3 minutes until free, Till #2 with 5 minutes, and Till #3 with 2 minutes. You want to point at Till #3 and say, "That's the one." This is what tills.indexOf() does. It finds the position (also known as the index) of that soonest free till in the tills array. The idx variable is like your finger pointing at that till.

tills[idx] += customers[i];

In this line, you're assigning a customer to a till. You look at your list of customers and take the next one in line. You see how much time this customer will take to check out (this is customers[i] -- the i is your place in the customer line). Then you walk over to the till you pointed at before (the idx till), and tell that till, "You're going to help this customer next."

Imagine a scenario where you're assigning tasks to your assistants. If Assistant #1 already has 2 tasks to do, and you assign them another 3 tasks, you'd say Assistant #1 now has 2 + 3 = 5 tasks to do. Similarly, tills[idx] += customers[i]; is adding the new customer's checkout time (the new task) to the current till's total time (the current tasks).

Here's what each part does:

  1. tills[idx] is getting the current total time for the till at index idx.

  2. customers[i] is the time it will take for the i-th customer to check out.

  3. += is adding the customer's checkout time to the till's total time.

After this line runs, the till at index idx has an updated total time that includes the time for the i-th customer to check out.

So if tills[idx] was 2 (meaning that the till at index idx will be free in 2 minutes), and customers[i] is 4 (meaning that the next customer in line will take 4 minutes to check out), then tills[idx] += customers[i]; will update tills[idx] to be 2 + 4 = 6. Now the till at index idx won't be free for 6 minutes. This is because the += operator adds the right side (customers[i]) to the left side (tills[idx]) and assigns the result back to the left side (tills[idx]).

After all customers have been allocated to tills, the checkout process continues until the customer at the till with the longest queue finishes. The time at which this happens is the total time required for all customers to check out.