Search code examples
rubyarraysalgorithmsortingcoupling

Fast Ruby method / algorithm to pair elements of two arrays


I have two sorted arrays of float numbers (usually 800-1500 elements), size of the two arrays can be different by +-20-30 %. I am looking for a fast method which pick a correspondent pair of all elements of the smaller array from the elements of the biggest array on the basis of minimal difference.

Currently I am using this

def get_pairs(ary1,ary2)
  if ary1.size<ary2.size then
    smaller=ary1;bigger=ary2
  else
    smaller=ary2;bigger=ary1;
  end
  p=Array.new(smaller.size)
  smaller.each_with_index do |z,i|
     pair=bigger.min_by{|elem| (elem-z).abs}
     p[i]=[z, pair]
  end
  return p
end

This is the key element of my program, it is called very often and unfortunately it is too slow for me.


Solution

  • The problem with using min_by is that you have to iterate over every single element of bigger for each element of smaller. Try breaking early once you've found the pair with lowest difference.

    def get_pairs(a, b)
      smaller, bigger = [a, b].map(&:sort).sort_by(&:length)
    
      smaller.map do |x|
        lowest_diff = nil
        lowest_element = nil
    
        bigger.each_with_index do |y, i|
          diff = (x - y).abs
    
          if lowest_diff.nil? || diff < lowest_diff
            lowest_diff = diff
            lowest_element = y
          elsif diff > lowest_diff || y == bigger.last
            break [x, lowest_element]
          end
        end
      end
    end