matt batista    about    contact    archive    feed

coding challenge => You have an array of integers, and for each index you want to find the product of every integer except the integer at that index.

#####That title is a mouthful; say it 5x fast…go. Jk. Below is how I went about solving this Q, written lovingly in Ruby.


Here’s the skinny: we are gonna’ need to write a function/method that takes in an array of integers for the argument and returns an array of the products (those integers multiplied with each other).

What really helps me is knowing what the expected output is going to look like when this method returns from doing its thing. What this question wants is something along these lines:

1
2
3
4
5
6
7
8
9
10
# Imagine this is what we start with
[2, 6, 3, 5]

# This is what the method should return
# Order doesn't matter here, as long as the array
# has these values
[36, 60, 30, 90]

# The method gets there by calculating this
[6*3*5, 2*3*5, 2*6*5, 2*6*3]

Feast them eyes on my solution. Don’t worry if this looks cray cray or confusing, I’ll explain it all the best I can. I also used long and descriptive variable names so others can quickly figure out what’s going on with the code. When I refer to line #’s, use the code snippet below.



1
2
3
4
5
6
7
8
9
def get_product_of_all_ints_except_at_index(start_array)
  final_array_of_products = []
  num_of_combos_needed = (start_array.length - 1)
  all_combos = start_array.combination(num_of_combos_needed).to_a

  all_combos.each { |combo| final_array_of_products << combo.reduce(:*) }

  final_array_of_products
end



I knew that I was going to have to iterate through the start_array. But how? Was I going to use Enumerable#each_with_index? Sounds reasonable. Got me thinking though: I need combinations. That’s the key to this problem.

Does the Array class have something already baked in to help with combinations? Does the Enumerable class?

Using Google-Fu, I came across this from the Ruby Documentation: Array#Combination. Like, omg. That’s exactly the type of behavior I want. It even has helpful examples on how to use it: noice!

1
2
3
4
5
6
# From Ruby Docs
a = [1, 2, 3, 4]
a.combination(1).to_a  #=> [[1],[2],[3],[4]]
a.combination(2).to_a  #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
a.combination(3).to_a  #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
a.combination(4).to_a  #=> [[1,2,3,4]]

I know I needed a combination of three (since we’re starting with 4 elements in the array), but what if the initial start_array has more integer elements inside it besides 4? Wouldn’t it be neat-o if, in the future, we can supply this method with an array of ANY amount of integers AND have it return what we expect?!

1
2
# Boom! Now we'll get just the right amount of combinations
num_of_combos_needed = (start_array.length - 1)

Stepping through the get_product_of_all_ints_except_at_index method so far, I first declared the variable final_array_of_products which references an empty array (I’ll use this later). Then line 3 takes the start_array’s length and subtracts 1 so we will always get the perfect amount of combinations; that value is referenced via the num_of_combos_needed variable.

On line 4, the start_array calls the combination method, supplies it with the variable num_of_combos_needed, which works its lovely combo magic, and finally there’s the to_a call at the end.

What to_a does is convert the calling object (in our case start_array) to an array. If we didn’t have that conversion to an array, the return value of the combination method is an Enumerable object and that just won’t cut the mustard. All of that is then referenced too via the all_combos variable.

1
2
# 'all_combos' will now reference [[2, 6, 3], [2, 6, 5], [2, 3, 5], [6, 3, 5]]
all_combos = start_array.combination(num_of_combos_needed).to_a

What we have now with the all_combos variable is 1 outer array with 4 little arrays inside it. On line 6, I iterate through those 4 little arrays and use Ruby’s helpful Enumerable method reduce on each little array.

What does the reduce method do? Always, always check the ruby documentation. It has everything you need, especially helpful examples.

1
all_combos.each { |combo| final_array_of_products << combo.reduce(:*) }

The above code is saying “Yo, for every little array inside of all_combos, multiply all the elements into one number via reduce, and then push that number into the final_array_of_products array via the << (shovel) operator.”

Finally, on line 8, we have the get_product_of_all_ints_except_at_index method return final_array_of_products variable which references that once empty array with 4 numbers inside.

1
2
# This gets returned from the method when the dust settles
final_array_of_products  # => [36, 60, 30, 90]

Hope this helps. Stay turnt.