arraysrubymethodsevent-simulation

ruby - calculating time in supermarket queue


So suppose there is a queue for the self-checkout tills at the supermarket. I'm trying to write a function to calculate the total time required for all the customers to check out!

Input:

customers: an array of positive integers representing the queue. Each integer represents a customer, and its value is the amount of time they require to check out.

n: a positive integer, the number of checkout tills.

Output:

The function should return an integer, the total time required. Examples:

queue_time([5,3,4], 1)
# should return 12
# because when n=1, the total time is just the sum of the times

queue_time([10,2,3,3], 2)
# should return 10
# because here n=2 and the 2nd, 3rd, and 4th people in the 
# queue finish before the 1st person has finished.

queue_time([2,3,10], 2)
# should return 12

There is only ONE queue serving many tills, and the order of the queue NEVER changes. The front person in the queue (first element in the array/list) proceeds to a till as soon as it's free. I tried this, but it doesn't work correctly, I'm not sure how to make the next person go into till when it's open.

def queue_time(customers, n)
  if customers == []
    n=0
  else
    x= customers.reduce(:+) / n 
    if x < customers.max
      customers.max
    else 
      x
    end
  end
end

For example, testing for

customers = [751, 304, 2, 629, 36, 674, 1] 
n = 2
expected: 1461, instead got: 1198

. Thanks :-)


Solution

  • Given an input of:

    customers = [751, 304, 2, 629, 36, 674, 1]
    n = 2
    

    You could create an array of tills: (each one is an array itself)

    tills = Array.new(n) { [] }
    #=> [[], []]
    

    Now, for each customer, you add its value to the shortest till:

    customers.each do |customer|
      tills.min_by(&:sum) << customer
    end
    

    In the end, this gives you:

    tills
    #=> [[751, 36, 674], [304, 2, 629, 1]]
    

    The first one has a sum of 1,461.