The code below passed tests on Ruby 1.8/1.9, but when I run these tests on Ruby 1.9.2, I'm getting no method errors for Array#sum. For example,
NoMethodError: undefined method `sum' for [3.2, 3.0, 1.5, 0.73, 0.47, 0.23]:Array
I came across inject(:+), but when I tried to substitute it in where sum was, it created other problems. There's two methods where sum is used, time_required and balance_queues. In the second method, it was complicated to work it into the old code q1.sum - q2.sum. As much detail/explanation would be helpful.
class FairDistribution
def initialize(jobs, num_of_queues)
@queues = [ jobs.sort.reverse ]
(num_of_queues - 1).times { @queues << [] }
# Balance the queues until they are perfectly balanced
while !balance_all_queues do; end
end
# Time required for all queues processing
def time_required
@queues.map { |q| q.sum }.max #SUM
end
# The actual distribution of jobs across the queues
def distribution
@queues
end
private
# Runs through all queues and balances them against each other.
# Makes one pass only and returns FALSE if there was nothing changed
# during the pass.
def balance_all_queues
updated = false
@queues.each_with_index do |q1, qi1|
(qi1+1 ... @queues.size).each do |qi2|
res = balance_queues(q1, @queues[qi2])
updated ||= res
end
end
return !updated
end
# Balances the two queues between themselves by finding the best possible
# swap of jobs between them. If there's nothing to be improved, returns FALSE.
def balance_queues(q1, q2)
delta = q1.sum - q2.sum #SUM
return false if delta == 0
best_swap = nil
best_swap_delta = delta.abs
q1.each_combination do |c1|
best_swap, best_swap_delta = choose_better_swap(c1, [], delta, best_swap, best_swap_delta)
q2.each_combination do |c2|
best_swap, best_swap_delta = choose_better_swap(c1, c2, delta, best_swap, best_swap_delta)
end
end
best_swap.apply(q1, q2) unless best_swap.nil?
return !best_swap.nil?
end
# Sees if the swap we have at hand is better than our current best
# swap and replaces the latest if it is.
def choose_better_swap(c1, c2, delta, best_swap, best_swap_delta)
unless c1 == c2
s = Swap.new(c1, c2, delta)
best_swap, best_swap_delta = s, s.delta if s.delta < best_swap_delta
end
return best_swap, best_swap_delta
end
end
Enumerable#sum is provided by ActiveSupport (part of Ruby on Rails). If you have the active_support gem installed, you can use [].sum by adding this to the top of your script:
require 'active_support/core_ext/enumerable'
Try using .inject(0, :+). This will result in '0' for an empty array, and might have been the cause of your problems with inject.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With