Summing an array
activesupport, arrays, ruby
Solution
`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`.
Problem
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 ```